summaryrefslogtreecommitdiff
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.h212
1 files changed, 50 insertions, 162 deletions
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 9204099cb..4b9cff5ad 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -109,13 +109,7 @@ namespace JSC {
public:
typedef JSCell Base;
- static size_t allocationSize(size_t inlineCapacity)
- {
- return sizeof(JSObject) + inlineCapacity * sizeof(WriteBarrierBase<Unknown>);
- }
-
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&);
JS_EXPORT_PRIVATE static String className(const JSObject*);
@@ -154,9 +148,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return 0;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->publicLength();
+ return m_butterfly->arrayStorage()->length();
default:
ASSERT_NOT_REACHED();
return 0;
@@ -168,9 +161,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return 0;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->vectorLength();
+ return m_butterfly->arrayStorage()->vectorLength();
default:
ASSERT_NOT_REACHED();
return 0;
@@ -215,8 +207,6 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return i < m_butterfly->vectorLength() && m_butterfly->contiguous()[i];
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i];
default:
@@ -228,8 +218,6 @@ namespace JSC {
JSValue getIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->contiguous()[i].get();
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_vector[i].get();
default:
@@ -243,13 +231,12 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- if (i < m_butterfly->publicLength())
- return m_butterfly->contiguous()[i].get();
- break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- if (i < m_butterfly->arrayStorage()->vectorLength())
- return m_butterfly->arrayStorage()->m_vector[i].get();
+ if (i < m_butterfly->arrayStorage()->vectorLength()) {
+ JSValue v = m_butterfly->arrayStorage()->m_vector[i].get();
+ if (v)
+ return v;
+ }
break;
default:
ASSERT_NOT_REACHED();
@@ -280,10 +267,9 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage:
- return i < m_butterfly->vectorLength();
+ return i < m_butterfly->arrayStorage()->vectorLength();
case NonArrayWithSlowPutArrayStorage:
case ArrayWithSlowPutArrayStorage:
return i < m_butterfly->arrayStorage()->vectorLength()
@@ -299,9 +285,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return i < m_butterfly->vectorLength();
+ return i < m_butterfly->arrayStorage()->vectorLength();
default:
ASSERT_NOT_REACHED();
return false;
@@ -311,23 +296,15 @@ namespace JSC {
void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
- if (i >= m_butterfly->publicLength())
- m_butterfly->setPublicLength(i + 1);
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
- ArrayStorage* storage = m_butterfly->arrayStorage();
- WriteBarrier<Unknown>& x = storage->m_vector[i];
- JSValue old = x.get();
- x.set(globalData, this, v);
- if (!old) {
+ WriteBarrier<Unknown>& x = m_butterfly->arrayStorage()->m_vector[i];
+ if (!x) {
+ ArrayStorage* storage = m_butterfly->arrayStorage();
++storage->m_numValuesInVector;
if (i >= storage->length())
storage->setLength(i + 1);
}
+ x.set(globalData, this, v);
break;
}
default:
@@ -338,12 +315,6 @@ namespace JSC {
void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->publicLength());
- ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
ASSERT(i < storage->length());
@@ -356,25 +327,10 @@ namespace JSC {
}
}
- bool hasSparseMap()
- {
- switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return false;
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_sparseMap;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
- }
-
bool inSparseIndexingMode()
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
return false;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->inSparseMode();
@@ -492,10 +448,10 @@ namespace JSC {
{
PropertyOffset result;
size_t offsetInInlineStorage = location - inlineStorageUnsafe();
- if (offsetInInlineStorage < static_cast<size_t>(firstOutOfLineOffset))
+ if (offsetInInlineStorage < static_cast<size_t>(inlineStorageCapacity))
result = offsetInInlineStorage;
else
- result = outOfLineStorage() - location + (firstOutOfLineOffset - 1);
+ result = outOfLineStorage() - location + (inlineStorageCapacity - 1);
validateOffset(result, structure()->typeInfo().type());
return result;
}
@@ -525,7 +481,7 @@ namespace JSC {
bool isNameScopeObject() const;
bool isActivationObject() const;
bool isErrorInstance() const;
- bool isProxy() const;
+ bool isGlobalThis() const;
void seal(JSGlobalData&);
void freeze(JSGlobalData&);
@@ -572,34 +528,23 @@ namespace JSC {
// foo->attemptToInterceptPutByIndexOnHole(...);
bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow);
- // Returns 0 if contiguous storage cannot be created - either because
- // indexing should be sparse or because we're having a bad time.
- WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData)
- {
- if (LIKELY(hasContiguous(structure()->indexingType())))
- return m_butterfly->contiguous();
-
- return ensureContiguousSlow(globalData);
- }
-
// Ensure that the object is in a mode where it has array storage. Use
// this if you're about to perform actions that would have required the
// object to be converted to have array storage, if it didn't have it
// already.
ArrayStorage* ensureArrayStorage(JSGlobalData& globalData)
{
- if (LIKELY(hasArrayStorage(structure()->indexingType())))
+ switch (structure()->indexingType()) {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage();
-
- return ensureArrayStorageSlow(globalData);
- }
-
- Butterfly* ensureIndexedStorage(JSGlobalData& globalData)
- {
- if (LIKELY(hasIndexedProperties(structure()->indexingType())))
- return m_butterfly;
-
- return ensureIndexedStorageSlow(globalData);
+
+ case ALL_BLANK_INDEXING_TYPES:
+ return createInitialArrayStorage(globalData);
+
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
static size_t offsetOfInlineStorage();
@@ -640,7 +585,6 @@ namespace JSC {
void resetInheritorID(JSGlobalData&);
void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize);
- void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize);
// Call this if you know that the object is in a mode where it has array
// storage. This will assert otherwise.
@@ -665,16 +609,11 @@ namespace JSC {
ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength);
ArrayStorage* createInitialArrayStorage(JSGlobalData&);
- WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&);
ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&);
bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
- void putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState*, unsigned propertyName, JSValue);
void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*);
bool increaseVectorLength(JSGlobalData&, unsigned newLength);
@@ -685,56 +624,6 @@ namespace JSC {
void notifyPresenceOfIndexedAccessors(JSGlobalData&);
bool attemptToInterceptPutByIndexOnHole(ExecState*, unsigned index, JSValue, bool shouldThrow);
-
- // Call this if you want setIndexQuickly to succeed and you're sure that
- // the array is contiguous.
- void ensureContiguousLength(JSGlobalData& globalData, unsigned length)
- {
- ASSERT(length < MAX_ARRAY_INDEX);
- ASSERT(hasContiguous(structure()->indexingType()));
-
- if (m_butterfly->vectorLength() < length)
- ensureContiguousLengthSlow(globalData, length);
-
- if (m_butterfly->publicLength() < length)
- m_butterfly->setPublicLength(length);
- }
-
- unsigned countElementsInContiguous(Butterfly*);
-
- template<IndexingType indexingType>
- WriteBarrier<Unknown>* indexingData()
- {
- switch (indexingType) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->contiguous();
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_vector;
-
- default:
- CRASH();
- return 0;
- }
- }
-
- template<IndexingType indexingType>
- unsigned relevantLength()
- {
- switch (indexingType) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->publicLength();
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return std::min(
- m_butterfly->arrayStorage()->length(),
- m_butterfly->arrayStorage()->vectorLength());
-
- default:
- CRASH();
- return 0;
- }
- }
private:
friend class LLIntOffsetsExtractor;
@@ -769,12 +658,6 @@ namespace JSC {
JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&);
- void ensureContiguousLengthSlow(JSGlobalData&, unsigned length);
-
- WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&);
- ArrayStorage* ensureArrayStorageSlow(JSGlobalData&);
- Butterfly* ensureIndexedStorageSlow(JSGlobalData&);
-
protected:
Butterfly* m_butterfly;
};
@@ -794,6 +677,11 @@ namespace JSC {
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
+ static bool hasInlineStorage()
+ {
+ return false;
+ }
+
protected:
explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0)
: JSObject(globalData, structure, butterfly)
@@ -821,43 +709,45 @@ namespace JSC {
static JSFinalObject* create(ExecState*, Structure*);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info, NonArray, INLINE_STORAGE_CAPACITY);
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info);
}
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
static JS_EXPORTDATA const ClassInfo s_info;
+ static bool hasInlineStorage()
+ {
+ return true;
+ }
protected:
void visitChildrenCommon(SlotVisitor&);
void finishCreation(JSGlobalData& globalData)
{
Base::finishCreation(globalData);
- ASSERT(structure()->totalStorageCapacity() == structure()->inlineCapacity());
+ ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double)));
+ ASSERT(this->structure()->inlineCapacity() == static_cast<unsigned>(inlineStorageCapacity));
+ ASSERT(this->structure()->totalStorageCapacity() == static_cast<unsigned>(inlineStorageCapacity));
ASSERT(classInfo());
}
private:
friend class LLIntOffsetsExtractor;
-
+
explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
: JSObject(globalData, structure)
{
}
static const unsigned StructureFlags = JSObject::StructureFlags;
+
+ WriteBarrierBase<Unknown> m_inlineStorage[INLINE_STORAGE_CAPACITY];
};
inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
{
- JSFinalObject* finalObject = new (
- NotNull,
- allocateCell<JSFinalObject>(
- *exec->heap(),
- allocationSize(structure->inlineCapacity())
- )
- ) JSFinalObject(exec->globalData(), structure);
+ JSFinalObject* finalObject = new (NotNull, allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure);
finalObject->finishCreation(exec->globalData());
return finalObject;
}
@@ -874,7 +764,7 @@ inline bool isJSFinalObject(JSValue value)
inline size_t JSObject::offsetOfInlineStorage()
{
- return sizeof(JSObject);
+ return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
}
inline bool JSObject::isGlobalObject() const
@@ -902,9 +792,9 @@ inline bool JSObject::isErrorInstance() const
return structure()->typeInfo().type() == ErrorInstanceType;
}
-inline bool JSObject::isProxy() const
+inline bool JSObject::isGlobalThis() const
{
- return structure()->typeInfo().type() == ProxyType;
+ return structure()->typeInfo().type() == GlobalThisType;
}
inline void JSObject::setButterfly(JSGlobalData& globalData, Butterfly* butterfly, Structure* structure)
@@ -966,14 +856,14 @@ inline JSValue JSObject::prototype() const
return structure()->storedPrototype();
}
-inline const MethodTable* JSCell::methodTable() const
+inline bool JSCell::inherits(const ClassInfo* info) const
{
- return &classInfo()->methodTable;
+ return classInfo()->isSubClassOf(info);
}
-inline bool JSCell::inherits(const ClassInfo* info) const
+inline const MethodTable* JSCell::methodTable() const
{
- return classInfo()->isSubClassOf(info);
+ return &classInfo()->methodTable;
}
// this method is here to be after the inline declaration of JSCell::inherits
@@ -1367,8 +1257,6 @@ inline int offsetRelativeToBase(PropertyOffset offset)
return JSObject::offsetOfInlineStorage() + offsetInInlineStorage(offset) * sizeof(EncodedJSValue);
}
-COMPILE_ASSERT(!(sizeof(JSObject) % sizeof(WriteBarrierBase<Unknown>)), JSObject_inline_storage_has_correct_alignment);
-
} // namespace JSC
#endif // JSObject_h