Don't segregate heap objects based on Structure immortality.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Apr 2015 19:12:48 +0000 (19:12 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Apr 2015 19:12:48 +0000 (19:12 +0000)
<https://webkit.org/b/143638>

Reviewed by Darin Adler.

Source/JavaScriptCore:

Put all objects that need a destructor call into the same MarkedBlock.
This reduces memory consumption in many situations, while improving locality,
since much more of the MarkedBlock space can be shared.

Instead of branching on the MarkedBlock type, we now check a bit in the
JSCell's inline type flags (StructureIsImmortal) to see whether it's safe
to access the cell's Structure during destruction or not.

Performance benchmarks look mostly neutral. Maybe a small regression on
SunSpider's date objects.

On the amazon.com landing page, this saves us 50 MarkedBlocks (3200kB) along
with a bunch of WeakBlocks that were hanging off of them. That's on the higher
end of savings we can get from this, but still a very real improvement.

Most of this patch is removing the "hasImmortalStructure" constant from JSCell
derived classes and passing that responsibility to the StructureIsImmortal flag.
StructureFlags is made public so that it's accessible from non-member functions.
I made sure to declare it everywhere and make classes final to try to make it
explicit what each class is doing to its inherited flags.

* API/JSCallbackConstructor.h:
* API/JSCallbackObject.h:
* bytecode/UnlinkedCodeBlock.h:
* debugger/DebuggerScope.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileMakeRope):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileMakeRope):
* heap/Heap.h:
(JSC::Heap::subspaceForObjectDestructor):
(JSC::Heap::allocatorForObjectWithDestructor):
(JSC::Heap::subspaceForObjectNormalDestructor): Deleted.
(JSC::Heap::subspaceForObjectsWithImmortalStructure): Deleted.
(JSC::Heap::allocatorForObjectWithNormalDestructor): Deleted.
(JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): Deleted.
* heap/HeapInlines.h:
(JSC::Heap::allocateWithDestructor):
(JSC::Heap::allocateObjectOfType):
(JSC::Heap::subspaceForObjectOfType):
(JSC::Heap::allocatorForObjectOfType):
(JSC::Heap::allocateWithNormalDestructor): Deleted.
(JSC::Heap::allocateWithImmortalStructureDestructor): Deleted.
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::allocateBlock):
* heap/MarkedAllocator.h:
(JSC::MarkedAllocator::needsDestruction):
(JSC::MarkedAllocator::MarkedAllocator):
(JSC::MarkedAllocator::init):
(JSC::MarkedAllocator::destructorType): Deleted.
* heap/MarkedBlock.cpp:
(JSC::MarkedBlock::create):
(JSC::MarkedBlock::MarkedBlock):
(JSC::MarkedBlock::callDestructor):
(JSC::MarkedBlock::specializedSweep):
(JSC::MarkedBlock::sweep):
(JSC::MarkedBlock::sweepHelper):
* heap/MarkedBlock.h:
(JSC::MarkedBlock::needsDestruction):
(JSC::MarkedBlock::destructorType): Deleted.
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::MarkedSpace):
(JSC::MarkedSpace::resetAllocators):
(JSC::MarkedSpace::forEachAllocator):
(JSC::MarkedSpace::isPagedOut):
(JSC::MarkedSpace::clearNewlyAllocated):
* heap/MarkedSpace.h:
(JSC::MarkedSpace::subspaceForObjectsWithDestructor):
(JSC::MarkedSpace::destructorAllocatorFor):
(JSC::MarkedSpace::allocateWithDestructor):
(JSC::MarkedSpace::forEachBlock):
(JSC::MarkedSpace::subspaceForObjectsWithNormalDestructor): Deleted.
(JSC::MarkedSpace::subspaceForObjectsWithImmortalStructure): Deleted.
(JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): Deleted.
(JSC::MarkedSpace::normalDestructorAllocatorFor): Deleted.
(JSC::MarkedSpace::allocateWithImmortalStructureDestructor): Deleted.
(JSC::MarkedSpace::allocateWithNormalDestructor): Deleted.
* inspector/JSInjectedScriptHost.h:
* inspector/JSInjectedScriptHostPrototype.h:
* inspector/JSJavaScriptCallFrame.h:
* inspector/JSJavaScriptCallFramePrototype.h:
* jsc.cpp:
* runtime/ArrayBufferNeuteringWatchpoint.h:
* runtime/ArrayConstructor.h:
* runtime/ArrayIteratorPrototype.h:
* runtime/BooleanPrototype.h:
* runtime/ClonedArguments.h:
* runtime/CustomGetterSetter.h:
* runtime/DateConstructor.h:
* runtime/DatePrototype.h:
* runtime/ErrorPrototype.h:
* runtime/ExceptionHelpers.h:
* runtime/Executable.h:
* runtime/GenericArguments.h:
* runtime/GetterSetter.h:
* runtime/InternalFunction.h:
* runtime/JSAPIValueWrapper.h:
* runtime/JSArgumentsIterator.h:
* runtime/JSArray.h:
* runtime/JSArrayBuffer.h:
* runtime/JSArrayBufferView.h:
* runtime/JSBoundFunction.h:
* runtime/JSCallee.h:
* runtime/JSCell.h:
* runtime/JSCellInlines.h:
(JSC::JSCell::classInfo):
* runtime/JSDataViewPrototype.h:
* runtime/JSEnvironmentRecord.h:
* runtime/JSFunction.h:
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGlobalObject.h:
* runtime/JSLexicalEnvironment.h:
* runtime/JSNameScope.h:
* runtime/JSNotAnObject.h:
* runtime/JSONObject.h:
* runtime/JSObject.h:
(JSC::JSFinalObject::JSFinalObject):
* runtime/JSPromiseConstructor.h:
* runtime/JSPromiseDeferred.h:
* runtime/JSPromisePrototype.h:
* runtime/JSPromiseReaction.h:
* runtime/JSPropertyNameEnumerator.h:
* runtime/JSProxy.h:
* runtime/JSScope.h:
* runtime/JSString.h:
* runtime/JSSymbolTableObject.h:
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::structureIsImmortal):
* runtime/MathObject.h:
* runtime/NumberConstructor.h:
* runtime/NumberPrototype.h:
* runtime/ObjectConstructor.h:
* runtime/PropertyMapHashTable.h:
* runtime/RegExp.h:
* runtime/RegExpConstructor.h:
* runtime/RegExpObject.h:
* runtime/RegExpPrototype.h:
* runtime/ScopedArgumentsTable.h:
* runtime/SparseArrayValueMap.h:
* runtime/StrictEvalActivation.h:
* runtime/StringConstructor.h:
* runtime/StringIteratorPrototype.h:
* runtime/StringObject.h:
* runtime/StringPrototype.h:
* runtime/Structure.cpp:
(JSC::Structure::Structure):
* runtime/Structure.h:
* runtime/StructureChain.h:
* runtime/StructureRareData.h:
* runtime/Symbol.h:
* runtime/SymbolPrototype.h:
* runtime/SymbolTable.h:
* runtime/WeakMapData.h:

Source/WebCore:

* bindings/js/JSDOMBinding.h:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GeneratePrototypeDeclaration):
* bridge/objc/objc_runtime.h:
* bridge/runtime_array.h:
* bridge/runtime_method.h:
* bridge/runtime_object.h:

Source/WebKit2:

* WebProcess/Plugins/Netscape/JSNPObject.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182747 268f45cc-cd09-0410-ab3c-d52691b4dbfc

96 files changed:
Source/JavaScriptCore/API/JSCallbackConstructor.h
Source/JavaScriptCore/API/JSCallbackObject.h
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/debugger/DebuggerScope.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapInlines.h
Source/JavaScriptCore/heap/MarkedAllocator.cpp
Source/JavaScriptCore/heap/MarkedAllocator.h
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/heap/MarkedSpace.cpp
Source/JavaScriptCore/heap/MarkedSpace.h
Source/JavaScriptCore/inspector/JSInjectedScriptHost.h
Source/JavaScriptCore/inspector/JSInjectedScriptHostPrototype.h
Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h
Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.h
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h
Source/JavaScriptCore/runtime/ArrayConstructor.h
Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h
Source/JavaScriptCore/runtime/BooleanPrototype.h
Source/JavaScriptCore/runtime/ClonedArguments.h
Source/JavaScriptCore/runtime/CustomGetterSetter.h
Source/JavaScriptCore/runtime/DateConstructor.h
Source/JavaScriptCore/runtime/DatePrototype.h
Source/JavaScriptCore/runtime/ErrorPrototype.h
Source/JavaScriptCore/runtime/ExceptionHelpers.h
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/GenericArguments.h
Source/JavaScriptCore/runtime/GetterSetter.h
Source/JavaScriptCore/runtime/InternalFunction.h
Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
Source/JavaScriptCore/runtime/JSArgumentsIterator.h
Source/JavaScriptCore/runtime/JSArray.h
Source/JavaScriptCore/runtime/JSArrayBuffer.h
Source/JavaScriptCore/runtime/JSArrayBufferView.h
Source/JavaScriptCore/runtime/JSBoundFunction.h
Source/JavaScriptCore/runtime/JSCallee.h
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSCellInlines.h
Source/JavaScriptCore/runtime/JSDataViewPrototype.h
Source/JavaScriptCore/runtime/JSEnvironmentRecord.h
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
Source/JavaScriptCore/runtime/JSNameScope.h
Source/JavaScriptCore/runtime/JSNotAnObject.h
Source/JavaScriptCore/runtime/JSONObject.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPromiseConstructor.h
Source/JavaScriptCore/runtime/JSPromiseDeferred.h
Source/JavaScriptCore/runtime/JSPromisePrototype.h
Source/JavaScriptCore/runtime/JSPromiseReaction.h
Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h
Source/JavaScriptCore/runtime/JSProxy.h
Source/JavaScriptCore/runtime/JSScope.h
Source/JavaScriptCore/runtime/JSString.h
Source/JavaScriptCore/runtime/JSSymbolTableObject.h
Source/JavaScriptCore/runtime/JSTypeInfo.h
Source/JavaScriptCore/runtime/MathObject.h
Source/JavaScriptCore/runtime/NumberConstructor.h
Source/JavaScriptCore/runtime/NumberPrototype.h
Source/JavaScriptCore/runtime/ObjectConstructor.h
Source/JavaScriptCore/runtime/PropertyMapHashTable.h
Source/JavaScriptCore/runtime/RegExp.h
Source/JavaScriptCore/runtime/RegExpConstructor.h
Source/JavaScriptCore/runtime/RegExpObject.h
Source/JavaScriptCore/runtime/RegExpPrototype.h
Source/JavaScriptCore/runtime/ScopedArgumentsTable.h
Source/JavaScriptCore/runtime/SparseArrayValueMap.h
Source/JavaScriptCore/runtime/StrictEvalActivation.h
Source/JavaScriptCore/runtime/StringConstructor.h
Source/JavaScriptCore/runtime/StringIteratorPrototype.h
Source/JavaScriptCore/runtime/StringObject.h
Source/JavaScriptCore/runtime/StringPrototype.h
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureChain.h
Source/JavaScriptCore/runtime/StructureRareData.h
Source/JavaScriptCore/runtime/Symbol.h
Source/JavaScriptCore/runtime/SymbolPrototype.h
Source/JavaScriptCore/runtime/SymbolTable.h
Source/JavaScriptCore/runtime/WeakMapData.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bridge/objc/objc_runtime.h
Source/WebCore/bridge/runtime_array.h
Source/WebCore/bridge/runtime_method.h
Source/WebCore/bridge/runtime_object.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h

