summaryrefslogtreecommitdiff
path: root/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h74
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);