summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/JSObject.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSObject.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h132
1 files changed, 70 insertions, 62 deletions
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 578b3cf..80735f8 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -29,7 +29,6 @@
#include "Completion.h"
#include "CallFrame.h"
#include "JSCell.h"
-#include "JSNumberCell.h"
#include "MarkStack.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
@@ -88,10 +87,10 @@ namespace JSC {
virtual ~JSObject();
JSValue prototype() const;
- void setPrototype(JSValue prototype);
- bool setPrototypeWithCycleCheck(JSValue prototype);
+ void setPrototype(JSGlobalData&, JSValue prototype);
+ bool setPrototypeWithCycleCheck(JSGlobalData&, JSValue prototype);
- void setStructure(NonNullPassRefPtr<Structure>);
+ void setStructure(JSGlobalData&, Structure*);
Structure* inheritorID(JSGlobalData&);
virtual UString className() const;
@@ -147,22 +146,22 @@ namespace JSC {
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
// This get function only looks at the property map.
- JSValue getDirect(const Identifier& propertyName) const
+ JSValue getDirect(JSGlobalData& globalData, const Identifier& propertyName) const
{
- size_t offset = m_structure->get(propertyName);
+ size_t offset = m_structure->get(globalData, propertyName);
return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
}
- WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName)
+ WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, const Identifier& propertyName)
{
- size_t offset = m_structure->get(propertyName);
+ size_t offset = m_structure->get(globalData, propertyName);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes)
{
JSCell* specificFunction;
- size_t offset = m_structure->get(propertyName, attributes, specificFunction);
+ size_t offset = m_structure->get(globalData, propertyName, attributes, specificFunction);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
@@ -171,9 +170,9 @@ namespace JSC {
return location - propertyStorage();
}
- void transitionTo(Structure*);
+ void transitionTo(JSGlobalData&, Structure*);
- void removeDirect(const Identifier& propertyName);
+ void removeDirect(JSGlobalData&, const Identifier& propertyName);
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
@@ -210,17 +209,17 @@ namespace JSC {
virtual bool isStrictModeFunction() const { return false; }
virtual bool isErrorInstance() const { return false; }
- void seal();
- void freeze();
- void preventExtensions();
- bool isSealed() { return m_structure->isSealed(); }
- bool isFrozen() { return m_structure->isFrozen(); }
+ void seal(JSGlobalData&);
+ void freeze(JSGlobalData&);
+ void preventExtensions(JSGlobalData&);
+ bool isSealed(JSGlobalData& globalData) { return m_structure->isSealed(globalData); }
+ bool isFrozen(JSGlobalData& globalData) { return m_structure->isFrozen(globalData); }
bool isExtensible() { return m_structure->isExtensible(); }
virtual ComplType exceptionType() const { return Throw; }
void allocatePropertyStorage(size_t oldSize, size_t newSize);
- bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
+ bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
static const unsigned baseExternalStorageCapacity = 16;
@@ -250,7 +249,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -264,7 +263,12 @@ namespace JSC {
// To instantiate objects you likely want JSFinalObject, below.
// To create derived types you likely want JSNonFinalObject, below.
- JSObject(NonNullPassRefPtr<Structure>, PropertyStorage inlineStorage);
+ JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
+ JSObject(VPtrStealingHackType, PropertyStorage inlineStorage)
+ : JSCell(VPtrStealingHack)
+ , m_propertyStorage(inlineStorage)
+ {
+ }
private:
// Nobody should ever ask any of these questions on something already known to be a JSObject.
@@ -299,7 +303,7 @@ namespace JSC {
Structure* createInheritorID(JSGlobalData&);
PropertyStorage m_propertyStorage;
- RefPtr<Structure> m_inheritorID;
+ WriteBarrier<Structure> m_inheritorID;
};
@@ -320,14 +324,19 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- explicit JSNonFinalObject(NonNullPassRefPtr<Structure> structure)
- : JSObject(structure, m_inlineStorage)
+ explicit JSNonFinalObject(VPtrStealingHackType)
+ : JSObject(VPtrStealingHack, m_inlineStorage)
+ {
+ }
+
+ explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure)
+ : JSObject(globalData, structure, m_inlineStorage)
{
ASSERT(!(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double)));
ASSERT(this->structure()->propertyStorageCapacity() == JSNonFinalObject_inlineStorageCapacity);
@@ -343,19 +352,19 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static JSFinalObject* create(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+ static JSFinalObject* create(ExecState* exec, Structure* structure)
{
- return new (exec) JSFinalObject(structure);
+ return new (exec) JSFinalObject(exec->globalData(), structure);
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
- explicit JSFinalObject(NonNullPassRefPtr<Structure> structure)
- : JSObject(structure, m_inlineStorage)
+ explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
+ : JSObject(globalData, structure, m_inlineStorage)
{
ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double) == 0);
ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity);
@@ -372,12 +381,12 @@ inline size_t JSObject::offsetOfInlineStorage()
return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
}
-inline JSObject* constructEmptyObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
{
return JSFinalObject::create(exec, structure);
}
-inline PassRefPtr<Structure> createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
+inline Structure* createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
{
return JSFinalObject::createStructure(globalData, prototype);
}
@@ -393,22 +402,22 @@ inline JSObject* asObject(JSValue value)
return asObject(value.asCell());
}
-inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure, PropertyStorage inlineStorage)
- : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
+inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, PropertyStorage inlineStorage)
+ : JSCell(globalData, structure)
, m_propertyStorage(inlineStorage)
{
ASSERT(inherits(&s_info));
ASSERT(m_structure->propertyStorageCapacity() < baseExternalStorageCapacity);
ASSERT(m_structure->isEmpty());
ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
+ ASSERT(static_cast<void*>(inlineStorage) == static_cast<void*>(this + 1));
+ ASSERT(m_structure->typeInfo().type() == ObjectType);
}
inline JSObject::~JSObject()
{
- ASSERT(m_structure);
if (!isUsingInlineStorage())
delete [] m_propertyStorage;
- m_structure->deref();
}
inline JSValue JSObject::prototype() const
@@ -416,7 +425,7 @@ inline JSValue JSObject::prototype() const
return m_structure->storedPrototype();
}
-inline bool JSObject::setPrototypeWithCycleCheck(JSValue prototype)
+inline bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
{
JSValue nextPrototypeValue = prototype;
while (nextPrototypeValue && nextPrototypeValue.isObject()) {
@@ -425,27 +434,27 @@ inline bool JSObject::setPrototypeWithCycleCheck(JSValue prototype)
return false;
nextPrototypeValue = nextPrototype->prototype();
}
- setPrototype(prototype);
+ setPrototype(globalData, prototype);
return true;
}
-inline void JSObject::setPrototype(JSValue prototype)
+inline void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
{
ASSERT(prototype);
- RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
- setStructure(newStructure.release());
+ setStructure(globalData, Structure::changePrototypeTransition(globalData, m_structure.get(), prototype));
}
-inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure)
+inline void JSObject::setStructure(JSGlobalData& globalData, Structure* structure)
{
- m_structure->deref();
- m_structure = structure.leakRef(); // ~JSObject balances this ref()
+ m_structure.set(globalData, this, structure);
}
inline Structure* JSObject::inheritorID(JSGlobalData& globalData)
{
- if (m_inheritorID)
+ if (m_inheritorID) {
+ ASSERT(m_inheritorID->isEmpty());
return m_inheritorID.get();
+ }
return createInheritorID(globalData);
}
@@ -471,7 +480,7 @@ inline bool JSValue::inherits(const ClassInfo* classInfo) const
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName)) {
+ if (WriteBarrierBase<Unknown>* location = getDirectLocation(exec->globalData(), propertyName)) {
if (m_structure->hasGetterSetterProperties() && location->isGetterSetter())
fillGetterPropertySlot(slot, location);
else
@@ -557,12 +566,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
if (m_structure->isDictionary()) {
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ size_t offset = m_structure->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
// If there is currently a specific function, and there now either isn't,
// or the new value is different, then despecify.
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
- m_structure->despecifyDictionaryFunction(propertyName);
+ m_structure->despecifyDictionaryFunction(globalData, propertyName);
if (checkReadOnly && currentAttributes & ReadOnly)
return false;
@@ -582,7 +591,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return false;
size_t currentCapacity = m_structure->propertyStorageCapacity();
- offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction);
+ offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
@@ -596,12 +605,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
size_t offset;
size_t currentCapacity = m_structure->propertyStorageCapacity();
- if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) {
+ if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(m_structure.get(), propertyName, attributes, specificFunction, offset)) {
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- setStructure(structure.release());
+ setStructure(globalData, structure);
putDirectOffset(globalData, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
@@ -612,7 +621,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ offset = m_structure->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
return false;
@@ -633,7 +642,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return true;
}
// case (2) Despecify, fall through to (3).
- setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
+ setStructure(globalData, Structure::despecifyFunctionTransition(globalData, m_structure.get(), propertyName));
}
// case (3) set the slot, do the put, return.
@@ -645,13 +654,13 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
if (!isExtensible())
return false;
- RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
+ Structure* structure = Structure::addPropertyTransition(globalData, m_structure.get(), propertyName, attributes, specificFunction, offset);
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- setStructure(structure.release());
+ setStructure(globalData, structure);
putDirectOffset(globalData, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
@@ -707,7 +716,7 @@ inline void JSObject::putDirectFunction(JSGlobalData& globalData, const Identifi
inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
size_t currentCapacity = m_structure->propertyStorageCapacity();
- size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0);
+ size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, 0);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
@@ -716,17 +725,17 @@ inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const
inline void JSObject::putDirectFunctionWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, JSCell* value, unsigned attributes)
{
size_t currentCapacity = m_structure->propertyStorageCapacity();
- size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value);
+ size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, value);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
}
-inline void JSObject::transitionTo(Structure* newStructure)
+inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure)
{
if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
- setStructure(newStructure);
+ setStructure(globalData, newStructure);
}
inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
@@ -814,13 +823,12 @@ inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
{
JSCell::markChildren(markStack);
-
- markStack.append(m_structure->storedPrototypeSlot());
- if (*m_structure->cachedPrototypeChainSlot())
- markStack.append(m_structure->cachedPrototypeChainSlot());
+
PropertyStorage storage = propertyStorage();
size_t storageSize = m_structure->propertyStorageSize();
markStack.appendValues(storage, storageSize);
+ if (m_inheritorID)
+ markStack.append(&m_inheritorID);
}
// --- JSValue inlines ----------------------------