index d2792f8..f178936 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
 class JSCallbackConstructor : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
 
     static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback) 
     {
@@ -56,7 +57,6 @@ public:
 protected:
     JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback);
     void finishCreation(JSGlobalObject*, JSClassRef);
-    static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
 
 private:
     friend struct APICallbackFunction;
index fc119da..36a255c 100644 (file)
@@ -125,6 +125,7 @@ protected:
 
 public:
     typedef Parent Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames;
 
     ~JSCallbackObject();
 
@@ -170,9 +171,6 @@ public:
 
     using Parent::methodTable;
 
-protected:
-    static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames | Parent::StructureFlags;
-
 private:
     static String className(const JSObject*);
 
index a7bf2d5..cb72ade 100644 (file)
@@ -1,3 +1,164 @@
+2015-04-13  Andreas Kling  <akling@apple.com>
+
+        Don't segregate heap objects based on Structure immortality.
+        <https://webkit.org/b/143638>
+
+        Reviewed by Darin Adler.
+
+        Put all objects that need a destructor call into the same MarkedBlock.
+        This reduces memory consumption in many situations, while improving locality,
+        since much more of the MarkedBlock space can be shared.
+
+        Instead of branching on the MarkedBlock type, we now check a bit in the
+        JSCell's inline type flags (StructureIsImmortal) to see whether it's safe
+        to access the cell's Structure during destruction or not.
+
+        Performance benchmarks look mostly neutral. Maybe a small regression on
+        SunSpider's date objects.
+
+        On the amazon.com landing page, this saves us 50 MarkedBlocks (3200kB) along
+        with a bunch of WeakBlocks that were hanging off of them. That's on the higher
+        end of savings we can get from this, but still a very real improvement.
+
+        Most of this patch is removing the "hasImmortalStructure" constant from JSCell
+        derived classes and passing that responsibility to the StructureIsImmortal flag.
+        StructureFlags is made public so that it's accessible from non-member functions.
+        I made sure to declare it everywhere and make classes final to try to make it
+        explicit what each class is doing to its inherited flags.
+
+        * API/JSCallbackConstructor.h:
+        * API/JSCallbackObject.h:
+        * bytecode/UnlinkedCodeBlock.h:
+        * debugger/DebuggerScope.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMakeRope):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+        * heap/Heap.h:
+        (JSC::Heap::subspaceForObjectDestructor):
+        (JSC::Heap::allocatorForObjectWithDestructor):
+        (JSC::Heap::subspaceForObjectNormalDestructor): Deleted.
+        (JSC::Heap::subspaceForObjectsWithImmortalStructure): Deleted.
+        (JSC::Heap::allocatorForObjectWithNormalDestructor): Deleted.
+        (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): Deleted.
+        * heap/HeapInlines.h:
+        (JSC::Heap::allocateWithDestructor):
+        (JSC::Heap::allocateObjectOfType):
+        (JSC::Heap::subspaceForObjectOfType):
+        (JSC::Heap::allocatorForObjectOfType):
+        (JSC::Heap::allocateWithNormalDestructor): Deleted.
+        (JSC::Heap::allocateWithImmortalStructureDestructor): Deleted.
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateBlock):
+        * heap/MarkedAllocator.h:
+        (JSC::MarkedAllocator::needsDestruction):
+        (JSC::MarkedAllocator::MarkedAllocator):
+        (JSC::MarkedAllocator::init):
+        (JSC::MarkedAllocator::destructorType): Deleted.
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::create):
+        (JSC::MarkedBlock::MarkedBlock):
+        (JSC::MarkedBlock::callDestructor):
+        (JSC::MarkedBlock::specializedSweep):
+        (JSC::MarkedBlock::sweep):
+        (JSC::MarkedBlock::sweepHelper):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::needsDestruction):
+        (JSC::MarkedBlock::destructorType): Deleted.
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::MarkedSpace):
+        (JSC::MarkedSpace::resetAllocators):
+        (JSC::MarkedSpace::forEachAllocator):
+        (JSC::MarkedSpace::isPagedOut):
+        (JSC::MarkedSpace::clearNewlyAllocated):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::subspaceForObjectsWithDestructor):
+        (JSC::MarkedSpace::destructorAllocatorFor):
+        (JSC::MarkedSpace::allocateWithDestructor):
+        (JSC::MarkedSpace::forEachBlock):
+        (JSC::MarkedSpace::subspaceForObjectsWithNormalDestructor): Deleted.
+        (JSC::MarkedSpace::subspaceForObjectsWithImmortalStructure): Deleted.
+        (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): Deleted.
+        (JSC::MarkedSpace::normalDestructorAllocatorFor): Deleted.
+        (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): Deleted.
+        (JSC::MarkedSpace::allocateWithNormalDestructor): Deleted.
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.h:
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.h:
+        * jsc.cpp:
+        * runtime/ArrayBufferNeuteringWatchpoint.h:
+        * runtime/ArrayConstructor.h:
+        * runtime/ArrayIteratorPrototype.h:
+        * runtime/BooleanPrototype.h:
+        * runtime/ClonedArguments.h:
+        * runtime/CustomGetterSetter.h:
+        * runtime/DateConstructor.h:
+        * runtime/DatePrototype.h:
+        * runtime/ErrorPrototype.h:
+        * runtime/ExceptionHelpers.h:
+        * runtime/Executable.h:
+        * runtime/GenericArguments.h:
+        * runtime/GetterSetter.h:
+        * runtime/InternalFunction.h:
+        * runtime/JSAPIValueWrapper.h:
+        * runtime/JSArgumentsIterator.h:
+        * runtime/JSArray.h:
+        * runtime/JSArrayBuffer.h:
+        * runtime/JSArrayBufferView.h:
+        * runtime/JSBoundFunction.h:
+        * runtime/JSCallee.h:
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::classInfo):
+        * runtime/JSDataViewPrototype.h:
+        * runtime/JSEnvironmentRecord.h:
+        * runtime/JSFunction.h:
+        * runtime/JSGenericTypedArrayView.h:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSLexicalEnvironment.h:
+        * runtime/JSNameScope.h:
+        * runtime/JSNotAnObject.h:
+        * runtime/JSONObject.h:
+        * runtime/JSObject.h:
+        (JSC::JSFinalObject::JSFinalObject):
+        * runtime/JSPromiseConstructor.h:
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPromisePrototype.h:
+        * runtime/JSPromiseReaction.h:
+        * runtime/JSPropertyNameEnumerator.h:
+        * runtime/JSProxy.h:
+        * runtime/JSScope.h:
+        * runtime/JSString.h:
+        * runtime/JSSymbolTableObject.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::structureIsImmortal):
+        * runtime/MathObject.h:
+        * runtime/NumberConstructor.h:
+        * runtime/NumberPrototype.h:
+        * runtime/ObjectConstructor.h:
+        * runtime/PropertyMapHashTable.h:
+        * runtime/RegExp.h:
+        * runtime/RegExpConstructor.h:
+        * runtime/RegExpObject.h:
+        * runtime/RegExpPrototype.h:
+        * runtime/ScopedArgumentsTable.h:
+        * runtime/SparseArrayValueMap.h:
+        * runtime/StrictEvalActivation.h:
+        * runtime/StringConstructor.h:
+        * runtime/StringIteratorPrototype.h:
+        * runtime/StringObject.h:
+        * runtime/StringPrototype.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        * runtime/Structure.h:
+        * runtime/StructureChain.h:
+        * runtime/StructureRareData.h:
+        * runtime/Symbol.h:
+        * runtime/SymbolPrototype.h:
+        * runtime/SymbolTable.h:
+        * runtime/WeakMapData.h:
+
 2015-04-13  Mark Lam  <mark.lam@apple.com>
 
         DFG inlining of op_call_varargs should keep the callee alive in case of OSR exit.
index 7972327..1dec5fb 100644 (file)
@@ -97,12 +97,15 @@ enum UnlinkedFunctionKind {
     UnlinkedBuiltinFunction,
 };
 
