diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r-- | Source/JavaScriptCore/runtime/Executable.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/Executable.h | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/JSFunction.cpp | 12 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/JSFunction.h | 15 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/JSObject.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/JSObject.h | 46 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/JSString.h | 10 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/Structure.cpp | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/runtime/Structure.h | 2 |
9 files changed, 67 insertions, 53 deletions
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp index 934533c46..3690c2c33 100644 --- a/Source/JavaScriptCore/runtime/Executable.cpp +++ b/Source/JavaScriptCore/runtime/Executable.cpp @@ -225,7 +225,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope ASSERT(exception); return exception; } - recordParse(evalNode->scopeFlags(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); + recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); @@ -357,7 +357,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc ASSERT(exception); return exception; } - recordParse(programNode->scopeFlags(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); + recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); @@ -512,7 +512,7 @@ PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChain if (m_forceUsesArguments) body->setUsesArguments(); body->finishParsing(m_parameters, m_name); - recordParse(body->scopeFlags(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); + recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); OwnPtr<FunctionCodeBlock> result; ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind)); diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h index 3b979ba82..b9d3e6ee1 100644 --- a/Source/JavaScriptCore/runtime/Executable.h +++ b/Source/JavaScriptCore/runtime/Executable.h @@ -271,14 +271,14 @@ namespace JSC { ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext) : ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED) , m_source(source) - , m_scopeFlags(isInStrictContext ? StrictModeFlag : NoScopeFlags) + , m_features(isInStrictContext ? StrictModeFeature : 0) { } ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext) : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED) , m_source(source) - , m_scopeFlags(isInStrictContext ? StrictModeFlag : NoScopeFlags) + , m_features(isInStrictContext ? StrictModeFeature : 0) { } @@ -292,10 +292,10 @@ namespace JSC { int lineNo() const { return m_firstLine; } int lastLine() const { return m_lastLine; } - bool usesEval() const { return m_scopeFlags & UsesEvalFlag; } - bool usesArguments() const { return m_scopeFlags & UsesArgumentsFlag; } - bool needsActivation() const { return m_hasCapturedVariables || m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); } - bool isStrictMode() const { return m_scopeFlags & StrictModeFlag; } + bool usesEval() const { return m_features & EvalFeature; } + bool usesArguments() const { return m_features & ArgumentsFeature; } + bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); } + bool isStrictMode() const { return m_features & StrictModeFeature; } void unlinkCalls(); @@ -311,16 +311,16 @@ namespace JSC { #endif } - void recordParse(ScopeFlags scopeFlags, bool hasCapturedVariables, int firstLine, int lastLine) + void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine) { - m_scopeFlags = scopeFlags; + m_features = features; m_hasCapturedVariables = hasCapturedVariables; m_firstLine = firstLine; m_lastLine = lastLine; } SourceCode m_source; - ScopeFlags m_scopeFlags; + CodeFeatures m_features; bool m_hasCapturedVariables; int m_firstLine; int m_lastLine; diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp index 243946ba9..563325ab0 100644 --- a/Source/JavaScriptCore/runtime/JSFunction.cpp +++ b/Source/JavaScriptCore/runtime/JSFunction.cpp @@ -112,6 +112,16 @@ void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable, putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue()); } +Structure* JSFunction::cacheInheritorID(ExecState* exec) +{ + JSValue prototype = get(exec, exec->globalData().propertyNames->prototype); + if (prototype.isObject()) + m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData())); + else + m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure()); + return m_cachedInheritorID.get(); +} + const UString& JSFunction::name(ExecState* exec) { return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue(); @@ -332,6 +342,7 @@ void JSFunction::put(JSCell* cell, ExecState* exec, const Identifier& propertyNa // following the rules set out in ECMA-262 8.12.9. PropertySlot slot; thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); + thisObject->m_cachedInheritorID.clear(); } if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) { // This will trigger the property to be reified, if this is not already the case! @@ -372,6 +383,7 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, const Iden // following the rules set out in ECMA-262 8.12.9. PropertySlot slot; thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); + thisObject->m_cachedInheritorID.clear(); return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); } diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h index 5553115bf..9de66d721 100644 --- a/Source/JavaScriptCore/runtime/JSFunction.h +++ b/Source/JavaScriptCore/runtime/JSFunction.h @@ -121,6 +121,18 @@ namespace JSC { return OBJECT_OFFSETOF(JSFunction, m_executable); } + Structure* cachedInheritorID(ExecState* exec) + { + if (UNLIKELY(!m_cachedInheritorID)) + return cacheInheritorID(exec); + return m_cachedInheritorID.get(); + } + + static size_t offsetOfCachedInheritorID() + { + return OBJECT_OFFSETOF(JSFunction, m_cachedInheritorID); + } + protected: const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; @@ -130,6 +142,8 @@ namespace JSC { void finishCreation(ExecState*, NativeExecutable*, int length, const Identifier& name); void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*); + Structure* cacheInheritorID(ExecState*); + static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&); static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&); static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties); @@ -152,6 +166,7 @@ namespace JSC { WriteBarrier<ExecutableBase> m_executable; WriteBarrier<ScopeChainNode> m_scopeChain; + WriteBarrier<Structure> m_cachedInheritorID; }; inline bool JSValue::isFunction() const diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index 500f3891a..a8c6c3f3f 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -552,7 +552,7 @@ Structure* JSObject::createInheritorID(JSGlobalData& globalData) return m_inheritorID.get(); } -PropertyStorage JSObject::growPropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize) +void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize) { ASSERT(newSize > oldSize); @@ -580,7 +580,7 @@ PropertyStorage JSObject::growPropertyStorage(JSGlobalData& globalData, size_t o } ASSERT(newPropertyStorage); - return newPropertyStorage; + m_propertyStorage.set(globalData, this, newPropertyStorage); } bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index d95860d62..7345bb700 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -212,9 +212,8 @@ namespace JSC { bool staticFunctionsReified() { return structure()->staticFunctionsReified(); } void reifyStaticFunctionsForDelete(ExecState* exec); - JS_EXPORT_PRIVATE PropertyStorage growPropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize); + JS_EXPORT_PRIVATE void allocatePropertyStorage(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*); void* addressOfPropertyStorage() { @@ -453,14 +452,6 @@ inline bool JSObject::isGlobalThis() const return structure()->typeInfo().type() == GlobalThisType; } -inline void JSObject::setPropertyStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure) -{ - ASSERT(storage); - ASSERT(structure); - setStructure(globalData, structure); - m_propertyStorage.set(globalData, this, storage); -} - inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure) { return JSFinalObject::create(exec, structure); @@ -672,11 +663,10 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi if ((mode == PutModePut) && !isExtensible()) return false; - PropertyStorage newStorage = propertyStorage(); - if (structure()->shouldGrowPropertyStorage()) - newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize()); + size_t currentCapacity = structure()->propertyStorageCapacity(); offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction); - setPropertyStorage(globalData, newStorage, structure()); + if (currentCapacity != structure()->propertyStorageCapacity()) + allocatePropertyStorage(globalData, currentCapacity, structure()->propertyStorageCapacity()); ASSERT(offset < structure()->propertyStorageCapacity()); putDirectOffset(globalData, offset, value); @@ -688,13 +678,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi size_t offset; size_t currentCapacity = structure()->propertyStorageCapacity(); - if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) { - PropertyStorage newStorage = propertyStorage(); + if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) { if (currentCapacity != structure->propertyStorageCapacity()) - newStorage = growPropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity()); + allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity()); ASSERT(offset < structure->propertyStorageCapacity()); - setPropertyStorage(globalData, newStorage, structure); + setStructure(globalData, 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. @@ -738,14 +727,13 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi 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); + if (currentCapacity != structure->propertyStorageCapacity()) + allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity()); + ASSERT(offset < structure->propertyStorageCapacity()); - setPropertyStorage(globalData, newStorage, structure); + setStructure(globalData, 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,20 +767,18 @@ inline void JSObject::putDirect(JSGlobalData& globalData, const Identifier& prop inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const Identifier& 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 currentCapacity = structure()->propertyStorageCapacity(); size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value)); - setPropertyStorage(globalData, newStorage, structure()); + if (currentCapacity != structure()->propertyStorageCapacity()) + allocatePropertyStorage(globalData, currentCapacity, structure()->propertyStorageCapacity()); 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); + allocatePropertyStorage(globalData, structure()->propertyStorageCapacity(), newStructure->propertyStorageCapacity()); + setStructure(globalData, newStructure); } inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h index 10ec799e5..c95233deb 100644 --- a/Source/JavaScriptCore/runtime/JSString.h +++ b/Source/JavaScriptCore/runtime/JSString.h @@ -67,6 +67,7 @@ namespace JSC { friend class JSGlobalData; friend class SpecializedThunkJIT; friend class JSRopeString; + friend class MarkStack; friend struct ThunkHelpers; typedef JSCell Base; @@ -91,6 +92,7 @@ namespace JSC { Base::finishCreation(globalData); m_length = length; m_is8Bit = m_value.impl()->is8Bit(); + m_isHashConstSingleton = false; } void finishCreation(JSGlobalData& globalData, size_t length, size_t cost) @@ -99,6 +101,7 @@ namespace JSC { Base::finishCreation(globalData); m_length = length; m_is8Bit = m_value.impl()->is8Bit(); + m_isHashConstSingleton = false; Heap::heap(this)->reportExtraMemoryCost(cost); } @@ -108,6 +111,7 @@ namespace JSC { Base::finishCreation(globalData); m_length = 0; m_is8Bit = true; + m_isHashConstSingleton = false; } public: @@ -161,9 +165,13 @@ namespace JSC { protected: bool isRope() const { return m_value.isNull(); } bool is8Bit() const { return m_is8Bit; } + bool isHashConstSingleton() const { return m_isHashConstSingleton; } + void clearHashConstSingleton() { m_isHashConstSingleton = false; } + void setHashConstSingleton() { m_isHashConstSingleton = true; } // A string is represented either by a UString or a rope of fibers. bool m_is8Bit : 1; + bool m_isHashConstSingleton : 1; unsigned m_length; mutable UString m_value; @@ -233,6 +241,7 @@ namespace JSC { Base::finishCreation(globalData); m_length = s1->length() + s2->length(); m_is8Bit = (s1->is8Bit() && s2->is8Bit()); + m_isHashConstSingleton = false; m_fibers[0].set(globalData, this, s1); m_fibers[1].set(globalData, this, s2); } @@ -242,6 +251,7 @@ namespace JSC { Base::finishCreation(globalData); m_length = s1->length() + s2->length() + s3->length(); m_is8Bit = (s1->is8Bit() && s2->is8Bit() && s3->is8Bit()); + m_isHashConstSingleton = false; m_fibers[0].set(globalData, this, s1); m_fibers[1].set(globalData, this, s2); m_fibers[2].set(globalData, this, s3); diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp index 074c8b354..ac4b4f1fe 100644 --- a/Source/JavaScriptCore/runtime/Structure.cpp +++ b/Source/JavaScriptCore/runtime/Structure.cpp @@ -267,13 +267,6 @@ void Structure::growPropertyStorageCapacity() m_propertyStorageCapacity *= 2; } -size_t Structure::suggestedNewPropertyStorageSize() -{ - if (isUsingInlineStorage()) - return JSObject::baseExternalStorageCapacity; - return m_propertyStorageCapacity * 2; -} - void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, const Identifier& propertyName) { StringImpl* rep = propertyName.impl(); diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h index 00bc76177..ee580e245 100644 --- a/Source/JavaScriptCore/runtime/Structure.h +++ b/Source/JavaScriptCore/runtime/Structure.h @@ -102,8 +102,6 @@ namespace JSC { bool isFrozen(JSGlobalData&); bool isExtensible() const { return !m_preventExtensions; } bool didTransition() const { return m_didTransition; } - bool shouldGrowPropertyStorage() { return propertyStorageCapacity() == propertyStorageSize(); } - JS_EXPORT_PRIVATE size_t suggestedNewPropertyStorageSize(); Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*); |