diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h')
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h index 5a89c40a8a..cd8f7f7127 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h @@ -122,8 +122,8 @@ namespace JSC { virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty); - virtual void getPropertyNames(ExecState*, PropertyNameArray&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); @@ -135,7 +135,6 @@ namespace JSC { virtual JSObject* toThisObject(ExecState*) const; virtual JSObject* unwrappedObject(); - virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const; // This get function only looks at the property map. @@ -207,19 +206,25 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); + } + + void flattenDictionaryObject() + { + m_structure->flattenDictionaryStructure(this); } protected: static const unsigned StructureFlags = 0; - void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { + ASSERT(index < m_structure->anonymousSlotCount()); *locationForOffset(index) = value; } - JSValue getAnonymousValue(unsigned index) + JSValue getAnonymousValue(unsigned index) const { + ASSERT(index < m_structure->anonymousSlotCount()); return *locationForOffset(index); } @@ -229,7 +234,7 @@ namespace JSC { using JSCell::isGetterSetter; using JSCell::toObject; void getObject(); - void getString(); + void getString(ExecState* exec); void isObject(); void isString(); #if USE(JSVALUE32) @@ -377,7 +382,7 @@ ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identif // It may seem crazy to inline a function this large but it makes a big difference // since this is function very hot in variable lookup -inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { JSObject* object = this; while (true) { @@ -390,7 +395,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert } } -inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) +ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { JSObject* object = this; while (true) { @@ -431,12 +436,20 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue JSCell* currentSpecificFunction; size_t offset = m_structure->get(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); if (checkReadOnly && currentAttributes & ReadOnly) return; putDirectOffset(offset, value); - if (!specificFunction && !currentSpecificFunction) + // At this point, the objects structure only has a specific value set if previously there + // had been one set, and if the new value being specified is the same (otherwise we would + // have despecified, above). So, if currentSpecificFunction is not set, or if the new + // value is different (or there is no new value), then the slot now has no value - and + // as such it is cachable. + // If there was previously a value, and the new value is the same, then we cannot cache. + if (!currentSpecificFunction || (specificFunction != currentSpecificFunction)) slot.setExistingProperty(this, offset); return; } @@ -463,7 +476,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue ASSERT(offset < structure->propertyStorageCapacity()); setStructure(structure.release()); putDirectOffset(offset, value); - // See comment on setNewProperty call below. + // This is a new property; transitions with specific values are not currently cachable, + // so leave the slot in an uncachable state. if (!specificFunction) slot.setNewProperty(this, offset); return; @@ -476,14 +490,28 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue if (checkReadOnly && currentAttributes & ReadOnly) return; - if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) { + // There are three possibilities here: + // (1) There is an existing specific value set, and we're overwriting with *the same value*. + // * Do nothing - no need to despecify, but that means we can't cache (a cached + // put could write a different value). Leave the slot in an uncachable state. + // (2) There is a specific value currently set, but we're writing a different value. + // * First, we have to despecify. Having done so, this is now a regular slot + // with no specific value, so go ahead & cache like normal. + // (3) Normal case, there is no specific value set. + // * Go ahead & cache like normal. + if (currentSpecificFunction) { + // case (1) Do the put, then return leaving the slot uncachable. + if (specificFunction == currentSpecificFunction) { + putDirectOffset(offset, value); + return; + } + // case (2) Despecify, fall through to (3). setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName)); - putDirectOffset(offset, value); - // Function transitions are not currently cachable, so leave the slot in an uncachable state. - return; } - putDirectOffset(offset, value); + + // case (3) set the slot, do the put, return. slot.setExistingProperty(this, offset); + putDirectOffset(offset, value); return; } @@ -505,7 +533,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue ASSERT(offset < structure->propertyStorageCapacity()); setStructure(structure.release()); putDirectOffset(offset, value); - // Function transitions are not currently cachable, so leave the slot in an uncachable state. + // This is a new property; transitions with specific values are not currently cachable, + // so leave the slot in an uncachable state. if (!specificFunction) slot.setNewProperty(this, offset); } @@ -524,17 +553,6 @@ inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value)); } -inline void JSObject::addAnonymousSlots(unsigned count) -{ - size_t currentCapacity = m_structure->propertyStorageCapacity(); - RefPtr<Structure> structure = Structure::addAnonymousSlotsTransition(m_structure, count); - - if (currentCapacity != structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); - - setStructure(structure.release()); -} - inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) { ASSERT(value); |