-class UnlinkedFunctionExecutable : public JSCell {
+class UnlinkedFunctionExecutable final : public JSCell {
 public:
     friend class BuiltinExecutables;
     friend class CodeCache;
     friend class VM;
+
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     {
         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
@@ -162,7 +165,6 @@ public:
     bool hasCapturedVariables() const { return m_hasCapturedVariables; }
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
@@ -214,8 +216,6 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
     }
 
-    static const unsigned StructureFlags = StructureIsImmortal | JSCell::StructureFlags;
-
     DECLARE_EXPORT_INFO;
 };
 
@@ -267,8 +267,9 @@ struct UnlinkedInstruction {
 class UnlinkedCodeBlock : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
 
     enum { CallFunction, ApplyFunction };
 
@@ -604,8 +605,6 @@ private:
     Vector<size_t> m_opProfileControlFlowBytecodeOffsets;
 
 protected:
-
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
     static void visitChildren(JSCell*, SlotVisitor&);
 
 public:
@@ -625,7 +624,7 @@ protected:
     DECLARE_INFO;
 };
 
-class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
+class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock {
 private:
     friend class CodeCache;
     static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
@@ -637,6 +636,8 @@ private:
 
 public:
     typedef UnlinkedGlobalCodeBlock Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static void destroy(JSCell*);
 
     void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
@@ -675,7 +676,7 @@ public:
     DECLARE_INFO;
 };
 
-class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
+class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock {
 private:
     friend class CodeCache;
 
@@ -688,6 +689,8 @@ private:
 
 public:
     typedef UnlinkedGlobalCodeBlock Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static void destroy(JSCell*);
 
     const Identifier& variable(unsigned index) { return m_variables[index]; }
@@ -715,8 +718,11 @@ public:
     DECLARE_INFO;
 };
 
-class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
+class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock {
 public:
+    typedef UnlinkedCodeBlock Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
     {
         UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
@@ -724,7 +730,6 @@ public:
         return instance;
     }
 
-    typedef UnlinkedCodeBlock Base;
     static void destroy(JSCell*);
 
 private:
index 227cb19..4416684 100644 (file)
@@ -36,6 +36,7 @@ class JSScope;
 class DebuggerScope : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static DebuggerScope* create(VM& vm, JSScope* scope)
     {
@@ -98,8 +99,6 @@ private:
 
     JSScope* jsScope() const { return m_scope.get(); }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
-
     WriteBarrier<JSScope> m_scope;
     WriteBarrier<DebuggerScope> m_next;
 
index eb50cad..1611765 100644 (file)
@@ -2795,7 +2795,7 @@ void SpeculativeJIT::compileMakeRope(Node* node)
     GPRReg scratchGPR = scratch.gpr();
     
     JITCompiler::JumpList slowPath;
-    MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(JSRopeString));
+    MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
     m_jit.move(TrustedImmPtr(&markedAllocator), allocatorGPR);
     emitAllocateJSCell(resultGPR, allocatorGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()), scratchGPR, slowPath);
         
index 7142559..e39d0df 100644 (file)
@@ -3419,7 +3419,7 @@ private:
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
         
         MarkedAllocator& allocator =
-            vm().heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(JSRopeString));
+            vm().heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
         
         LValue result = allocateCell(
             m_out.constIntPtr(&allocator),
index 9019fc7..22b0fc7 100644 (file)
@@ -137,12 +137,10 @@ public:
     // true if an allocation or collection is in progress
     bool isBusy();
     MarkedSpace::Subspace& subspaceForObjectWithoutDestructor() { return m_objectSpace.subspaceForObjectsWithoutDestructor(); }
-    MarkedSpace::Subspace& subspaceForObjectNormalDestructor() { return m_objectSpace.subspaceForObjectsWithNormalDestructor(); }
-    MarkedSpace::Subspace& subspaceForObjectsWithImmortalStructure() { return m_objectSpace.subspaceForObjectsWithImmortalStructure(); }
+    MarkedSpace::Subspace& subspaceForObjectDestructor() { return m_objectSpace.subspaceForObjectsWithDestructor(); }
     template<typename ClassType> MarkedSpace::Subspace& subspaceForObjectOfType();
     MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
-    MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); }
-    MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); }
+    MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
     template<typename ClassType> MarkedAllocator& allocatorForObjectOfType(size_t bytes);
     CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
     CheckedBoolean tryAllocateStorage(JSCell* intendedOwner, size_t, void**);
@@ -266,8 +264,7 @@ private:
     template<typename T> friend void* allocateCell(Heap&);
     template<typename T> friend void* allocateCell(Heap&, size_t);
 
-    void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die.
-    void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject.
+    void* allocateWithDestructor(size_t); // For use with objects with destructors.
     void* allocateWithoutDestructor(size_t); // For use with objects without destructors.
     template<typename ClassType> void* allocateObjectOfType(size_t); // Chooses one of the methods above based on type.
 
index 6ba54da..955cacb 100644 (file)
@@ -209,22 +209,13 @@ template<typename Functor> inline void Heap::forEachCodeBlock(Functor& functor)
     return m_codeBlocks.iterate<Functor>(functor);
 }
 
-inline void* Heap::allocateWithNormalDestructor(size_t bytes)
+inline void* Heap::allocateWithDestructor(size_t bytes)
 {
 #if ENABLE(ALLOCATION_LOGGING)
     dataLogF("JSC GC allocating %lu bytes with normal destructor.\n", bytes);
 #endif
     ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithNormalDestructor(bytes);
-}
-
-inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes)
-{
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF("JSC GC allocating %lu bytes with immortal structure destructor.\n", bytes);
-#endif
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithImmortalStructureDestructor(bytes);
+    return m_objectSpace.allocateWithDestructor(bytes);
 }
 
 inline void* Heap::allocateWithoutDestructor(size_t bytes)
@@ -240,12 +231,10 @@ template<typename ClassType>
 void* Heap::allocateObjectOfType(size_t bytes)
 {
     // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value));
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
 
-    if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
-        return allocateWithImmortalStructureDestructor(bytes);
     if (ClassType::needsDestruction)
-        return allocateWithNormalDestructor(bytes);
+        return allocateWithDestructor(bytes);
     return allocateWithoutDestructor(bytes);
 }
 
@@ -253,12 +242,10 @@ template<typename ClassType>
 MarkedSpace::Subspace& Heap::subspaceForObjectOfType()
 {
     // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value));
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
     
-    if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
-        return subspaceForObjectsWithImmortalStructure();
     if (ClassType::needsDestruction)
-        return subspaceForObjectNormalDestructor();
+        return subspaceForObjectDestructor();
     return subspaceForObjectWithoutDestructor();
 }
 
@@ -266,12 +253,10 @@ template<typename ClassType>
 MarkedAllocator& Heap::allocatorForObjectOfType(size_t bytes)
 {
     // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value));
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
     
-    if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
-        return allocatorForObjectWithImmortalStructureDestructor(bytes);
     if (ClassType::needsDestruction)
-        return allocatorForObjectWithNormalDestructor(bytes);
+        return allocatorForObjectWithDestructor(bytes);
     return allocatorForObjectWithoutDestructor(bytes);
 }
 
index a7d29bb..2dbf8ae 100644 (file)
@@ -180,7 +180,7 @@ MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
 
     size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
 
-    return MarkedBlock::create(this, blockSize, cellSize, m_destructorType);
+    return MarkedBlock::create(this, blockSize, cellSize, m_needsDestruction);
 }
 
 void MarkedAllocator::addBlock(MarkedBlock* block)
index b497f8f..161af48 100644 (file)
@@ -26,7 +26,7 @@ public:
     void stopAllocating();
     void resumeAllocating();
     size_t cellSize() { return m_cellSize; }
-    MarkedBlock::DestructorType destructorType() { return m_destructorType; }
+    bool needsDestruction() { return m_needsDestruction; }
     void* allocate(size_t);
     Heap* heap() { return m_heap; }
     MarkedBlock* takeLastActiveBlock()
@@ -40,7 +40,7 @@ public:
     
     void addBlock(MarkedBlock*);
     void removeBlock(MarkedBlock*);
-    void init(Heap*, MarkedSpace*, size_t cellSize, MarkedBlock::DestructorType);
+    void init(Heap*, MarkedSpace*, size_t cellSize, bool needsDestruction);
 
     bool isPagedOut(double deadline);
    
@@ -59,7 +59,7 @@ private:
     DoublyLinkedList<MarkedBlock> m_blockList;
     DoublyLinkedList<MarkedBlock> m_retiredBlocks;
     size_t m_cellSize;
-    MarkedBlock::DestructorType m_destructorType;
+    bool m_needsDestruction { false };
     Heap* m_heap;
     MarkedSpace* m_markedSpace;
 };
@@ -74,18 +74,17 @@ inline MarkedAllocator::MarkedAllocator()
     , m_lastActiveBlock(0)
     , m_nextBlockToSweep(0)
     , m_cellSize(0)
-    , m_destructorType(MarkedBlock::None)
     , m_heap(0)
     , m_markedSpace(0)
 {
 }
 
-inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType)
+inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool needsDestruction)
 {
     m_heap = heap;
     m_markedSpace = markedSpace;
     m_cellSize = cellSize;
-    m_destructorType = destructorType;
+    m_needsDestruction = needsDestruction;
 }
 
 inline void* MarkedAllocator::allocate(size_t bytes)
index e10722d..5cbff13 100644 (file)
@@ -33,9 +33,9 @@
 
 namespace JSC {
 
-MarkedBlock* MarkedBlock::create(MarkedAllocator* allocator, size_t capacity, size_t cellSize, DestructorType destructorType)
+MarkedBlock* MarkedBlock::create(MarkedAllocator* allocator, size_t capacity, size_t cellSize, bool needsDestruction)
 {
-    return new (NotNull, fastAlignedMalloc(blockSize, capacity)) MarkedBlock(allocator, capacity, cellSize, destructorType);
+    return new (NotNull, fastAlignedMalloc(blockSize, capacity)) MarkedBlock(allocator, capacity, cellSize, needsDestruction);
 }
 
 void MarkedBlock::destroy(MarkedBlock* block)
@@ -44,12 +44,12 @@ void MarkedBlock::destroy(MarkedBlock* block)
     fastAlignedFree(block);
 }
 
-MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t capacity, size_t cellSize, DestructorType destructorType)
+MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t capacity, size_t cellSize, bool needsDestruction)
     : DoublyLinkedListNode<MarkedBlock>()
     , m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
     , m_endAtom((allocator->cellSize() ? atomsPerBlock : capacity / atomSize) - m_atomsPerCell + 1)
     , m_capacity(capacity)
-    , m_destructorType(destructorType)
+    , m_needsDestruction(needsDestruction)
     , m_allocator(allocator)
     , m_state(New) // All cells start out unmarked.
     , m_weakSet(allocator->heap()->vm())
@@ -58,7 +58,6 @@ MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t capacity, size_t cel
     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
 }
 
-template<MarkedBlock::DestructorType dtorType>
 inline void MarkedBlock::callDestructor(JSCell* cell)
 {
     // A previous eager sweep may already have run cell's destructor.
@@ -66,20 +65,20 @@ inline void MarkedBlock::callDestructor(JSCell* cell)
         return;
 
     ASSERT(cell->structureID());
-    if (dtorType == MarkedBlock::Normal)
-        jsCast<JSDestructibleObject*>(cell)->classInfo()->methodTable.destroy(cell);
-    else
+    if (cell->inlineTypeFlags() & StructureIsImmortal)
         cell->structure(*vm())->classInfo()->methodTable.destroy(cell);
+    else
+        jsCast<JSDestructibleObject*>(cell)->classInfo()->methodTable.destroy(cell);
     cell->zap();
 }
 
-template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, MarkedBlock::DestructorType dtorType>
+template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool callDestructors>
 MarkedBlock::FreeList MarkedBlock::specializedSweep()
 {
     ASSERT(blockState != Allocated && blockState != FreeListed);
-    ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly));
+    ASSERT(!(!callDestructors && sweepMode == SweepOnly));
 
-    SamplingRegion samplingRegion((dtorType != MarkedBlock::None && blockState != New) ? "Calling destructors" : "sweeping");
+    SamplingRegion samplingRegion((!callDestructors && blockState != New) ? "Calling destructors" : "sweeping");
     
     // This produces a free list that is ordered in reverse through the block.
     // This is fine, since the allocation code makes no assumptions about the
@@ -92,8 +91,8 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
 
         JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
 
