Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (121626 => 121627)
--- trunk/Source/_javascript_Core/ChangeLog 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,3 +1,55 @@
+2012-06-30 Zan Dobersek <[email protected]>
+
+ Unreviewed, rolling out r121605.
+ http://trac.webkit.org/changeset/121605
+ https://bugs.webkit.org/show_bug.cgi?id=90336
+
+ Changes caused flaky crashes in sputnik/Unicode tests on Apple
+ WK1 and GTK Linux builders
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateBasicJSObject):
+ (JSC::JIT::emitAllocateJSFinalObject):
+ (JSC):
+ (JSC::JIT::emitAllocateJSFunction):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_func):
+ (JSC::JIT::emitSlow_op_new_func):
+ (JSC):
+ (JSC::JIT::emit_op_new_func_exp):
+ (JSC::JIT::emitSlow_op_new_func_exp):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::finishCreation):
+ * runtime/JSObject.h:
+ (JSC::JSObject::isUsingInlineStorage):
+ (JSObject):
+ (JSC::JSObject::finishCreation):
+ (JSC):
+ (JSNonFinalObject):
+ (JSC::JSNonFinalObject::JSNonFinalObject):
+ (JSC::JSNonFinalObject::finishCreation):
+ (JSFinalObject):
+ (JSC::JSFinalObject::finishCreation):
+ (JSC::JSObject::offsetOfInlineStorage):
+ (JSC::JSObject::setPropertyStorage):
+ (JSC::Structure::isUsingInlineStorage):
+ (JSC::JSObject::putDirectInternal):
+ (JSC::JSObject::putDirectWithoutTransition):
+ (JSC::JSObject::transitionTo):
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC):
+ (JSC::Structure::growPropertyStorageCapacity):
+ (JSC::Structure::suggestedNewPropertyStorageSize):
+ * runtime/Structure.h:
+ (JSC::Structure::shouldGrowPropertyStorage):
+ (JSC::Structure::propertyStorageSize):
+
2012-06-29 Mark Hahnenberg <[email protected]>
Remove warning about protected values when the Heap is being destroyed
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (121626 => 121627)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -3602,7 +3602,7 @@
proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
}
}
- baseObject->setStructureAndReallocateStorageIfNecessary(*globalData, newStructure);
+ baseObject->transitionTo(*globalData, newStructure);
int value = vPC[3].u.operand;
unsigned offset = vPC[7].u.operand;
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (121626 => 121627)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -472,6 +472,8 @@
DEFINE_SLOWCASE_OP(op_neq)
DEFINE_SLOWCASE_OP(op_new_array)
DEFINE_SLOWCASE_OP(op_new_object)
+ DEFINE_SLOWCASE_OP(op_new_func)
+ DEFINE_SLOWCASE_OP(op_new_func_exp)
DEFINE_SLOWCASE_OP(op_not)
DEFINE_SLOWCASE_OP(op_nstricteq)
DEFINE_SLOWCASE_OP(op_post_dec)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (121626 => 121627)
--- trunk/Source/_javascript_Core/jit/JIT.h 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -423,6 +423,7 @@
template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
void emitAllocateBasicStorage(size_t, RegisterID result, RegisterID storagePtr);
template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
+ void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr);
void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr);
#if ENABLE(VALUE_PROFILER)
@@ -749,6 +750,8 @@
void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_new_func(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_new_func_exp(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_new_array(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitRightShift(Instruction*, bool isUnsigned);
Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (121626 => 121627)
--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -429,11 +429,8 @@
storePtr(TrustedImmPtr(0), Address(result, JSObject::offsetOfInheritorID()));
// initialize the object's property storage pointer
- if (ClassType::hasInlineStorage()) {
- addPtr(TrustedImm32(sizeof(JSObject)), result, storagePtr);
- storePtr(storagePtr, Address(result, ClassType::offsetOfPropertyStorage()));
- } else
- storePtr(TrustedImmPtr(0), Address(result, ClassType::offsetOfPropertyStorage()));
+ addPtr(TrustedImm32(sizeof(JSObject)), result, storagePtr);
+ storePtr(storagePtr, Address(result, ClassType::offsetOfPropertyStorage()));
}
template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
@@ -441,6 +438,28 @@
emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch);
}
+inline void JIT::emitAllocateJSFunction(FunctionExecutable* executable, RegisterID scopeChain, RegisterID result, RegisterID storagePtr)
+{
+ emitAllocateBasicJSObject<JSFunction, true>(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), result, storagePtr);
+
+ // store the function's scope chain
+ storePtr(scopeChain, Address(result, JSFunction::offsetOfScopeChain()));
+
+ // store the function's executable member
+ storePtr(TrustedImmPtr(executable), Address(result, JSFunction::offsetOfExecutable()));
+
+ // clear the function's inheritorID
+ storePtr(TrustedImmPtr(0), Address(result, JSFunction::offsetOfCachedInheritorID()));
+
+ // store the function's name
+ ASSERT(executable->nameValue());
+ int functionNameOffset = sizeof(JSValue) * m_codeBlock->globalObject()->functionNameOffset();
+ storePtr(TrustedImmPtr(executable->nameValue()), Address(regT1, functionNameOffset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+#if USE(JSVALUE32_64)
+ store32(TrustedImm32(JSValue::CellTag), Address(regT1, functionNameOffset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+#endif
+}
+
inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result, RegisterID storagePtr)
{
CopiedAllocator* allocator = &m_globalData->heap.storageAllocator();
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (121626 => 121627)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2010 Patrick Gansterer <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -1618,10 +1618,12 @@
#endif
}
- JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
- stubCall.call(dst);
+ FunctionExecutable* executable = m_codeBlock->functionDecl(currentInstruction[2].u.operand);
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ emitAllocateJSFunction(executable, regT2, regT0, regT1);
+ emitStoreCell(dst, regT0);
+
if (currentInstruction[3].u.operand) {
#if USE(JSVALUE32_64)
unmap();
@@ -1632,13 +1634,44 @@
}
}
+void JIT::emitSlow_op_new_func(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_new_func);
+ stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
{
+ FunctionExecutable* executable = m_codeBlock->functionExpr(currentInstruction[2].u.operand);
+
+ // We only inline the allocation of a anonymous function expressions
+ // If we want to be able to allocate a named function _expression_, we would
+ // need to be able to do inline allocation of a JSStaticScopeObject.
+ if (executable->name().isNull()) {
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ emitAllocateJSFunction(executable, regT2, regT0, regT1);
+ emitStoreCell(currentInstruction[1].u.operand, regT0);
+ return;
+ }
+
JITStubCall stubCall(this, cti_op_new_func_exp);
stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emitSlow_op_new_func_exp(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ FunctionExecutable* executable = m_codeBlock->functionExpr(currentInstruction[2].u.operand);
+ if (!executable->name().isNull())
+ return;
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_new_func_exp);
+ stubCall.addArgument(TrustedImmPtr(executable));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
void JIT::emit_op_new_array(Instruction* currentInstruction)
{
int length = currentInstruction[3].u.operand;
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (121626 => 121627)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2012-06-30 12:09:15 UTC (rev 121627)
@@ -103,16 +103,13 @@
void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode)
{
- JSGlobalData& globalData = exec->globalData();
- Base::finishCreation(globalData);
+ Base::finishCreation(exec->globalData());
ASSERT(inherits(&s_info));
// Switching the structure here is only safe if we currently have the function structure!
ASSERT(structure() == scopeChainNode->globalObject->functionStructure());
- setStructureAndReallocateStorageIfNecessary(
- globalData,
- scopeChainNode->globalObject->namedFunctionStructure());
- putDirectOffset(globalData, scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
+ setStructure(exec->globalData(), scopeChainNode->globalObject->namedFunctionStructure());
+ putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
}
Structure* JSFunction::cacheInheritorID(ExecState* exec)
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (121626 => 121627)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2012-06-30 12:09:15 UTC (rev 121627)
@@ -79,14 +79,6 @@
Accessor = 1 << 5, // property is a getter/setter
};
-#if USE(JSVALUE32_64)
-#define JSFinalObject_inlineStorageCapacity 6
-#else
-#define JSFinalObject_inlineStorageCapacity 4
-#endif
-
-COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= 0), final_storage_non_negative);
-
class JSObject : public JSCell {
friend class BatchedTransitionOptimizer;
friend class JIT;
@@ -229,25 +221,16 @@
void reifyStaticFunctionsForDelete(ExecState* exec);
JS_EXPORT_PRIVATE PropertyStorage growPropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
- bool isUsingInlineStorage() const
- {
- bool result =
- !m_propertyStorage.get()
- || static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1);
- ASSERT(result == structure()->isUsingInlineStorage());
- return result;
- }
+ bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1); }
void setPropertyStorage(JSGlobalData&, PropertyStorage, Structure*);
-
- bool reallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*);
- void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*);
- void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, Structure*);
void* addressOfPropertyStorage()
{
return &m_propertyStorage;
}
+ static const unsigned baseExternalStorageCapacity = 16;
+
void flattenDictionaryObject(JSGlobalData& globalData)
{
structure()->flattenDictionaryStructure(globalData, this);
@@ -267,13 +250,14 @@
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(JSGlobalData& globalData, PropertyStorage inlineStorage)
{
Base::finishCreation(globalData);
ASSERT(inherits(&s_info));
- ASSERT(structure()->isUsingInlineStorage());
+ ASSERT(structure()->propertyStorageCapacity() < baseExternalStorageCapacity);
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());
}
@@ -332,6 +316,16 @@
};
+#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.
@@ -346,23 +340,22 @@
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, 0)
+ : JSObject(globalData, structure, m_inlineStorage)
{
}
void finishCreation(JSGlobalData& globalData)
{
- Base::finishCreation(globalData);
- ASSERT(!this->structure()->propertyStorageCapacity());
+ Base::finishCreation(globalData, m_inlineStorage);
+ ASSERT(!(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double)));
+ ASSERT(this->structure()->propertyStorageCapacity() == JSNonFinalObject_inlineStorageCapacity);
ASSERT(classInfo());
}
+
+ private:
+ WriteBarrier<Unknown> m_inlineStorage[JSNonFinalObject_inlineStorageCapacity];
};
class JSFinalObject;
@@ -383,14 +376,10 @@
static JS_EXPORTDATA const ClassInfo s_info;
- static bool hasInlineStorage()
- {
- return true;
- }
protected:
void finishCreation(JSGlobalData& globalData)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(globalData, m_inlineStorage);
ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double)));
ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity);
ASSERT(classInfo());
@@ -428,6 +417,7 @@
inline size_t JSObject::offsetOfInlineStorage()
{
+ ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) == OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage));
return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
}
@@ -475,8 +465,6 @@
{
ASSERT(storage);
ASSERT(structure);
- ASSERT(!structure->isUsingInlineStorage()
- || (classInfo() == &JSFinalObject::s_info && static_cast<void*>(storage) == static_cast<void*>(this + 1)));
setStructure(globalData, structure);
m_propertyStorage.set(globalData, this, storage);
}
@@ -542,17 +530,9 @@
return createInheritorID(globalData);
}
-inline size_t Structure::inlineStorageCapacity() const
-{
- if (classInfo() == &JSFinalObject::s_info)
- return JSFinalObject_inlineStorageCapacity;
- return 0;
-}
-
inline bool Structure::isUsingInlineStorage() const
{
- ASSERT(propertyStorageCapacity() >= inlineStorageCapacity());
- return propertyStorageCapacity() == inlineStorageCapacity();
+ return propertyStorageCapacity() < JSObject::baseExternalStorageCapacity;
}
inline bool JSCell::inherits(const ClassInfo* info) const
@@ -701,7 +681,7 @@
return false;
PropertyStorage newStorage = propertyStorage();
- if (structure()->putWillGrowPropertyStorage())
+ if (structure()->shouldGrowPropertyStorage())
newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
setPropertyStorage(globalData, newStorage, structure());
@@ -766,11 +746,14 @@
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);
-
- ASSERT(offset < structure->propertyStorageCapacity());
- 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.
@@ -779,26 +762,6 @@
return true;
}
-inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, unsigned oldCapacity, Structure* newStructure)
-{
- ASSERT(oldCapacity <= newStructure->propertyStorageCapacity());
-
- if (oldCapacity == newStructure->propertyStorageCapacity()) {
- setStructure(globalData, newStructure);
- return;
- }
-
- PropertyStorage newStorage = growPropertyStorage(
- globalData, oldCapacity, newStructure->suggestedNewPropertyStorageSize());
- setPropertyStorage(globalData, newStorage, newStructure);
-}
-
-inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, Structure* newStructure)
-{
- setStructureAndReallocateStorageIfNecessary(
- globalData, structure()->propertyStorageCapacity(), newStructure);
-}
-
inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(value);
@@ -825,13 +788,21 @@
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PropertyStorage newStorage = propertyStorage();
- if (structure()->putWillGrowPropertyStorage())
+ if (structure()->shouldGrowPropertyStorage())
newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
setPropertyStorage(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);
Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (121626 => 121627)
--- trunk/Source/_javascript_Core/runtime/Structure.cpp 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp 2012-06-30 12:09:15 UTC (rev 121627)
@@ -156,7 +156,7 @@
, m_prototype(globalData, this, prototype)
, m_classInfo(classInfo)
, m_transitionWatchpointSet(InitializedWatching)
- , m_propertyStorageCapacity(typeInfo.isFinalObject() ? JSFinalObject_inlineStorageCapacity : 0)
+ , m_propertyStorageCapacity(typeInfo.isFinalObject() ? JSFinalObject_inlineStorageCapacity : JSNonFinalObject_inlineStorageCapacity)
, m_offset(noOffset)
, m_dictionaryKind(NoneDictionaryKind)
, m_isPinnedPropertyTable(false)
@@ -256,21 +256,19 @@
}
}
-inline size_t nextPropertyStorageCapacity(size_t currentCapacity)
-{
- if (!currentCapacity)
- return 4;
- return currentCapacity * 2;
-}
-
void Structure::growPropertyStorageCapacity()
{
- m_propertyStorageCapacity = nextPropertyStorageCapacity(m_propertyStorageCapacity);
+ if (isUsingInlineStorage())
+ m_propertyStorageCapacity = JSObject::baseExternalStorageCapacity;
+ else
+ m_propertyStorageCapacity *= 2;
}
size_t Structure::suggestedNewPropertyStorageSize()
{
- return nextPropertyStorageCapacity(m_propertyStorageCapacity);
+ if (isUsingInlineStorage())
+ return JSObject::baseExternalStorageCapacity;
+ return m_propertyStorageCapacity * 2;
}
void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName)
Modified: trunk/Source/_javascript_Core/runtime/Structure.h (121626 => 121627)
--- trunk/Source/_javascript_Core/runtime/Structure.h 2012-06-30 11:56:38 UTC (rev 121626)
+++ trunk/Source/_javascript_Core/runtime/Structure.h 2012-06-30 12:09:15 UTC (rev 121627)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -103,23 +103,7 @@
bool isFrozen(JSGlobalData&);
bool isExtensible() const { return !m_preventExtensions; }
bool didTransition() const { return m_didTransition; }
- bool putWillGrowPropertyStorage()
- {
- ASSERT(propertyStorageCapacity() >= propertyStorageSize());
-
- if (!m_propertyTable) {
- unsigned currentSize = static_cast<unsigned>(m_offset + 1);
- ASSERT(propertyStorageCapacity() >= currentSize);
- return currentSize == propertyStorageCapacity();
- }
-
- ASSERT(propertyStorageCapacity() >= m_propertyTable->propertyStorageSize());
- if (m_propertyTable->hasDeletedOffset())
- return false;
-
- ASSERT(propertyStorageCapacity() >= m_propertyTable->size());
- return m_propertyTable->size() == propertyStorageCapacity();
- }
+ bool shouldGrowPropertyStorage() { return propertyStorageCapacity() == propertyStorageSize(); }
JS_EXPORT_PRIVATE size_t suggestedNewPropertyStorageSize();
Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
@@ -155,7 +139,6 @@
void growPropertyStorageCapacity();
unsigned propertyStorageCapacity() const { ASSERT(structure()->classInfo() == &s_info); return m_propertyStorageCapacity; }
unsigned propertyStorageSize() const { ASSERT(structure()->classInfo() == &s_info); return (m_propertyTable ? m_propertyTable->propertyStorageSize() : static_cast<unsigned>(m_offset + 1)); }
- size_t inlineStorageCapacity() const;
bool isUsingInlineStorage() const;
size_t get(JSGlobalData&, PropertyName);