diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
| commit | d6a599dbc9d824a462b2b206316e102bf8136446 (patch) | |
| tree | ecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/JavaScriptCore/runtime/JSObject.h | |
| parent | 3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff) | |
| download | qtwebkit-d6a599dbc9d824a462b2b206316e102bf8136446.tar.gz | |
Imported WebKit commit 8ff1f22783a32de82fee915abd55bd1b298f2644 (http://svn.webkit.org/repository/webkit/trunk@122325)
New snapshot that should work with the latest Qt build system changes
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSObject.h')
| -rw-r--r-- | Source/JavaScriptCore/runtime/JSObject.h | 290 |
1 files changed, 181 insertions, 109 deletions
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index fdb708dd9..9972d6077 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -79,10 +79,13 @@ namespace JSC { Accessor = 1 << 5, // property is a getter/setter }; + class JSFinalObject; + class JSObject : public JSCell { friend class BatchedTransitionOptimizer; friend class JIT; friend class JSCell; + friend class JSFinalObject; friend class MarkedBlock; JS_EXPORT_PRIVATE friend bool setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject*, PropertyName, PropertySlot&); @@ -161,26 +164,72 @@ namespace JSC { // This get function only looks at the property map. JSValue getDirect(JSGlobalData& globalData, PropertyName propertyName) const { - size_t offset = structure()->get(globalData, propertyName); - return offset != WTF::notFound ? getDirectOffset(offset) : JSValue(); + PropertyOffset offset = structure()->get(globalData, propertyName); + checkOffset(offset, structure()->typeInfo().type()); + return offset != invalidOffset ? getDirectOffset(offset) : JSValue(); } WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName) { - size_t offset = structure()->get(globalData, propertyName); - return offset != WTF::notFound ? locationForOffset(offset) : 0; + PropertyOffset offset = structure()->get(globalData, propertyName); + checkOffset(offset, structure()->typeInfo().type()); + return offset != invalidOffset ? locationForOffset(offset) : 0; } WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes) { JSCell* specificFunction; - size_t offset = structure()->get(globalData, propertyName, attributes, specificFunction); - return offset != WTF::notFound ? locationForOffset(offset) : 0; + PropertyOffset offset = structure()->get(globalData, propertyName, attributes, specificFunction); + return offset != invalidOffset ? locationForOffset(offset) : 0; } - size_t offsetForLocation(WriteBarrierBase<Unknown>* location) const + bool hasInlineStorage() const { return structure()->hasInlineStorage(); } + ConstPropertyStorage inlineStorageUnsafe() const + { + return bitwise_cast<ConstPropertyStorage>(this + 1); + } + PropertyStorage inlineStorageUnsafe() + { + return bitwise_cast<PropertyStorage>(this + 1); + } + ConstPropertyStorage inlineStorage() const + { + ASSERT(hasInlineStorage()); + return inlineStorageUnsafe(); + } + PropertyStorage inlineStorage() { - return location - propertyStorage(); + ASSERT(hasInlineStorage()); + return inlineStorageUnsafe(); + } + + ConstPropertyStorage outOfLineStorage() const { return m_outOfLineStorage.get(); } + PropertyStorage outOfLineStorage() { return m_outOfLineStorage.get(); } + + const WriteBarrierBase<Unknown>* locationForOffset(PropertyOffset offset) const + { + if (isInlineOffset(offset)) + return &inlineStorage()[offsetInInlineStorage(offset)]; + return &outOfLineStorage()[offsetInOutOfLineStorage(offset)]; + } + + WriteBarrierBase<Unknown>* locationForOffset(PropertyOffset offset) + { + if (isInlineOffset(offset)) + return &inlineStorage()[offsetInInlineStorage(offset)]; + return &outOfLineStorage()[offsetInOutOfLineStorage(offset)]; + } + + PropertyOffset offsetForLocation(WriteBarrierBase<Unknown>* location) const + { + PropertyOffset result; + size_t offsetInInlineStorage = location - inlineStorageUnsafe(); + if (offsetInInlineStorage < static_cast<size_t>(inlineStorageCapacity)) + result = offsetInInlineStorage; + else + result = location - outOfLineStorage() + firstOutOfLineOffset; + validateOffset(result, structure()->typeInfo().type()); + return result; } void transitionTo(JSGlobalData&, Structure*); @@ -197,9 +246,9 @@ namespace JSC { bool putOwnDataProperty(JSGlobalData&, PropertyName, JSValue, PutPropertySlot&); // Fast access to known property offsets. - JSValue getDirectOffset(size_t offset) const { return propertyStorage()[offset].get(); } - void putDirectOffset(JSGlobalData& globalData, size_t offset, JSValue value) { propertyStorage()[offset].set(globalData, this, value); } - void putUndefinedAtDirectOffset(size_t offset) { propertyStorage()[offset].setUndefined(); } + JSValue getDirectOffset(PropertyOffset offset) const { return locationForOffset(offset)->get(); } + void putDirectOffset(JSGlobalData& globalData, PropertyOffset offset, JSValue value) { locationForOffset(offset)->set(globalData, this, value); } + void putUndefinedAtDirectOffset(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); } JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); @@ -220,17 +269,18 @@ namespace JSC { bool staticFunctionsReified() { return structure()->staticFunctionsReified(); } void reifyStaticFunctionsForDelete(ExecState* exec); - JS_EXPORT_PRIVATE PropertyStorage growPropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize); - bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1); } - void setPropertyStorage(JSGlobalData&, PropertyStorage, Structure*); + JS_EXPORT_PRIVATE PropertyStorage growOutOfLineStorage(JSGlobalData&, size_t oldSize, size_t newSize); + void setOutOfLineStorage(JSGlobalData&, PropertyStorage, Structure*); + + bool reallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*); + void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*); + void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, Structure*); - void* addressOfPropertyStorage() + void* addressOfOutOfLineStorage() { - return &m_propertyStorage; + return &m_outOfLineStorage; } - static const unsigned baseExternalStorageCapacity = 16; - void flattenDictionaryObject(JSGlobalData& globalData) { structure()->flattenDictionaryStructure(globalData, this); @@ -244,20 +294,19 @@ namespace JSC { } static size_t offsetOfInlineStorage(); - static size_t offsetOfPropertyStorage(); + static size_t offsetOfOutOfLineStorage(); static size_t offsetOfInheritorID(); static JS_EXPORTDATA const ClassInfo s_info; protected: - void finishCreation(JSGlobalData& globalData, PropertyStorage inlineStorage) + void finishCreation(JSGlobalData& globalData) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); - ASSERT(structure()->propertyStorageCapacity() < baseExternalStorageCapacity); + ASSERT(!structure()->outOfLineCapacity()); ASSERT(structure()->isEmpty()); ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype())); - ASSERT_UNUSED(inlineStorage, static_cast<void*>(inlineStorage) == static_cast<void*>(this + 1)); ASSERT(structure()->isObject()); ASSERT(classInfo()); } @@ -271,7 +320,7 @@ namespace JSC { // To instantiate objects you likely want JSFinalObject, below. // To create derived types you likely want JSNonFinalObject, below. - JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage); + JSObject(JSGlobalData&, Structure*); void resetInheritorID() { @@ -289,19 +338,6 @@ namespace JSC { void isObject(); void isString(); - ConstPropertyStorage propertyStorage() const { return m_propertyStorage.get(); } - PropertyStorage propertyStorage() { return m_propertyStorage.get(); } - - const WriteBarrierBase<Unknown>* locationForOffset(size_t offset) const - { - return &propertyStorage()[offset]; - } - - WriteBarrierBase<Unknown>* locationForOffset(size_t offset) - { - return &propertyStorage()[offset]; - } - template<PutMode> bool putDirectInternal(JSGlobalData&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*); @@ -311,21 +347,11 @@ namespace JSC { const HashEntry* findPropertyHashEntry(ExecState*, PropertyName) const; Structure* createInheritorID(JSGlobalData&); - StorageBarrier m_propertyStorage; + StorageBarrier m_outOfLineStorage; WriteBarrier<Structure> m_inheritorID; }; -#if USE(JSVALUE32_64) -#define JSNonFinalObject_inlineStorageCapacity 4 -#define JSFinalObject_inlineStorageCapacity 6 -#else -#define JSNonFinalObject_inlineStorageCapacity 2 -#define JSFinalObject_inlineStorageCapacity 4 -#endif - -COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineStorageCapacity), final_storage_is_at_least_as_large_as_non_final); - // JSNonFinalObject is a type of JSObject that has some internal storage, // but also preserves some space in the collector cell for additional // data members in derived types. @@ -340,22 +366,23 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); } + static bool hasInlineStorage() + { + return false; + } + protected: explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure) - : JSObject(globalData, structure, m_inlineStorage) + : JSObject(globalData, structure) { } void finishCreation(JSGlobalData& globalData) { - Base::finishCreation(globalData, m_inlineStorage); - ASSERT(!(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double))); - ASSERT(this->structure()->propertyStorageCapacity() == JSNonFinalObject_inlineStorageCapacity); + Base::finishCreation(globalData); + ASSERT(!this->structure()->totalStorageCapacity()); ASSERT(classInfo()); } - - private: - WriteBarrier<Unknown> m_inlineStorage[JSNonFinalObject_inlineStorageCapacity]; }; class JSFinalObject; @@ -374,14 +401,23 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt 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, m_inlineStorage); + Base::finishCreation(globalData); ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double))); - ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity); + ASSERT(this->structure()->inlineCapacity() == static_cast<unsigned>(inlineStorageCapacity)); + ASSERT(this->structure()->totalStorageCapacity() == static_cast<unsigned>(inlineStorageCapacity)); ASSERT(classInfo()); } @@ -389,13 +425,13 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt friend class LLIntOffsetsExtractor; explicit JSFinalObject(JSGlobalData& globalData, Structure* structure) - : JSObject(globalData, structure, m_inlineStorage) + : JSObject(globalData, structure) { } static const unsigned StructureFlags = JSObject::StructureFlags; - WriteBarrierBase<Unknown> m_inlineStorage[JSFinalObject_inlineStorageCapacity]; + WriteBarrierBase<Unknown> m_inlineStorage[INLINE_STORAGE_CAPACITY]; }; inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure) @@ -417,13 +453,12 @@ inline bool isJSFinalObject(JSValue value) inline size_t JSObject::offsetOfInlineStorage() { - ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) == OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage)); return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage); } -inline size_t JSObject::offsetOfPropertyStorage() +inline size_t JSObject::offsetOfOutOfLineStorage() { - return OBJECT_OFFSETOF(JSObject, m_propertyStorage); + return OBJECT_OFFSETOF(JSObject, m_outOfLineStorage); } inline size_t JSObject::offsetOfInheritorID() @@ -461,12 +496,18 @@ inline bool JSObject::isGlobalThis() const return structure()->typeInfo().type() == GlobalThisType; } -inline void JSObject::setPropertyStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure) +inline void JSObject::setOutOfLineStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure) { - ASSERT(storage); ASSERT(structure); + if (!storage) { + ASSERT(!structure->outOfLineCapacity()); + ASSERT(!structure->outOfLineSize()); + } else { + ASSERT(structure->outOfLineCapacity()); + ASSERT(structure->outOfLineSize()); + } setStructure(globalData, structure); - m_propertyStorage.set(globalData, this, storage); + m_outOfLineStorage.set(globalData, this, storage); } inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure) @@ -504,9 +545,9 @@ inline JSObject* asObject(JSValue value) return asObject(value.asCell()); } -inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, PropertyStorage inlineStorage) +inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure) : JSCell(globalData, structure) - , m_propertyStorage(globalData, this, inlineStorage) + , m_outOfLineStorage(globalData, this, 0) { } @@ -530,11 +571,6 @@ inline Structure* JSObject::inheritorID(JSGlobalData& globalData) return createInheritorID(globalData); } -inline bool Structure::isUsingInlineStorage() const -{ - return propertyStorageCapacity() < JSObject::baseExternalStorageCapacity; -} - inline bool JSCell::inherits(const ClassInfo* info) const { return classInfo()->isSubClassOf(info); @@ -591,10 +627,10 @@ ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, PropertyName ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const UString& name) { if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) { - size_t offset = name.impl()->hasHash() + PropertyOffset offset = name.impl()->hasHash() ? structure()->get(exec->globalData(), Identifier(exec, name)) : structure()->get(exec->globalData(), name); - if (offset != WTF::notFound) + if (offset != invalidOffset) return asObject(this)->locationForOffset(offset)->get(); } return JSValue(); @@ -656,8 +692,8 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p if (structure()->isDictionary()) { unsigned currentAttributes; JSCell* currentSpecificFunction; - size_t offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction); - if (offset != WTF::notFound) { + PropertyOffset offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction); + if (offset != invalidOffset) { // 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)) @@ -680,13 +716,14 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p if ((mode == PutModePut) && !isExtensible()) return false; - PropertyStorage newStorage = propertyStorage(); - if (structure()->shouldGrowPropertyStorage()) - newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize()); + PropertyStorage newStorage = outOfLineStorage(); + if (structure()->putWillGrowOutOfLineStorage()) + newStorage = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity()); offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction); - setPropertyStorage(globalData, newStorage, structure()); + setOutOfLineStorage(globalData, newStorage, structure()); - ASSERT(offset < structure()->propertyStorageCapacity()); + validateOffset(offset); + ASSERT(structure()->isValidOffset(offset)); putDirectOffset(globalData, offset, value); // See comment on setNewProperty call below. if (!specificFunction) @@ -694,15 +731,16 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p return true; } - size_t offset; - size_t currentCapacity = structure()->propertyStorageCapacity(); + PropertyOffset offset; + size_t currentCapacity = structure()->outOfLineCapacity(); if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) { - PropertyStorage newStorage = propertyStorage(); - if (currentCapacity != structure->propertyStorageCapacity()) - newStorage = growPropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity()); + PropertyStorage newStorage = outOfLineStorage(); + if (currentCapacity != structure->outOfLineCapacity()) + newStorage = growOutOfLineStorage(globalData, currentCapacity, structure->outOfLineCapacity()); - ASSERT(offset < structure->propertyStorageCapacity()); - setPropertyStorage(globalData, newStorage, structure); + validateOffset(offset); + ASSERT(structure->isValidOffset(offset)); + setOutOfLineStorage(globalData, newStorage, 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. @@ -714,7 +752,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p unsigned currentAttributes; JSCell* currentSpecificFunction; offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction); - if (offset != WTF::notFound) { + if (offset != invalidOffset) { if ((mode == PutModePut) && currentAttributes & ReadOnly) return false; @@ -746,14 +784,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p if ((mode == PutModePut) && !isExtensible()) return false; - PropertyStorage newStorage = propertyStorage(); - if (structure()->shouldGrowPropertyStorage()) - newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize()); - Structure* structure = Structure::addPropertyTransition(globalData, this->structure(), propertyName, attributes, specificFunction, offset); + + validateOffset(offset); + ASSERT(structure->isValidOffset(offset)); + setStructureAndReallocateStorageIfNecessary(globalData, structure); - ASSERT(offset < structure->propertyStorageCapacity()); - setPropertyStorage(globalData, newStorage, 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. @@ -762,6 +798,26 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p return true; } +inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, unsigned oldCapacity, Structure* newStructure) +{ + ASSERT(oldCapacity <= newStructure->outOfLineCapacity()); + + if (oldCapacity == newStructure->outOfLineCapacity()) { + setStructure(globalData, newStructure); + return; + } + + PropertyStorage newStorage = growOutOfLineStorage( + globalData, oldCapacity, newStructure->outOfLineCapacity()); + setOutOfLineStorage(globalData, newStorage, newStructure); +} + +inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, Structure* newStructure) +{ + setStructureAndReallocateStorageIfNecessary( + globalData, structure()->outOfLineCapacity(), newStructure); +} + inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { ASSERT(value); @@ -787,22 +843,14 @@ inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyN inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes) { ASSERT(!value.isGetterSetter() && !(attributes & Accessor)); - PropertyStorage newStorage = propertyStorage(); - if (structure()->shouldGrowPropertyStorage()) - newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize()); - size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value)); - setPropertyStorage(globalData, newStorage, structure()); + PropertyStorage newStorage = outOfLineStorage(); + if (structure()->putWillGrowOutOfLineStorage()) + newStorage = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity()); + PropertyOffset offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value)); + setOutOfLineStorage(globalData, newStorage, structure()); putDirectOffset(globalData, offset, value); } -inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure) -{ - PropertyStorage newStorage = propertyStorage(); - if (structure()->propertyStorageCapacity() != newStructure->propertyStorageCapacity()) - newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), newStructure->propertyStorageCapacity()); - setPropertyStorage(globalData, newStorage, newStructure); -} - inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const { return methodTable()->defaultValue(this, exec, preferredType); @@ -877,8 +925,6 @@ inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow); } -// --- JSValue inlines ---------------------------- - ALWAYS_INLINE JSObject* Register::function() const { if (!jsValue()) @@ -893,6 +939,32 @@ ALWAYS_INLINE Register Register::withCallee(JSObject* callee) return r; } +// This is a helper for patching code where you want to emit a load or store and +// the base is: +// For inline offsets: a pointer to the out-of-line storage pointer. +// For out-of-line offsets: the base of the out-of-line storage. +inline size_t offsetRelativeToPatchedStorage(PropertyOffset offset) +{ + if (isOutOfLineOffset(offset)) + return sizeof(EncodedJSValue) * offsetInOutOfLineStorage(offset); + return JSObject::offsetOfInlineStorage() - JSObject::offsetOfOutOfLineStorage() + sizeof(EncodedJSValue) * offsetInInlineStorage(offset); +} + +inline int indexRelativeToBase(PropertyOffset offset) +{ + if (isOutOfLineOffset(offset)) + return offsetInOutOfLineStorage(offset); + ASSERT(!(JSObject::offsetOfInlineStorage() % sizeof(EncodedJSValue))); + return JSObject::offsetOfInlineStorage() / sizeof(EncodedJSValue) + offsetInInlineStorage(offset); +} + +inline int offsetRelativeToBase(PropertyOffset offset) +{ + if (isOutOfLineOffset(offset)) + return offsetInOutOfLineStorage(offset) * sizeof(EncodedJSValue); + return JSObject::offsetOfInlineStorage() + offsetInInlineStorage(offset) * sizeof(EncodedJSValue); +} + } // namespace JSC #endif // JSObject_h |