-        if (dtorType != MarkedBlock::None && blockState != New)
-            callDestructor<dtorType>(cell);
+        if (callDestructors && blockState != New)
+            callDestructor(cell);
 
         if (sweepMode == SweepToFreeList) {
             FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell);
@@ -118,23 +117,21 @@ MarkedBlock::FreeList MarkedBlock::sweep(SweepMode sweepMode)
 
     m_weakSet.sweep();
 
-    if (sweepMode == SweepOnly && m_destructorType == MarkedBlock::None)
+    if (sweepMode == SweepOnly && !m_needsDestruction)
         return FreeList();
 
-    if (m_destructorType == MarkedBlock::ImmortalStructure)
-        return sweepHelper<MarkedBlock::ImmortalStructure>(sweepMode);
-    if (m_destructorType == MarkedBlock::Normal)
-        return sweepHelper<MarkedBlock::Normal>(sweepMode);
-    return sweepHelper<MarkedBlock::None>(sweepMode);
+    if (m_needsDestruction)
+        return sweepHelper<true>(sweepMode);
+    return sweepHelper<false>(sweepMode);
 }
 
-template<MarkedBlock::DestructorType dtorType>
+template<bool callDestructors>
 MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
 {
     switch (m_state) {
     case New:
         ASSERT(sweepMode == SweepToFreeList);
-        return specializedSweep<New, SweepToFreeList, dtorType>();
+        return specializedSweep<New, SweepToFreeList, callDestructors>();
     case FreeListed:
         // Happens when a block transitions to fully allocated.
         ASSERT(sweepMode == SweepToFreeList);
@@ -145,8 +142,8 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
         return FreeList();
     case Marked:
         return sweepMode == SweepToFreeList
-            ? specializedSweep<Marked, SweepToFreeList, dtorType>()
-            : specializedSweep<Marked, SweepOnly, dtorType>();
+            ? specializedSweep<Marked, SweepToFreeList, callDestructors>()
+            : specializedSweep<Marked, SweepOnly, callDestructors>();
     }
 
     RELEASE_ASSERT_NOT_REACHED();
index 576ed52..4674937 100644 (file)
@@ -111,8 +111,7 @@ namespace JSC {
             ReturnType m_count;
         };
 
-        enum DestructorType { None, ImmortalStructure, Normal };
-        static MarkedBlock* create(MarkedAllocator*, size_t capacity, size_t cellSize, DestructorType);
+        static MarkedBlock* create(MarkedAllocator*, size_t capacity, size_t cellSize, bool needsDestruction);
         static void destroy(MarkedBlock*);
 
         static bool isAtomAligned(const void*);
@@ -155,7 +154,7 @@ namespace JSC {
         bool isEmpty();
 
         size_t cellSize();
-        DestructorType destructorType();
+        bool needsDestruction() const;
 
         size_t size();
         size_t capacity();
@@ -190,15 +189,15 @@ namespace JSC {
         static const size_t atomAlignmentMask = atomSize - 1; // atomSize must be a power of two.
 
         enum BlockState { New, FreeListed, Allocated, Marked, Retired };
-        template<DestructorType> FreeList sweepHelper(SweepMode = SweepOnly);
+        template<bool callDestructors> FreeList sweepHelper(SweepMode = SweepOnly);
 
         typedef char Atom[atomSize];
 
-        MarkedBlock(MarkedAllocator*, size_t capacity, size_t cellSize, DestructorType);
+        MarkedBlock(MarkedAllocator*, size_t capacity, size_t cellSize, bool needsDestruction);
         Atom* atoms();
         size_t atomNumber(const void*);
-        template<DestructorType> void callDestructor(JSCell*);
-        template<BlockState, SweepMode, DestructorType> FreeList specializedSweep();
+        void callDestructor(JSCell*);
+        template<BlockState, SweepMode, bool callDestructors> FreeList specializedSweep();
         
         MarkedBlock* m_prev;
         MarkedBlock* m_next;
@@ -215,7 +214,7 @@ namespace JSC {
         std::unique_ptr<WTF::Bitmap<atomsPerBlock>> m_newlyAllocated;
 
         size_t m_capacity;
-        DestructorType m_destructorType;
+        bool m_needsDestruction;
         MarkedAllocator* m_allocator;
         BlockState m_state;
         WeakSet m_weakSet;
@@ -325,9 +324,9 @@ namespace JSC {
         return m_atomsPerCell * atomSize;
     }
 
-    inline MarkedBlock::DestructorType MarkedBlock::destructorType()
+    inline bool MarkedBlock::needsDestruction() const
     {
-        return m_destructorType; 
+        return m_needsDestruction;
     }
 
     inline size_t MarkedBlock::size()
index 31fe942..4f30890 100644 (file)
@@ -83,20 +83,17 @@ MarkedSpace::MarkedSpace(Heap* heap)
     , m_isIterating(false)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
-        allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
-        normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
-        immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
-        allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
-        normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
-        immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
     }
 
-    m_normalSpace.largeAllocator.init(heap, this, 0, MarkedBlock::None);
-    m_normalDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::Normal);
-    m_immortalStructureDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::ImmortalStructure);
+    m_normalSpace.largeAllocator.init(heap, this, 0, false);
+    m_destructorSpace.largeAllocator.init(heap, this, 0, true);
 }
 
 MarkedSpace::~MarkedSpace()
@@ -134,19 +131,16 @@ void MarkedSpace::resetAllocators()
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         allocatorFor(cellSize).reset();
-        normalDestructorAllocatorFor(cellSize).reset();
-        immortalStructureDestructorAllocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         allocatorFor(cellSize).reset();
-        normalDestructorAllocatorFor(cellSize).reset();
-        immortalStructureDestructorAllocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
     }
 
     m_normalSpace.largeAllocator.reset();
-    m_normalDestructorSpace.largeAllocator.reset();
-    m_immortalStructureDestructorSpace.largeAllocator.reset();
+    m_destructorSpace.largeAllocator.reset();
 
 #if ENABLE(GGC)
     m_blocksWithNewObjects.clear();
@@ -184,19 +178,16 @@ void MarkedSpace::forEachAllocator(Functor& functor)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         functor(allocatorFor(cellSize));
-        functor(normalDestructorAllocatorFor(cellSize));
-        functor(immortalStructureDestructorAllocatorFor(cellSize));
+        functor(destructorAllocatorFor(cellSize));
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         functor(allocatorFor(cellSize));
-        functor(normalDestructorAllocatorFor(cellSize));
-        functor(immortalStructureDestructorAllocatorFor(cellSize));
+        functor(destructorAllocatorFor(cellSize));
     }
 
     functor(m_normalSpace.largeAllocator);
-    functor(m_normalDestructorSpace.largeAllocator);
-    functor(m_immortalStructureDestructorSpace.largeAllocator);
+    functor(m_destructorSpace.largeAllocator);
 }
 
 struct StopAllocatingFunctor {
@@ -223,21 +214,18 @@ bool MarkedSpace::isPagedOut(double deadline)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         if (allocatorFor(cellSize).isPagedOut(deadline) 
-            || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 
-            || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
+            || destructorAllocatorFor(cellSize).isPagedOut(deadline))
             return true;
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         if (allocatorFor(cellSize).isPagedOut(deadline) 
-            || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 
-            || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
+            || destructorAllocatorFor(cellSize).isPagedOut(deadline))
             return true;
     }
 
     if (m_normalSpace.largeAllocator.isPagedOut(deadline)
-        || m_normalDestructorSpace.largeAllocator.isPagedOut(deadline)
-        || m_immortalStructureDestructorSpace.largeAllocator.isPagedOut(deadline))
+        || m_destructorSpace.largeAllocator.isPagedOut(deadline))
         return true;
 
     return false;
@@ -292,14 +280,12 @@ void MarkedSpace::clearNewlyAllocated()
 {
     for (size_t i = 0; i < preciseCount; ++i) {
         clearNewlyAllocatedInBlock(m_normalSpace.preciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_normalDestructorSpace.preciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_immortalStructureDestructorSpace.preciseAllocators[i].takeLastActiveBlock());
+        clearNewlyAllocatedInBlock(m_destructorSpace.preciseAllocators[i].takeLastActiveBlock());
     }
 
     for (size_t i = 0; i < impreciseCount; ++i) {
         clearNewlyAllocatedInBlock(m_normalSpace.impreciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_normalDestructorSpace.impreciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_immortalStructureDestructorSpace.impreciseAllocators[i].takeLastActiveBlock());
+        clearNewlyAllocatedInBlock(m_destructorSpace.impreciseAllocators[i].takeLastActiveBlock());
     }
 
     // We have to iterate all of the blocks in the large allocators because they are
@@ -307,8 +293,7 @@ void MarkedSpace::clearNewlyAllocated()
     // which creates the m_newlyAllocated bitmap.
     ClearNewlyAllocated functor;
     m_normalSpace.largeAllocator.forEachBlock(functor);
-    m_normalDestructorSpace.largeAllocator.forEachBlock(functor);
-    m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor);
+    m_destructorSpace.largeAllocator.forEachBlock(functor);
 
 #ifndef NDEBUG
     VerifyNewlyAllocated verifyFunctor;
index 9f32ee3..e939912 100644 (file)
@@ -103,14 +103,11 @@ public:
 
     MarkedAllocator& firstAllocator();
     MarkedAllocator& allocatorFor(size_t);
-    MarkedAllocator& immortalStructureDestructorAllocatorFor(size_t);
-    MarkedAllocator& normalDestructorAllocatorFor(size_t);
-    void* allocateWithNormalDestructor(size_t);
-    void* allocateWithImmortalStructureDestructor(size_t);
+    MarkedAllocator& destructorAllocatorFor(size_t);
+    void* allocateWithDestructor(size_t);
     void* allocateWithoutDestructor(size_t);
 
-    Subspace& subspaceForObjectsWithNormalDestructor() { return m_normalDestructorSpace; }
-    Subspace& subspaceForObjectsWithImmortalStructure() { return m_immortalStructureDestructorSpace; }
+    Subspace& subspaceForObjectsWithDestructor() { return m_destructorSpace; }
     Subspace& subspaceForObjectsWithoutDestructor() { return m_normalSpace; }
 
     void resetAllocators();
@@ -168,8 +165,7 @@ private:
     template<typename Functor> void forEachAllocator(Functor&);
     template<typename Functor> void forEachAllocator();
 
-    Subspace m_normalDestructorSpace;
-    Subspace m_immortalStructureDestructorSpace;
+    Subspace m_destructorSpace;
     Subspace m_normalSpace;
 
     Heap* m_heap;
@@ -219,24 +215,14 @@ inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
     return m_normalSpace.largeAllocator;
 }
 
-inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes)
+inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes)
 {
     ASSERT(bytes);
     if (bytes <= preciseCutoff)
-        return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
+        return m_destructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
     if (bytes <= impreciseCutoff)
-        return m_immortalStructureDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
-    return m_immortalStructureDestructorSpace.largeAllocator;
-}
-
-inline MarkedAllocator& MarkedSpace::normalDestructorAllocatorFor(size_t bytes)
-{
-    ASSERT(bytes);
-    if (bytes <= preciseCutoff)
-        return m_normalDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
-    if (bytes <= impreciseCutoff)
-        return m_normalDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
-    return m_normalDestructorSpace.largeAllocator;
+        return m_destructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
+    return m_destructorSpace.largeAllocator;
 }
 
 inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes)
@@ -244,14 +230,9 @@ inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes)
     return allocatorFor(bytes).allocate(bytes);
 }
 
-inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes)
+inline void* MarkedSpace::allocateWithDestructor(size_t bytes)
 {
-    return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes);
-}
-
-inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes)
-{
-    return normalDestructorAllocatorFor(bytes).allocate(bytes);
+    return destructorAllocatorFor(bytes).allocate(bytes);
 }
 
 template <typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachBlock(Functor& functor)
@@ -263,16 +244,10 @@ template <typename Functor> inline typename Functor::ReturnType MarkedSpace::for
     m_normalSpace.largeAllocator.forEachBlock(functor);
 
     for (size_t i = 0; i < preciseCount; ++i)
-        m_normalDestructorSpace.preciseAllocators[i].forEachBlock(functor);
-    for (size_t i = 0; i < impreciseCount; ++i)
-        m_normalDestructorSpace.impreciseAllocators[i].forEachBlock(functor);
-    m_normalDestructorSpace.largeAllocator.forEachBlock(functor);
-
-    for (size_t i = 0; i < preciseCount; ++i)
-        m_immortalStructureDestructorSpace.preciseAllocators[i].forEachBlock(functor);
+        m_destructorSpace.preciseAllocators[i].forEachBlock(functor);
     for (size_t i = 0; i < impreciseCount; ++i)
-        m_immortalStructureDestructorSpace.impreciseAllocators[i].forEachBlock(functor);
-    m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor);
+        m_destructorSpace.impreciseAllocators[i].forEachBlock(functor);
+    m_destructorSpace.largeAllocator.forEachBlock(functor);
 
     return functor.returnValue();
 }
index 0456a3e..2584ad6 100644 (file)
@@ -35,6 +35,7 @@ class InjectedScriptHost;
 class JSInjectedScriptHost : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     DECLARE_INFO;
 
@@ -70,8 +71,6 @@ public:
     JSC::JSValue iteratorEntries(JSC::ExecState*);
 
 protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     void finishCreation(JSC::VM&);
 
 private:
index 3eeb690..aa4963e 100644 (file)
@@ -33,6 +33,7 @@ namespace Inspector {
 class JSInjectedScriptHostPrototype : public JSC::JSNonFinalObject {
 public:
     typedef JSC::JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
 
     DECLARE_INFO;
 
@@ -48,9 +49,6 @@ public:
         return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     JSInjectedScriptHostPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
         : JSC::JSNonFinalObject(vm, structure)
index 7f0761b..b77c06e 100644 (file)
@@ -34,6 +34,7 @@ namespace Inspector {
 class JSJavaScriptCallFrame : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     DECLARE_INFO;
 
@@ -78,8 +79,6 @@ public:
     static const unsigned short FUNCTION_NAME_SCOPE = 5;
 
 protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     void finishCreation(JSC::VM&);
 
 private:
index 9aa7ee1..0811c24 100644 (file)
@@ -33,6 +33,7 @@ namespace Inspector {
 class JSJavaScriptCallFramePrototype : public JSC::JSNonFinalObject {
 public:
     typedef JSC::JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
 
     DECLARE_INFO;
 
@@ -48,9 +49,6 @@ public:
         return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     JSJavaScriptCallFramePrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
         : JSC::JSNonFinalObject(vm, structure)
index 37f9242..d8a6bae 100644 (file)
@@ -181,6 +181,7 @@ public:
     }
 
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::MasqueradesAsUndefined;
 
     static Masquerader* create(VM& vm, JSGlobalObject* globalObject)
     {
@@ -197,9 +198,6 @@ public:
     }
 
     DECLARE_INFO;
-
-protected:
-    static const unsigned StructureFlags = JSC::MasqueradesAsUndefined | Base::StructureFlags;
 };
 
 class Root : public JSDestructibleObject {
@@ -257,6 +255,7 @@ public:
 
     DECLARE_INFO;
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
@@ -277,8 +276,6 @@ public:
             m_delegate.set(vm, this, delegate);
     }
 
-    static const unsigned StructureFlags = JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
-
     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
     {
         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
@@ -308,6 +305,7 @@ private:
 class RuntimeArray : public JSArray {
 public:
     typedef JSArray Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
     static RuntimeArray* create(ExecState* exec)
     {
@@ -391,8 +389,6 @@ protected:
             m_vector.append(exec->argument(i).toInt32(exec));
     }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSArray::StructureFlags;
-
 private:
     RuntimeArray(ExecState* exec, Structure* structure)
         : JSArray(exec->vm(), structure, 0)
index 0efedf8..ab26f03 100644 (file)
 
 namespace JSC {
 
-class ArrayBufferNeuteringWatchpoint : public JSCell {
+class ArrayBufferNeuteringWatchpoint final : public JSCell {
 public:
     typedef JSCell Base;
-    
-private:
-    ArrayBufferNeuteringWatchpoint(VM&);
-    
-public:
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     DECLARE_INFO;
     
     static ArrayBufferNeuteringWatchpoint* create(VM&);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
     
     static Structure* createStructure(VM&);
@@ -54,6 +50,8 @@ public:
     void fireAll();
 
 private:
+    explicit ArrayBufferNeuteringWatchpoint(VM&);
+    
     RefPtr<WatchpointSet> m_set;
 };
 
index a6ac76e..040f26c 100644 (file)
@@ -32,6 +32,7 @@ class JSArray;
 class ArrayConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
     static ArrayConstructor* create(VM& vm, Structure* structure, ArrayPrototype* arrayPrototype)
     {
@@ -49,7 +50,6 @@ public:
 
 protected:
     void finishCreation(VM&, ArrayPrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     ArrayConstructor(VM&, Structure*);
index 547e332..2b234f8 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class ArrayIteratorPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
     static ArrayIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -48,9 +49,6 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     ArrayIteratorPrototype(VM& vm, Structure* structure)
         : Base(vm, structure)
index 35ece4b..6d8fc5e 100644 (file)
@@ -28,6 +28,7 @@ namespace JSC {
 class BooleanPrototype : public BooleanObject {
 public:
     typedef BooleanObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static BooleanPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -45,7 +46,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | BooleanObject::StructureFlags;
 
 private:
     BooleanPrototype(VM&, Structure*);
index c506948..1219d99 100644 (file)
@@ -41,6 +41,7 @@ namespace JSC {
 class ClonedArguments : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
     
 private:
     ClonedArguments(VM&, Structure*);
@@ -54,8 +55,6 @@ public:
     
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
-
     DECLARE_INFO;
 
 private:
index 4de7ded..54519eb 100644 (file)
 
 namespace JSC {
 
-class CustomGetterSetter : public JSCell {
+class CustomGetterSetter final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     typedef PropertySlot::GetValueFunc CustomGetter;
     typedef PutPropertySlot::PutValueFunc CustomSetter;
index 18bc340..054f571 100644 (file)
@@ -30,6 +30,7 @@ class DatePrototype;
 class DateConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static DateConstructor* create(VM& vm, Structure* structure, DatePrototype* datePrototype)
     {
@@ -47,7 +48,6 @@ public:
 
 protected:
     void finishCreation(VM&, DatePrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     DateConstructor(VM&, Structure*);
index 820e60b..6714d7e 100644 (file)
@@ -33,6 +33,7 @@ private:
 
 public:
     typedef DateInstance Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static DatePrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -51,7 +52,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
 };
 
 } // namespace JSC
index 2157ce4..29cd6a9 100644 (file)
@@ -30,6 +30,7 @@ class ObjectPrototype;
 class ErrorPrototype : public ErrorInstance {
 public:
     typedef ErrorInstance Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static ErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -49,8 +50,6 @@ protected:
     ErrorPrototype(VM&, Structure*);
     void finishCreation(VM&, JSGlobalObject*);
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
-
 private:
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 };
index d10d91f..d50e1d1 100644 (file)
@@ -56,17 +56,10 @@ JS_EXPORT_PRIVATE JSObject* throwStackOverflowError(ExecState*);
 JS_EXPORT_PRIVATE JSObject* throwTerminatedExecutionException(ExecState*);
 
 
-class TerminatedExecutionError : public JSNonFinalObject {
-private:
-    TerminatedExecutionError(VM& vm)
-        : JSNonFinalObject(vm, vm.terminatedExecutionErrorStructure.get())
-    {
-    }
-
-    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
-
+class TerminatedExecutionError final : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static TerminatedExecutionError* create(VM& vm)
     {
@@ -81,6 +74,15 @@ public:
     }
 
     DECLARE_EXPORT_INFO;
+
+private:
+    explicit TerminatedExecutionError(VM& vm)
+        : JSNonFinalObject(vm, vm.terminatedExecutionErrorStructure.get())
+    {
+    }
+
+    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
+
 };
 
 } // namespace JSC
index 48104e4..ba5f155 100644 (file)
@@ -84,9 +84,9 @@ protected:
 
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
         
     CodeBlockHash hashFor(CodeSpecializationKind) const;
@@ -117,7 +117,6 @@ public:
     DECLARE_EXPORT_INFO;
 
 protected:
-    static const unsigned StructureFlags = StructureIsImmortal;
     int m_numParametersForCall;
     int m_numParametersForConstruct;
 
@@ -278,11 +277,12 @@ protected:
     MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheckAndPreserveRegs;
 };
 
-class NativeExecutable : public ExecutableBase {
+class NativeExecutable final : public ExecutableBase {
     friend class JIT;
     friend class LLIntOffsetsExtractor;
 public:
     typedef ExecutableBase Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic)
     {
@@ -347,8 +347,7 @@ private:
 class ScriptExecutable : public ExecutableBase {
 public:
     typedef ExecutableBase Base;
-
-    ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     static void destroy(JSCell*);
         
@@ -416,6 +415,8 @@ private:
     JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
 
 protected:
+    ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);
+
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
@@ -441,10 +442,11 @@ protected:
     unsigned m_typeProfilingEndOffset;
 };
 
-class EvalExecutable : public ScriptExecutable {
+class EvalExecutable final : public ScriptExecutable {
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static void destroy(JSCell*);
 
@@ -486,10 +488,11 @@ private:
     WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
 };
 
-class ProgramExecutable : public ScriptExecutable {
+class ProgramExecutable final : public ScriptExecutable {
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
     {
@@ -539,11 +542,12 @@ private:
     RefPtr<ProgramCodeBlock> m_programCodeBlock;
 };
 
-class FunctionExecutable : public ScriptExecutable {
+class FunctionExecutable final : public ScriptExecutable {
     friend class JIT;
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static FunctionExecutable* create(
         VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, 
index 2e9373c..67f1b03 100644 (file)
@@ -36,8 +36,7 @@ template<typename Type>
 class GenericArguments : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
-
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
 protected:
     GenericArguments(VM& vm, Structure* structure)
index 8080a80..b983f04 100644 (file)
@@ -41,7 +41,7 @@ class JSObject;
 // that if a property holding a GetterSetter reference is constant-inferred and
 // that constant is observed to have a non-null setter (or getter) then we can
 // constant fold that setter (or getter).
-class GetterSetter : public JSCell {
+class GetterSetter final : public JSCell {
     friend class JIT;
 
 private:
@@ -54,6 +54,7 @@ private:
 
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static GetterSetter* create(VM& vm, JSGlobalObject* globalObject)
     {
index 37b5fe1..79f4791 100644 (file)
@@ -34,6 +34,7 @@ class FunctionPrototype;
 class InternalFunction : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
 
     DECLARE_EXPORT_INFO;
 
@@ -47,8 +48,6 @@ public:
     }
 
 protected:
-    static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
-
     JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);
 
     JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
index 56a816d..66e61c7 100644 (file)
@@ -34,6 +34,7 @@ class JSAPIValueWrapper : public JSCell {
     friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     JSValue value() const { return m_value.get(); }
 
index efcf91e..0567a57 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class JSArgumentsIterator : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     DECLARE_EXPORT_INFO;
 
@@ -62,9 +63,6 @@ public:
     JSArgumentsIterator* clone(ExecState*);
 
 private:
-
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     JSArgumentsIterator(VM& vm, Structure* structure)
         : Base(vm, structure)
         , m_nextIndex(0)
index 01e5a3b..aabd55b 100644 (file)
@@ -37,6 +37,7 @@ class JSArray : public JSNonFinalObject {
 
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static size_t allocationSize(size_t inlineCapacity)
     {
@@ -140,7 +141,6 @@ public:
     }
         
 protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
 
     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
index 319b82e..7529e36 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
 class JSArrayBuffer : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot;
     
 protected:
     JSArrayBuffer(VM&, Structure*, PassRefPtr<ArrayBuffer>);
@@ -56,8 +57,6 @@ protected:
     
     static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     ArrayBuffer* m_impl;
 };
index 3feb03b..0514452 100644 (file)
@@ -93,6 +93,7 @@ inline bool hasArrayBuffer(TypedArrayMode mode)
 class JSArrayBufferView : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot;
     
     static const unsigned fastSizeLimit = 1000;
     
@@ -174,8 +175,6 @@ private:
     static void finalize(JSCell*);
 
 protected:
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | Base::StructureFlags;
-    
     ArrayBuffer* existingBufferInButterfly();
 
     void* m_vector;
index 3644b29..1795c96 100644 (file)
@@ -36,6 +36,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState*);
 class JSBoundFunction : public JSFunction {
 public:
     typedef JSFunction Base;
+    const static unsigned StructureFlags = OverridesHasInstance | Base::StructureFlags;
 
     static JSBoundFunction* create(VM&, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&);
     
@@ -56,8 +57,6 @@ public:
     DECLARE_INFO;
 
 protected:
-    const static unsigned StructureFlags = OverridesHasInstance | Base::StructureFlags;
-
     static void visitChildren(JSCell*, SlotVisitor&);
 
 private:
index ebb11e3..5cd82bf 100644 (file)
@@ -46,6 +46,7 @@ class JSCallee : public JSDestructibleObject {
 
 public:
     typedef JSDestructibleObject Base;
+    const static unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
 
     static JSCallee* create(VM& vm, JSGlobalObject* globalObject, JSScope* scope)
     {
@@ -90,8 +91,6 @@ public:
     }
 
 protected:
-    const static unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
-
     JS_EXPORT_PRIVATE JSCallee(VM&, JSGlobalObject*, Structure*);
     JSCallee(VM&, JSScope*, Structure*);
 
index 4839f64..c47fc10 100644 (file)
@@ -73,7 +73,6 @@ public:
     static const unsigned StructureFlags = 0;
 
     static const bool needsDestruction = false;
-    static const bool hasImmortalStructure = false;
 
     enum CreatingEarlyCellTag { CreatingEarlyCell };
     JSCell(CreatingEarlyCellTag);
index dbb1004..ff93537 100644 (file)
@@ -240,7 +240,7 @@ inline bool JSCell::canUseFastGetOwnProperty(const Structure& structure)
 inline const ClassInfo* JSCell::classInfo() const
 {
     MarkedBlock* block = MarkedBlock::blockFor(this);
-    if (block->destructorType() == MarkedBlock::Normal)
+    if (block->needsDestruction() && !(inlineTypeFlags() & StructureIsImmortal))
         return static_cast<const JSDestructibleObject*>(this)->classInfo();
     return structure(*block->vm())->classInfo();
 }
index 9d2ba2c..bc72455 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class JSDataViewPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
 protected:
     JSDataViewPrototype(VM&, Structure*);
@@ -46,8 +47,6 @@ public:
 
 protected:
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 };
 
 } // namespace JSC
index 811e4d1..4b2c0df 100644 (file)
@@ -45,6 +45,7 @@ class JSEnvironmentRecord : public JSSymbolTableObject {
 
 public:
     typedef JSSymbolTableObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     WriteBarrierBase<Unknown>* variables()
     {
@@ -85,8 +86,6 @@ public:
     }
     
 protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     JSEnvironmentRecord(
         VM& vm,
         Structure* structure,
index 9bd3fe2..58aa9bd 100644 (file)
@@ -57,6 +57,7 @@ class JSFunction : public JSCallee {
 
 public:
     typedef JSCallee Base;
+    const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
 
@@ -128,8 +129,6 @@ public:
     bool isClassConstructorFunction() const;
 
 protected:
-    const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesGetPropertyNames | JSObject::StructureFlags;
-
     JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
     JSFunction(VM&, FunctionExecutable*, JSScope*);
 
index 1343eee..3996e1c 100644 (file)
@@ -87,6 +87,8 @@ template<typename Adaptor>
 class JSGenericTypedArrayView : public JSArrayBufferView {
 public:
     typedef JSArrayBufferView Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero;
+
     static const unsigned elementSize = sizeof(typename Adaptor::Type);
     
 protected:
@@ -228,8 +230,6 @@ public:
     
 protected:
     friend struct TypedArrayClassInfos;
-    
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
 
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
index 3e57837..32c291c 100644 (file)
@@ -296,6 +296,7 @@ protected:
         
 public:
     typedef JSSegmentedVariableObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static JSGlobalObject* create(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = nullptr)
     {
@@ -604,9 +605,6 @@ public:
     UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode);
 
 protected:
-
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
-
     struct GlobalPropertyInfo {
         GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
             : identifier(i)
index 9ec06c6..4d9e341 100644 (file)
@@ -44,6 +44,7 @@ private:
     
 public:
     typedef JSEnvironmentRecord Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static JSLexicalEnvironment* create(
         VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
@@ -78,9 +79,6 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
 
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
-
 private:
     bool symbolTableGet(PropertyName, PropertySlot&);
     bool symbolTableGet(PropertyName, PropertyDescriptor&);
index c2b6952..db8d008 100644 (file)
@@ -35,6 +35,7 @@ namespace JSC {
 class JSNameScope : public JSEnvironmentRecord {
 public:
     typedef JSEnvironmentRecord Base;
+    static const unsigned StructureFlags = Base::StructureFlags| OverridesGetOwnPropertySlot;
 
     enum Type {
         CatchScope,
@@ -68,8 +69,6 @@ protected:
         variableAt(ScopeOffset(0)).set(vm, this, value);
     }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
-
     JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
         : Base(vm, structure, next, symbolTable)
     {
index e7c0a04..0c26ec9 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 // This unholy class is used to allow us to avoid multiple exception checks
 // in certain SquirrelFish bytecodes -- effectively it just silently consumes
 // any operations performed on the result of a failed toObject call.
-class JSNotAnObject : public JSNonFinalObject {
+class JSNotAnObject final : public JSNonFinalObject {
 private:
     explicit JSNotAnObject(VM& vm)
         : JSNonFinalObject(vm, vm.notAnObjectStructure.get())
@@ -45,6 +45,7 @@ private:
 
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
     static JSNotAnObject* create(VM& vm)
     {
@@ -61,9 +62,6 @@ public:
     DECLARE_INFO;
 
 private:
-
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
-
     // JSValue methods
     static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
 
index 4e1a5ac..eb6daad 100644 (file)
@@ -35,6 +35,7 @@ class Stringifier;
 class JSONObject : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static JSONObject* create(VM& vm, Structure* structure)
     {
@@ -52,7 +53,6 @@ public:
 
 protected:
     void finishCreation(VM&);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
 
 private:
     JSONObject(VM&, Structure*);
index 53f7f5b..a46902a 100644 (file)
@@ -1031,6 +1031,7 @@ class JSFinalObject : public JSObject {
 
 public:
     typedef JSObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     static size_t allocationSize(size_t inlineCapacity)
     {
@@ -1077,8 +1078,6 @@ private:
         : JSObject(vm, structure, butterfly)
     {
     }
-
-    static const unsigned StructureFlags = JSObject::StructureFlags;
 };
 
 inline JSFinalObject* JSFinalObject::create(
index 498bb8b..fc0f04d 100644 (file)
@@ -38,6 +38,7 @@ class JSPromisePrototype;
 class JSPromiseConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static JSPromiseConstructor* create(VM&, Structure*, JSPromisePrototype*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
@@ -46,7 +47,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSPromisePrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     JSPromiseConstructor(VM&, Structure*);
index fbcf0c6..b9dc28b 100644 (file)
 
 namespace JSC {
 
-class JSPromiseDeferred : public JSCell {
+class JSPromiseDeferred final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     JS_EXPORT_PRIVATE static JSPromiseDeferred* create(ExecState*, JSGlobalObject*);
     JS_EXPORT_PRIVATE static JSPromiseDeferred* create(VM&, JSObject* promise, JSValue resolve, JSValue reject);
@@ -45,8 +46,6 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
-    static const bool hasImmortalStructure = true;
-
     DECLARE_EXPORT_INFO;
 
     JSObject* promise() const { return m_promise.get(); }
index 893fc4a..cd7cef4 100644 (file)
@@ -35,6 +35,7 @@ namespace JSC {
 class JSPromisePrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static JSPromisePrototype* create(ExecState*, JSGlobalObject*, Structure*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
@@ -43,7 +44,6 @@ public:
 
 protected:
     void finishCreation(VM&, Structure*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
 
 private:
     JSPromisePrototype(ExecState*, Structure*);
index b42794a..09be2df 100644 (file)
@@ -36,9 +36,10 @@ namespace JSC {
 class JSPromiseDeferred;
 class Microtask;
 
-class JSPromiseReaction : public JSCell {
+class JSPromiseReaction final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static JSPromiseReaction* create(VM&, JSPromiseDeferred*, JSValue);
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -46,8 +47,6 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
-    static const bool hasImmortalStructure = true;
-
     DECLARE_INFO;
 
     JSPromiseDeferred* deferred() const { return m_deferred.get(); }
index 778308a..3d8c89d 100644 (file)
@@ -35,15 +35,15 @@ namespace JSC {
 
 class Identifier;
 
-class JSPropertyNameEnumerator : public JSCell {
+class JSPropertyNameEnumerator final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static JSPropertyNameEnumerator* create(VM&);
     static JSPropertyNameEnumerator* create(VM&, Structure*, uint32_t, uint32_t, PropertyNameArray&);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -92,8 +92,6 @@ public:
     static void visitChildren(JSCell*, SlotVisitor&);
 
 private:
-    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
-
     JSPropertyNameEnumerator(VM&, StructureID, uint32_t, RefCountedIdentifierSet*);
     void finishCreation(VM&, uint32_t, uint32_t, PassRefPtr<PropertyNameArrayData>);
 
index cda621b..2bdcd1b 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class JSProxy : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero;
 
     static JSProxy* create(VM& vm, Structure* structure, JSObject* target)
     {
@@ -68,8 +69,6 @@ protected:
         m_target.set(vm, this, target);
     }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
-
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
     JS_EXPORT_PRIVATE void setTarget(VM&, JSGlobalObject*);
index aa8bdeb..df581a0 100644 (file)
@@ -149,6 +149,7 @@ enum GetOrPut { Get, Put };
 class JSScope : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     friend class LLIntOffsetsExtractor;
     static size_t offsetOfNext();
index 34af52d..a22e6fb 100644 (file)
@@ -73,9 +73,9 @@ public:
     friend struct ThunkHelpers;
 
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
 private:
@@ -182,8 +182,6 @@ public:
     };
 
 protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
-
     friend class JSValue;
 
     bool isRope() const { return m_value.isNull(); }
@@ -219,7 +217,7 @@ private:
     friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
 };
 
-class JSRopeString : public JSString {
+class JSRopeString final : public JSString {
     friend class JSString;
 
     friend JSRopeString* jsStringBuilder(VM*);
index 2685346..d92509a 100644 (file)
@@ -41,6 +41,7 @@ class JSSymbolTableObject;
 class JSSymbolTableObject : public JSScope {
 public:
     typedef JSScope Base;
+    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord | OverridesGetPropertyNames;
     
     SymbolTable* symbolTable() const { return m_symbolTable.get(); }
     
@@ -50,8 +51,6 @@ public:
     static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
     
 protected:
-    static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetPropertyNames | Base::StructureFlags;
-    
     JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
         : Base(vm, structure, scope)
     {
index f695968..ecf6c34 100644 (file)
@@ -43,12 +43,12 @@ static const unsigned ImplementsDefaultHasInstance = 1 << 3;
 static const unsigned IsEnvironmentRecord = 1 << 4;
 static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
 static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
+static const unsigned StructureIsImmortal = 1 << 7;
 
 static const unsigned OverridesGetPropertyNames = 1 << 8;
 static const unsigned ProhibitsPropertyCaching = 1 << 9;
 static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
 static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
-static const unsigned StructureIsImmortal = 1 << 12;
 
 class TypeInfo {
 public:
@@ -91,7 +91,7 @@ public:
     bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
     bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
     bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
-    bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
+    bool structureIsImmortal() const { return isSetOnFlags1(StructureIsImmortal); }
 
     static ptrdiff_t flagsOffset()
     {
index 84d1f4f..fb7d928 100644 (file)
@@ -31,6 +31,7 @@ private:
 
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static MathObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -48,7 +49,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
 };
 
 } // namespace JSC
index 630f5e5..f8b1f7f 100644 (file)
@@ -30,6 +30,7 @@ class NumberPrototype;
 class NumberConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | ImplementsHasInstance;
 
     static NumberConstructor* create(VM& vm, Structure* structure, NumberPrototype* numberPrototype)
     {
@@ -47,7 +48,6 @@ public:
 
 protected:
     void finishCreation(VM&, NumberPrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
 
 private:
     NumberConstructor(VM&, Structure*);
index 5972f7b..45acd8f 100644 (file)
@@ -28,6 +28,7 @@ namespace JSC {
 class NumberPrototype : public NumberObject {
 public:
     typedef NumberObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static NumberPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -45,7 +46,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NumberObject::StructureFlags;
 
 private:
     NumberPrototype(VM&, Structure*);
index bb067b1..fbbf8f5 100644 (file)
@@ -32,6 +32,7 @@ class ObjectPrototype;
 class ObjectConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static ObjectConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, ObjectPrototype* objectPrototype)
     {
@@ -51,7 +52,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*, ObjectPrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     ObjectConstructor(VM&, Structure*);
index 754da2d..7e8e1d0 100644 (file)
@@ -77,7 +77,7 @@ inline unsigned nextPowerOf2(unsigned v)
     return v;
 }
 
-class PropertyTable : public JSCell {
+class PropertyTable final : public JSCell {
 
     // This is the implementation for 'iterator' and 'const_iterator',
     // used for iterating over the table in insertion order.
@@ -120,8 +120,10 @@ class PropertyTable : public JSCell {
     };
 
 public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     DECLARE_EXPORT_INFO;
@@ -190,9 +192,6 @@ public:
     void checkConsistency();
 #endif
 
-protected:
-    static const unsigned StructureFlags = StructureIsImmortal;
-
 private:
     PropertyTable(VM&, unsigned initialCapacity);
     PropertyTable(VM&, const PropertyTable&);
index 2e16f29..670505f 100644 (file)
@@ -42,13 +42,13 @@ class VM;
 
 JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
 
-class RegExp : public JSCell {
+class RegExp final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     bool global() const { return m_flags & FlagGlobal; }
@@ -85,8 +85,6 @@ public:
     RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
 
 protected:
-    static const unsigned StructureFlags = StructureIsImmortal;
-
     void finishCreation(VM&);
 
 private:
index a832006..cabee19 100644 (file)
@@ -33,6 +33,7 @@ class RegExpPrototype;
 class RegExpConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
     {
@@ -68,7 +69,6 @@ public:
 
 protected:
     void finishCreation(VM&, RegExpPrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
 private:
     RegExpConstructor(VM&, Structure*, RegExpPrototype*);
index 7c4b750..a1f571d 100644 (file)
@@ -29,6 +29,7 @@ namespace JSC {
 class RegExpObject : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
     {
@@ -77,8 +78,6 @@ protected:
     JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
     JS_EXPORT_PRIVATE void finishCreation(VM&);
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
-
     static void visitChildren(JSCell*, SlotVisitor&);
 
     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
index f98fd06..cb6ee69 100644 (file)
@@ -29,6 +29,7 @@ namespace JSC {
 class RegExpPrototype : public RegExpObject {
 public:
     typedef RegExpObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static RegExpPrototype* create(VM& vm, Structure* structure, RegExp* regExp)
     {
@@ -46,7 +47,6 @@ public:
 
 protected:
     RegExpPrototype(VM&, Structure*, RegExp*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | RegExpObject::StructureFlags;
 
 private:
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
index 8efd23d..b6d7ddc 100644 (file)
@@ -38,9 +38,10 @@ namespace JSC {
 // and aliases one of these and then decides to modify it; in that case we do copy-on-write. This
 // makes sense because such modifications are so uncommon. You'd have to do something crazy like
 // "delete arguments[i]" or some variant of defineOwnProperty.
-class ScopedArgumentsTable : public JSCell {
+class ScopedArgumentsTable final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     
 private:
     ScopedArgumentsTable(VM&);
@@ -51,7 +52,6 @@ public:
     static ScopedArgumentsTable* create(VM&, uint32_t length);
     
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     ScopedArgumentsTable* clone(VM&);
@@ -79,8 +79,6 @@ public:
     static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); }
 
 private:
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
-
     ScopeOffset& at(uint32_t i)
     {
         ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
index 0890672..ff36caa 100644 (file)
@@ -51,9 +51,10 @@ struct SparseArrayEntry : public WriteBarrier<Unknown> {
     unsigned attributes;
 };
 
-class SparseArrayValueMap : public JSCell {
+class SparseArrayValueMap final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     
 private:
     typedef HashMap<uint64_t, SparseArrayEntry, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> Map;
@@ -69,8 +70,6 @@ private:
     
     void finishCreation(VM&);
 
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
-
 public:
     DECLARE_EXPORT_INFO;
     
@@ -81,7 +80,6 @@ public:
     static SparseArrayValueMap* create(VM&);
     
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
     
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
index 816a1a4..13157f6 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class StrictEvalActivation : public JSScope {
 public:
     typedef JSScope Base;
+    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord;
 
     static StrictEvalActivation* create(ExecState* exec, JSScope* currentScope)
     {
@@ -51,9 +52,6 @@ public:
     
     DECLARE_INFO;
 
-protected:
-    static const unsigned StructureFlags = IsEnvironmentRecord | Base::StructureFlags;
-
 private:
     StrictEvalActivation(ExecState*, JSScope*);
 };
index 0086a6b..357511a 100644 (file)
@@ -30,6 +30,7 @@ class StringPrototype;
 class StringConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static StringConstructor* create(VM& vm, Structure* structure, StringPrototype* stringPrototype)
     {
@@ -45,9 +46,6 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
-
 private:
     StringConstructor(VM&, Structure*);
     void finishCreation(VM&, StringPrototype*);
index cbbd960..393af56 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
 class StringIteratorPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static StringIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -49,9 +50,6 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     StringIteratorPrototype(VM& vm, Structure* structure)
         : Base(vm, structure)
index 0cebfde..90e6e5c 100644 (file)
@@ -29,6 +29,7 @@ namespace JSC {
 class StringObject : public JSWrapperObject {
 public:
     typedef JSWrapperObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
     static StringObject* create(VM& vm, Structure* structure)
     {
@@ -67,7 +68,6 @@ public:
 
 protected:
     JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
     JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
 };
 
index 9657796..bd4f02a 100644 (file)
@@ -33,6 +33,7 @@ private:
 
 public:
     typedef StringObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     static StringPrototype* create(VM&, JSGlobalObject*, Structure*);
 
@@ -45,7 +46,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*, JSString*);
-    static const unsigned StructureFlags = StringObject::StructureFlags;
 };
 
 } // namespace JSC
index 1738ca6..046b061 100644 (file)
@@ -202,7 +202,7 @@ Structure::Structure(VM& vm)
     setStaticFunctionsReified(false);
     setHasRareData(false);
  
-    TypeInfo typeInfo = TypeInfo(CellType, StructureIsImmortal);
+    TypeInfo typeInfo = TypeInfo(CellType, StructureFlags);
     m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo);
     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
 
index 7b48d34..1b44e2a 100644 (file)
@@ -92,11 +92,12 @@ struct PropertyMapEntry {
     }
 };
 
-class Structure : public JSCell {
+class Structure final : public JSCell {
 public:
     friend class StructureTransitionTable;
 
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     
     static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
 
@@ -153,7 +154,6 @@ public:
     JS_EXPORT_PRIVATE Structure* flattenDictionaryStructure(VM&, JSObject*);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     // These should be used with caution.  
index 49f3e46..0fbd1e2 100644 (file)
@@ -40,11 +40,12 @@ namespace JSC {
 class LLIntOffsetsExtractor;
 class Structure;
 
-class StructureChain : public JSCell {
+class StructureChain final : public JSCell {
     friend class JIT;
 
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static StructureChain* create(VM& vm, Structure* head)
     { 
@@ -63,12 +64,9 @@ public:
     DECLARE_INFO;
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
 protected:
-    static const unsigned StructureFlags = StructureIsImmortal;
-
     void finishCreation(VM& vm, Structure* head)
     {
         Base::finishCreation(vm);
index 23f05f9..2b11ab8 100644 (file)
@@ -36,12 +36,14 @@ namespace JSC {
 class JSPropertyNameEnumerator;
 class Structure;
 
-class StructureRareData : public JSCell {
+class StructureRareData final : public JSCell {
 public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static StructureRareData* create(VM&, Structure*);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     static void visitChildren(JSCell*, SlotVisitor&);
@@ -65,8 +67,6 @@ private:
     
     StructureRareData(VM&, Structure*);
 
-    static const unsigned StructureFlags = JSCell::StructureFlags;
-
     WriteBarrier<Structure> m_previous;
     WriteBarrier<JSString> m_objectToStringValue;
     WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator;
index 27b01fc..19b6f4f 100644 (file)
 
 namespace JSC {
 
-class Symbol : public JSCell {
+class Symbol final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
 
     DECLARE_EXPORT_INFO;
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
@@ -81,8 +81,6 @@ public:
     double toNumber(ExecState*) const;
 
 protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
-
     static void destroy(JSCell*);
 
     Symbol(VM&);
index 85a93d3..8b221e5 100644 (file)
@@ -36,6 +36,7 @@ namespace JSC {
 class SymbolPrototype : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static SymbolPrototype* create(VM& vm, JSGlobalObject*, Structure* structure)
     {
@@ -55,8 +56,6 @@ protected:
     SymbolPrototype(VM&, Structure*);
     void finishCreation(VM&);
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 };
index a6a21e7..37cbb24 100644 (file)
@@ -404,9 +404,10 @@ struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
     static const bool needsDestruction = true;
 };
 
-class SymbolTable : public JSCell {
+class SymbolTable final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, SymbolTableIndexHashTraits> Map;
     typedef HashMap<RefPtr<StringImpl>, GlobalVariableID> UniqueIDMap;
@@ -429,7 +430,6 @@ public:
     }
     
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -642,9 +642,6 @@ public:
 
     DECLARE_EXPORT_INFO;
 
-protected:
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
-
 private:
     class WatchpointCleanup : public UnconditionalFinalizer {
     public:
index d1c91f2..cfcd853 100644 (file)
 
 namespace JSC {
 
-class WeakMapData : public JSCell {
+class WeakMapData final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static WeakMapData* create(VM& vm)
     {
@@ -51,7 +52,6 @@ public:
     }
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
 
     void set(VM&, JSObject*, JSValue);
     JSValue get(JSObject*);
@@ -61,8 +61,6 @@ public:
 
     DECLARE_INFO;
 
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
-
     typedef HashMap<JSObject*, WriteBarrier<Unknown>> MapType;
     MapType::const_iterator begin() const { return m_map.begin(); }
     MapType::const_iterator end() const { return m_map.end(); }
index bcea040..88ad56c 100644 (file)
@@ -1,3 +1,19 @@
+2015-04-13  Andreas Kling  <akling@apple.com>
+
+        Don't segregate heap objects based on Structure immortality.
+        <https://webkit.org/b/143638>
+
+        Reviewed by Darin Adler.
+
+        * bindings/js/JSDOMBinding.h:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader):
+        (GeneratePrototypeDeclaration):
+        * bridge/objc/objc_runtime.h:
+        * bridge/runtime_array.h:
+        * bridge/runtime_method.h:
+        * bridge/runtime_object.h:
+
 2015-04-13  Simon Fraser  <simon.fraser@apple.com>
 
         Fixed position element is truncated if moved onscreen by a transform
index edb2b79..1e0c8fd 100644 (file)
@@ -84,15 +84,16 @@ WEBCORE_EXPORT JSC::EncodedJSValue throwThisTypeError(JSC::ExecState&, const cha
 
 // Base class for all constructor objects in the JSC bindings.
 class DOMConstructorObject : public JSDOMWrapper {
-    typedef JSDOMWrapper Base;
 public:
+    typedef JSDOMWrapper Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::ImplementsHasInstance;
+
     static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
         return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
     }
 
 protected:
-    static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSDOMWrapper::StructureFlags;
     DOMConstructorObject(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
         : JSDOMWrapper(structure, globalObject)
     {
index 0731949..625c139 100644 (file)
@@ -1103,6 +1103,16 @@ sub GenerateHeader
         push(@headerContent, "    }\n");
     }
 
+    # structure flags
+    if (%structureFlags) {
+        push(@headerContent, "public:\n");
+        push(@headerContent, "    static const unsigned StructureFlags = ");
+        foreach my $structureFlag (sort (keys %structureFlags)) {
+            push(@headerContent, $structureFlag . " | ");
+        }
+        push(@headerContent, "Base::StructureFlags;\n");
+    }
+
     push(@headerContent, "protected:\n");
 
     # Constructor
@@ -1119,15 +1129,6 @@ sub GenerateHeader
         push(@headerContent, "    }\n\n");
     }
 
-    # structure flags
-    if (%structureFlags) {
-        push(@headerContent, "    static const unsigned StructureFlags = ");
-        foreach my $structureFlag (sort (keys %structureFlags)) {
-            push(@headerContent, $structureFlag . " | ");
-        }
-        push(@headerContent, "Base::StructureFlags;\n");
-    }
-
     # Index setter
     if ($interface->extendedAttributes->{"CustomIndexedSetter"}) {
         push(@headerContent, "    void indexSetter(JSC::ExecState*, unsigned index, JSC::JSValue);\n");
@@ -4303,7 +4304,7 @@ sub GeneratePrototypeDeclaration
 
     # structure flags
     if (%structureFlags) {
-        push(@$outputArray, "protected:\n");
+        push(@$outputArray, "public:\n");
         push(@$outputArray, "    static const unsigned StructureFlags = ");
         foreach my $structureFlag (sort (keys %structureFlags)) {
             push(@$outputArray, $structureFlag . " | ");
index e6a9bc9..f55116e 100644 (file)
@@ -93,6 +93,7 @@ private:
 class ObjcFallbackObjectImp : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static ObjcFallbackObjectImp* create(ExecState* exec, JSGlobalObject* globalObject, ObjcInstance* instance, const String& propertyName)
     {
@@ -123,7 +124,6 @@ protected:
 private:
     ObjcFallbackObjectImp(JSGlobalObject*, Structure*, ObjcInstance*, const String& propertyName);
     static void destroy(JSCell*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     static CallType getCallData(JSCell*, CallData&);
index b6d1f68..0d3f0e6 100644 (file)
@@ -35,6 +35,7 @@ namespace JSC {
 class RuntimeArray : public JSArray {
 public:
     typedef JSArray Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
     static RuntimeArray* create(ExecState* exec, Bindings::Array* array)
     {
@@ -80,8 +81,6 @@ public:
 protected:
     void finishCreation(VM&, Bindings::Array*);
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSArray::StructureFlags;
-
 private:
     RuntimeArray(ExecState*, Structure*);
     static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
index e7dc7f4..8ad2743 100644 (file)
@@ -35,6 +35,7 @@ namespace JSC {
 class WEBCORE_EXPORT RuntimeMethod : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static RuntimeMethod* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const String& name, Bindings::Method* method)
     {
@@ -60,7 +61,6 @@ public:
 protected:
     RuntimeMethod(JSGlobalObject*, Structure*, Bindings::Method*);
     void finishCreation(VM&, const String&);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
     static CallType getCallData(JSCell*, CallData&);
 
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
index 2c2ae5f..14394c2 100644 (file)
@@ -35,6 +35,7 @@ namespace Bindings {
 class WEBCORE_EXPORT RuntimeObject : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static RuntimeObject* create(VM& vm, Structure* structure, PassRefPtr<Instance> instance)
     {
@@ -75,7 +76,6 @@ public:
 protected:
     RuntimeObject(VM&, Structure*, PassRefPtr<Instance>);
     void finishCreation(VM&);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
 
 private:
     static EncodedJSValue fallbackObjectGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
index 49eedef..d6cd922 100644 (file)
@@ -1,3 +1,12 @@
+2015-04-13  Andreas Kling  <akling@apple.com>
+
+        Don't segregate heap objects based on Structure immortality.
+        <https://webkit.org/b/143638>
+
+        Reviewed by Darin Adler.
+
+        * WebProcess/Plugins/Netscape/JSNPObject.h:
+
 2015-04-13  Timothy Horton  <timothy_horton@apple.com>
 
         javascript: links in inline PDFs shouldn't execute JavaScript in the context of the host website
index 79daf5b..757ffbe 100644 (file)
@@ -44,6 +44,7 @@ class NPRuntimeObjectMap;
 class JSNPObject : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames;
 
     static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject)
     {
@@ -74,8 +75,6 @@ protected:
 
 private:
     JSNPObject(JSC::JSGlobalObject*, JSC::Structure*, NPRuntimeObjectMap*, NPObject*);
-
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags;
     
     static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {