De-virtualize destructors
authormhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Dec 2011 19:06:44 +0000 (19:06 +0000)
committermhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Dec 2011 19:06:44 +0000 (19:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=74331

Reviewed by Geoffrey Garen.

.:

* Source/autotools/symbols.filter: Removed symbol no longer present.

Source/JavaScriptCore:

This is a megapatch which frees us from the chains of virtual destructors.

In order to remove the virtual destructors, which are the last of the virtual
functions, from the JSCell hierarchy, we need to add the ClassInfo pointer to
the cell rather than to the structure because in order to be able to lazily call
the static destroy() functions that will replace the virtual destructors, we
need to be able to access the ClassInfo without the danger of the object's
Structure being collected before the object itself.

After adding the ClassInfo to the cell, we can then begin to remove our use
of vptrs for optimizations within the JIT and the GC.  When we have removed
all of the stored vptrs from JSGlobalData, we can then also remove all of
the related VPtrStealingHack code.

The replacement for virtual destructors will be to add a static destroy function
pointer to the MethodTable stored in ClassInfo.  Any subclass of JSCell that has
a non-trivial destructor will require its own static destroy function to static
call its corresponding destructor, which will now be non-virtual.  In future
patches we will slowly move away from destructors altogether as we make more and
more objects backed by GC memory rather than malloc-ed memory.  The GC will now
call the static destroy method rather than the virtual destructor.

As we go through the hierarchy and add static destroy functions to classes,
we will also add a new assert, ASSERT_HAS_TRIVIAL_DESTRUCTOR, to those classes
to which it applies.  The future goal is to eventually have every class have that assert.

* API/JSCallbackConstructor.cpp:
(JSC::JSCallbackConstructor::destroy): Add a destroy function to statically call
~JSCallbackConstructor because it has some extra destruction logic.
* API/JSCallbackConstructor.h:
* API/JSCallbackFunction.cpp: Add trivial destructor assert for JSCallbackFunction.
* API/JSCallbackObject.cpp: Add a destroy function to statically call ~JSCallbackObject
because it has a member OwnPtr that needs destruction.
(JSC::::destroy):
* API/JSCallbackObject.h:
* JavaScriptCore.exp: Add/remove necessary symbols for JSC.
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Same for Windows symbols.
* debugger/DebuggerActivation.cpp: DebuggerActivation, for some strange reason, didn't
have its own ClassInfo despite the fact that it overrides a number of MethodTable
methods.  Added the ClassInfo, along with an assertion that its destructor is trivial.
* debugger/DebuggerActivation.h:
* dfg/DFGOperations.cpp: Remove global data first argument to isJSArray, isJSByteArray,
isJSString, as it is no longer necessary.
(JSC::DFG::putByVal):
* dfg/DFGRepatch.cpp:  Ditto.  Also remove uses of jsArrayVPtr in favor of using the
JSArray ClassInfo pointer.
(JSC::DFG::tryCacheGetByID):
* dfg/DFGSpeculativeJIT.cpp:  Replace uses of the old vptrs with new ClassInfo
comparisons since we don't have vptrs anymore.
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::compilePutByValForByteArray):
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
* dfg/DFGSpeculativeJIT.h: Ditto.
(JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
* dfg/DFGSpeculativeJIT32_64.cpp: Ditto.
(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp: Ditto.
(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* heap/Heap.cpp: Remove all uses of vptrs in GC optimizations and replace them with
ClassInfo comparisons.
(JSC::Heap::Heap):
* heap/MarkStack.cpp: Ditto.
(JSC::MarkStackThreadSharedData::markingThreadMain):
(JSC::visitChildren):
(JSC::SlotVisitor::drain):
* heap/MarkStack.h: Ditto.
(JSC::MarkStack::MarkStack):
* heap/MarkedBlock.cpp: Ditto.
(JSC::MarkedBlock::callDestructor):
(JSC::MarkedBlock::specializedSweep):
* heap/MarkedBlock.h: Ditto.
* heap/SlotVisitor.h: Ditto.
(JSC::SlotVisitor::SlotVisitor):
* heap/VTableSpectrum.cpp: Now that we don't have vptrs, we can't count them.
We'll have to rename this class and make it use ClassInfo ptrs in a future patch.
(JSC::VTableSpectrum::count):
* interpreter/Interpreter.cpp: Remove all global data arguments from isJSArray,
etc. functions.
(JSC::loadVarargs):
(JSC::Interpreter::tryCacheGetByID):
(JSC::Interpreter::privateExecute):
* jit/JIT.h: Remove vptr argument from emitAllocateBasicJSObject
* jit/JITInlineMethods.h: Remove vptr planting, and add ClassInfo planting,
remove all vtable related code.
(JSC::JIT::emitLoadCharacterString):
(JSC::JIT::emitAllocateBasicJSObject):
(JSC::JIT::emitAllocateJSFinalObject):
(JSC::JIT::emitAllocateJSFunction):
* jit/JITOpcodes.cpp: Replace vptr related branch code with corresponding ClassInfo.
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::emit_op_to_primitive):
(JSC::JIT::emit_op_convert_this):
* jit/JITOpcodes32_64.cpp: Ditto.
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::emit_op_to_primitive):
(JSC::JIT::emitSlow_op_eq):
(JSC::JIT::emitSlow_op_neq):
(JSC::JIT::compileOpStrictEq):
(JSC::JIT::emit_op_convert_this):
* jit/JITPropertyAccess.cpp: Ditto.
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
* jit/JITPropertyAccess32_64.cpp: Ditto.
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::privateCompilePatchGetArrayLength):
* jit/JITStubs.cpp: Remove global data argument from isJSString, etc.
(JSC::JITThunks::tryCacheGetByID):
(JSC::DEFINE_STUB_FUNCTION):
* jit/SpecializedThunkJIT.h: Replace vptr related stuff with ClassInfo stuff.
(JSC::SpecializedThunkJIT::loadJSStringArgument):
* runtime/ArrayConstructor.cpp: Add trivial destructor assert.
* runtime/ArrayPrototype.cpp: Remove global data argument from isJSArray.
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncJoin):
(JSC::arrayProtoFuncPop):
(JSC::arrayProtoFuncPush):
(JSC::arrayProtoFuncShift):
(JSC::arrayProtoFuncSplice):
(JSC::arrayProtoFuncUnShift):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncForEach):
(JSC::arrayProtoFuncSome):
(JSC::arrayProtoFuncReduce):
(JSC::arrayProtoFuncReduceRight):
* runtime/BooleanConstructor.cpp: Add trivial destructor assert.
* runtime/BooleanObject.cpp: Ditto.
* runtime/BooleanPrototype.cpp: Ditto.
* runtime/ClassInfo.h: Add destroy function pointer to MethodTable.
* runtime/DateConstructor.cpp: Add trivial destructor assert.
* runtime/DateInstance.cpp: Add destroy function for DateInstance because it has a RefPtr
that needs destruction.
(JSC::DateInstance::destroy):
* runtime/DateInstance.h:
* runtime/Error.cpp: Ditto (because of UString member).
(JSC::StrictModeTypeErrorFunction::destroy):
* runtime/Error.h:
* runtime/ErrorConstructor.cpp: Add trivial destructor assert.
* runtime/ErrorInstance.cpp: Ditto.
* runtime/ExceptionHelpers.cpp: Ditto.
* runtime/Executable.cpp: Add destroy functions for ExecutableBase and subclasses.
(JSC::ExecutableBase::destroy):
(JSC::NativeExecutable::destroy):
(JSC::ScriptExecutable::destroy):
(JSC::EvalExecutable::destroy):
(JSC::ProgramExecutable::destroy):
(JSC::FunctionExecutable::destroy):
* runtime/Executable.h:
* runtime/FunctionConstructor.cpp: Add trivial destructor assert.
* runtime/FunctionPrototype.cpp: Ditto. Also remove global data first arg from isJSArray.
(JSC::functionProtoFuncApply):
* runtime/GetterSetter.cpp: Ditto.
* runtime/InitializeThreading.cpp: Remove call to JSGlobalData::storeVPtrs since it no
longer exists.
(JSC::initializeThreadingOnce):
* runtime/InternalFunction.cpp: Remove vtableAnchor function, add trivial destructor assert,
remove first arg from isJSString.
(JSC::InternalFunction::displayName):
* runtime/InternalFunction.h: Remove VPtrStealingHack.
* runtime/JSAPIValueWrapper.cpp: Add trivial destructor assert.
* runtime/JSArray.cpp: Add static destroy to call ~JSArray.  Replace vptr checks in
destructor with ClassInfo checks.
(JSC::JSArray::~JSArray):
(JSC::JSArray::destroy):
* runtime/JSArray.h: Remove VPtrStealingHack.  Remove globalData argument from isJSArray
and change them to check the ClassInfo rather than the vptrs.
(JSC::isJSArray):
* runtime/JSBoundFunction.cpp: Add trival destructor assert. Remove first arg from isJSArray.
(JSC::boundFunctionCall):
(JSC::boundFunctionConstruct):
* runtime/JSByteArray.cpp: Add static destroy function, replace vptr checks with ClassInfo checks.
(JSC::JSByteArray::~JSByteArray):
(JSC::JSByteArray::destroy):
* runtime/JSByteArray.h: Remove VPtrStealingHack code.
(JSC::isJSByteArray):
* runtime/JSCell.cpp: Add trivial destructor assert.  Add static destroy function.
(JSC::JSCell::destroy):
* runtime/JSCell.h: Remove VPtrStealingHack code.  Add function for returning the offset
of the ClassInfo pointer in the object for use by the JIT.  Add the ClassInfo pointer to
the JSCell itself, and grab it from the Structure.  Remove the vptr and setVPtr functions,
as they are no longer used.  Add a validatedClassInfo function to JSCell for any clients
that want to verify, while in Debug mode, that the ClassInfo contained in the cell is the
same one as that contained in the Structure.  This isn't used too often, because most of
the places where we compare the ClassInfo to things can be called during destruction.
Since the Structure is unreliable during the phase when destructors are being called,
we can't call validatedClassInfo.
(JSC::JSCell::classInfoOffset):
(JSC::JSCell::structure):
(JSC::JSCell::classInfo):
* runtime/JSFunction.cpp: Remove VPtrStealingHack code.  Add static destroy, remove vtableAnchor,
remove first arg from call to isJSString.
(JSC::JSFunction::destroy):
(JSC::JSFunction::displayName):
* runtime/JSFunction.h:
* runtime/JSGlobalData.cpp: Remove all VPtr stealing code and storage, including storeVPtrs,
as these vptrs are no longer needed in the codebase.
* runtime/JSGlobalData.h:
(JSC::TypedArrayDescriptor::TypedArrayDescriptor): Changed the TypedArrayDescriptor to use
ClassInfo rather than the vptr.
* runtime/JSGlobalObject.cpp: Add static destroy function.
(JSC::JSGlobalObject::destroy):
* runtime/JSGlobalObject.h:
* runtime/JSGlobalThis.cpp: Add trivial destructor assert.
* runtime/JSNotAnObject.cpp: Ditto.
* runtime/JSONObject.cpp: Ditto. Remove first arg from isJSArray calls.
(JSC::Stringifier::Holder::appendNextProperty):
(JSC::Walker::walk):
* runtime/JSObject.cpp:
(JSC::JSFinalObject::destroy):
(JSC::JSNonFinalObject::destroy):
(JSC::JSObject::destroy):
* runtime/JSObject.h: Add trivial destructor assert for JSObject, remove vtableAnchor
from JSNonFinalObject and JSFinalObject, add static destroy for JSFinalObject and
JSNonFinalObject, add isJSFinalObject utility function similar to isJSArray, remove all VPtrStealingHack code.
(JSC::JSObject::finishCreation):
(JSC::JSNonFinalObject::finishCreation):
(JSC::JSFinalObject::finishCreation):
(JSC::isJSFinalObject):
* runtime/JSPropertyNameIterator.cpp: Add static destroy.
(JSC::JSPropertyNameIterator::destroy):
* runtime/JSPropertyNameIterator.h:
* runtime/JSStaticScopeObject.cpp: Ditto.
(JSC::JSStaticScopeObject::destroy):
* runtime/JSStaticScopeObject.h: Ditto.
* runtime/JSString.cpp:
(JSC::JSString::destroy):
* runtime/JSString.h: Ditto. Remove VPtrStealingHack code. Also remove fixupVPtr code,
since we no longer need to fixup vptrs.
(JSC::jsSingleCharacterString):
(JSC::jsSingleCharacterSubstring):
(JSC::jsNontrivialString):
(JSC::jsString):
(JSC::jsSubstring8):
(JSC::jsSubstring):
(JSC::jsOwnedString):
(JSC::jsStringBuilder):
(JSC::isJSString):
* runtime/JSVariableObject.cpp:
(JSC::JSVariableObject::destroy):
* runtime/JSVariableObject.h: Ditto.
* runtime/JSWrapperObject.cpp:
* runtime/JSWrapperObject.h: Add trivial destructor assert.
* runtime/MathObject.cpp: Ditto.
* runtime/NativeErrorConstructor.cpp: Ditto.
* runtime/NumberConstructor.cpp: Ditto.
* runtime/NumberObject.cpp: Ditto.
* runtime/NumberPrototype.cpp: Ditto.
* runtime/ObjectConstructor.cpp: Ditto.
* runtime/ObjectPrototype.cpp: Ditto.
* runtime/Operations.h: Remove calls to fixupVPtr, remove first arg to isJSString.
(JSC::jsString):
(JSC::jsLess):
(JSC::jsLessEq):
* runtime/RegExp.cpp: Add static destroy.
(JSC::RegExp::destroy):
* runtime/RegExp.h:
* runtime/RegExpConstructor.cpp: Add static destroy for RegExpConstructor and RegExpMatchesArray.
(JSC::RegExpConstructor::destroy):
(JSC::RegExpMatchesArray::destroy):
* runtime/RegExpConstructor.h:
* runtime/RegExpMatchesArray.h:
* runtime/RegExpObject.cpp: Add static destroy.
(JSC::RegExpObject::destroy):
* runtime/RegExpObject.h:
* runtime/ScopeChain.cpp: Add trivial destructor assert.
* runtime/ScopeChain.h:
* runtime/StrictEvalActivation.cpp: Ditto.
* runtime/StringConstructor.cpp:
* runtime/StringObject.cpp: Ditto. Remove vtableAnchor.
* runtime/StringObject.h:
* runtime/StringPrototype.cpp: Ditto.
* runtime/Structure.cpp: Add static destroy.
(JSC::Structure::destroy):
* runtime/Structure.h: Move JSCell::finishCreation and JSCell constructor into Structure.h
because they need to have the full Structure type to access the ClassInfo to store in the JSCell.
(JSC::JSCell::setStructure):
(JSC::JSCell::validatedClassInfo):
(JSC::JSCell::JSCell):
(JSC::JSCell::finishCreation):
* runtime/StructureChain.cpp: Add static destroy.
(JSC::StructureChain::destroy):
* runtime/StructureChain.h:
* wtf/Assertions.h: Add new assertion ASSERT_HAS_TRIVIAL_DESTRUCTOR, which uses clangs
ability to tell us when a class has a trivial destructor. We will use this assert
more in future patches as we move toward having all JSC objects backed by GC memory,
which means moving away from using destructors/finalizers.

Source/JavaScriptGlue:

* UserObjectImp.cpp: Add static destroy function.
(UserObjectImp::destroy):
* UserObjectImp.h:

Source/WebCore:

No new tests.

Doing everything here that was done to the JSCell hierarchy in JavaScriptCore.
See the ChangeLog for this commit for a more in-depth description.

* WebCore.exp.in: Add/remove symbols.
* bindings/js/JSCanvasRenderingContext2DCustom.cpp: Remove first arg from isJSArray call.
(WebCore::JSCanvasRenderingContext2D::setWebkitLineDash):
* bindings/js/JSDOMBinding.cpp: Add trival destructor assert for DOMConstructorObject
and DOMConstructorWithDocument.
* bindings/js/JSDOMGlobalObject.cpp: Add static destroy.  Add implementation for
scriptExecutionContext that dispatches to different functions in subclasses
depending on our current ClassInfo.  We do this so that we can get rid of the
virtual-ness of scriptExecutionContext, because any virtual functions will throw
off the layout of the object and we'll crash at runtime.
(WebCore::JSDOMGlobalObject::destroy):
(WebCore::JSDOMGlobalObject::scriptExecutionContext):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMWindowBase.cpp: Add static destroy.
(WebCore::JSDOMWindowBase::destroy):
* bindings/js/JSDOMWindowBase.h: De-virtualize scriptExecutionContext.
* bindings/js/JSDOMWindowShell.cpp: Add static destroy.
(WebCore::JSDOMWindowShell::destroy):
* bindings/js/JSDOMWindowShell.h:
* bindings/js/JSDOMWrapper.cpp: Add trivial destructor assert.
* bindings/js/JSDOMWrapper.h: Add a ClassInfo to JSDOMWrapper since it now overrides
a MethodTable function. Remove vtableAnchor virtual function.
* bindings/js/JSImageConstructor.cpp: Add trivial destructor assert.
* bindings/js/JSNodeCustom.cpp: Change implementation of pushEventHandlerScope so that
it dispatches to the correct function depending on the
identity of the class as specified by the ClassInfo.
See JSDOMGlobalObject::scriptExecutionContext for explanation.
(WebCore::JSNode::pushEventHandlerScope):
* bindings/js/JSWebSocketCustom.cpp: Remove first arg to isJSArray call.
(WebCore::JSWebSocketConstructor::constructJSWebSocket):
* bindings/js/JSWorkerContextBase.cpp: Add static destroy.
(WebCore::JSWorkerContextBase::destroy):
* bindings/js/JSWorkerContextBase.h:
* bindings/js/ScriptValue.cpp: Remove first arg to isJSArray call.
(WebCore::jsToInspectorValue):
* bindings/js/SerializedScriptValue.cpp: Ditto.
(WebCore::CloneSerializer::isArray):
(WebCore::CloneSerializer::getSparseIndex):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader): Remove virtual-ness of any custom pushEventHandlerScope (see
JSNodeCustom::pushEventHandlerScope for explanation).  Remove virtual toBoolean
for anybody who masquerades as undefined, since our JSObject implementation handles
this based on the TypeInfo in the Structure. Add trivial destructor assert for any
class other than DOMWindow or WorkerContexts.
(GenerateImplementation): Change ClassInfo definitions to use Base::s_info, since
typing the parent class more than once is duplication of information and increases
the likelihood of mistakes.  Pass ClassInfo to TypeArrayDescriptors instead of vptr.
(GenerateConstructorDefinition): Add trivial destructor assert for all generated constructors.
* bridge/c/CRuntimeObject.cpp: Remove empty virtual destructor.
* bridge/c/CRuntimeObject.h:
* bridge/jni/jsc/JavaRuntimeObject.cpp: Ditto.
* bridge/jni/jsc/JavaRuntimeObject.h:
* bridge/objc/ObjCRuntimeObject.h: Ditto.
* bridge/objc/ObjCRuntimeObject.mm:
* bridge/objc/objc_runtime.h: Add static destroy for ObjcFallbackObjectImp. De-virtualize
toBoolean in the short term.  Need longer term fix.
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcFallbackObjectImp::destroy):
* bridge/qt/qt_runtime.cpp: Add static destroy to QtRuntimeMethod.
(JSC::Bindings::QtRuntimeMethod::destroy):
* bridge/qt/qt_runtime.h: De-virtualize ~QtRuntimeMethod.
* bridge/runtime_array.cpp: De-virtualize destructor. Add static destroy.
(JSC::RuntimeArray::destroy):
* bridge/runtime_array.h:
* bridge/runtime_method.cpp: Remove vtableAnchor. Add static destroy.
(JSC::RuntimeMethod::destroy):
* bridge/runtime_method.h:
* bridge/runtime_object.cpp: Add static destroy.
(JSC::Bindings::RuntimeObject::destroy):
* bridge/runtime_object.h:

Source/WebKit/mac:

* Plugins/Hosted/ProxyRuntimeObject.h: Remove empty virtual destructor.
* Plugins/Hosted/ProxyRuntimeObject.mm:

Source/WebKit2:

* WebProcess/Plugins/Netscape/JSNPMethod.cpp: Add trivial destructor assert.
* WebProcess/Plugins/Netscape/JSNPObject.cpp: Add static destroy.
(WebKit::JSNPObject::destroy):
* WebProcess/Plugins/Netscape/JSNPObject.h:
* win/WebKit2.def: Add/remove necessary symbols.
* win/WebKit2CFLite.def: Ditto.

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

167 files changed:
ChangeLog
Source/JavaScriptCore/API/JSCallbackConstructor.cpp
Source/JavaScriptCore/API/JSCallbackConstructor.h
Source/JavaScriptCore/API/JSCallbackFunction.cpp
Source/JavaScriptCore/API/JSCallbackObject.cpp
Source/JavaScriptCore/API/JSCallbackObject.h
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.exp
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/debugger/DebuggerActivation.cpp
Source/JavaScriptCore/debugger/DebuggerActivation.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGRepatch.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/MarkStack.cpp
Source/JavaScriptCore/heap/MarkStack.h
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/heap/SlotVisitor.h
Source/JavaScriptCore/heap/VTableSpectrum.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITInlineMethods.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/jit/SpecializedThunkJIT.h
Source/JavaScriptCore/runtime/ArrayConstructor.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/BooleanConstructor.cpp
Source/JavaScriptCore/runtime/BooleanObject.cpp
Source/JavaScriptCore/runtime/BooleanPrototype.cpp
Source/JavaScriptCore/runtime/ClassInfo.h
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/DateInstance.cpp
Source/JavaScriptCore/runtime/DateInstance.h
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/Error.h
Source/JavaScriptCore/runtime/ErrorConstructor.cpp
Source/JavaScriptCore/runtime/ErrorInstance.cpp
Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/FunctionConstructor.cpp
Source/JavaScriptCore/runtime/FunctionPrototype.cpp
Source/JavaScriptCore/runtime/GetterSetter.cpp
Source/JavaScriptCore/runtime/InitializeThreading.cpp
Source/JavaScriptCore/runtime/InternalFunction.cpp
Source/JavaScriptCore/runtime/InternalFunction.h
Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp
Source/JavaScriptCore/runtime/JSArray.cpp
Source/JavaScriptCore/runtime/JSArray.h
Source/JavaScriptCore/runtime/JSBoundFunction.cpp
Source/JavaScriptCore/runtime/JSByteArray.cpp
Source/JavaScriptCore/runtime/JSByteArray.h
Source/JavaScriptCore/runtime/JSCell.cpp
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/JavaScriptCore/runtime/JSGlobalData.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSGlobalThis.cpp
Source/JavaScriptCore/runtime/JSNotAnObject.cpp
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
Source/JavaScriptCore/runtime/JSStaticScopeObject.h
Source/JavaScriptCore/runtime/JSString.cpp
Source/JavaScriptCore/runtime/JSString.h
Source/JavaScriptCore/runtime/JSVariableObject.cpp
Source/JavaScriptCore/runtime/JSVariableObject.h
Source/JavaScriptCore/runtime/JSWrapperObject.cpp
Source/JavaScriptCore/runtime/JSWrapperObject.h
Source/JavaScriptCore/runtime/MathObject.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
Source/JavaScriptCore/runtime/NumberConstructor.cpp
Source/JavaScriptCore/runtime/NumberObject.cpp
Source/JavaScriptCore/runtime/NumberPrototype.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ObjectPrototype.cpp
Source/JavaScriptCore/runtime/Operations.h
Source/JavaScriptCore/runtime/RegExp.cpp
Source/JavaScriptCore/runtime/RegExp.h
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.h
Source/JavaScriptCore/runtime/RegExpMatchesArray.h
Source/JavaScriptCore/runtime/RegExpObject.cpp
Source/JavaScriptCore/runtime/RegExpObject.h
Source/JavaScriptCore/runtime/ScopeChain.cpp
Source/JavaScriptCore/runtime/ScopeChain.h
Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
Source/JavaScriptCore/runtime/StringConstructor.cpp
Source/JavaScriptCore/runtime/StringObject.cpp
Source/JavaScriptCore/runtime/StringObject.h
Source/JavaScriptCore/runtime/StringPrototype.cpp
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureChain.cpp
Source/JavaScriptCore/runtime/StructureChain.h
Source/JavaScriptCore/wtf/Assertions.h
Source/JavaScriptGlue/ChangeLog
Source/JavaScriptGlue/UserObjectImp.cpp
Source/JavaScriptGlue/UserObjectImp.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.h
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bindings/js/JSDOMWindowBase.h
Source/WebCore/bindings/js/JSDOMWindowShell.cpp
Source/WebCore/bindings/js/JSDOMWindowShell.h
Source/WebCore/bindings/js/JSDOMWrapper.cpp
Source/WebCore/bindings/js/JSDOMWrapper.h
Source/WebCore/bindings/js/JSImageConstructor.cpp
Source/WebCore/bindings/js/JSNodeCustom.cpp
Source/WebCore/bindings/js/JSWebSocketCustom.cpp
Source/WebCore/bindings/js/JSWorkerContextBase.cpp
Source/WebCore/bindings/js/JSWorkerContextBase.h
Source/WebCore/bindings/js/ScriptValue.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSFloat64Array.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
Source/WebCore/bridge/c/CRuntimeObject.cpp
Source/WebCore/bridge/c/CRuntimeObject.h
Source/WebCore/bridge/jni/jsc/JavaRuntimeObject.cpp
Source/WebCore/bridge/jni/jsc/JavaRuntimeObject.h
Source/WebCore/bridge/objc/ObjCRuntimeObject.h
Source/WebCore/bridge/objc/ObjCRuntimeObject.mm
Source/WebCore/bridge/objc/objc_runtime.h
Source/WebCore/bridge/objc/objc_runtime.mm
Source/WebCore/bridge/qt/qt_runtime.cpp
Source/WebCore/bridge/qt/qt_runtime.h
Source/WebCore/bridge/runtime_array.cpp
Source/WebCore/bridge/runtime_array.h
Source/WebCore/bridge/runtime_method.cpp
Source/WebCore/bridge/runtime_method.h
Source/WebCore/bridge/runtime_object.cpp
Source/WebCore/bridge/runtime_object.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.h
Source/WebKit/mac/Plugins/Hosted/ProxyRuntimeObject.mm
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h
Source/WebKit2/win/WebKit2.def
Source/WebKit2/win/WebKit2CFLite.def
Source/autotools/symbols.filter

index c8f0aa4..20936e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-12-16  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        De-virtualize destructors
+        https://bugs.webkit.org/show_bug.cgi?id=74331
+
+        Reviewed by Geoffrey Garen.
+
+        * Source/autotools/symbols.filter: Removed symbol no longer present.
+
 2011-12-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Update NEWS and configure.ac for 1.7.3 release
index b601f3e..1349e4f 100644 (file)
@@ -59,6 +59,11 @@ JSCallbackConstructor::~JSCallbackConstructor()
         JSClassRelease(m_class);
 }
 
+void JSCallbackConstructor::destroy(JSCell* cell)
+{
+    jsCast<JSCallbackConstructor*>(cell)->JSCallbackConstructor::~JSCallbackConstructor();
+}
+
 static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec)
 {
     JSObject* constructor = exec->callee();
index b320a90..43a73c3 100644 (file)
@@ -42,7 +42,8 @@ public:
         return constructor;
     }
     
-    virtual ~JSCallbackConstructor();
+    ~JSCallbackConstructor();
+    static void destroy(JSCell*);
     JSClassRef classRef() const { return m_class; }
     JSObjectCallAsConstructorCallback callback() const { return m_callback; }
     static const ClassInfo s_info;
index dd106cc..3fbc004 100644 (file)
@@ -40,6 +40,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSCallbackFunction);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction);
 
 const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
 
index fb9d730..ef9cb92 100644 (file)
@@ -51,6 +51,12 @@ Structure* JSCallbackObject<JSGlobalObject>::createStructure(JSGlobalData& globa
     return Structure::create(globalData, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info); 
 }
 
+template <class Parent>
+void JSCallbackObject<Parent>::destroy(JSCell* cell)
+{
+    jsCast<JSCallbackObject*>(cell)->JSCallbackObject::~JSCallbackObject();
+}
+
 void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)
 {
     JSClassRef jsClass = static_cast<JSClassRef>(context);
index 91ff624..a51ed3e 100644 (file)
@@ -177,6 +177,8 @@ protected:
 private:
     static UString className(const JSObject*);
 
+    static void destroy(JSCell*);
+
     static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
     static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
     
index f2cc59e..b9983a7 100644 (file)
@@ -1,3 +1,322 @@
+2011-12-16  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        De-virtualize destructors
+        https://bugs.webkit.org/show_bug.cgi?id=74331
+
+        Reviewed by Geoffrey Garen.
+
+        This is a megapatch which frees us from the chains of virtual destructors.
+
+        In order to remove the virtual destructors, which are the last of the virtual 
+        functions, from the JSCell hierarchy, we need to add the ClassInfo pointer to 
+        the cell rather than to the structure because in order to be able to lazily call 
+        the static destroy() functions that will replace the virtual destructors, we 
+        need to be able to access the ClassInfo without the danger of the object's 
+        Structure being collected before the object itself.
+
+        After adding the ClassInfo to the cell, we can then begin to remove our use 
+        of vptrs for optimizations within the JIT and the GC.  When we have removed 
+        all of the stored vptrs from JSGlobalData, we can then also remove all of 
+        the related VPtrStealingHack code.
+
+        The replacement for virtual destructors will be to add a static destroy function 
+        pointer to the MethodTable stored in ClassInfo.  Any subclass of JSCell that has 
+        a non-trivial destructor will require its own static destroy function to static 
+        call its corresponding destructor, which will now be non-virtual.  In future 
+        patches we will slowly move away from destructors altogether as we make more and 
+        more objects backed by GC memory rather than malloc-ed memory.  The GC will now 
+        call the static destroy method rather than the virtual destructor.
+
+        As we go through the hierarchy and add static destroy functions to classes, 
+        we will also add a new assert, ASSERT_HAS_TRIVIAL_DESTRUCTOR, to those classes 
+        to which it applies.  The future goal is to eventually have every class have that assert.
+
+        * API/JSCallbackConstructor.cpp:
+        (JSC::JSCallbackConstructor::destroy): Add a destroy function to statically call 
+        ~JSCallbackConstructor because it has some extra destruction logic.
+        * API/JSCallbackConstructor.h:
+        * API/JSCallbackFunction.cpp: Add trivial destructor assert for JSCallbackFunction.
+        * API/JSCallbackObject.cpp: Add a destroy function to statically call ~JSCallbackObject 
+        because it has a member OwnPtr that needs destruction.
+        (JSC::::destroy):
+        * API/JSCallbackObject.h:
+        * JavaScriptCore.exp: Add/remove necessary symbols for JSC.
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Same for Windows symbols.
+        * debugger/DebuggerActivation.cpp: DebuggerActivation, for some strange reason, didn't 
+        have its own ClassInfo despite the fact that it overrides a number of MethodTable 
+        methods.  Added the ClassInfo, along with an assertion that its destructor is trivial.
+        * debugger/DebuggerActivation.h:
+        * dfg/DFGOperations.cpp: Remove global data first argument to isJSArray, isJSByteArray, 
+        isJSString, as it is no longer necessary.
+        (JSC::DFG::putByVal):
+        * dfg/DFGRepatch.cpp:  Ditto.  Also remove uses of jsArrayVPtr in favor of using the 
+        JSArray ClassInfo pointer.
+        (JSC::DFG::tryCacheGetByID):
+        * dfg/DFGSpeculativeJIT.cpp:  Replace uses of the old vptrs with new ClassInfo 
+        comparisons since we don't have vptrs anymore.
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+        (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForByteArray):
+        (JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+        (JSC::DFG::SpeculativeJIT::compare):
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+        * dfg/DFGSpeculativeJIT.h: Ditto.
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
+        * dfg/DFGSpeculativeJIT32_64.cpp: Ditto.
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp: Ditto.
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * heap/Heap.cpp: Remove all uses of vptrs in GC optimizations and replace them with 
+        ClassInfo comparisons.
+        (JSC::Heap::Heap):
+        * heap/MarkStack.cpp: Ditto.
+        (JSC::MarkStackThreadSharedData::markingThreadMain):
+        (JSC::visitChildren):
+        (JSC::SlotVisitor::drain):
+        * heap/MarkStack.h: Ditto.
+        (JSC::MarkStack::MarkStack):
+        * heap/MarkedBlock.cpp: Ditto.
+        (JSC::MarkedBlock::callDestructor):
+        (JSC::MarkedBlock::specializedSweep):
+        * heap/MarkedBlock.h: Ditto.
+        * heap/SlotVisitor.h: Ditto.
+        (JSC::SlotVisitor::SlotVisitor):
+        * heap/VTableSpectrum.cpp: Now that we don't have vptrs, we can't count them.  
+        We'll have to rename this class and make it use ClassInfo ptrs in a future patch.
+        (JSC::VTableSpectrum::count):
+        * interpreter/Interpreter.cpp: Remove all global data arguments from isJSArray, 
+        etc. functions.
+        (JSC::loadVarargs):
+        (JSC::Interpreter::tryCacheGetByID):
+        (JSC::Interpreter::privateExecute):
+        * jit/JIT.h: Remove vptr argument from emitAllocateBasicJSObject 
+        * jit/JITInlineMethods.h: Remove vptr planting, and add ClassInfo planting, 
+        remove all vtable related code.
+        (JSC::JIT::emitLoadCharacterString):
+        (JSC::JIT::emitAllocateBasicJSObject):
+        (JSC::JIT::emitAllocateJSFinalObject):
+        (JSC::JIT::emitAllocateJSFunction):
+        * jit/JITOpcodes.cpp: Replace vptr related branch code with corresponding ClassInfo.
+        (JSC::JIT::privateCompileCTIMachineTrampolines):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::emit_op_convert_this):
+        * jit/JITOpcodes32_64.cpp: Ditto.
+        (JSC::JIT::privateCompileCTIMachineTrampolines):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::emitSlow_op_eq):
+        (JSC::JIT::emitSlow_op_neq):
+        (JSC::JIT::compileOpStrictEq):
+        (JSC::JIT::emit_op_convert_this):
+        * jit/JITPropertyAccess.cpp: Ditto.
+        (JSC::JIT::stringGetByValStubGenerator):
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emit_op_put_by_val):
+        (JSC::JIT::privateCompilePutByIdTransition):
+        (JSC::JIT::privateCompilePatchGetArrayLength):
+        * jit/JITPropertyAccess32_64.cpp: Ditto.
+        (JSC::JIT::stringGetByValStubGenerator):
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emit_op_put_by_val):
+        (JSC::JIT::privateCompilePatchGetArrayLength):
+        * jit/JITStubs.cpp: Remove global data argument from isJSString, etc.
+        (JSC::JITThunks::tryCacheGetByID):
+        (JSC::DEFINE_STUB_FUNCTION):
+        * jit/SpecializedThunkJIT.h: Replace vptr related stuff with ClassInfo stuff.
+        (JSC::SpecializedThunkJIT::loadJSStringArgument):
+        * runtime/ArrayConstructor.cpp: Add trivial destructor assert.
+        * runtime/ArrayPrototype.cpp: Remove global data argument from isJSArray.
+        (JSC::arrayProtoFuncToString):
+        (JSC::arrayProtoFuncJoin):
+        (JSC::arrayProtoFuncPop):
+        (JSC::arrayProtoFuncPush):
+        (JSC::arrayProtoFuncShift):
+        (JSC::arrayProtoFuncSplice):
+        (JSC::arrayProtoFuncUnShift):
+        (JSC::arrayProtoFuncFilter):
+        (JSC::arrayProtoFuncMap):
+        (JSC::arrayProtoFuncEvery):
+        (JSC::arrayProtoFuncForEach):
+        (JSC::arrayProtoFuncSome):
+        (JSC::arrayProtoFuncReduce):
+        (JSC::arrayProtoFuncReduceRight):
+        * runtime/BooleanConstructor.cpp: Add trivial destructor assert.
+        * runtime/BooleanObject.cpp: Ditto.
+        * runtime/BooleanPrototype.cpp: Ditto.
+        * runtime/ClassInfo.h: Add destroy function pointer to MethodTable.
+        * runtime/DateConstructor.cpp: Add trivial destructor assert.
+        * runtime/DateInstance.cpp: Add destroy function for DateInstance because it has a RefPtr 
+        that needs destruction.
+        (JSC::DateInstance::destroy):
+        * runtime/DateInstance.h:
+        * runtime/Error.cpp: Ditto (because of UString member).
+        (JSC::StrictModeTypeErrorFunction::destroy):
+        * runtime/Error.h:
+        * runtime/ErrorConstructor.cpp: Add trivial destructor assert.
+        * runtime/ErrorInstance.cpp: Ditto.
+        * runtime/ExceptionHelpers.cpp: Ditto.
+        * runtime/Executable.cpp: Add destroy functions for ExecutableBase and subclasses.
+        (JSC::ExecutableBase::destroy):
+        (JSC::NativeExecutable::destroy):
+        (JSC::ScriptExecutable::destroy):
+        (JSC::EvalExecutable::destroy):
+        (JSC::ProgramExecutable::destroy):
+        (JSC::FunctionExecutable::destroy):
+        * runtime/Executable.h:
+        * runtime/FunctionConstructor.cpp: Add trivial destructor assert.
+        * runtime/FunctionPrototype.cpp: Ditto. Also remove global data first arg from isJSArray.
+        (JSC::functionProtoFuncApply):
+        * runtime/GetterSetter.cpp: Ditto.
+        * runtime/InitializeThreading.cpp: Remove call to JSGlobalData::storeVPtrs since it no 
+        longer exists.
+        (JSC::initializeThreadingOnce):
+        * runtime/InternalFunction.cpp: Remove vtableAnchor function, add trivial destructor assert, 
+        remove first arg from isJSString.
+        (JSC::InternalFunction::displayName):
+        * runtime/InternalFunction.h: Remove VPtrStealingHack.
+        * runtime/JSAPIValueWrapper.cpp: Add trivial destructor assert.
+        * runtime/JSArray.cpp: Add static destroy to call ~JSArray.  Replace vptr checks in 
+        destructor with ClassInfo checks.
+        (JSC::JSArray::~JSArray):
+        (JSC::JSArray::destroy):
+        * runtime/JSArray.h: Remove VPtrStealingHack.  Remove globalData argument from isJSArray 
+        and change them to check the ClassInfo rather than the vptrs.
+        (JSC::isJSArray):
+        * runtime/JSBoundFunction.cpp: Add trival destructor assert. Remove first arg from isJSArray.
+        (JSC::boundFunctionCall):
+        (JSC::boundFunctionConstruct):
+        * runtime/JSByteArray.cpp: Add static destroy function, replace vptr checks with ClassInfo checks.
+        (JSC::JSByteArray::~JSByteArray):
+        (JSC::JSByteArray::destroy):
+        * runtime/JSByteArray.h: Remove VPtrStealingHack code.
+        (JSC::isJSByteArray):
+        * runtime/JSCell.cpp: Add trivial destructor assert.  Add static destroy function.
+        (JSC::JSCell::destroy):
+        * runtime/JSCell.h: Remove VPtrStealingHack code.  Add function for returning the offset 
+        of the ClassInfo pointer in the object for use by the JIT.  Add the ClassInfo pointer to 
+        the JSCell itself, and grab it from the Structure.  Remove the vptr and setVPtr functions, 
+        as they are no longer used.  Add a validatedClassInfo function to JSCell for any clients 
+        that want to verify, while in Debug mode, that the ClassInfo contained in the cell is the 
+        same one as that contained in the Structure.  This isn't used too often, because most of 
+        the places where we compare the ClassInfo to things can be called during destruction.  
+        Since the Structure is unreliable during the phase when destructors are being called, 
+        we can't call validatedClassInfo.
+        (JSC::JSCell::classInfoOffset):
+        (JSC::JSCell::structure):
+        (JSC::JSCell::classInfo):
+        * runtime/JSFunction.cpp: Remove VPtrStealingHack code.  Add static destroy, remove vtableAnchor, 
+        remove first arg from call to isJSString.
+        (JSC::JSFunction::destroy):
+        (JSC::JSFunction::displayName):
+        * runtime/JSFunction.h: 
+        * runtime/JSGlobalData.cpp: Remove all VPtr stealing code and storage, including storeVPtrs, 
+        as these vptrs are no longer needed in the codebase.
+        * runtime/JSGlobalData.h:
+        (JSC::TypedArrayDescriptor::TypedArrayDescriptor): Changed the TypedArrayDescriptor to use 
+        ClassInfo rather than the vptr.
+        * runtime/JSGlobalObject.cpp: Add static destroy function.
+        (JSC::JSGlobalObject::destroy):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSGlobalThis.cpp: Add trivial destructor assert.
+        * runtime/JSNotAnObject.cpp: Ditto.
+        * runtime/JSONObject.cpp: Ditto. Remove first arg from isJSArray calls.
+        (JSC::Stringifier::Holder::appendNextProperty):
+        (JSC::Walker::walk):
+        * runtime/JSObject.cpp: 
+        (JSC::JSFinalObject::destroy):
+        (JSC::JSNonFinalObject::destroy):
+        (JSC::JSObject::destroy):
+        * runtime/JSObject.h: Add trivial destructor assert for JSObject, remove vtableAnchor 
+        from JSNonFinalObject and JSFinalObject, add static destroy for JSFinalObject and 
+        JSNonFinalObject, add isJSFinalObject utility function similar to isJSArray, remove all VPtrStealingHack code.
+        (JSC::JSObject::finishCreation):
+        (JSC::JSNonFinalObject::finishCreation):
+        (JSC::JSFinalObject::finishCreation):
+        (JSC::isJSFinalObject):
+        * runtime/JSPropertyNameIterator.cpp: Add static destroy.
+        (JSC::JSPropertyNameIterator::destroy):
+        * runtime/JSPropertyNameIterator.h:
+        * runtime/JSStaticScopeObject.cpp: Ditto.
+        (JSC::JSStaticScopeObject::destroy):
+        * runtime/JSStaticScopeObject.h: Ditto. 
+        * runtime/JSString.cpp:
+        (JSC::JSString::destroy):
+        * runtime/JSString.h: Ditto. Remove VPtrStealingHack code. Also remove fixupVPtr code, 
+        since we no longer need to fixup vptrs.
+        (JSC::jsSingleCharacterString):
+        (JSC::jsSingleCharacterSubstring):
+        (JSC::jsNontrivialString):
+        (JSC::jsString):
+        (JSC::jsSubstring8):
+        (JSC::jsSubstring):
+        (JSC::jsOwnedString):
+        (JSC::jsStringBuilder):
+        (JSC::isJSString):
+        * runtime/JSVariableObject.cpp: 
+        (JSC::JSVariableObject::destroy):
+        * runtime/JSVariableObject.h: Ditto.
+        * runtime/JSWrapperObject.cpp:
+        * runtime/JSWrapperObject.h: Add trivial destructor assert.
+        * runtime/MathObject.cpp: Ditto.
+        * runtime/NativeErrorConstructor.cpp: Ditto.
+        * runtime/NumberConstructor.cpp: Ditto.
+        * runtime/NumberObject.cpp: Ditto.
+        * runtime/NumberPrototype.cpp: Ditto.
+        * runtime/ObjectConstructor.cpp: Ditto.
+        * runtime/ObjectPrototype.cpp: Ditto.
+        * runtime/Operations.h: Remove calls to fixupVPtr, remove first arg to isJSString.
+        (JSC::jsString):
+        (JSC::jsLess):
+        (JSC::jsLessEq):
+        * runtime/RegExp.cpp: Add static destroy.
+        (JSC::RegExp::destroy):
+        * runtime/RegExp.h:
+        * runtime/RegExpConstructor.cpp: Add static destroy for RegExpConstructor and RegExpMatchesArray.
+        (JSC::RegExpConstructor::destroy):
+        (JSC::RegExpMatchesArray::destroy):
+        * runtime/RegExpConstructor.h:
+        * runtime/RegExpMatchesArray.h:
+        * runtime/RegExpObject.cpp: Add static destroy.
+        (JSC::RegExpObject::destroy):
+        * runtime/RegExpObject.h:
+        * runtime/ScopeChain.cpp: Add trivial destructor assert.
+        * runtime/ScopeChain.h:
+        * runtime/StrictEvalActivation.cpp: Ditto.
+        * runtime/StringConstructor.cpp:
+        * runtime/StringObject.cpp: Ditto. Remove vtableAnchor.
+        * runtime/StringObject.h:
+        * runtime/StringPrototype.cpp: Ditto.
+        * runtime/Structure.cpp: Add static destroy.
+        (JSC::Structure::destroy):
+        * runtime/Structure.h: Move JSCell::finishCreation and JSCell constructor into Structure.h 
+        because they need to have the full Structure type to access the ClassInfo to store in the JSCell.
+        (JSC::JSCell::setStructure):
+        (JSC::JSCell::validatedClassInfo):
+        (JSC::JSCell::JSCell):
+        (JSC::JSCell::finishCreation):
+        * runtime/StructureChain.cpp: Add static destroy.
+        (JSC::StructureChain::destroy):
+        * runtime/StructureChain.h:
+        * wtf/Assertions.h: Add new assertion ASSERT_HAS_TRIVIAL_DESTRUCTOR, which uses clangs 
+        ability to tell us when a class has a trivial destructor. We will use this assert 
+        more in future patches as we move toward having all JSC objects backed by GC memory, 
+        which means moving away from using destructors/finalizers.
+
 2011-12-15  Martin Robinson  <mrobinson@igalia.com>
 
         Fix 'make dist' in preparation for the GTK+ release.
index 4f8352c..438a417 100644 (file)
@@ -125,6 +125,7 @@ __ZN3JSC11JSByteArray24getOwnPropertyDescriptorEPNS_8JSObjectEPNS_9ExecStateERKN
 __ZN3JSC11JSByteArray25getOwnPropertySlotByIndexEPNS_6JSCellEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC11JSByteArray3putEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC11JSByteArray6s_infoE
+__ZN3JSC11JSByteArray7destroyEPNS_6JSCellE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeEPNS_7JSValueE
@@ -134,13 +135,10 @@ __ZN3JSC12DateInstance14finishCreationERNS_12JSGlobalDataEd
 __ZN3JSC12DateInstance6s_infoE
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEPNS_9StructureE
 __ZN3JSC12JSGlobalData10ClientDataD2Ev
-__ZN3JSC12JSGlobalData11jsArrayVPtrE
 __ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeENS_8HeapSizeE
-__ZN3JSC12JSGlobalData12jsStringVPtrE
 __ZN3JSC12JSGlobalData12stopSamplingEv
 __ZN3JSC12JSGlobalData13startSamplingEv
 __ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
-__ZN3JSC12JSGlobalData14jsFunctionVPtrE
 __ZN3JSC12JSGlobalData14resetDateCacheEv
 __ZN3JSC12JSGlobalData14sharedInstanceEv
 __ZN3JSC12JSGlobalData15dumpRegExpTraceEv
@@ -178,6 +176,7 @@ __ZN3JSC14JSGlobalObject25s_globalObjectMethodTableE
 __ZN3JSC14JSGlobalObject3putEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
 __ZN3JSC14JSGlobalObject6s_infoE
+__ZN3JSC14JSGlobalObject7destroyEPNS_6JSCellE
 __ZN3JSC14JSGlobalObjectD2Ev
 __ZN3JSC14MachineThreads16addCurrentThreadEv
 __ZN3JSC14MarkStackArray6expandEv
@@ -194,14 +193,15 @@ __ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEP
 __ZN3JSC15WeakHandleOwner8finalizeENS_6HandleINS_7UnknownEEEPv
 __ZN3JSC15WeakHandleOwnerD2Ev
 __ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC16InternalFunction12vtableAnchorEv
 __ZN3JSC16InternalFunction14finishCreationERNS_12JSGlobalDataERKNS_10IdentifierE
 __ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
 __ZN3JSC16InternalFunction6s_infoE
 __ZN3JSC16InternalFunctionC2EPNS_14JSGlobalObjectEPNS_9StructureE
+__ZN3JSC16JSNonFinalObject7destroyEPNS_6JSCellE
 __ZN3JSC16JSVariableObject14deletePropertyEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_8JSObjectEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC16JSVariableObject7destroyEPNS_6JSCellE
 __ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC16slowValidateCellEPNS_14JSGlobalObjectE
 __ZN3JSC16slowValidateCellEPNS_6JSCellE
@@ -211,6 +211,7 @@ __ZN3JSC17JSAPIValueWrapper6s_infoE
 __ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
 __ZN3JSC17createSyntaxErrorEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC18DebuggerActivation14finishCreationERNS_12JSGlobalDataEPNS_8JSObjectE
+__ZN3JSC18DebuggerActivation6s_infoE
 __ZN3JSC18DebuggerActivationC1ERNS_12JSGlobalDataE
 __ZN3JSC18PropertyDescriptor11setWritableEb
 __ZN3JSC18PropertyDescriptor12setUndefinedEv
@@ -265,6 +266,7 @@ __ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternERKNS_7UStringEjjPi
 __ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
 __ZN3JSC6JSCell11getCallDataEPS0_RNS_8CallDataE
 __ZN3JSC6JSCell16getConstructDataEPS0_RNS_13ConstructDataE
+__ZN3JSC6JSCell7destroyEPS0_
 __ZN3JSC6JSCell9getObjectEv
 __ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE
 __ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
@@ -276,13 +278,13 @@ __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
 __ZN3JSC6RegExp5matchERNS_12JSGlobalDataERKNS_7UStringEiPN3WTF6VectorIiLm32EEE
 __ZN3JSC6RegExp6createERNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE
-__ZN3JSC6RegExpD1Ev
 __ZN3JSC7JSArray13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC7JSArray14finishCreationERNS_12JSGlobalDataE
 __ZN3JSC7JSArray14finishCreationERNS_12JSGlobalDataERKNS_7ArgListE
 __ZN3JSC7JSArray15setSubclassDataEPv
 __ZN3JSC7JSArray25getOwnPropertySlotByIndexEPNS_6JSCellEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC7JSArray6s_infoE
+__ZN3JSC7JSArray7destroyEPNS_6JSCellE
 __ZN3JSC7JSArray9setLengthEj
 __ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureE
 __ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureE
@@ -313,7 +315,6 @@ __ZN3JSC8JSObject12defineSetterEPS0_PNS_9ExecStateERKNS_10IdentifierES1_j
 __ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC8JSObject12toThisObjectEPNS_6JSCellEPNS_9ExecStateE
-__ZN3JSC8JSObject12vtableAnchorEv
 __ZN3JSC8JSObject13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC8JSObject14deletePropertyEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC8JSObject16getPropertyNamesEPS0_PNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
@@ -330,6 +331,7 @@ __ZN3JSC8JSObject24getOwnPropertyDescriptorEPS0_PNS_9ExecStateERKNS_10Identifier
 __ZN3JSC8JSObject25getOwnPropertySlotByIndexEPNS_6JSCellEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC8JSObject3putEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC8JSObject6s_infoE
+__ZN3JSC8JSObject7destroyEPNS_6JSCellE
 __ZN3JSC8JSObject9classNameEPKS0_
 __ZN3JSC8JSString6s_infoE
 __ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
@@ -350,7 +352,6 @@ __ZN3JSC9Structure3getERNS_12JSGlobalDataEPN3WTF10StringImplERjRPNS_6JSCellE
 __ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
 __ZN3JSC9Structure6s_infoE
 __ZN3JSC9StructureC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectENS_7JSValueERKNS_8TypeInfoEPKNS_9ClassInfoE
-__ZN3JSC9StructureD1Ev
 __ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
 __ZN3JSCeqERKNS_7UStringEPKc
 __ZN3JSCgtERKNS_7UStringES2_
@@ -619,16 +620,7 @@ __ZNK3WTF6String8toIntPtrEPb
 __ZNK3WTF6String8toUInt64EPb
 __ZNK3WTF6String9substringEjj
 __ZNK3WTF8Collator7collateEPKtmS2_m
-__ZTVN3JSC12StringObjectE
-__ZTVN3JSC13JSFinalObjectE
-__ZTVN3JSC14JSGlobalObjectE
-__ZTVN3JSC14ScopeChainNodeE
-__ZTVN3JSC15JSWrapperObjectE
 __ZTVN3JSC15WeakHandleOwnerE
-__ZTVN3JSC16InternalFunctionE
-__ZTVN3JSC16JSVariableObjectE
 __ZTVN3JSC8DebuggerE
-__ZTVN3JSC8JSObjectE
-__ZTVN3JSC8JSStringE
 _jscore_fastmalloc_introspection
 _kJSClassDefinitionEmpty
index ffd5a52..fc516ac 100644 (file)
@@ -33,11 +33,9 @@ EXPORTS
     ??1Debugger@JSC@@UAE@XZ
     ??1DropAllLocks@JSLock@JSC@@QAE@XZ
     ??1JSGlobalData@JSC@@QAE@XZ
-    ??1JSGlobalObject@JSC@@UAE@XZ
-    ??1JSVariableObject@JSC@@UAE@XZ
+   ??1JSGlobalObject@JSC@@QAE@XZ
     ??1Mutex@WTF@@QAE@XZ
     ??1RefCountedLeakCounter@WTF@@QAE@XZ
-    ??1ScopeChainNode@JSC@@EAE@XZ
     ??1SourceProviderCache@JSC@@QAE@XZ
     ??1ThreadCondition@WTF@@QAE@XZ
     ??1WTFThreadData@WTF@@QAE@XZ
@@ -158,6 +156,9 @@ EXPORTS
     ?despecifyDictionaryFunction@Structure@JSC@@QAEXAAVJSGlobalData@2@ABVIdentifier@2@@Z
     ?despecifyFunctionTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@ABVIdentifier@2@@Z
     ?destroy@Heap@JSC@@QAEXXZ
+    ?destroy@JSByteArray@JSC@@SAXPAVJSCell@2@@Z
+    ?destroy@JSGlobalObject@JSC@@SAXPAVJSCell@2@@Z
+    ?destroy@JSNonFinalObject@JSC@@SAXPAVJSCell@2@@Z
     ?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z
     ?detachThread@WTF@@YAXI@Z
     ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
@@ -363,9 +364,6 @@ EXPORTS
     ?visitChildren@JSGlobalObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z
     ?visitChildren@JSGlobalThis@JSC@@KAXPAVJSCell@2@AAVSlotVisitor@2@@Z
     ?visitChildren@JSObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z
-    ?vtableAnchor@InternalFunction@JSC@@EAEXXZ
-    ?vtableAnchor@JSFinalObject@JSC@@EAEXXZ
-    ?vtableAnchor@JSObject@JSC@@UAEXXZ
     ?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
     ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
     ?writable@PropertyDescriptor@JSC@@QBE_NXZ
index 1e03cd1..80be310 100644 (file)
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(DebuggerActivation);
+
+const ClassInfo DebuggerActivation::s_info = { "DebuggerActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(DebuggerActivation) };
+
 DebuggerActivation::DebuggerActivation(JSGlobalData& globalData)
     : JSNonFinalObject(globalData, globalData.debuggerActivationStructure.get())
 {
index 44d09a1..68cc3a3 100644 (file)
@@ -52,6 +52,8 @@ namespace JSC {
         static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes);
         static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes);
 
+        static const ClassInfo s_info;
+
         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 
         {
             return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); 
index 7139006..fe78d7f 100644 (file)
@@ -144,7 +144,7 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
 {
     JSGlobalData* globalData = &exec->globalData();
 
-    if (isJSArray(globalData, baseValue)) {
+    if (isJSArray(baseValue)) {
         JSArray* array = asArray(baseValue);
         if (array->canSetIndex(index)) {
             array->setIndex(*globalData, index, value);
@@ -155,7 +155,7 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
         return;
     }
 
-    if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(index)) {
+    if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(index)) {
         JSByteArray* byteArray = asByteArray(baseValue);
         // FIXME: the JITstub used to relink this to an optimized form!
         if (value.isInt32()) {
@@ -269,18 +269,16 @@ EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, Encoded
 
 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
 {
-    JSGlobalData* globalData = &exec->globalData();
-
     // FIXME: the JIT used to handle these in compiled code!
-    if (isJSArray(globalData, base) && asArray(base)->canGetIndex(index))
+    if (isJSArray(base) && asArray(base)->canGetIndex(index))
         return JSValue::encode(asArray(base)->getIndex(index));
 
     // FIXME: the JITstub used to relink this to an optimized form!
-    if (isJSString(globalData, base) && asString(base)->canGetIndex(index))
+    if (isJSString(base) && asString(base)->canGetIndex(index))
         return JSValue::encode(asString(base)->getIndex(exec, index));
 
     // FIXME: the JITstub used to relink this to an optimized form!
-    if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(index))
+    if (isJSByteArray(base) && asByteArray(base)->canAccessIndex(index))
         return JSValue::encode(asByteArray(base)->getIndex(exec, index));
 
     return JSValue::encode(JSValue(base).get(exec, index));
index 2b56808..c44e8b7 100644 (file)
@@ -164,7 +164,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
     CodeBlock* codeBlock = exec->codeBlock();
     JSGlobalData* globalData = &exec->globalData();
     
-    if (isJSArray(globalData, baseValue) && propertyName == exec->propertyNames().length) {
+    if (isJSArray(baseValue) && propertyName == exec->propertyNames().length) {
         GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
 #if USE(JSVALUE32_64)
         GPRReg resultTagGPR = static_cast<GPRReg>(stubInfo.valueTagGPR);
@@ -183,7 +183,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
         
         MacroAssembler::JumpList failureCases;
         
-        failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(globalData->jsArrayVPtr)));
+        failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), scratchGPR);
         stubJit.load32(MacroAssembler::Address(scratchGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), scratchGPR);
index 9bbfd33..020f12c 100644 (file)
@@ -803,7 +803,7 @@ void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNod
         addBranch(m_jit.jump(), notTaken);
 }
 
-void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, void* vptr, PredictionChecker predictionCheck)
+void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, const ClassInfo* classInfo, PredictionChecker predictionCheck)
 {
     Node& branchNode = at(branchNodeIndex);
     BlockIndex taken = branchNode.takenBlockIndex();
@@ -825,9 +825,9 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchN
     GPRReg op2GPR = op2.gpr();
     
     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
-        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
-        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     
     addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken);
     if (notTaken != (m_block + 1))
@@ -887,11 +887,11 @@ bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::Relationa
             use(node.child1());
             use(node.child2());
         } else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
+            compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction);
             use(node.child1());
             use(node.child2());
         } else if (node.op == CompareEq && Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
+            compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction);
             use(node.child1());
             use(node.child2());
         } else
@@ -1067,12 +1067,12 @@ void SpeculativeJIT::checkArgumentTypes()
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         } else if (isByteArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
         } else if (isBooleanPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
@@ -1082,42 +1082,42 @@ void SpeculativeJIT::checkArgumentTypes()
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
         } else if (isInt16ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
         } else if (isInt32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
         } else if (isUint8ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
         } else if (isUint16ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_classInfo)));
         } else if (isUint32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_classInfo)));
         } else if (isFloat32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_classInfo)));
         } else if (isFloat64ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
         }
 #else
         if (isInt32Prediction(predictedType))
@@ -1127,13 +1127,13 @@ void SpeculativeJIT::checkArgumentTypes()
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         } else if (isByteArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
         } else if (isBooleanPrediction(predictedType))
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
         else if (isInt8ArrayPrediction(predictedType)) {
@@ -1141,49 +1141,49 @@ void SpeculativeJIT::checkArgumentTypes()
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
         } else if (isInt16ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
         } else if (isInt32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
         } else if (isUint8ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
         } else if (isUint16ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_classInfo)));
         }  else if (isUint32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_classInfo)));
         }  else if (isFloat32ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_classInfo)));
         }   else if (isFloat64ArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
-            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_vptr)));
+            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
         } 
 #endif
     }
@@ -1551,7 +1551,7 @@ void SpeculativeJIT::compilePutByValForByteArray(GPRReg base, GPRReg property, N
     NodeIndex valueIndex = node.child3();
     
     if (!isByteArrayPrediction(m_state.forNode(baseIndex).m_type))
-        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
     GPRTemporary value;
     GPRReg valueGPR;
 
@@ -1645,7 +1645,7 @@ void SpeculativeJIT::compileGetTypedArrayLength(const TypedArrayDescriptor& desc
     GPRReg resultGPR = result.gpr();
     
     if (needsSpeculationCheck)
-        speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
     
     m_jit.load32(MacroAssembler::Address(baseGPR, descriptor.m_lengthOffset), resultGPR);
     
@@ -1708,7 +1708,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
     NodeIndex valueIndex = node.child3();
     
     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
-        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
     GPRTemporary value;
     GPRReg valueGPR;
     
@@ -1831,7 +1831,7 @@ void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescripto
     SpeculateDoubleOperand valueOp(this, valueIndex);
     
     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
-        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
     
     GPRTemporary result(this);
     
@@ -2208,9 +2208,9 @@ bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition con
     else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2())))
         compileDoubleCompare(node, doubleCondition);
     else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2())))
-        compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
+        compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
     else if (node.op == CompareEq && Node::shouldSpeculateArray(at(node.child1()), at(node.child2())))
-        compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
+        compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
     else
         nonSpeculativeNonPeepholeCompare(node, condition, operation);
     
@@ -2342,26 +2342,26 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
     if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
         NodeIndex branchNodeIndex = detectPeepHoleBranch();
         if (branchNodeIndex != NoNode) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
+            compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction);
             use(node.child1());
             use(node.child2());
             m_compileIndex = branchNodeIndex;
             return true;
         }
-        compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
+        compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
         return false;
     }
     
     if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
         NodeIndex branchNodeIndex = detectPeepHoleBranch();
         if (branchNodeIndex != NoNode) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
+            compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction);
             use(node.child1());
             use(node.child2());
             m_compileIndex = branchNodeIndex;
             return true;
         }
-        compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
+        compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
         return false;
     }
     
@@ -2387,7 +2387,7 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
     GPRReg storageReg = storage.gpr();
     if (at(node.child1()).prediction() == PredictString) {
         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
 
         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
         
@@ -2397,51 +2397,51 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
         m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
     } else if (at(node.child1()).shouldSpeculateByteArray()) {
         if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSByteArray::offsetOfStorage()), storageReg);
     } else if (at(node.child1()).shouldSpeculateInt8Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int8ArrayDescriptor();
         if (!isInt8ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateInt16Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int16ArrayDescriptor();
         if (!isInt16ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateInt32Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int32ArrayDescriptor();
         if (!isInt32ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateUint8Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ArrayDescriptor();
         if (!isUint8ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateUint16Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint16ArrayDescriptor();
         if (!isUint16ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateUint32Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint32ArrayDescriptor();
         if (!isUint32ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateFloat32Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float32ArrayDescriptor();
         if (!isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else if (at(node.child1()).shouldSpeculateFloat64Array()) {
         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float64ArrayDescriptor();
         if (!isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
     } else {
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
     }
     storageResult(storageReg, m_compileIndex);
index 6ad8eb0..0c16327 100644 (file)
@@ -1950,12 +1950,12 @@ private:
     bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
     void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
     void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
-    void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, void* vptr, PredictionChecker);
-    void compileObjectEquality(Node&, void* vptr, PredictionChecker);
+    void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, const ClassInfo*, PredictionChecker);
+    void compileObjectEquality(Node&, const ClassInfo*, PredictionChecker);
     void compileValueAdd(Node&);
-    void compileObjectOrOtherLogicalNot(NodeIndex value, void* vptr, bool needSpeculationCheck);
+    void compileObjectOrOtherLogicalNot(NodeIndex value, const ClassInfo*, bool needSpeculationCheck);
     void compileLogicalNot(Node&);
-    void emitObjectOrOtherBranch(NodeIndex value, BlockIndex taken, BlockIndex notTaken, void *vptr, bool needSpeculationCheck);
+    void emitObjectOrOtherBranch(NodeIndex value, BlockIndex taken, BlockIndex notTaken, const ClassInfo*, bool needSpeculationCheck);
     void emitBranch(Node&);
     
     void compileIntegerCompare(Node&, MacroAssembler::RelationalCondition);
@@ -2011,8 +2011,8 @@ private:
         m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
         m_jit.storePtr(scratchGPR, &sizeClass->firstFreeCell);
         
-        // Initialize the object's vtable
-        m_jit.storePtr(MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr), MacroAssembler::Address(resultGPR));
+        // Initialize the object's classInfo pointer
+        m_jit.storePtr(MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info), MacroAssembler::Address(resultGPR, JSCell::classInfoOffset()));
         
         // Initialize the object's inheritorID.
         m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::offsetOfInheritorID()));
index 75f1d5d..255fec4 100644 (file)
@@ -1710,7 +1710,7 @@ JITCompiler::Jump SpeculativeJIT::convertToDouble(JSValueOperand& op, FPRReg res
     return notNumber;
 }
 
-void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr, PredictionChecker predictionCheck)
+void SpeculativeJIT::compileObjectEquality(Node& node, const ClassInfo* classInfo, PredictionChecker predictionCheck)
 {
     SpeculateCellOperand op1(this, node.child1());
     SpeculateCellOperand op2(this, node.child2());
@@ -1721,9 +1721,9 @@ void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr, PredictionChe
     GPRReg resultPayloadGPR = resultPayload.gpr();
     
     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
-        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
-        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     
     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
     m_jit.move(Imm32(1), resultPayloadGPR);
@@ -1783,7 +1783,7 @@ void SpeculativeJIT::compileValueAdd(Node& node)
     jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
 }
 
-void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void* vptr, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const ClassInfo* classInfo, bool needSpeculationCheck)
 {
     JSValueOperand value(this, nodeIndex);
     GPRTemporary resultPayload(this);
@@ -1793,7 +1793,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void* v
     
     MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
     if (needSpeculationCheck)
-        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     m_jit.move(TrustedImm32(0), resultPayloadGPR);
     MacroAssembler::Jump done = m_jit.jump();
     
@@ -1822,11 +1822,11 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
         return;
     }
     if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
-        compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        compileObjectOrOtherLogicalNot(node.child1(), &JSFinalObject::s_info, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
         return;
     }
     if (at(node.child1()).shouldSpeculateArrayOrOther()) {
-        compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        compileObjectOrOtherLogicalNot(node.child1(), &JSArray::s_info, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
         return;
     }
     if (at(node.child1()).shouldSpeculateInteger()) {
@@ -1871,7 +1871,7 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
     booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
 }
 
-void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, void *vptr, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
 {
     JSValueOperand value(this, nodeIndex);
     GPRTemporary scratch(this);
@@ -1881,7 +1881,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex tak
     
     MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
     if (needSpeculationCheck)
-        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     addBranch(m_jit.jump(), taken);
     
     notCell.link(&m_jit);
@@ -1921,9 +1921,9 @@ void SpeculativeJIT::emitBranch(Node& node)
 
         noResult(m_compileIndex);
     } else if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
-        emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        emitObjectOrOtherBranch(node.child1(), taken, notTaken, &JSFinalObject::s_info, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
     } else if (at(node.child1()).shouldSpeculateArrayOrOther()) {
-        emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        emitObjectOrOtherBranch(node.child1(), taken, notTaken, &JSArray::s_info, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
     } else if (at(node.child1()).shouldSpeculateNumber()) {
         if (at(node.child1()).shouldSpeculateInteger()) {
             bool invert = false;
@@ -2098,14 +2098,14 @@ void SpeculativeJIT::compile(Node& node)
                 SpeculateCellOperand cell(this, node.child1());
                 GPRReg cellGPR = cell.gpr();
                 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-                    speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+                    speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
                 m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
                 noResult(m_compileIndex);
             } else if (isByteArrayPrediction(predictedType)) {
                 SpeculateCellOperand cell(this, node.child1());
                 GPRReg cellGPR = cell.gpr();
                 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
-                    speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+                    speculationCheck(BadType, JSValueSource::unboxedCell(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
                 m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
                 noResult(m_compileIndex);
             } else if (isBooleanPrediction(predictedType)) {
@@ -2677,7 +2677,7 @@ void SpeculativeJIT::compile(Node& node)
             SpeculateCellOperand base(this, node.child1());
             GPRReg baseReg = base.gpr();
             if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-                speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+                speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
         }
 
@@ -2796,7 +2796,7 @@ void SpeculativeJIT::compile(Node& node)
         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
         // If we have predicted the base to be type array, we can skip the check.
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
 
         base.use();
         property.use();
@@ -2940,7 +2940,7 @@ void SpeculativeJIT::compile(Node& node)
         writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, storageGPR, storageLengthGPR);
 
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
@@ -2986,7 +2986,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg storageLengthGPR = storageLength.gpr();
         
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
@@ -3148,7 +3148,7 @@ void SpeculativeJIT::compile(Node& node)
             MacroAssembler::JumpList alreadyPrimitive;
             
             alreadyPrimitive.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag)));
-            alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1PayloadGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+            alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1PayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
             
             silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
             callOperation(operationToPrimitive, resultTagGPR, resultPayloadGPR, op1TagGPR, op1PayloadGPR);
@@ -3269,7 +3269,7 @@ void SpeculativeJIT::compile(Node& node)
             GPRReg resultGPR = result.gpr();
             
             if (!isObjectPrediction(m_state.forNode(node.child1()).m_type))
-                speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+                speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::classInfoOffset()), JITCompiler::TrustedImmPtr(&JSString::s_info)));
             
             m_jit.move(thisValueGPR, resultGPR);
             cellResult(resultGPR, m_compileIndex);
@@ -3314,7 +3314,7 @@ void SpeculativeJIT::compile(Node& node)
         // do the slow (structure-based) check.
         if (at(node.child1()).shouldSpeculateFinalObject()) {
             if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type))
-                speculationCheck(BadType, JSValueSource::unboxedCell(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));
+                speculationCheck(BadType, JSValueSource::unboxedCell(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info)));
         } else {
             m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);
             slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
@@ -3486,7 +3486,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
@@ -3505,7 +3505,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
         
         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
 
@@ -3521,7 +3521,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+            speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSByteArray::offsetOfStorage()), resultGPR);
         m_jit.load32(MacroAssembler::Address(baseGPR, ByteArray::offsetOfSize()), resultGPR);
index 97b512a..d78786e 100644 (file)
@@ -1737,7 +1737,7 @@ JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, G
     return notNumber;
 }
 
-void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr, PredictionChecker predictionCheck)
+void SpeculativeJIT::compileObjectEquality(Node& node, const ClassInfo* classInfo, PredictionChecker predictionCheck)
 {
     SpeculateCellOperand op1(this, node.child1());
     SpeculateCellOperand op2(this, node.child2());
@@ -1748,9 +1748,9 @@ void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr, PredictionChe
     GPRReg resultGPR = result.gpr();
     
     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
-        speculationCheck(BadType, JSValueRegs(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
-        speculationCheck(BadType, JSValueRegs(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     
     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
     m_jit.move(Imm32(ValueTrue), resultGPR);
@@ -1808,7 +1808,7 @@ void SpeculativeJIT::compileValueAdd(Node& node)
     jsValueResult(result.gpr(), m_compileIndex);
 }
 
-void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void *vptr, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const ClassInfo* classInfo, bool needSpeculationCheck)
 {
     JSValueOperand value(this, nodeIndex);
     GPRTemporary result(this);
@@ -1817,7 +1817,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void *v
     
     MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     if (needSpeculationCheck)
-        speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     m_jit.move(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
     MacroAssembler::Jump done = m_jit.jump();
     
@@ -1848,11 +1848,11 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
         return;
     }
     if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
-        compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        compileObjectOrOtherLogicalNot(node.child1(), &JSFinalObject::s_info, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
         return;
     }
     if (at(node.child1()).shouldSpeculateArrayOrOther()) {
-        compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        compileObjectOrOtherLogicalNot(node.child1(), &JSArray::s_info, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
         return;
     }
     if (at(node.child1()).shouldSpeculateInteger()) {
@@ -1912,7 +1912,7 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
 }
 
-void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, void *vptr, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
 {
     JSValueOperand value(this, nodeIndex);
     GPRTemporary scratch(this);
@@ -1921,7 +1921,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex tak
     
     MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     if (needSpeculationCheck)
-        speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));
+        speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
     addBranch(m_jit.jump(), taken);
     
     notCell.link(&m_jit);
@@ -1961,9 +1961,9 @@ void SpeculativeJIT::emitBranch(Node& node)
         
         noResult(m_compileIndex);
     } else if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
-        emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        emitObjectOrOtherBranch(node.child1(), taken, notTaken, &JSFinalObject::s_info, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
     } else if (at(node.child1()).shouldSpeculateArrayOrOther()) {
-        emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
+        emitObjectOrOtherBranch(node.child1(), taken, notTaken, &JSArray::s_info, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
     } else if (at(node.child1()).shouldSpeculateNumber()) {
         if (at(node.child1()).shouldSpeculateInteger()) {
             bool invert = false;
@@ -2131,14 +2131,14 @@ void SpeculativeJIT::compile(Node& node)
                 SpeculateCellOperand cell(this, node.child1());
                 GPRReg cellGPR = cell.gpr();
                 if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-                    speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+                    speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
                 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
                 noResult(m_compileIndex);
             } else if (isByteArrayPrediction(predictedType)) {
                 SpeculateCellOperand cell(this, node.child1());
                 GPRReg cellGPR = cell.gpr();
                 if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
-                    speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+                    speculationCheck(BadType, JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
                 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
                 noResult(m_compileIndex);
             } else if (isBooleanPrediction(predictedType)) {
@@ -2680,7 +2680,7 @@ void SpeculativeJIT::compile(Node& node)
             return;
 
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
 
         // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
@@ -2791,7 +2791,7 @@ void SpeculativeJIT::compile(Node& node)
         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
         // If we have predicted the base to be type array, we can skip the check.
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
 
         base.use();
         property.use();
@@ -2935,7 +2935,7 @@ void SpeculativeJIT::compile(Node& node)
         writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, storageGPR, storageLengthGPR);
 
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
@@ -2978,7 +2978,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg storageLengthGPR = storageLength.gpr();
         
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
@@ -3121,7 +3121,7 @@ void SpeculativeJIT::compile(Node& node)
             MacroAssembler::JumpList alreadyPrimitive;
             
             alreadyPrimitive.append(m_jit.branchTestPtr(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister));
-            alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+            alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
             
             silentSpillAllRegisters(resultGPR);
             callOperation(operationToPrimitive, resultGPR, op1GPR);
@@ -3231,7 +3231,7 @@ void SpeculativeJIT::compile(Node& node)
             GPRReg resultGPR = result.gpr();
             
             if (!isObjectPrediction(m_state.forNode(node.child1()).m_type))
-                speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+                speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::classInfoOffset()), JITCompiler::TrustedImmPtr(&JSString::s_info)));
             
             m_jit.move(thisValueGPR, resultGPR);
             
@@ -3275,7 +3275,7 @@ void SpeculativeJIT::compile(Node& node)
         // do the slow (structure-based) check.
         if (at(node.child1()).shouldSpeculateFinalObject()) {
             if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type))
-                speculationCheck(BadType, JSValueRegs(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));
+                speculationCheck(BadType, JSValueRegs(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info)));
         } else {
             m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);
             slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
@@ -3438,7 +3438,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
@@ -3457,7 +3457,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
         
         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
 
@@ -3473,7 +3473,7 @@ void SpeculativeJIT::compile(Node& node)
         GPRReg resultGPR = result.gpr();
         
         if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
-            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
+            speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
         
         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSByteArray::offsetOfStorage()), resultGPR);
         m_jit.load32(MacroAssembler::Address(baseGPR, ByteArray::offsetOfSize()), resultGPR);
index 06c0afd..61eba08 100644 (file)
@@ -319,7 +319,7 @@ Heap::Heap(JSGlobalData* globalData, HeapSize heapSize)
     , m_activityCallback(DefaultGCActivityCallback::create(this))
     , m_machineThreads(this)
     , m_sharedData(globalData)
-    , m_slotVisitor(m_sharedData, globalData->jsArrayVPtr, globalData->jsFinalObjectVPtr, globalData->jsStringVPtr)
+    , m_slotVisitor(m_sharedData)
     , m_handleHeap(globalData)
     , m_isSafeToCollect(false)
     , m_globalData(globalData)
index dd0e6fd..02cf328 100644 (file)
@@ -219,7 +219,7 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other)
 void MarkStackThreadSharedData::markingThreadMain()
 {
     WTF::registerGCThread();
-    SlotVisitor slotVisitor(*this, m_globalData->jsArrayVPtr, m_globalData->jsFinalObjectVPtr, m_globalData->jsStringVPtr);
+    SlotVisitor slotVisitor(*this);
     ParallelModeEnabler enabler(slotVisitor);
     slotVisitor.drainFromShared(SlotVisitor::SlaveDrain);
 }
@@ -294,7 +294,7 @@ void MarkStack::append(ConservativeRoots& conservativeRoots)
         internalAppend(roots[i]);
 }
 
-ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell, void* jsFinalObjectVPtr, void* jsArrayVPtr, void* jsStringVPtr)
+ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell)
 {
 #if ENABLE(SIMPLE_HEAP_PROFILING)
     m_visitedTypeCounts.count(cell);
@@ -302,17 +302,17 @@ ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell
 
     ASSERT(Heap::isMarked(cell));
 
-    if (cell->vptr() == jsStringVPtr) {
+    if (isJSString(cell)) {
         JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
         return;
     }
 
-    if (cell->vptr() == jsFinalObjectVPtr) {
+    if (isJSFinalObject(cell)) {
         JSObject::visitChildren(const_cast<JSCell*>(cell), visitor);
         return;
     }
 
-    if (cell->vptr() == jsArrayVPtr) {
+    if (isJSArray(cell)) {
         JSArray::visitChildren(const_cast<JSCell*>(cell), visitor);
         return;
     }
@@ -338,16 +338,12 @@ void SlotVisitor::drain()
 {
     ASSERT(m_isInParallelMode);
     
-    void* jsFinalObjectVPtr = m_jsFinalObjectVPtr;
-    void* jsArrayVPtr = m_jsArrayVPtr;
-    void* jsStringVPtr = m_jsStringVPtr;
-
 #if ENABLE(PARALLEL_GC)
     if (Options::numberOfGCMarkers > 1) {
         while (!m_stack.isEmpty()) {
             m_stack.refill();
             for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance; m_stack.canRemoveLast() && countdown--;)
-                visitChildren(*this, m_stack.removeLast(), jsFinalObjectVPtr, jsArrayVPtr, jsStringVPtr);
+                visitChildren(*this, m_stack.removeLast());
             donateKnownParallel();
         }
         
@@ -359,7 +355,7 @@ void SlotVisitor::drain()
     while (!m_stack.isEmpty()) {
         m_stack.refill();
         while (m_stack.canRemoveLast())
-            visitChildren(*this, m_stack.removeLast(), jsFinalObjectVPtr, jsArrayVPtr, jsStringVPtr);
+            visitChildren(*this, m_stack.removeLast());
     }
 }
 
index 8cbdc62..1478011 100644 (file)
@@ -204,7 +204,7 @@ namespace JSC {
         friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
 
     public:
-        MarkStack(MarkStackThreadSharedData&, void* jsArrayVPtr, void* jsFinalObjectVPtr, void* jsStringVPtr);
+        MarkStack(MarkStackThreadSharedData&);
         ~MarkStack();
 
         void append(ConservativeRoots&);
@@ -267,9 +267,6 @@ namespace JSC {
         }
         
         MarkStackArray m_stack;
-        void* m_jsArrayVPtr;
-        void* m_jsFinalObjectVPtr;
-        void* m_jsStringVPtr;
         HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
         
 #if !ASSERT_DISABLED
@@ -286,11 +283,8 @@ namespace JSC {
         MarkStackThreadSharedData& m_shared;
     };
 
-    inline MarkStack::MarkStack(MarkStackThreadSharedData& shared, void* jsArrayVPtr, void* jsFinalObjectVPtr, void* jsStringVPtr)
+    inline MarkStack::MarkStack(MarkStackThreadSharedData& shared)
         : m_stack(shared.m_segmentAllocator)
-        , m_jsArrayVPtr(jsArrayVPtr)
-        , m_jsFinalObjectVPtr(jsFinalObjectVPtr)
-        , m_jsStringVPtr(jsStringVPtr)
 #if !ASSERT_DISABLED
         , m_isCheckingForDefaultMarkViolation(false)
         , m_isDraining(false)
index d6fb853..f2529fd 100644 (file)
@@ -60,18 +60,17 @@ MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, si
     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
 }
 
-inline void MarkedBlock::callDestructor(JSCell* cell, void* jsFinalObjectVPtr)
+inline void MarkedBlock::callDestructor(JSCell* cell)
 {
     // A previous eager sweep may already have run cell's destructor.
     if (cell->isZapped())
         return;
 
-    void* vptr = cell->vptr();
 #if ENABLE(SIMPLE_HEAP_PROFILING)
     m_heap->m_destroyedTypeCounts.countVPtr(vptr);
 #endif
-    if (vptr != jsFinalObjectVPtr)
-        cell->~JSCell();
+    if (cell->classInfo() != &JSFinalObject::s_info)
+        cell->methodTable()->destroy(cell);
 
     cell->zap();
 }
@@ -85,7 +84,6 @@ MarkedBlock::FreeCell* MarkedBlock::specializedSweep()
     // This is fine, since the allocation code makes no assumptions about the
     // order of the free list.
     FreeCell* head = 0;
-    void* jsFinalObjectVPtr = m_heap->globalData()->jsFinalObjectVPtr;
     for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
         if (blockState == Marked && m_marks.get(i))
             continue;
@@ -95,7 +93,7 @@ MarkedBlock::FreeCell* MarkedBlock::specializedSweep()
             continue;
 
         if (blockState != New)
-            callDestructor(cell, jsFinalObjectVPtr);
+            callDestructor(cell);
 
         if (sweepMode == SweepToFreeList) {
             FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell);
index adc6572..8c665dd 100644 (file)
@@ -165,7 +165,7 @@ namespace JSC {
         MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize);
         Atom* atoms();
         size_t atomNumber(const void*);
-        void callDestructor(JSCell*, void* jsFinalObjectVPtr);
+        void callDestructor(JSCell*);
         template<BlockState, SweepMode> FreeCell* specializedSweep();
         
 #if ENABLE(GGC)
index 647b2cb..142d8ca 100644 (file)
@@ -35,7 +35,7 @@ class Heap;
 class SlotVisitor : public MarkStack {
     friend class HeapRootVisitor;
 public:
-    SlotVisitor(MarkStackThreadSharedData&, void* jsArrayVPtr, void* jsFinalObjectVPtr, void* jsStringVPtr);
+    SlotVisitor(MarkStackThreadSharedData&);
 
     void donate()
     {
@@ -71,8 +71,8 @@ private:
     }
 };
 
-inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared, void* jsArrayVPtr, void* jsFinalObjectVPtr, void* jsStringVPtr)
-    : MarkStack(shared, jsArrayVPtr, jsFinalObjectVPtr, jsStringVPtr)
+inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared)
+    : MarkStack(shared)
 {
 }
 
index b98d1a5..acb4940 100644 (file)
@@ -54,7 +54,8 @@ void VTableSpectrum::countVPtr(void* vTablePointer)
 
 void VTableSpectrum::count(JSCell* cell)
 {
-    countVPtr(cell->vptr());
+    // FIXME: we need to change this class to count ClassInfos rather than vptrs
+    UNUSED_PARAM(cell);
 }
 
 void VTableSpectrum::dump(FILE* output, const char* comment)
index 70a4432..d389427 100644 (file)
@@ -506,7 +506,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
         return newCallFrame;
     }
 
-    if (isJSArray(&callFrame->globalData(), arguments)) {
+    if (isJSArray(arguments)) {
         JSArray* array = asArray(arguments);
         unsigned argCount = array->length();
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
@@ -1508,13 +1508,12 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
-    JSGlobalData* globalData = &callFrame->globalData();
-    if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+    if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
         vPC[0] = getOpcode(op_get_array_length);
         return;
     }
 
-    if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+    if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
         vPC[0] = getOpcode(op_get_string_length);
         return;
     }
@@ -3218,7 +3217,7 @@ skip_id_custom_self:
 
         int base = vPC[2].u.operand;
         JSValue baseValue = callFrame->r(base).jsValue();
-        if (LIKELY(isJSArray(globalData, baseValue))) {
+        if (LIKELY(isJSArray(baseValue))) {
             int dst = vPC[1].u.operand;
             callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length());
             vPC += OPCODE_LENGTH(op_get_array_length);
@@ -3242,7 +3241,7 @@ skip_id_custom_self:
 
         int base = vPC[2].u.operand;
         JSValue baseValue = callFrame->r(base).jsValue();
-        if (LIKELY(isJSString(globalData, baseValue))) {
+        if (LIKELY(isJSString(baseValue))) {
             int dst = vPC[1].u.operand;
             callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length());
             vPC += OPCODE_LENGTH(op_get_string_length);
@@ -3511,15 +3510,15 @@ skip_id_custom_self:
 
         if (LIKELY(subscript.isUInt32())) {
             uint32_t i = subscript.asUInt32();
-            if (isJSArray(globalData, baseValue)) {
+            if (isJSArray(baseValue)) {
                 JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canGetIndex(i))
                     result = jsArray->getIndex(i);
                 else
                     result = jsArray->JSArray::get(callFrame, i);
-            } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
+            } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
                 result = asString(baseValue)->getIndex(callFrame, i);
-            else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i))
+            else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
                 result = asByteArray(baseValue)->getIndex(callFrame, i);
             else
                 result = baseValue.get(callFrame, i);
@@ -3553,13 +3552,13 @@ skip_id_custom_self:
 
         if (LIKELY(subscript.isUInt32())) {
             uint32_t i = subscript.asUInt32();
-            if (isJSArray(globalData, baseValue)) {
+            if (isJSArray(baseValue)) {
                 JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canSetIndex(i))
                     jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue());
                 else
                     jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue());
-            } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
                 JSByteArray* jsByteArray = asByteArray(baseValue);
                 JSValue jsValue = callFrame->r(value).jsValue();
                 if (jsValue.isInt32())
index f83a759..e64e690 100644 (file)
@@ -329,7 +329,7 @@ namespace JSC {
         void emitWriteBarrier(RegisterID owner, RegisterID valueTag, RegisterID scratch, RegisterID scratch2, WriteBarrierMode, WriteBarrierUseKind);
         void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
 
-        template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, void* vtable, RegisterID result, RegisterID storagePtr);
+        template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
         template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
         void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr);
         
index efe7080..f485157 100644 (file)
@@ -84,7 +84,7 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHea
 
 ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
 {
-    failures.append(branchPtr(NotEqual, Address(src), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    failures.append(branchPtr(NotEqual, Address(src, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
     failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
     loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
     failures.append(branchTest32(Zero, dst));
@@ -399,7 +399,7 @@ ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(unsigned src)
     return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isString() && asString(getConstantOperand(src).asCell())->length() == 1;
 }
 
-template <typename ClassType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, void* vtable, RegisterID result, RegisterID storagePtr)
+template <typename ClassType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr)
 {
     MarkedSpace::SizeClass* sizeClass = &m_globalData->heap.sizeClassForObject(sizeof(ClassType));
     loadPtr(&sizeClass->firstFreeCell, result);
@@ -409,12 +409,12 @@ template <typename ClassType, typename StructureType> inline void JIT::emitAlloc
     loadPtr(Address(result), storagePtr);
     storePtr(storagePtr, &sizeClass->firstFreeCell);
 
-    // initialize the object's vtable
-    storePtr(TrustedImmPtr(vtable), Address(result));
-
     // initialize the object's structure
     storePtr(structure, Address(result, JSCell::structureOffset()));
 
+    // initialize the object's classInfo pointer
+    storePtr(TrustedImmPtr(&ClassType::s_info), Address(result, JSCell::classInfoOffset()));
+
     // initialize the inheritor ID
     storePtr(TrustedImmPtr(0), Address(result, JSObject::offsetOfInheritorID()));
 
@@ -425,12 +425,12 @@ template <typename ClassType, typename StructureType> inline void JIT::emitAlloc
 
 template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
 {
-    emitAllocateBasicJSObject<JSFinalObject>(structure, m_globalData->jsFinalObjectVPtr, result, scratch);
+    emitAllocateBasicJSObject<JSFinalObject>(structure, result, scratch);
 }
 
 inline void JIT::emitAllocateJSFunction(FunctionExecutable* executable, RegisterID scopeChain, RegisterID result, RegisterID storagePtr)
 {
-    emitAllocateBasicJSObject<JSFunction>(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), m_globalData->jsFunctionVPtr, result, storagePtr);
+    emitAllocateBasicJSObject<JSFunction>(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), result, storagePtr);
 
     // store the function's scope chain
     storePtr(scopeChain, Address(result, JSFunction::offsetOfScopeChain()));
index 7054b53..f5be279 100644 (file)
@@ -49,7 +49,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl
 
     // Check eax is a string
     Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
-    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
+    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
 
     // Checks out okay! - get the length from the Ustring.
     load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
@@ -579,7 +579,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
     emitGetVirtualRegister(src, regT0);
     
     Jump isImm = emitJumpIfNotJSCell(regT0);
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
     isImm.link(this);
 
     if (dst != src)
@@ -1202,7 +1202,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
 
     emitJumpSlowCaseIfNotJSCell(regT0);
-    addSlowCase(branchPtr(Equal, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    addSlowCase(branchPtr(Equal, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
 }
 
 void JIT::emit_op_get_callee(Instruction* currentInstruction)
index 0cea49e..59c42b8 100644 (file)
@@ -52,7 +52,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl
     // regT0 holds payload, regT1 holds tag
 
     Jump string_failureCases1 = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
+    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
 
     // Checks out okay! - get the length from the Ustring.
     load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT2);
@@ -671,7 +671,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
     emitLoad(src, regT1, regT0);
 
     Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
     isImm.link(this);
 
     if (dst != src)
@@ -963,8 +963,8 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
     genericCase.append(getSlowCase(iter)); // tags not equal
 
     linkSlowCase(iter); // tags equal and JSCell
-    genericCase.append(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
-    genericCase.append(branchPtr(NotEqual, Address(regT2), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+    genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
 
     // String case.
     JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1011,8 +1011,8 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
     genericCase.append(getSlowCase(iter)); // tags not equal
 
     linkSlowCase(iter); // tags equal and JSCell
-    genericCase.append(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
-    genericCase.append(branchPtr(NotEqual, Address(regT2), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+    genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
 
     // String case.
     JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1048,8 +1048,8 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
 
     // Jump to a slow case if both are strings.
     Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    Jump firstNotString = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
-    addSlowCase(branchPtr(Equal, Address(regT2), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
+    addSlowCase(branchPtr(Equal, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
     notCell.link(this);
     firstNotString.link(this);
 
@@ -1524,7 +1524,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
     emitLoad(thisRegister, regT1, regT0);
 
     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
-    addSlowCase(branchPtr(Equal, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+    addSlowCase(branchPtr(Equal, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
 
     map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0);
 }
index 6717a10..48951e8 100644 (file)
@@ -54,7 +54,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
 {
     JSInterfaceJIT jit;
     JumpList failures;
-    failures.append(jit.branchPtr(NotEqual, Address(regT0), TrustedImmPtr(globalData->jsStringVPtr)));
+    failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
 
     // Load string length to regT2, and start the process of loading the data pointer into regT0
     jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
@@ -108,7 +108,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     zeroExtend32ToPtr(regT1, regT1);
 
     emitJumpSlowCaseIfNotJSCell(regT0, base);
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
 
     loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
     addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
@@ -130,7 +130,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
     linkSlowCaseIfNotJSCell(iter, base); // base cell check
     Jump nonCell = jump();
     linkSlowCase(iter); // base array check
-    Jump notString = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
+    Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
     emitNakedCall(CodeLocationLabel(m_globalData->getCTIStub(stringGetByValStubGenerator).code()));
     Jump failed = branchTestPtr(Zero, regT0);
     emitPutVirtualRegister(dst, regT0);
@@ -209,7 +209,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
     // See comment in op_get_by_val.
     zeroExtend32ToPtr(regT1, regT1);
     emitJumpSlowCaseIfNotJSCell(regT0, base);
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
     addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
 
     loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
@@ -559,6 +559,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
     // an unconditional barrier here.
     emitWriteBarrier(regT0, regT1, regT2, regT3, UnconditionalWriteBarrier, WriteBarrierForPropertyAccess);
 
+    ASSERT(newStructure->classInfo() == oldStructure->classInfo());
     storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
     compilePutDirectOffset(regT0, regT1, cachedOffset);
 
@@ -618,7 +619,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
     StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
 
     // Check eax is an array
-    Jump failureCases1 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr));
+    Jump failureCases1 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info));
 
     // Checks out okay! - get the length from the storage
     loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
index feaf8b8..b73d7ab 100644 (file)
@@ -171,7 +171,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
 {
     JSInterfaceJIT jit;
     JumpList failures;
-    failures.append(jit.branchPtr(NotEqual, Address(regT0), TrustedImmPtr(globalData->jsStringVPtr)));
+    failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
     
     // Load string length to regT1, and start the process of loading the data pointer into regT0
     jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
@@ -219,7 +219,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     
     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
     emitJumpSlowCaseIfNotJSCell(base, regT1);
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
     
     loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
     addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
@@ -244,7 +244,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
 
     Jump nonCell = jump();
     linkSlowCase(iter); // base array check
-    Jump notString = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
+    Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
     emitNakedCall(m_globalData->getCTIStub(stringGetByValStubGenerator).code());
     Jump failed = branchTestPtr(Zero, regT0);
     emitStore(dst, regT1, regT0);
@@ -274,7 +274,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
     
     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
     emitJumpSlowCaseIfNotJSCell(base, regT1);
-    addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
     addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
 
     emitWriteBarrier(regT0, regT1, regT1, regT3, UnconditionalWriteBarrier, WriteBarrierForPropertyAccess);
@@ -606,7 +606,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
     // regT0 holds a JSCell*
     
     // Check for array
-    Jump failureCases1 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr));
+    Jump failureCases1 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSArray::s_info));
     
     // Checks out okay! - get the length from the storage
     loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
index 0d46369..eda8c8f 100644 (file)
@@ -875,12 +875,12 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
     
     JSGlobalData* globalData = &callFrame->globalData();
 
-    if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+    if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
         JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
         return;
     }
     
-    if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+    if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
         // The tradeoff of compiling an patched inline string length access routine does not seem
         // to pay off, so we currently only do this for arrays.
         ctiPatchCallByReturnAddress(codeBlock, returnAddress, globalData->jitStubs->ctiStringLengthTrampoline());
@@ -2478,7 +2478,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
-    JSGlobalData* globalData = stackFrame.globalData;
 
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
@@ -2492,13 +2491,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
 
     if (subscript.isUInt32()) {
         uint32_t i = subscript.asUInt32();
-        if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
+        if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
             JSValue result = asString(baseValue)->getIndex(callFrame, i);
             CHECK_FOR_EXCEPTION();
             return JSValue::encode(result);
         }
-        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+        if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
             return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
@@ -2519,7 +2518,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
     STUB_INIT_STACK_FRAME(stackFrame);
     
     CallFrame* callFrame = stackFrame.callFrame;
-    JSGlobalData* globalData = stackFrame.globalData;
     
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
@@ -2528,11 +2526,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
     
     if (LIKELY(subscript.isUInt32())) {
         uint32_t i = subscript.asUInt32();
-        if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
+        if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
             result = asString(baseValue)->getIndex(callFrame, i);
         else {
             result = baseValue.get(callFrame, i);
-            if (!isJSString(globalData, baseValue))
+            if (!isJSString(baseValue))
                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
         }
     } else {
@@ -2549,7 +2547,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array)
     STUB_INIT_STACK_FRAME(stackFrame);
     
     CallFrame* callFrame = stackFrame.callFrame;
-    JSGlobalData* globalData = stackFrame.globalData;
     
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
@@ -2558,13 +2555,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array)
 
     if (LIKELY(subscript.isUInt32())) {
         uint32_t i = subscript.asUInt32();
-        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+        if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
             return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
         }
 
         result = baseValue.get(callFrame, i);
-        if (!isJSByteArray(globalData, baseValue))
+        if (!isJSByteArray(baseValue))
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
     } else {
         Identifier property(callFrame, subscript.toString(callFrame));
@@ -2604,13 +2601,13 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
 
     if (LIKELY(subscript.isUInt32())) {
         uint32_t i = subscript.asUInt32();
-        if (isJSArray(globalData, baseValue)) {
+        if (isJSArray(baseValue)) {
             JSArray* jsArray = asArray(baseValue);
             if (jsArray->canSetIndex(i))
                 jsArray->setIndex(*globalData, i, value);
             else
                 JSArray::putByIndex(jsArray, callFrame, i, value);
-        } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+        } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
             JSByteArray* jsByteArray = asByteArray(baseValue);
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array));
             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
@@ -2643,7 +2640,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
     STUB_INIT_STACK_FRAME(stackFrame);
     
     CallFrame* callFrame = stackFrame.callFrame;
-    JSGlobalData* globalData = stackFrame.globalData;
     
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
@@ -2651,7 +2647,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
     
     if (LIKELY(subscript.isUInt32())) {
         uint32_t i = subscript.asUInt32();
-        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+        if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
             JSByteArray* jsByteArray = asByteArray(baseValue);
             
             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
@@ -2666,7 +2662,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
             }
         }
 
-        if (!isJSByteArray(globalData, baseValue))
+        if (!isJSByteArray(baseValue))
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
         baseValue.put(callFrame, i, value);
     } else {
@@ -3433,7 +3429,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_string)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
 
-    return JSValue::encode(jsBoolean(isJSString(stackFrame.globalData, stackFrame.args[0].jsValue())));
+    return JSValue::encode(jsBoolean(isJSString(stackFrame.args[0].jsValue())));
 }
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
index ecc491e..ab78eaa 100644 (file)
@@ -60,7 +60,7 @@ namespace JSC {
         void loadJSStringArgument(int argument, RegisterID dst)
         {
             loadCellArgument(argument, dst);
-            m_failures.append(branchPtr(NotEqual, Address(dst, 0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+            m_failures.append(branchPtr(NotEqual, Address(dst, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
         }
         
         void loadInt32Argument(int argument, RegisterID dst, Jump& failTarget)
index 9836a12..d1195fb 100644 (file)
@@ -41,6 +41,8 @@ static EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*);
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ArrayConstructor);
+
 const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) };
 
 /* Source for ArrayConstructor.lut.h
index b784413..d8d14f3 100644 (file)
@@ -170,7 +170,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
 {
     JSValue thisValue = exec->hostThisValue();
 
-    bool isRealArray = isJSArray(&exec->globalData(), thisValue);
+    bool isRealArray = isJSArray(thisValue);
     if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
         return throwVMTypeError(exec);
     JSArray* thisObj = asArray(thisValue);
@@ -300,7 +300,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
         separator = exec->argument(0).toString(exec);
 
     unsigned k = 0;
-    if (isJSArray(&exec->globalData(), thisObj)) {
+    if (isJSArray(thisObj)) {
         JSArray* array = asArray(thisObj);
 
         if (length) {
@@ -388,7 +388,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
 {
     JSValue thisValue = exec->hostThisValue();
 
-    if (isJSArray(&exec->globalData(), thisValue))
+    if (isJSArray(thisValue))
         return JSValue::encode(asArray(thisValue)->pop());
 
     JSObject* thisObj = thisValue.toObject(exec);
@@ -412,7 +412,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
 {
     JSValue thisValue = exec->hostThisValue();
 
-    if (isJSArray(&exec->globalData(), thisValue) && exec->argumentCount() == 1) {
+    if (isJSArray(thisValue) && exec->argumentCount() == 1) {
         JSArray* array = asArray(thisValue);
         array->push(exec, exec->argument(0));
         return JSValue::encode(jsNumber(array->length()));
@@ -481,7 +481,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
         result = jsUndefined();
     } else {
         result = thisObj->get(exec, 0);
-        if (isJSArray(&exec->globalData(), thisObj))
+        if (isJSArray(thisObj))
             ((JSArray *)thisObj)->shiftCount(exec, 1);
         else {
             for (unsigned k = 1; k < length; k++) {
@@ -627,7 +627,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
     unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
     if (additionalArgs != deleteCount) {
         if (additionalArgs < deleteCount) {
-            if ((!begin) && (isJSArray(&exec->globalData(), thisObj)))
+            if ((!begin) && (isJSArray(thisObj)))
                 ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs);
             else {
                 for (unsigned k = begin; k < length - deleteCount; ++k) {
@@ -643,7 +643,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
                     thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
             }
         } else {
-            if ((!begin) && (isJSArray(&exec->globalData(), thisObj)))
+            if ((!begin) && (isJSArray(thisObj)))
                 ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount);
             else {
                 for (unsigned k = length - deleteCount; k > begin; --k) {
@@ -676,7 +676,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
 
     unsigned nrArgs = exec->argumentCount();
     if ((nrArgs) && (length)) {
-        if (isJSArray(&exec->globalData(), thisObj))
+        if (isJSArray(thisObj))
             ((JSArray *)thisObj)->unshiftCount(exec, nrArgs);
         else {
             for (unsigned k = length; k > 0; --k) {
@@ -715,7 +715,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
 
     unsigned filterIndex = 0;
     unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+    if (callType == CallTypeJS && isJSArray(thisObj)) {
         JSFunction* f = asFunction(function);
         JSArray* array = asArray(thisObj);
         CachedCall cachedCall(exec, f, 3);
@@ -773,7 +773,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
 
     JSArray* resultArray = constructEmptyArray(exec, length);
     unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+    if (callType == CallTypeJS && isJSArray(thisObj)) {
         JSFunction* f = asFunction(function);
         JSArray* array = asArray(thisObj);
         CachedCall cachedCall(exec, f, 3);
@@ -836,7 +836,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
     JSValue result = jsBoolean(true);
 
     unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+    if (callType == CallTypeJS && isJSArray(thisObj)) {
         JSFunction* f = asFunction(function);
         JSArray* array = asArray(thisObj);
         CachedCall cachedCall(exec, f, 3);
@@ -892,7 +892,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
     JSValue applyThis = exec->argument(1);
 
     unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+    if (callType == CallTypeJS && isJSArray(thisObj)) {
         JSFunction* f = asFunction(function);
         JSArray* array = asArray(thisObj);
         CachedCall cachedCall(exec, f, 3);
@@ -944,7 +944,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
     JSValue result = jsBoolean(false);
 
     unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+    if (callType == CallTypeJS && isJSArray(thisObj)) {
         JSFunction* f = asFunction(function);
         JSArray* array = asArray(thisObj);
         CachedCall cachedCall(exec, f, 3);
@@ -1002,7 +1002,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
         return throwVMTypeError(exec);
 
     JSArray* array = 0;
-    if (isJSArray(&exec->globalData(), thisObj))
+    if (isJSArray(thisObj))
         array = asArray(thisObj);
 
     if (exec->argumentCount() >= 2)
@@ -1079,7 +1079,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
         return throwVMTypeError(exec);
 
     JSArray* array = 0;
-    if (isJSArray(&exec->globalData(), thisObj))
+    if (isJSArray(thisObj))
         array = asArray(thisObj);
     
     if (exec->argumentCount() >= 2)
index dc28de1..a54d281 100644 (file)
@@ -27,6 +27,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanConstructor);
 
 const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) };
 
index 5a449c0..37c6eab 100644 (file)
@@ -24,6 +24,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanObject);
 
 const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) };
 
index c7ea964..b9605d0 100644 (file)
@@ -48,6 +48,7 @@ const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info,
 */
 
 ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanPrototype);
 
 BooleanPrototype::BooleanPrototype(ExecState* exec, Structure* structure)
     : BooleanObject(exec->globalData(), structure)
index 09fedb3..9fff64e 100644 (file)
@@ -33,6 +33,9 @@ namespace JSC {
     struct HashTable;
 
     struct MethodTable {
+        typedef void (*DestroyFunctionPtr)(JSCell*);
+        DestroyFunctionPtr destroy;
+
         typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&);
         VisitChildrenFunctionPtr visitChildren;
 
@@ -114,6 +117,7 @@ struct MemberCheck##member { \
 #define HAS_MEMBER_NAMED(klass, name) (MemberCheck##name<klass>::has)
 
 #define CREATE_METHOD_TABLE(ClassName) { \
+        &ClassName::destroy, \
         &ClassName::visitChildren, \
         &ClassName::getCallData, \
         &ClassName::getConstructData, \
index 931899e..ad402c7 100644 (file)
@@ -72,6 +72,7 @@ const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_inf
 */
 
 ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(DateConstructor);
 
 DateConstructor::DateConstructor(JSGlobalObject* globalObject, Structure* structure)
     : InternalFunction(globalObject, structure) 
index 545757b..a502770 100644 (file)
@@ -53,6 +53,11 @@ void DateInstance::finishCreation(JSGlobalData& globalData, double time)
     setInternalValue(globalData, jsNumber(timeClip(time)));
 }
 
+void DateInstance::destroy(JSCell* cell)
+{
+    jsCast<DateInstance*>(cell)->DateInstance::~DateInstance();
+}
+
 const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exec) const
 {
     double milli = internalNumber();
index 324170b..8d90cf0 100644 (file)
@@ -34,7 +34,9 @@ namespace JSC {
         DateInstance(ExecState*, Structure*);
         void finishCreation(JSGlobalData&);
         void finishCreation(JSGlobalData&, double);
-        
+
+        static void destroy(JSCell*);
     public:
         typedef JSWrapperObject Base;
 
index 4a1e148..a5373d5 100644 (file)
@@ -170,6 +170,11 @@ ASSERT_CLASS_FITS_IN_CELL(StrictModeTypeErrorFunction);
 
 const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
 
+void StrictModeTypeErrorFunction::destroy(JSCell* cell)
+{
+    jsCast<StrictModeTypeErrorFunction*>(cell)->StrictModeTypeErrorFunction::~StrictModeTypeErrorFunction();
+}
+
 JSValue createTypeErrorFunction(ExecState* exec, const UString& message)
 {
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
index ac7354d..17c3498 100644 (file)
@@ -82,6 +82,8 @@ namespace JSC {
         {
         }
 
+        static void destroy(JSCell*);
+
     public:
         typedef InternalFunction Base;
 
index 52309d1..c8f93ba 100644 (file)
@@ -28,6 +28,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorConstructor);
 
 const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorConstructor) };
 
index 83abe5c..91a6fc4 100644 (file)
@@ -23,6 +23,8 @@
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorInstance);
+
 const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorInstance) };
 
 ErrorInstance::ErrorInstance(JSGlobalData& globalData, Structure* structure)
index d5ace80..05e971f 100644 (file)
@@ -41,6 +41,8 @@
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(InterruptedExecutionError);
+
 const ClassInfo InterruptedExecutionError::s_info = { "InterruptedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InterruptedExecutionError) };
 
 JSValue InterruptedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint)
@@ -66,6 +68,8 @@ bool isInterruptedExecutionException(JSValue value)
 }
 
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(TerminatedExecutionError);
+
 const ClassInfo TerminatedExecutionError::s_info = { "TerminatedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(TerminatedExecutionError) };
 
 JSValue TerminatedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint)
index 64e92e8..ad86463 100644 (file)
@@ -38,6 +38,11 @@ namespace JSC {
 
 const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0, CREATE_METHOD_TABLE(ExecutableBase) };
 
+void ExecutableBase::destroy(JSCell* cell)
+{
+    jsCast<ExecutableBase*>(cell)->ExecutableBase::~ExecutableBase();
+}
+
 inline void ExecutableBase::clearCode()
 {
 #if ENABLE(JIT)
@@ -61,8 +66,9 @@ Intrinsic ExecutableBase::intrinsic() const
 
 const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(NativeExecutable) };
 
-NativeExecutable::~NativeExecutable()
+void NativeExecutable::destroy(JSCell* cell)
 {
+    jsCast<NativeExecutable*>(cell)->NativeExecutable::~NativeExecutable();
 }
 
 #if ENABLE(DFG_JIT)
@@ -93,6 +99,11 @@ void NativeExecutable::finalize(JSCell* cell)
 
 const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(ScriptExecutable) };
 
+void ScriptExecutable::destroy(JSCell* cell)
+{
+    jsCast<ScriptExecutable*>(cell)->ScriptExecutable::~ScriptExecutable();
+}
+
 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
 
 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
@@ -100,8 +111,9 @@ EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool i
 {
 }
 
-EvalExecutable::~EvalExecutable()
+void EvalExecutable::destroy(JSCell* cell)
 {
+    jsCast<EvalExecutable*>(cell)->EvalExecutable::~EvalExecutable();
 }
 
 const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
@@ -111,8 +123,9 @@ ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
 {
 }
 
-ProgramExecutable::~ProgramExecutable()
+void ProgramExecutable::destroy(JSCell* cell)
 {
+    jsCast<ProgramExecutable*>(cell)->ProgramExecutable::~ProgramExecutable();
 }
 
 const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
@@ -137,8 +150,9 @@ FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name,
 {
 }
 
-FunctionExecutable::~FunctionExecutable()
+void FunctionExecutable::destroy(JSCell* cell)
 {
+    jsCast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
 }
 
 JSObject* EvalExecutable::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode)
index 6395843..7f85c90 100644 (file)
@@ -77,6 +77,8 @@ namespace JSC {
     public:
         typedef JSCell Base;
 
+        static void destroy(JSCell*);
+
         bool isHostFunction() const
         {
             ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
@@ -206,7 +208,7 @@ namespace JSC {
         }
 #endif
 
-        virtual ~NativeExecutable();
+        static void destroy(JSCell*);
 
         NativeFunction function() { return m_function; }
         NativeFunction constructor() { return m_constructor; }
@@ -274,6 +276,8 @@ namespace JSC {
         {
         }
 
+        static void destroy(JSCell*);
+
         const SourceCode& source() { return m_source; }
         intptr_t sourceID() const { return m_source.provider()->asID(); }
         const UString& sourceURL() const { return m_source.provider()->url(); }
@@ -318,7 +322,7 @@ namespace JSC {
     public:
         typedef ScriptExecutable Base;
 
-        virtual ~EvalExecutable();
+        static void destroy(JSCell*);
 
         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
         {
@@ -391,7 +395,7 @@ namespace JSC {
             return executable;
         }
 
-        virtual ~ProgramExecutable();
+        static void destroy(JSCell*);
 
         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
         {
@@ -468,7 +472,7 @@ namespace JSC {
             return executable;
         }
 
-        virtual ~FunctionExecutable();
+        static void destroy(JSCell*);
 
         JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
         {
index be4c63c..e08e58c 100644 (file)
@@ -36,6 +36,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionConstructor);
 
 const ClassInfo FunctionConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionConstructor) };
 
index 1989827..b1017e4 100644 (file)
@@ -33,6 +33,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionPrototype);
 
 const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionPrototype) };
 
@@ -136,7 +137,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec)
             if (asArguments(array)->length(exec) > Arguments::MaxArguments)
                 return JSValue::encode(throwStackOverflowError(exec));
             asArguments(array)->fillArgList(exec, applyArgs);
-        } else if (isJSArray(&exec->globalData(), array)) {
+        } else if (isJSArray(array)) {
             if (asArray(array)->length() > Arguments::MaxArguments)
                 return JSValue::encode(throwStackOverflowError(exec));
             asArray(array)->fillArgList(exec, applyArgs);
index 17cbb44..920399d 100644 (file)
@@ -28,6 +28,8 @@
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(GetterSetter);
+
 const ClassInfo GetterSetter::s_info = { "GetterSetter", 0, 0, 0, CREATE_METHOD_TABLE(GetterSetter) };
 
 void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor)
index 6989572..2b874c7 100644 (file)
@@ -57,7 +57,6 @@ static void initializeThreadingOnce()
 #if ENABLE(WRITE_BARRIER_PROFILING)
     WriteBarrierCounters::initialize();
 #endif
-    JSGlobalData::storeVPtrs();
 #if ENABLE(JIT) && ENABLE(ASSEMBLER)
     ExecutableAllocator::initializeAllocator();
 #endif
index 1714163..50ea504 100644 (file)
 
 namespace JSC {
 
-// Ensure the compiler generates a vtable for InternalFunction!
-void InternalFunction::vtableAnchor() {}
-
 ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction);
 
 const ClassInfo InternalFunction::s_info = { "Function", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
 
-InternalFunction::InternalFunction(VPtrStealingHackType)
-    : JSNonFinalObject(VPtrStealingHack)
-{
-}
-
 InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure)
     : JSNonFinalObject(globalObject->globalData(), structure)
 {
@@ -63,7 +56,7 @@ const UString InternalFunction::displayName(ExecState* exec)
 {
     JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
     
-    if (displayName && isJSString(&exec->globalData(), displayName))
+    if (displayName && isJSString(displayName))
         return asString(displayName)->tryGetValue();
     
     return UString();
index 8e2178e..a038b7a 100644 (file)
@@ -49,17 +49,11 @@ namespace JSC {
     protected:
         static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
 
-        // Only used to allow us to determine the JSFunction vptr
-        InternalFunction(VPtrStealingHackType);
-
         InternalFunction(JSGlobalObject*, Structure*);
 
         void finishCreation(JSGlobalData&, const Identifier& name);
 
         static CallType getCallData(JSCell*, CallData&);
-
-    private:
-        virtual void vtableAnchor();
     };
 
     InternalFunction* asInternalFunction(JSValue);
index b1b33f5..8517085 100644 (file)
@@ -28,6 +28,8 @@
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSAPIValueWrapper);
+
 const ClassInfo JSAPIValueWrapper::s_info = { "API Wrapper", 0, 0, 0, CREATE_METHOD_TABLE(JSAPIValueWrapper) };
 
 } // namespace JSC
index f756c7b..0c9220e 100644 (file)
@@ -126,11 +126,6 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
 
 #endif
 
-JSArray::JSArray(VPtrStealingHackType)
-    : JSNonFinalObject(VPtrStealingHack)
-{
-}
-
 JSArray::JSArray(JSGlobalData& globalData, Structure* structure)
     : JSNonFinalObject(globalData, structure)
 {
@@ -277,13 +272,18 @@ void JSArray::finishCreation(JSGlobalData& globalData, const JSValue* values, si
 
 JSArray::~JSArray()
 {
-    ASSERT(vptr() == JSGlobalData::jsArrayVPtr);
+    ASSERT(jsCast<JSArray*>(this));
     checkConsistency(DestructorConsistencyCheck);
 
     delete m_storage->m_sparseValueMap;
     fastFree(m_storage->m_allocBase);
 }
 
+void JSArray::destroy(JSCell* cell)
+{
+    jsCast<JSArray*>(cell)->JSArray::~JSArray();
+}
+
 bool JSArray::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i, PropertySlot& slot)
 {
     JSArray* thisObject = jsCast<JSArray*>(cell);
index e958d55..1ead82c 100644 (file)
@@ -71,8 +71,8 @@ namespace JSC {
     public:
         typedef JSNonFinalObject Base;
 
-        JSArray(VPtrStealingHackType);
-        virtual ~JSArray();
+        ~JSArray();
+        static void destroy(JSCell*);
 
         static JSArray* create(JSGlobalData& globalData, Structure* structure)
         {
@@ -216,8 +216,8 @@ namespace JSC {
         return asArray(value.asCell());
     }
 
-    inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; }
-    inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && isJSArray(globalData, v.asCell()); }
+    inline bool isJSArray(JSCell* cell) { return cell->classInfo() == &JSArray::s_info; }
+    inline bool isJSArray(JSValue v) { return v.isCell() && isJSArray(v.asCell()); }
 
     // Rule from ECMA 15.2 about what an array index is.
     // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
index cf0ba83..0e5a99a 100644 (file)
@@ -31,6 +31,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSBoundFunction);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSBoundFunction);
 
 const ClassInfo JSBoundFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSBoundFunction) };
 
@@ -38,7 +39,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState* exec)
 {
     JSBoundFunction* boundFunction = static_cast<JSBoundFunction*>(exec->callee());
 
-    ASSERT(isJSArray(&exec->globalData(), boundFunction->boundArgs())); // Currently this is true!
+    ASSERT(isJSArray(boundFunction->boundArgs())); // Currently this is true!
     JSArray* boundArgs = asArray(boundFunction->boundArgs());
 
     MarkedArgumentBuffer args;
@@ -58,7 +59,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState* exec)
 {
     JSBoundFunction* boundFunction = static_cast<JSBoundFunction*>(exec->callee());
 
-    ASSERT(isJSArray(&exec->globalData(), boundFunction->boundArgs())); // Currently this is true!
+    ASSERT(isJSArray(boundFunction->boundArgs())); // Currently this is true!
     JSArray* boundArgs = asArray(boundFunction->boundArgs());
 
     MarkedArgumentBuffer args;
index 9973c56..7478a08 100644 (file)
@@ -41,13 +41,15 @@ JSByteArray::JSByteArray(ExecState* exec, Structure* structure, ByteArray* stora
 {
 }
         
-#if !ASSERT_DISABLED
 JSByteArray::~JSByteArray()
 {
-    ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr);
+    ASSERT(jsCast<JSByteArray*>(this));
 }
-#endif
 
+void JSByteArray::destroy(JSCell* cell)
+{
+    jsCast<JSByteArray*>(cell)->JSByteArray::~JSByteArray();
+}
 
 Structure* JSByteArray::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const JSC::ClassInfo* classInfo)
 {
index 0041d14..5122bad 100644 (file)
@@ -102,9 +102,8 @@ namespace JSC {
 
         WTF::ByteArray* storage() const { return m_storage.get(); }
 
-#if !ASSERT_DISABLED
-        virtual ~JSByteArray();
-#endif
+        ~JSByteArray();
+        static void destroy(JSCell*);
 
         static size_t offsetOfStorage() { return OBJECT_OFFSETOF(JSByteArray, m_storage); }
 
@@ -118,11 +117,6 @@ namespace JSC {
         }
 
     private:
-        JSByteArray(VPtrStealingHackType)
-            : JSNonFinalObject(VPtrStealingHack)
-        {
-        }
-
         RefPtr<WTF::ByteArray> m_storage;
     };
     
@@ -132,7 +126,7 @@ namespace JSC {
         return static_cast<JSByteArray*>(value.asCell());
     }
 
-    inline bool isJSByteArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; }
+    inline bool isJSByteArray(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSByteArray::s_info; }
 
 } // namespace JSC
 
index 491ef08..065fd13 100644 (file)
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCell);
+
+void JSCell::destroy(JSCell* cell)
+{
+    cell->JSCell::~JSCell();
+}
+
 bool JSCell::getString(ExecState* exec, UString&stringValue) const
 {
     if (!isString())
index 76cef04..c755a60 100644 (file)
@@ -65,15 +65,12 @@ namespace JSC {
         enum CreatingEarlyCellTag { CreatingEarlyCell };
         JSCell(CreatingEarlyCellTag);
 
-        enum VPtrStealingHackType { VPtrStealingHack };
-        explicit JSCell(VPtrStealingHackType) { }
-
     public:
         void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; } // Used for initialization after GC allocation.
 
     protected:
         JSCell(JSGlobalData&, Structure*);
-        virtual ~JSCell(); // Invoked by GC finalization.
+        static void destroy(JSCell*);
 
     public:
         // Querying the type.
@@ -108,6 +105,7 @@ namespace JSC {
 
         // Object operations, with the toObject operation included.
         const ClassInfo* classInfo() const;
+        const ClassInfo* validatedClassInfo() const;
         const MethodTable* methodTable() const;
         static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
@@ -117,8 +115,6 @@ namespace JSC {
 
         static JSObject* toThisObject(JSCell*, ExecState*);
 
-        void* vptr() const { ASSERT(!isZapped()); return *reinterpret_cast<void* const*>(this); }
-        void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; ASSERT(!isZapped()); }
         void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
         bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
 
@@ -133,6 +129,11 @@ namespace JSC {
         {
             return OBJECT_OFFSETOF(JSCell, m_structure);
         }
+
+        static ptrdiff_t classInfoOffset()
+        {
+            return OBJECT_OFFSETOF(JSCell, m_classInfo);
+        }
         
         void* structureAddress()
         {
@@ -166,13 +167,9 @@ namespace JSC {
         static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
 
     private:
+        const ClassInfo* m_classInfo;
         WriteBarrier<Structure> m_structure;
     };
-    
-    inline JSCell::JSCell(JSGlobalData& globalData, Structure* structure)
-        : m_structure(globalData, this, structure)
-    {
-    }
 
     inline JSCell::JSCell(CreatingEarlyCellTag)
     {
@@ -189,25 +186,14 @@ namespace JSC {
         ASSERT(m_structure);
     }
 
-    inline void JSCell::finishCreation(JSGlobalData& globalData, Structure* structure, CreatingEarlyCellTag)
-    {
-#if ENABLE(GC_VALIDATION)
-        ASSERT(globalData.isInitializingObject());
-        globalData.setInitializingObject(false);
-        if (structure)
-#endif
-            m_structure.setEarlyValue(globalData, this, structure);
-        // Very first set of allocations won't have a real structure.
-        ASSERT(m_structure || !globalData.structureStructure);
-    }
-
-    inline JSCell::~JSCell()
+    inline Structure* JSCell::structure() const
     {
+        return m_structure.get();
     }
 
-    inline Structure* JSCell::structure() const
+    inline const ClassInfo* JSCell::classInfo() const
     {
-        return m_structure.get();
+        return m_classInfo;
     }
 
     inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
index 0812f21..4e05535 100644 (file)
@@ -73,11 +73,6 @@ JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, in
     return function;
 }
 
-JSFunction::JSFunction(VPtrStealingHackType)
-    : Base(VPtrStealingHack)
-{
-}
-
 JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
     : Base(exec->globalData(), structure)
     , m_executable()
@@ -113,14 +108,11 @@ void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable,
     putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
 }
 
-JSFunction::~JSFunction()
+void JSFunction::destroy(JSCell* cell)
 {
-    ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
-}
-
-void JSFunction::vtableAnchor()
-{
-    fprintf(stderr, "We need something here that Visual Studio can't optimize away.\n");
+    JSFunction* thisObject = jsCast<JSFunction*>(cell);
+    ASSERT(thisObject->classInfo()->isSubClassOf(&JSFunction::s_info));
+    thisObject->JSFunction::~JSFunction();
 }
 
 void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
@@ -138,7 +130,7 @@ const UString JSFunction::displayName(ExecState* exec)
 {
     JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
     
-    if (displayName && isJSString(&exec->globalData(), displayName))
+    if (displayName && isJSString(displayName))
         return asString(displayName)->tryGetValue();
     
     return UString();
index b75332a..988ae12 100644 (file)
@@ -35,7 +35,6 @@ namespace JSC {
     class JSGlobalObject;
     class NativeExecutable;
     class SourceCode;
-    class VPtrHackExecutable;
     namespace DFG {
     class SpeculativeJIT;
     class JITCompiler;
@@ -65,8 +64,7 @@ namespace JSC {
             return function;
         }
         
-        virtual ~JSFunction();
-        virtual void vtableAnchor(); // FIXME: Remove this once optimizations no longer rely on testing vtables
+        static void destroy(JSCell*);
 
         const UString& name(ExecState*);
         const UString displayName(ExecState*);
@@ -144,8 +142,6 @@ namespace JSC {
         static void visitChildren(JSCell*, SlotVisitor&);
 
     private:
-        explicit JSFunction(VPtrStealingHackType);
-
         bool isHostFunctionNonInline() const;
 
         static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
index a535fc2..22e7693 100644 (file)
@@ -109,12 +109,6 @@ extern const HashTable regExpPrototypeTable;
 extern const HashTable stringTable;
 extern const HashTable stringConstructorTable;
 
-void* JSGlobalData::jsFinalObjectVPtr;
-void* JSGlobalData::jsArrayVPtr;
-void* JSGlobalData::jsByteArrayVPtr;
-void* JSGlobalData::jsStringVPtr;
-void* JSGlobalData::jsFunctionVPtr;
-
 #if COMPILER(GCC)
 // Work around for gcc trying to coalesce our reads of the various cell vptrs
 #define CLOBBER_MEMORY() do { \
@@ -124,52 +118,6 @@ void* JSGlobalData::jsFunctionVPtr;
 #define CLOBBER_MEMORY() do { } while (false)
 #endif
 
-void JSGlobalData::storeVPtrs()
-{
-    // Enough storage to fit a JSArray, JSByteArray, JSString, or JSFunction.
-    // COMPILE_ASSERTS below check that this is true.
-    char storage[64];
-
-    COMPILE_ASSERT(sizeof(JSFinalObject) <= sizeof(storage), sizeof_JSFinalObject_must_be_less_than_storage);
-    JSCell* jsFinalObject = new (storage) JSFinalObject(JSFinalObject::VPtrStealingHack);
-    CLOBBER_MEMORY();
-    JSGlobalData::jsFinalObjectVPtr = jsFinalObject->vptr();
-
-    COMPILE_ASSERT(sizeof(JSArray) <= sizeof(storage), sizeof_JSArray_must_be_less_than_storage);
-    JSCell* jsArray = new (storage) JSArray(JSArray::VPtrStealingHack);
-    CLOBBER_MEMORY();
-    JSGlobalData::jsArrayVPtr = jsArray->vptr();
-
-    COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(storage), sizeof_JSByteArray_must_be_less_than_storage);
-    JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
-    CLOBBER_MEMORY();
-    JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
-
-    COMPILE_ASSERT(sizeof(JSString) <= sizeof(storage), sizeof_JSString_must_be_less_than_storage);
-    JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
-    CLOBBER_MEMORY();
-    JSGlobalData::jsStringVPtr = jsString->vptr();
-
-    COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(storage), sizeof_JSFunction_must_be_less_than_storage);
-    JSCell* jsFunction = new (storage) JSFunction(JSCell::VPtrStealingHack);
-    CLOBBER_MEMORY();
-    JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
-
-    // Until we fully remove our reliance on vptrs, we need to make sure that everybody that 
-    // we think has a unique virtual pointer actually does.
-    if (jsFinalObjectVPtr == jsArrayVPtr
-        || jsFinalObjectVPtr == jsByteArrayVPtr
-        || jsFinalObjectVPtr == jsStringVPtr
-        || jsFinalObjectVPtr == jsFunctionVPtr
-        || jsArrayVPtr == jsByteArrayVPtr
-        || jsArrayVPtr == jsStringVPtr
-        || jsArrayVPtr == jsFunctionVPtr
-        || jsByteArrayVPtr == jsStringVPtr
-        || jsByteArrayVPtr == jsFunctionVPtr
-        || jsStringVPtr == jsFunctionVPtr)
-        CRASH();
-}
-
 JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType, HeapSize heapSize)
     : globalDataType(globalDataType)
     , clientData(0)
index 139dd42..1619f92 100644 (file)
@@ -105,18 +105,18 @@ namespace JSC {
 
     struct TypedArrayDescriptor {
         TypedArrayDescriptor()
-            : m_vptr(0)
+            : m_classInfo(0)
             , m_storageOffset(0)
             , m_lengthOffset(0)
         {
         }
-        TypedArrayDescriptor(void* vptr, size_t storageOffset, size_t lengthOffset)
-            : m_vptr(vptr)
+        TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset)
+            : m_classInfo(classInfo)
             , m_storageOffset(storageOffset)
             , m_lengthOffset(lengthOffset)
         {
         }
-        void* m_vptr;
+        const ClassInfo* m_classInfo;
         size_t m_storageOffset;
         size_t m_lengthOffset;
     };
@@ -193,13 +193,6 @@ namespace JSC {
         Strong<Structure> regExpStructure;
         Strong<Structure> structureChainStructure;
 
-        static void storeVPtrs();
-        static JS_EXPORTDATA void* jsFinalObjectVPtr;
-        static JS_EXPORTDATA void* jsArrayVPtr;
-        static JS_EXPORTDATA void* jsByteArrayVPtr;
-        static JS_EXPORTDATA void* jsStringVPtr;
-        static JS_EXPORTDATA void* jsFunctionVPtr;
-
         IdentifierTable* identifierTable;
         CommonIdentifiers* propertyNames;
         const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
@@ -340,7 +333,7 @@ namespace JSC {
 #define registerTypedArrayFunction(type, capitalizedType) \
         void registerTypedArrayDescriptor(const capitalizedType##Array*, const TypedArrayDescriptor& descriptor) \
         { \
-            ASSERT(!m_##type##ArrayDescriptor.m_vptr || m_##type##ArrayDescriptor.m_vptr == descriptor.m_vptr); \
+            ASSERT(!m_##type##ArrayDescriptor.m_classInfo || m_##type##ArrayDescriptor.m_classInfo == descriptor.m_classInfo); \
             m_##type##ArrayDescriptor = descriptor; \
         } \
         const TypedArrayDescriptor& type##ArrayDescriptor() const { return m_##type##ArrayDescriptor; }
index 342985c..420bc89 100644 (file)
@@ -122,6 +122,11 @@ JSGlobalObject::~JSGlobalObject()
     }
 }
 
+void JSGlobalObject::destroy(JSCell* cell)
+{
+    jsCast<JSGlobalObject*>(cell)->JSGlobalObject::~JSGlobalObject();
+}
+
 void JSGlobalObject::init(JSObject* thisValue)
 {
     ASSERT(JSLock::currentThreadIsHoldingLock());
index 3f93cd8..782e3a3 100644 (file)
@@ -193,7 +193,8 @@ namespace JSC {
         }
 
     public:
-        virtual ~JSGlobalObject();
+        ~JSGlobalObject();
+        static void destroy(JSCell*);
 
         static void visitChildren(JSCell*, SlotVisitor&);
 
index 85bfb7a..8b2a7a1 100644 (file)
@@ -31,6 +31,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSGlobalThis);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSGlobalThis);
 
 const ClassInfo JSGlobalThis::s_info = { "JSGlobalThis", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSGlobalThis) };
 
index 91f90d6..6824002 100644 (file)
@@ -35,6 +35,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSNotAnObject);
 
 const ClassInfo JSNotAnObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNotAnObject) };
 
index ea4c1ad..05c6c29 100644 (file)
@@ -43,6 +43,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSONObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSONObject);
 
 static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*);
 static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*);
@@ -495,7 +496,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu
     // First time through, initialize.
     if (!m_index) {
         if (m_isArray) {
-            m_isJSArray = isJSArray(&exec->globalData(), m_object.get());
+            m_isJSArray = isJSArray(m_object.get());
             m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
             builder.append('[');
         } else {
@@ -669,7 +670,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
             arrayStartState:
             case ArrayStartState: {
                 ASSERT(inValue.isObject());
-                ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue)) || asObject(inValue)->inherits(&JSArray::s_info));
+                ASSERT(isJSArray(asObject(inValue)) || asObject(inValue)->inherits(&JSArray::s_info));
                 if (objectStack.size() + arrayStack.size() > maximumFilterRecursion)
                     return throwError(m_exec, createStackOverflowError(m_exec));
 
@@ -694,7 +695,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
                     indexStack.removeLast();
                     break;
                 }
-                if (isJSArray(&m_exec->globalData(), array) && array->canGetIndex(index))
+                if (isJSArray(array) && array->canGetIndex(index))
                     inValue = array->getIndex(index);
                 else {
                     PropertySlot slot;
@@ -717,7 +718,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
                 if (filteredValue.isUndefined())
                     array->methodTable()->deletePropertyByIndex(array, m_exec, indexStack.last());
                 else {
-                    if (isJSArray(&m_exec->globalData(), array) && array->canSetIndex(indexStack.last()))
+                    if (isJSArray(array) && array->canSetIndex(indexStack.last()))
                         array->setIndex(m_exec->globalData(), indexStack.last(), filteredValue);
                     else
                         array->methodTable()->putByIndex(array, m_exec, indexStack.last(), filteredValue);
@@ -730,7 +731,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
             objectStartState:
             case ObjectStartState: {
                 ASSERT(inValue.isObject());
-                ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue)) && !asObject(inValue)->inherits(&JSArray::s_info));
+                ASSERT(!isJSArray(asObject(inValue)) && !asObject(inValue)->inherits(&JSArray::s_info));
                 if (objectStack.size() + arrayStack.size() > maximumFilterRecursion)
                     return throwError(m_exec, createStackOverflowError(m_exec));
 
@@ -797,7 +798,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
                     break;
                 }
                 JSObject* object = asObject(inValue);
-                if (isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::s_info))
+                if (isJSArray(object) || object->inherits(&JSArray::s_info))
                     goto arrayStartState;
                 goto objectStartState;
         }
index 14f0935..9cc2961 100644 (file)
@@ -46,15 +46,22 @@ ASSERT_CLASS_FITS_IN_CELL(JSObject);
 ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
 ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSObject);
+
 const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
 
 const ClassInfo JSObject::s_info = { "Object", 0, 0, 0, CREATE_METHOD_TABLE(JSObject) };
 
 const ClassInfo JSFinalObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFinalObject) };
 
-void JSFinalObject::vtableAnchor()
+void JSFinalObject::destroy(JSCell* cell)
+{
+    jsCast<JSFinalObject*>(cell)->JSFinalObject::~JSFinalObject();
+}
+
+void JSNonFinalObject::destroy(JSCell* cell)
 {
-    printf("Something Visual Studio can't optimize away.\n");
+    jsCast<JSNonFinalObject*>(cell)->JSNonFinalObject::~JSNonFinalObject();
 }
 
 static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
@@ -81,8 +88,9 @@ void JSObject::finalize(JSCell* cell)
     delete [] jsCast<JSObject*>(cell)->m_propertyStorage.get();
 }
 
-void JSObject::vtableAnchor()
+void JSObject::destroy(JSCell* cell)
 {
+    jsCast<JSObject*>(cell)->JSObject::~JSObject();
 }
 
 void JSObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
index f568d42..363ec30 100644 (file)
@@ -80,7 +80,7 @@ namespace JSC {
     public:
         typedef JSCell Base;
 
-        virtual void vtableAnchor();
+        static void destroy(JSCell*);
 
         static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -243,6 +243,7 @@ namespace JSC {
             ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
             ASSERT_UNUSED(inlineStorage, static_cast<void*>(inlineStorage) == static_cast<void*>(this + 1));
             ASSERT(structure()->isObject());
+            ASSERT(classInfo());
         }
 
         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
@@ -255,11 +256,6 @@ namespace JSC {
         // To instantiate objects you likely want JSFinalObject, below.
         // To create derived types you likely want JSNonFinalObject, below.
         JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
-        JSObject(VPtrStealingHackType, PropertyStorage inlineStorage)
-            : JSCell(VPtrStealingHack)
-            , m_propertyStorage(inlineStorage, StorageBarrier::Unchecked)
-        {
-        }
 
     private:
         // Nobody should ever ask any of these questions on something already known to be a JSObject.
@@ -319,12 +315,9 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
             return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
         }
 
+        static void destroy(JSCell*);
+
     protected:
-        explicit JSNonFinalObject(VPtrStealingHackType)
-            : JSObject(VPtrStealingHack, m_inlineStorage)
-        {
-        }
-    
         explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure)
             : JSObject(globalData, structure, m_inlineStorage)
         {
@@ -335,6 +328,7 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
             Base::finishCreation(globalData, m_inlineStorage);
             ASSERT(!(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double)));
             ASSERT(this->structure()->propertyStorageCapacity() == JSNonFinalObject_inlineStorageCapacity);
+            ASSERT(classInfo());
         }
 
     private:
@@ -349,11 +343,6 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
     public:
         typedef JSObject Base;
 
-        explicit JSFinalObject(VPtrStealingHackType)
-            : JSObject(VPtrStealingHack, m_inlineStorage)
-        {
-        }
-        
         static JSFinalObject* create(ExecState* exec, Structure* structure)
         {
             JSFinalObject* finalObject = new (allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure);
@@ -374,21 +363,32 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
             Base::finishCreation(globalData, m_inlineStorage);
             ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double)));
             ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity);
+            ASSERT(classInfo());
         }
 
+        static void destroy(JSCell*);
+
     private:
         explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
             : JSObject(globalData, structure, m_inlineStorage)
         {
         }
 
-        virtual void vtableAnchor();
-
         static const unsigned StructureFlags = JSObject::StructureFlags;
 
         WriteBarrierBase<Unknown> m_inlineStorage[JSFinalObject_inlineStorageCapacity];
     };
 
+inline bool isJSFinalObject(JSCell* cell)
+{
+    return cell->classInfo() == &JSFinalObject::s_info;
+}
+
+inline bool isJSFinalObject(JSValue value)
+{
+    return value.isCell() && isJSFinalObject(value.asCell());
+}
+
 inline size_t JSObject::offsetOfInlineStorage()
 {
     ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) == OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage));
index f431042..7207a4c 100644 (file)
@@ -81,6 +81,11 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
     return jsPropertyNameIterator;
 }
 
+void JSPropertyNameIterator::destroy(JSCell* cell)
+{
+    jsCast<JSPropertyNameIterator*>(cell)->JSPropertyNameIterator::~JSPropertyNameIterator();
+}
+
 JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
 {
     JSValue identifier = m_jsStrings[i].get();
index 97a5032..ce2e44e 100644 (file)
@@ -52,7 +52,9 @@ namespace JSC {
             iterator->finishCreation(exec, propertyNameArrayData);
             return iterator;
         }
-        
+
+        static void destroy(JSCell*);
+       
         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
         {
             return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info);
index d90c68c..3084f3f 100644 (file)
@@ -34,6 +34,11 @@ ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
 
 const ClassInfo JSStaticScopeObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSStaticScopeObject) };
 
+void JSStaticScopeObject::destroy(JSCell* cell)
+{
+    jsCast<JSStaticScopeObject*>(cell)->JSStaticScopeObject::~JSStaticScopeObject();
+}
+
 void JSStaticScopeObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSStaticScopeObject* thisObject = jsCast<JSStaticScopeObject*>(cell);
index 23a3aca..de0b816 100644 (file)
@@ -67,7 +67,9 @@ namespace JSC{
             : JSVariableObject(exec->globalData(), exec->globalData().staticScopeStructure.get(), &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1))
         {
         }
-        
+
+        static void destroy(JSCell*);
+
         SymbolTable m_symbolTable;
         WriteBarrier<Unknown> m_registerStore;
     };
index 0e6a48a..62cc55c 100644 (file)
@@ -45,9 +45,10 @@ void JSString::RopeBuilder::expand()
     append(jsString);
 }
 
-JSString::~JSString()
+void JSString::destroy(JSCell* cell)
 {
-    ASSERT(vptr() == JSGlobalData::jsStringVPtr);
+    JSString* thisObject = jsCast<JSString*>(cell);
+    thisObject->JSString::~JSString();
 }
 
 void JSString::visitChildren(JSCell* cell, SlotVisitor& visitor)
index 7cf8382..d51a23f 100644 (file)
@@ -69,6 +69,8 @@ namespace JSC {
 
         typedef JSCell Base;
 
+        static void destroy(JSCell*);
+
         class RopeBuilder {
         public:
             RopeBuilder(JSGlobalData& globalData)
@@ -197,8 +199,6 @@ namespace JSC {
             return newString;
         }
 
-        virtual ~JSString();
-
         const UString& value(ExecState* exec) const
         {
             if (isRope())
@@ -243,11 +243,6 @@ namespace JSC {
         static void visitChildren(JSCell*, SlotVisitor&);
 
     private:
-        JSString(VPtrStealingHackType) 
-            : JSCell(VPtrStealingHack)
-        {
-        }
-
         void resolveRope(ExecState*) const;
         void resolveRopeSlowCase8(LChar*) const;
         void resolveRopeSlowCase(UChar*) const;
@@ -279,16 +274,6 @@ namespace JSC {
 
     JSString* asString(JSValue);
 
-    // When an object is created from a different DLL, MSVC changes vptr to a "local" one right after invoking a constructor,
-    // see <http://groups.google.com/group/microsoft.public.vc.language/msg/55cdcefeaf770212>.
-    // This breaks isJSString(), and we don't need that hack anyway, so we change vptr back to primary one.
-    // The below function must be called by any inline function that invokes a JSString constructor.
-#if COMPILER(MSVC) && !defined(BUILDING_JavaScriptCore)
-    inline JSString* fixupVPtr(JSGlobalData* globalData, JSString* string) { string->setVPtr(globalData->jsStringVPtr); return string; }
-#else
-    inline JSString* fixupVPtr(JSGlobalData*, JSString* string) { return string; }
-#endif
-
     inline JSString* asString(JSValue value)
     {
         ASSERT(value.asCell()->isString());
@@ -304,7 +289,7 @@ namespace JSC {
     {
         if (c <= maxSingleCharacterString)
             return globalData->smallStrings.singleCharacterString(globalData, c);
-        return fixupVPtr(globalData, JSString::create(*globalData, UString(&c, 1).impl()));
+        return JSString::create(*globalData, UString(&c, 1).impl());
     }
 
     inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset)
@@ -314,7 +299,7 @@ namespace JSC {
         UChar c = s[offset];
         if (c <= maxSingleCharacterString)
             return globalData->smallStrings.singleCharacterString(globalData, c);
-        return fixupVPtr(globalData, JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1)));
+        return JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1));
     }
 
     inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
@@ -322,13 +307,13 @@ namespace JSC {
         ASSERT(s);
         ASSERT(s[0]);
         ASSERT(s[1]);
-        return fixupVPtr(globalData, JSString::create(*globalData, UString(s).impl()));
+        return JSString::create(*globalData, UString(s).impl());
     }
 
     inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s)
     {
         ASSERT(s.length() > 1);
-        return fixupVPtr(globalData, JSString::create(*globalData, s.impl()));
+        return JSString::create(*globalData, s.impl());
     }
 
     inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
@@ -350,7 +335,7 @@ namespace JSC {
             if (c <= maxSingleCharacterString)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
-        return fixupVPtr(globalData, JSString::create(*globalData, s.impl()));
+        return JSString::create(*globalData, s.impl());
     }
 
     inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
@@ -376,7 +361,7 @@ namespace JSC {
             if (c <= maxSingleCharacterString)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
-        return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length)));
+        return JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length));
     }
 
     inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
@@ -391,7 +376,7 @@ namespace JSC {
             if (c <= maxSingleCharacterString)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
-        return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length)));
+        return JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length));
     }
 
     inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
@@ -404,12 +389,12 @@ namespace JSC {
             if (c <= maxSingleCharacterString)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
-        return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, s.impl()));
+        return JSString::createHasOtherOwner(*globalData, s.impl());
     }
 
     inline JSString* jsStringBuilder(JSGlobalData* globalData)
     {
-        return fixupVPtr(globalData, JSString::createNull(*globalData));
+        return JSString::createNull(*globalData);
     }
 
     inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
@@ -448,7 +433,7 @@ namespace JSC {
         return false;
     }
 
-    inline bool isJSString(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsStringVPtr; }
+    inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSString::s_info; }
 
     inline bool JSCell::toBoolean(ExecState* exec) const
     {
index 9f38ea9..706e3de 100644 (file)
@@ -37,8 +37,9 @@
 
 namespace JSC {
 
-JSVariableObject::~JSVariableObject()
+void JSVariableObject::destroy(JSCell* cell)
 {
+    jsCast<JSVariableObject*>(cell)->JSVariableObject::~JSVariableObject();
 }
 
 bool JSVariableObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
index e49fb71..8a5c5a0 100644 (file)
@@ -48,7 +48,7 @@ namespace JSC {
 
         SymbolTable& symbolTable() const { return *m_symbolTable; }
 
-        virtual ~JSVariableObject();
+        static void destroy(JSCell*);
 
         static NO_RETURN_DUE_TO_ASSERT void putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
 
index ca5bd87..f8f5727 100644 (file)
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject);
-
-JSWrapperObject::~JSWrapperObject()
-{
-}
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSWrapperObject);
 
 void JSWrapperObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
index 73713c0..65b4bdb 100644 (file)
@@ -46,8 +46,6 @@ namespace JSC {
 
         static void visitChildren(JSCell*, SlotVisitor&);
 
-        virtual ~JSWrapperObject();
-        
     private:
         WriteBarrier<Unknown> m_internalValue;
     };
index 006559d..58b0912 100644 (file)
@@ -59,6 +59,8 @@ static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject);
+
 const ClassInfo MathObject::s_info = { "Math", &JSNonFinalObject::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) };
 
 /* Source for MathObject.lut.h
index dde9278..b6aff91 100644 (file)
@@ -29,6 +29,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(NativeErrorConstructor);
 
 const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(NativeErrorConstructor) };
 
index 084c63f..e863e86 100644 (file)
@@ -42,6 +42,8 @@ static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&)
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberConstructor);
+
 const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::numberConstructorTable, CREATE_METHOD_TABLE(NumberConstructor) };
 
 /* Source for NumberConstructor.lut.h
index b751053..1fea254 100644 (file)
@@ -28,6 +28,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NumberObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberObject);
 
 const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(NumberObject) };
 
index 3bcb9bb..4612b56 100644 (file)
@@ -69,6 +69,7 @@ const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0,
 */
 
 ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberPrototype);
 
 NumberPrototype::NumberPrototype(ExecState* exec, Structure* structure)
     : NumberObject(exec->globalData(), structure)
index 5952ce8..65d28c1 100644 (file)
@@ -55,6 +55,8 @@ static EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ObjectConstructor);
+
 const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
 
 /* Source for ObjectConstructor.lut.h
index a1e4966..3f4dc19 100644 (file)
@@ -44,6 +44,8 @@ static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ObjectPrototype);
+
 const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, ExecState::objectPrototypeTable, CREATE_METHOD_TABLE(ObjectPrototype) };
 
 /* Source for ObjectPrototype.lut.h
index 97dae3e..ca2174f 100644 (file)
@@ -47,7 +47,7 @@ namespace JSC {
         if ((length1 + length2) < length1)
             return throwOutOfMemoryError(exec);
 
-        return fixupVPtr(&globalData, JSString::create(globalData, s1, s2));
+        return JSString::create(globalData, s1, s2);
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
@@ -69,7 +69,7 @@ namespace JSC {
         if ((length1 + length2 + length3) < length3)
             return throwOutOfMemoryError(exec);
 
-        return fixupVPtr(globalData, JSString::create(exec->globalData(), jsString(globalData, u1), jsString(globalData, u2), jsString(globalData, u3)));
+        return JSString::create(exec->globalData(), jsString(globalData, u1), jsString(globalData, u2), jsString(globalData, u3));
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
@@ -230,8 +230,7 @@ namespace JSC {
         if (v1.isNumber() && v2.isNumber())
             return v1.asNumber() < v2.asNumber();
 
-        JSGlobalData* globalData = &callFrame->globalData();
-        if (isJSString(globalData, v1) && isJSString(globalData, v2))
+        if (isJSString(v1) && isJSString(v2))
             return asString(v1)->value(callFrame) < asString(v2)->value(callFrame);
 
         double n1;
@@ -265,8 +264,7 @@ namespace JSC {
         if (v1.isNumber() && v2.isNumber())
             return v1.asNumber() <= v2.asNumber();
 
-        JSGlobalData* globalData = &callFrame->globalData();
-        if (isJSString(globalData, v1) && isJSString(globalData, v2))
+        if (isJSString(v1) && isJSString(v2))
             return !(asString(v2)->value(callFrame) < asString(v1)->value(callFrame));
 
         double n1;
index 05df32b..594b225 100644 (file)
@@ -248,11 +248,13 @@ void RegExp::finishCreation(JSGlobalData& globalData)
         m_numSubpatterns = pattern.m_numSubpatterns;
 }
 
-RegExp::~RegExp()
+void RegExp::destroy(JSCell* cell)
 {
+    RegExp* thisObject = jsCast<RegExp*>(cell);
 #if REGEXP_FUNC_TEST_DATA_GEN
     RegExpFunctionalTestCollector::get()->clearRegExp(this);
 #endif
+    thisObject->RegExp::~RegExp();
 }
 
 RegExp* RegExp::createWithoutCaching(JSGlobalData& globalData, const UString& patternString, RegExpFlags flags)
index aa3a61f..65eb484 100644 (file)
@@ -42,7 +42,7 @@ namespace JSC {
         typedef JSCell Base;
 
         static RegExp* create(JSGlobalData&, const UString& pattern, RegExpFlags);
-        ~RegExp();
+        static void destroy(JSCell*);
 
         bool global() const { return m_flags & FlagGlobal; }
         bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
index 03d2fd2..a287377 100644 (file)
@@ -115,6 +115,11 @@ void RegExpConstructor::finishCreation(ExecState* exec, RegExpPrototype* regExpP
     putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
 }
 
+void RegExpConstructor::destroy(JSCell* cell)
+{
+    jsCast<RegExpConstructor*>(cell)->RegExpConstructor::~RegExpConstructor();
+}
+
 RegExpMatchesArray::RegExpMatchesArray(ExecState* exec)
     : JSArray(exec->globalData(), exec->lexicalGlobalObject()->regExpMatchesArrayStructure())
 {
@@ -140,6 +145,11 @@ RegExpMatchesArray::~RegExpMatchesArray()
     delete static_cast<RegExpConstructorPrivate*>(subclassData());
 }
 
+void RegExpMatchesArray::destroy(JSCell* cell)
+{
+    jsCast<RegExpMatchesArray*>(cell)->RegExpMatchesArray::~RegExpMatchesArray();
+}
+
 void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
 {
     RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData());
index 5f930eb..7fb88d2 100644 (file)
@@ -98,6 +98,7 @@ namespace JSC {
 
     private:
         RegExpConstructor(JSGlobalObject*, Structure*);
+        static void destroy(JSCell*);
         static ConstructType getConstructData(JSCell*, ConstructData&);
         static CallType getCallData(JSCell*, CallData&);
 
index 1cc898e..1c117b0 100644 (file)
@@ -37,7 +37,8 @@ namespace JSC {
             regExp->finishCreation(exec->globalData(), ctorPrivate);
             return regExp;
         }
-        virtual ~RegExpMatchesArray();
+        ~RegExpMatchesArray();
+        static void destroy(JSCell*);
 
         static JS_EXPORTDATA const ClassInfo s_info;
         
index 7213dc2..4553f7a 100644 (file)
@@ -75,8 +75,9 @@ void RegExpObject::finishCreation(JSGlobalObject* globalObject)
     ASSERT(inherits(&s_info));
 }
 
-RegExpObject::~RegExpObject()
+void RegExpObject::destroy(JSCell* cell)
 {
+    jsCast<RegExpObject*>(cell)->RegExpObject::~RegExpObject();
 }
 
 void RegExpObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
index a117f36..ee98b66 100644 (file)
@@ -44,8 +44,6 @@ namespace JSC {
             return object;
         }
 
-        virtual ~RegExpObject();
-
         void setRegExp(JSGlobalData& globalData, RegExp* r) { d->regExp.set(globalData, this, r); }
         RegExp* regExp() const { return d->regExp.get(); }
 
@@ -79,6 +77,8 @@ namespace JSC {
     protected:
         RegExpObject(JSGlobalObject*, Structure*, RegExp*);
         void finishCreation(JSGlobalObject*);
+        static void destroy(JSCell*);
+
         static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | Base::StructureFlags;
 
         static void visitChildren(JSCell*, SlotVisitor&);
index 79f2a7a..099f7fd 100644 (file)
@@ -29,9 +29,7 @@
 
 namespace JSC {
 
-ScopeChainNode::~ScopeChainNode()
-{
-}
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(ScopeChainNode);
 
 #ifndef NDEBUG
 
index 48385d0..fde690e 100644 (file)
@@ -45,8 +45,6 @@ namespace JSC {
         {
         }
 
-        virtual ~ScopeChainNode();
-
     protected:
         void finishCreation(JSGlobalData* globalData, JSGlobalObject* globalObject)
         {
index 21283db..fbd9d5f 100644 (file)
@@ -28,6 +28,8 @@
 
 namespace JSC {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(StrictEvalActivation);
+
 const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictEvalActivation) };
 
 StrictEvalActivation::StrictEvalActivation(ExecState* exec)
index 96570b2..d2f75a0 100644 (file)
@@ -46,6 +46,7 @@ const ClassInfo StringConstructor::s_info = { "Function", &InternalFunction::s_i
 */
 
 ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringConstructor);
 
 StringConstructor::StringConstructor(JSGlobalObject* globalObject, Structure* structure)
     : InternalFunction(globalObject, structure)
index 3eed267..4a24698 100644 (file)
@@ -26,6 +26,7 @@
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(StringObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject);
 
 const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
 
@@ -34,10 +35,6 @@ StringObject::StringObject(JSGlobalData& globalData, Structure* structure)
 {
 }
 
-void StringObject::vtableAnchor()
-{
-}
-
 void StringObject::finishCreation(JSGlobalData& globalData, JSString* string)
 {
     Base::finishCreation(globalData);
index d65ecc5..806d07b 100644 (file)
@@ -30,8 +30,6 @@ namespace JSC {
     public:
         typedef JSWrapperObject Base;
 
-        virtual void vtableAnchor();
-
         static StringObject* create(ExecState* exec, Structure* structure)
         {
             JSString* string = jsEmptyString(exec);
index 3de8953..9bf18de 100644 (file)
@@ -45,6 +45,7 @@ using namespace WTF;
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringPrototype);
 
 static EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*);
 static EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*);
index 6b4ca2b..dda8c73 100644 (file)
@@ -218,8 +218,9 @@ Structure::Structure(JSGlobalData& globalData, const Structure* previous)
         m_globalObject.set(globalData, this, previous->m_globalObject.get());
 }
 
-Structure::~Structure()
+void Structure::destroy(JSCell* cell)
 {
+    jsCast<Structure*>(cell)->Structure::~Structure();
 }
 
 void Structure::materializePropertyMap(JSGlobalData& globalData)
index e372b20..92e1b3b 100644 (file)
@@ -103,7 +103,7 @@ namespace JSC {
 
         Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
 
-        ~Structure();
+        static void destroy(JSCell*);
 
         // These should be used with caution.  
         size_t addPropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
@@ -335,16 +335,18 @@ namespace JSC {
     inline void JSCell::setStructure(JSGlobalData& globalData, Structure* structure)
     {
         ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
+        ASSERT(structure->classInfo() == m_structure->classInfo());
         m_structure.set(globalData, this, structure);
     }
 
-    inline const ClassInfo* JSCell::classInfo() const
+    inline const ClassInfo* JSCell::validatedClassInfo() const
     {
 #if ENABLE(GC_VALIDATION)
-        return m_structure.unvalidatedGet()->classInfo();
+        ASSERT(m_structure.unvalidatedGet()->classInfo() == m_classInfo);
 #else
-        return m_structure->classInfo();
+        ASSERT(m_structure->classInfo() == m_classInfo);
 #endif
+        return m_classInfo;
     }
 
     ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
@@ -380,6 +382,25 @@ namespace JSC {
         return false;
     }
 
+    inline JSCell::JSCell(JSGlobalData& globalData, Structure* structure)
+        : m_classInfo(structure->classInfo())
+        , m_structure(globalData, this, structure)
+    {
+    }
+
+    inline void JSCell::finishCreation(JSGlobalData& globalData, Structure* structure, CreatingEarlyCellTag)
+    {
+#if ENABLE(GC_VALIDATION)
+        ASSERT(globalData.isInitializingObject());
+        globalData.setInitializingObject(false);
+        if (structure)
+#endif
+            m_structure.setEarlyValue(globalData, this, structure);
+        m_classInfo = structure->classInfo();
+        // Very first set of allocations won't have a real structure.
+        ASSERT(m_structure || !globalData.structureStructure);
+    }
+
 } // namespace JSC
 
 #endif // Structure_h
index 3a08569..afb2d95 100644 (file)
@@ -39,8 +39,9 @@ StructureChain::StructureChain(JSGlobalData& globalData, Structure* structure)
 {
 }
 
-StructureChain::~StructureChain()
+void StructureChain::destroy(JSCell* cell)
 {
+    jsCast<StructureChain*>(cell)->StructureChain::~StructureChain();
 }
 
 void StructureChain::visitChildren(JSCell* cell, SlotVisitor& visitor)
index 281f602..01a59bf 100644 (file)
@@ -75,7 +75,7 @@ namespace JSC {
 
     private:
         StructureChain(JSGlobalData&, Structure*);
-        ~StructureChain();
+        static void destroy(JSCell*);
         OwnArrayPtr<WriteBarrier<Structure> > m_vector;
     };
 
index d4f5d80..2b3d794 100644 (file)
@@ -383,4 +383,10 @@ while (0)
 #define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do { (void)object; (void)classInfo; } while (0)
 #endif
 
+#if COMPILER(CLANG)
+#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass) COMPILE_ASSERT(__has_trivial_destructor(klass), klass##_has_trivial_destructor_check)
+#else
+#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass)
+#endif
+
 #endif /* WTF_Assertions_h */
index 2857311..37c30b1 100644 (file)
@@ -1,3 +1,14 @@
+2011-12-16  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        De-virtualize destructors
+        https://bugs.webkit.org/show_bug.cgi?id=74331
+
+        Reviewed by Geoffrey Garen.
+
+        * UserObjectImp.cpp: Add static destroy function.
+        (UserObjectImp::destroy):
+        * UserObjectImp.h:
+
 2011-12-14  Hajime Morrita  <morrita@chromium.org>
 
         JS_INLINE and WTF_INLINE should be visible from WebCore
index 8ea5d29..6800fdf 100644 (file)
@@ -46,6 +46,11 @@ UserObjectImp::~UserObjectImp()
         fJSUserObject->Release();
 }
 
+void UserObjectImp::destroy(JSCell* cell)
+{
+    jsCast<UserObjectImp*>(cell)->UserObjectImp::~UserObjectImp();
+}
+
 CallType UserObjectImp::getCallData(JSCell* cell, CallData& callData)
 {
     UserObjectImp* thisObject = jsCast<UserObjectImp*>(cell);
index d648a95..49a653e 100644 (file)
@@ -45,7 +45,8 @@ public:
         return object;
     }
     
-    virtual ~UserObjectImp();
+    ~UserObjectImp();
+    static void destroy(JSCell*);
 
     static const ClassInfo s_info;
 
@@ -53,12 +54,12 @@ public:
 
     static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
-    virtual JSValue callAsFunction(ExecState *exec);
+    JSValue callAsFunction(ExecState*); // TODO: Figure out how to re-virtualize this without breaking the fact that we don't allow vptrs in the JSCell hierarchy.
     static bool getOwnPropertySlot(JSCell*, ExecState *, const Identifier&, PropertySlot&);
     static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
 
     JSValue toPrimitive(ExecState*, PreferredPrimitiveType preferredType = NoPreference) const;
-    virtual bool toBoolean(ExecState *exec) const;
+    bool toBoolean(ExecState*) const; // TODO: Figure out how to re-virtualize this without breaking the fact that we don't allow vptrs in the JSCell hierarchy.
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
index d26fa8d..431b579 100644 (file)
@@ -1,3 +1,86 @@
+2011-12-16  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        De-virtualize destructors
+        https://bugs.webkit.org/show_bug.cgi?id=74331
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests.
+
+        Doing everything here that was done to the JSCell hierarchy in JavaScriptCore. 
+        See the ChangeLog for this commit for a more in-depth description.
+
+        * WebCore.exp.in: Add/remove symbols.
+        * bindings/js/JSCanvasRenderingContext2DCustom.cpp: Remove first arg from isJSArray call.
+        (WebCore::JSCanvasRenderingContext2D::setWebkitLineDash):
+        * bindings/js/JSDOMBinding.cpp: Add trival destructor assert for DOMConstructorObject 
+        and DOMConstructorWithDocument.
+        * bindings/js/JSDOMGlobalObject.cpp: Add static destroy.  Add implementation for 
+        scriptExecutionContext that dispatches to different functions in subclasses 
+        depending on our current ClassInfo.  We do this so that we can get rid of the 
+        virtual-ness of scriptExecutionContext, because any virtual functions will throw 
+        off the layout of the object and we'll crash at runtime.
+        (WebCore::JSDOMGlobalObject::destroy):
+        (WebCore::JSDOMGlobalObject::scriptExecutionContext):
+        * bindings/js/JSDOMGlobalObject.h:
+        * bindings/js/JSDOMWindowBase.cpp: Add static destroy.
+        (WebCore::JSDOMWindowBase::destroy):
+        * bindings/js/JSDOMWindowBase.h: De-virtualize scriptExecutionContext.
+        * bindings/js/JSDOMWindowShell.cpp: Add static destroy.
+        (WebCore::JSDOMWindowShell::destroy):
+        * bindings/js/JSDOMWindowShell.h:
+        * bindings/js/JSDOMWrapper.cpp: Add trivial destructor assert.
+        * bindings/js/JSDOMWrapper.h: Add a ClassInfo to JSDOMWrapper since it now overrides 
+        a MethodTable function. Remove vtableAnchor virtual function.
+        * bindings/js/JSImageConstructor.cpp: Add trivial destructor assert.
+        * bindings/js/JSNodeCustom.cpp: Change implementation of pushEventHandlerScope so that 
+        it dispatches to the correct function depending on the 
+        identity of the class as specified by the ClassInfo.  
+        See JSDOMGlobalObject::scriptExecutionContext for explanation.
+        (WebCore::JSNode::pushEventHandlerScope):
+        * bindings/js/JSWebSocketCustom.cpp: Remove first arg to isJSArray call.
+        (WebCore::JSWebSocketConstructor::constructJSWebSocket):
+        * bindings/js/JSWorkerContextBase.cpp: Add static destroy.
+        (WebCore::JSWorkerContextBase::destroy):
+        * bindings/js/JSWorkerContextBase.h: 
+        * bindings/js/ScriptValue.cpp: Remove first arg to isJSArray call.
+        (WebCore::jsToInspectorValue): 
+        * bindings/js/SerializedScriptValue.cpp: Ditto.
+        (WebCore::CloneSerializer::isArray):
+        (WebCore::CloneSerializer::getSparseIndex):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader): Remove virtual-ness of any custom pushEventHandlerScope (see 
+        JSNodeCustom::pushEventHandlerScope for explanation).  Remove virtual toBoolean 
+        for anybody who masquerades as undefined, since our JSObject implementation handles 
+        this based on the TypeInfo in the Structure. Add trivial destructor assert for any 
+        class other than DOMWindow or WorkerContexts.
+        (GenerateImplementation): Change ClassInfo definitions to use Base::s_info, since 
+        typing the parent class more than once is duplication of information and increases 
+        the likelihood of mistakes.  Pass ClassInfo to TypeArrayDescriptors instead of vptr. 
+        (GenerateConstructorDefinition): Add trivial destructor assert for all generated constructors.
+        * bridge/c/CRuntimeObject.cpp: Remove empty virtual destructor.
+        * bridge/c/CRuntimeObject.h: 
+        * bridge/jni/jsc/JavaRuntimeObject.cpp: Ditto.
+        * bridge/jni/jsc/JavaRuntimeObject.h: 
+        * bridge/objc/ObjCRuntimeObject.h: Ditto.
+        * bridge/objc/ObjCRuntimeObject.mm:
+        * bridge/objc/objc_runtime.h: Add static destroy for ObjcFallbackObjectImp. De-virtualize 
+        toBoolean in the short term.  Need longer term fix.
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::ObjcFallbackObjectImp::destroy):
+        * bridge/qt/qt_runtime.cpp: Add static destroy to QtRuntimeMethod.
+        (JSC::Bindings::QtRuntimeMethod::destroy):
+        * bridge/qt/qt_runtime.h: De-virtualize ~QtRuntimeMethod.
+        * bridge/runtime_array.cpp: De-virtualize destructor. Add static destroy.
+        (JSC::RuntimeArray::destroy):
+        * bridge/runtime_array.h:
+        * bridge/runtime_method.cpp: Remove vtableAnchor. Add static destroy.
+        (JSC::RuntimeMethod::destroy):
+        * bridge/runtime_method.h:
+        * bridge/runtime_object.cpp: Add static destroy.
+        (JSC::Bindings::RuntimeObject::destroy):
+        * bridge/runtime_object.h:
+
 2011-12-15  Alexey Proskuryakov  <ap@apple.com>
 
         Poor XPath performance when evaluating an expression that returns a lot of nodes
index 1987f75..a83a51c 100644 (file)
@@ -263,7 +263,7 @@ __ZN7WebCore12IconDatabase27checkIntegrityBeforeOpeningEv
 __ZN7WebCore12IconDatabase5closeEv
 __ZN7WebCore12IconDatabase9setClientEPNS_18IconDatabaseClientE
 __ZN7WebCore12IconDatabaseC1Ev
-__ZN7WebCore12JSDOMWrapper34virtualFunctionToPreventWeakVtableEv
+__ZN7WebCore12JSDOMWrapper6s_infoE
 __ZN7WebCore12PopupMenuMacC1EPNS_15PopupMenuClientE
 __ZN7WebCore12PrintContext12pagePropertyEPNS_5FrameEPKci
 __ZN7WebCore12PrintContext13numberOfPagesEPNS_5FrameERKNS_9FloatSizeE
@@ -1275,6 +1275,7 @@ __ZNK7WebCore16VisibleSelection17toNormalizedRangeEv
 __ZNK7WebCore16VisibleSelection19rootEditableElementEv
 __ZNK7WebCore16VisibleSelection23isContentRichlyEditableEv
 __ZNK7WebCore16VisibleSelection5isAllENS_27EditingBoundaryCrossingRuleE
+__ZNK7WebCore17JSDOMGlobalObject22scriptExecutionContextEv
 __ZNK7WebCore17RegularExpression13matchedLengthEv
 __ZNK7WebCore17RegularExpression5matchERKN3WTF6StringEiPi
 __ZNK7WebCore17RegularExpression9searchRevERKN3WTF6StringE
@@ -1439,7 +1440,6 @@ __ZNK7WebCore9PageCache10frameCountEv
 __ZNK7WebCore9PageCache21autoreleasedPageCountEv
 __ZNK7WebCore9TreeScope14getElementByIdERKN3WTF12AtomicStringE
 __ZTVN7WebCore12ChromeClientE
-__ZTVN7WebCore12JSDOMWrapperE
 __ZTVN7WebCore16IconDatabaseBaseE
 __ZTVN7WebCore17FrameLoaderClientE
 __ZTVN7WebCore18PlatformStrategiesE
@@ -1722,11 +1722,11 @@ __ZN7WebCore5Frame26sendOrientationChangeEventEi
 
 #if USE(PLUGIN_HOST_PROCESS)
 __ZN3JSC13RuntimeMethod11getCallDataEPNS_6JSCellERNS_8CallDataE
-__ZN3JSC13RuntimeMethod12vtableAnchorEv
 __ZN3JSC13RuntimeMethod14finishCreationERNS_12JSGlobalDataERKNS_10IdentifierE
 __ZN3JSC13RuntimeMethod18getOwnPropertySlotEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC13RuntimeMethod24getOwnPropertyDescriptorEPNS_8JSObjectEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC13RuntimeMethod6s_infoE
+__ZN3JSC13RuntimeMethod7destroyEPNS_6JSCellE
 __ZN3JSC13RuntimeMethodC2EPNS_14JSGlobalObjectEPNS_9StructureERN3WTF6VectorIPNS_8Bindings6MethodELm0EEE
 __ZN3JSC8Bindings10RootObjectD1Ev
 __ZN3JSC8Bindings13RuntimeObject11getCallDataEPNS_6JSCellERNS_8CallDataE
@@ -1739,14 +1739,13 @@ __ZN3JSC8Bindings13RuntimeObject19getOwnPropertyNamesEPNS_8JSObjectEPNS_9ExecSta
 __ZN3JSC8Bindings13RuntimeObject24getOwnPropertyDescriptorEPNS_8JSObjectEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8Bindings13RuntimeObject3putEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC8Bindings13RuntimeObject6s_infoE
+__ZN3JSC8Bindings13RuntimeObject7destroyEPNS_6JSCellE
 __ZN3JSC8Bindings13RuntimeObjectC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEN3WTF10PassRefPtrINS0_8InstanceEEE
-__ZN3JSC8Bindings13RuntimeObjectD2Ev
 __ZN3JSC8Bindings8Instance19createRuntimeObjectEPNS_9ExecStateE
 __ZN3JSC8Bindings8InstanceC2EN3WTF10PassRefPtrINS0_10RootObjectEEE
 __ZN3JSC8Bindings8InstanceD2Ev
 __ZN7WebCore13IdentifierRep7isValidEPS0_
 __ZN7WebCore16ScriptController16createRootObjectEPv
-__ZTVN3JSC13RuntimeMethodE
 #endif
 
 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
index 178b130..1275029 100644 (file)
@@ -154,7 +154,7 @@ JSValue JSCanvasRenderingContext2D::webkitLineDash(ExecState* exec) const
 
 void JSCanvasRenderingContext2D::setWebkitLineDash(ExecState* exec, JSValue value)
 {
-    if (!isJSArray(&exec->globalData(), value))
+    if (!isJSArray(value))
         return;
 
     DashArray dash;
index 59bd9f2..2f49994 100644 (file)
@@ -38,6 +38,9 @@ using namespace JSC;
 
 namespace WebCore {
 
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(DOMConstructorObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(DOMConstructorWithDocument);
+
 const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable)
 {
     return DOMObjectHashTableMap::mapFor(globalData).get(staticTable);
index 8c574d9..31ffb54 100644 (file)
@@ -49,8 +49,9 @@ JSDOMGlobalObject::JSDOMGlobalObject(JSGlobalData& globalData, Structure* struct
 {
 }
 
-JSDOMGlobalObject::~JSDOMGlobalObject()
+void JSDOMGlobalObject::destroy(JSCell* cell)
 {
+    jsCast<JSDOMGlobalObject*>(cell)->JSDOMGlobalObject::~JSDOMGlobalObject();
 }
 
 void JSDOMGlobalObject::finishCreation(JSGlobalData& globalData)
@@ -65,6 +66,18 @@ void JSDOMGlobalObject::finishCreation(JSGlobalData& globalData, JSGlobalThis* t
     ASSERT(inherits(&s_info));
 }
 
+ScriptExecutionContext* JSDOMGlobalObject::scriptExecutionContext() const
+{
+    if (inherits(&JSDOMWindowBase::s_info))
+        return jsCast<const JSDOMWindowBase*>(this)->scriptExecutionContext();
+#if ENABLE(WORKERS)
+    if (inherits(&JSWorkerContextBase::s_info))
+        return jsCast<const JSWorkerContextBase*>(this)->scriptExecutionContext();
+#endif
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 void JSDOMGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSDOMGlobalObject* thisObject = jsCast<JSDOMGlobalObject*>(cell);
index 8755ffb..adcd388 100644 (file)
@@ -48,7 +48,7 @@ namespace WebCore {
         struct JSDOMGlobalObjectData;
 
         JSDOMGlobalObject(JSC::JSGlobalData&, JSC::Structure*, PassRefPtr<DOMWrapperWorld>, const JSC::GlobalObjectMethodTable* = 0);
-        virtual ~JSDOMGlobalObject();
+        static void destroy(JSC::JSCell*);
         void finishCreation(JSC::JSGlobalData&);
         void finishCreation(JSC::JSGlobalData&, JSC::JSGlobalThis*);
 
@@ -56,7 +56,7 @@ namespace WebCore {
         JSDOMStructureMap& structures() { return m_structures; }
         JSDOMConstructorMap& constructors() { return m_constructors; }
 
-        virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
+        ScriptExecutionContext* scriptExecutionContext() const;
 
         // Make binding code generation easier.
         JSDOMGlobalObject* globalObject() { return this; }
index e68bca1..8de432e 100644 (file)
@@ -65,6 +65,11 @@ void JSDOMWindowBase::finishCreation(JSGlobalData& globalData, JSDOMWindowShell*
     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
 }
 
+void JSDOMWindowBase::destroy(JSCell* cell)
+{
+    jsCast<JSDOMWindowBase*>(cell)->JSDOMWindowBase::~JSDOMWindowBase();
+}
+
 void JSDOMWindowBase::updateDocument()
 {
     ASSERT(m_impl->document());
index 91f3f7a..84c1862 100644 (file)
@@ -40,11 +40,13 @@ namespace WebCore {
         JSDOMWindowBase(JSC::JSGlobalData&, JSC::Structure*, PassRefPtr<DOMWindow>, JSDOMWindowShell*);
         void finishCreation(JSC::JSGlobalData&, JSDOMWindowShell*);
 
+        static void destroy(JSCell*);
+
     public:
         void updateDocument();
 
         DOMWindow* impl() const { return m_impl.get(); }
-        virtual ScriptExecutionContext* scriptExecutionContext() const;
+        ScriptExecutionContext* scriptExecutionContext() const;
 
         // Called just before removing this window from the JSDOMWindowShell.
         void willRemoveFromWindowShell();
index 25d384a..d96f840 100644 (file)
@@ -57,8 +57,9 @@ void JSDOMWindowShell::finishCreation(JSGlobalData& globalData, PassRefPtr<DOMWi
     setWindow(window);
 }
 
-JSDOMWindowShell::~JSDOMWindowShell()
+void JSDOMWindowShell::destroy(JSCell* cell)
 {
+    jsCast<JSDOMWindowShell*>(cell)->JSDOMWindowShell::~JSDOMWindowShell();
 }
 
 void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> domWindow)
index 43b96e2..d86766d 100644 (file)
@@ -41,7 +41,7 @@ namespace WebCore {
         typedef JSC::JSGlobalThis Base;
     public:
         JSDOMWindowShell(PassRefPtr<DOMWindow>, JSC::Structure*, DOMWrapperWorld*);
-        virtual ~JSDOMWindowShell();
+        static void destroy(JSCell*);
 
         JSDOMWindow* window() const { return static_cast<JSDOMWindow*>(m_unwrappedObject.get()); }
         void setWindow(JSC::JSGlobalData& globalData, JSDOMWindow* window)
index d54fe74..05da402 100644 (file)
@@ -32,9 +32,8 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSDOMWrapper::virtualFunctionToPreventWeakVtable()
-{
-    ASSERT_NOT_REACHED();
-}
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSDOMWrapper);
+
+const ClassInfo JSDOMWrapper::s_info = { "JSDOMWrapper", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSDOMWrapper) };
 
 } // namespace WebCore
index 3685c89..acd796a 100644 (file)
@@ -42,16 +42,14 @@ public:
         return globalObject()->scriptExecutionContext();
     }
 
+    static const JSC::ClassInfo s_info;
+
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
         return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
 protected:
-    // An inline function cannot be the first non-abstract virtual function declared
-    // in the class as it results in the vtable being generated as a weak symbol.
-    virtual void virtualFunctionToPreventWeakVtable();
-
     explicit JSDOMWrapper(JSC::Structure* structure, JSC::JSGlobalObject* globalObject) 
         : JSNonFinalObject(globalObject->globalData(), structure)
     {
index 4a396e4..956c961 100644 (file)
@@ -31,8 +31,9 @@ using namespace JSC;
 namespace WebCore {
 
 ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSImageConstructor);
 
-const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", &DOMConstructorWithDocument::s_info, 0, 0, CREATE_METHOD_TABLE(JSImageConstructor) };
+const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSImageConstructor) };
 
 JSImageConstructor::JSImageConstructor(Structure* structure, JSDOMGlobalObject* globalObject)
     : DOMConstructorWithDocument(structure, globalObject)
index 5af7e37..61c15d6 100644 (file)
@@ -188,8 +188,10 @@ JSValue JSNode::appendChild(ExecState* exec)
     return jsNull();
 }
 
-ScopeChainNode* JSNode::pushEventHandlerScope(ExecState*, ScopeChainNode* node) const
+ScopeChainNode* JSNode::pushEventHandlerScope(ExecState* exec, ScopeChainNode* node) const
 {
+    if (inherits(&JSHTMLElement::s_info))
+        return jsCast<const JSHTMLElement*>(this)->pushEventHandlerScope(exec, node);
     return node;
 }
 
index 49a828c..777e5b8 100644 (file)
@@ -69,7 +69,7 @@ EncodedJSValue JSC_HOST_CALL JSWebSocketConstructor::constructJSWebSocket(ExecSt
         webSocket->connect(urlString, ec);
     else {
         JSValue protocolsValue = exec->argument(1);
-        if (isJSArray(&exec->globalData(), protocolsValue)) {
+        if (isJSArray(protocolsValue)) {
             Vector<String> protocols;
             JSArray* protocolsArray = asArray(protocolsValue);
             for (unsigned i = 0; i < protocolsArray->length(); ++i) {
index 92b79f4..e79c6e4 100644 (file)
@@ -60,8 +60,9 @@ void JSWorkerContextBase::finishCreation(JSGlobalData& globalData)
     ASSERT(inherits(&s_info));
 }
 
-JSWorkerContextBase::~JSWorkerContextBase()
+void JSWorkerContextBase::destroy(JSCell* cell)
 {
+    jsCast<JSWorkerContextBase*>(cell)->JSWorkerContextBase::~JSWorkerContextBase();
 }
 
 ScriptExecutionContext* JSWorkerContextBase::scriptExecutionContext() const
index d8171c1..abcbeb6 100644 (file)
@@ -41,12 +41,12 @@ namespace WebCore {
     class JSWorkerContextBase : public JSDOMGlobalObject {
         typedef JSDOMGlobalObject Base;
     public:
-        virtual ~JSWorkerContextBase();
+        static void destroy(JSC::JSCell*);
 
         static const JSC::ClassInfo s_info;
 
         WorkerContext* impl() const { return m_impl.get(); }
-        virtual ScriptExecutionContext* scriptExecutionContext() const;
+        ScriptExecutionContext* scriptExecutionContext() const;
 
         static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
         {
index cb86b29..bfa93aa 100644 (file)
@@ -133,7 +133,7 @@ static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, J
         return InspectorString::create(String(s.characters(), s.length()));
     }
     if (value.isObject()) {
-        if (isJSArray(&scriptState->globalData(), value)) {
+        if (isJSArray(value)) {
             RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
             JSArray* array = asArray(value);
             unsigned length = array->length();
index b675ca3..a56a8dc 100644 (file)
@@ -310,7 +310,7 @@ private:
         if (!value.isObject())
             return false;
         JSObject* object = asObject(value);
-        return isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::s_info);
+        return isJSArray(object) || object->inherits(&JSArray::s_info);
     }
 
     bool startObjectInternal(JSObject* object)
@@ -357,7 +357,7 @@ private:
     JSValue getSparseIndex(JSArray* array, unsigned propertyName, bool& hasIndex)
     {
         PropertySlot slot(array);
-        if (isJSArray(&m_exec->globalData(), array)) {
+        if (isJSArray(array)) {
             if (JSArray::getOwnPropertySlotByIndex(array, m_exec, propertyName, slot)) {
                 hasIndex = true;
                 return slot.getValue(m_exec, propertyName);
index fc23e72..82241d4 100644 (file)
@@ -830,7 +830,7 @@ sub GenerateHeader
     push(@headerContent, "    }\n\n");
 
     # Custom pushEventHandlerScope function
-    push(@headerContent, "    virtual JSC::ScopeChainNode* pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChainNode*) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"};
+    push(@headerContent, "    JSC::ScopeChainNode* pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChainNode*) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"};
 
     # Custom call functions
     push(@headerContent, "    static JSC::CallType getCallData(JSC::JSCell*, JSC::CallData&);\n\n") if $dataNode->extendedAttributes->{"CustomCall"};
@@ -861,7 +861,6 @@ sub GenerateHeader
 
     # Override toBoolean to return false for objects that want to 'MasqueradesAsUndefined'.
     if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"}) {
-        push(@headerContent, "    virtual bool toBoolean(JSC::ExecState*) const { return false; };\n");
         $structureFlags{"JSC::MasqueradesAsUndefined"} = 1;
     }
 
@@ -1369,7 +1368,10 @@ sub GenerateImplementation
     push(@implContent, "\nusing namespace JSC;\n\n");
     push(@implContent, "namespace WebCore {\n\n");
 
-    push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className);\n\n");
+    push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className);\n");
+    if ($interfaceName ne "DOMWindow" && !$dataNode->extendedAttributes->{"IsWorkerContext"}) {
+        push(@implContent, "ASSERT_HAS_TRIVIAL_DESTRUCTOR($className);\n\n");
+    }
 
     my $numAttributes = GenerateAttributesHashTable($object, $dataNode);
 
@@ -1501,9 +1503,9 @@ sub GenerateImplementation
         push(@implContent, "{\n");
         push(@implContent, "    return getHashTableForGlobalData(exec->globalData(), &${className}PrototypeTable);\n");
         push(@implContent, "}\n\n");
-        push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", &JSC::JSNonFinalObject::s_info, 0, get${className}PrototypeTable, CREATE_METHOD_TABLE(${className}Prototype) };\n\n");
+        push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", &Base::s_info, 0, get${className}PrototypeTable, CREATE_METHOD_TABLE(${className}Prototype) };\n\n");
     } else {
-        push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", &JSC::JSNonFinalObject::s_info, &${className}PrototypeTable, 0, CREATE_METHOD_TABLE(${className}Prototype) };\n\n");
+        push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", &Base::s_info, &${className}PrototypeTable, 0, CREATE_METHOD_TABLE(${className}Prototype) };\n\n");
     }
     if ($interfaceName ne "DOMWindow" && !$dataNode->extendedAttributes->{"IsWorkerContext"}) {
         push(@implContent, "JSObject* ${className}Prototype::self(ExecState* exec, JSGlobalObject* globalObject)\n");
@@ -1511,6 +1513,7 @@ sub GenerateImplementation
         push(@implContent, "    return getDOMPrototype<${className}>(exec, globalObject);\n");
         push(@implContent, "}\n\n");
     }
+
     if ($numConstants > 0 || $numFunctions > 0 || $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) {
         push(@implContent, "bool ${className}Prototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
         push(@implContent, "{\n");
@@ -1571,7 +1574,7 @@ sub GenerateImplementation
         push(@implContent, "}\n\n");
     }
 
-    push(@implContent, "const ClassInfo $className" . "::s_info = { \"${visibleClassName}\", &" . $parentClassName . "::s_info, ");
+    push(@implContent, "const ClassInfo $className" . "::s_info = { \"${visibleClassName}\", &Base::s_info, ");
 
     if ($numAttributes > 0 && !$dataNode->extendedAttributes->{"NoStaticTables"}) {
         push(@implContent, "&${className}Table");
@@ -1621,7 +1624,7 @@ sub GenerateImplementation
         push(@implContent, "{\n");
         push(@implContent, "    Base::finishCreation(globalData);\n");
         if (IsTypedArrayType($implType) and ($implType ne "ArrayBufferView") and ($implType ne "ArrayBuffer")) {
-            push(@implContent, "    TypedArrayDescriptor descriptor(vptr(), OBJECT_OFFSETOF(${className}, m_storage), OBJECT_OFFSETOF(${className}, m_storageLength));\n");
+            push(@implContent, "    TypedArrayDescriptor descriptor(&${className}::s_info, OBJECT_OFFSETOF(${className}, m_storage), OBJECT_OFFSETOF(${className}, m_storageLength));\n");
             push(@implContent, "    globalData.registerTypedArrayDescriptor(impl(), descriptor);\n");
             push(@implContent, "    m_storage = impl()->data();\n");
             push(@implContent, "    m_storageLength = impl()->length();\n");
@@ -3388,13 +3391,15 @@ sub GenerateConstructorDefinition
     my $numberOfconstructParameters = $dataNode->extendedAttributes->{"ConstructorParameters"};
 
     if ($generatingNamedConstructor) {
-        push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &DOMConstructorObject::s_info, 0, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
+        push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &Base::s_info, 0, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
         push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
         push(@$outputArray, "    : DOMConstructorWithDocument(structure, globalObject)\n");
         push(@$outputArray, "{\n");
         push(@$outputArray, "}\n\n");
     } else {
-        push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &DOMConstructorObject::s_info, &${constructorClassName}Table, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
+        push(@$outputArray, "ASSERT_HAS_TRIVIAL_DESTRUCTOR(${constructorClassName});\n\n");
+
+        push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &Base::s_info, &${constructorClassName}Table, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n");
         push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
         push(@$outputArray, "    : DOMConstructorObject(structure, globalObject)\n");
         push(@$outputArray, "{\n");
index b27d32c..8277478 100644 (file)
@@ -36,6 +36,7 @@ using namespace JSC;
 namespace WebCore {
 
 ASSERT_CLASS_FITS_IN_CELL(JSFloat64Array);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFloat64Array);
 
 /* Hash table */
 
@@ -54,7 +55,9 @@ static const HashTableValue JSFloat64ArrayConstructorTableValues[] =
 };
 
 static const HashTable JSFloat64ArrayConstructorTable = { 1, 0, JSFloat64ArrayConstructorTableValues, 0 };
-const ClassInfo JSFloat64ArrayConstructor::s_info = { "Float64ArrayConstructor", &DOMConstructorObject::s_info, &JSFloat64ArrayConstructorTable, 0, CREATE_METHOD_TABLE(JSFloat64ArrayConstructor) };
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFloat64ArrayConstructor);
+
+const ClassInfo JSFloat64ArrayConstructor::s_info = { "Float64ArrayConstructor", &Base::s_info, &JSFloat64ArrayConstructorTable, 0, CREATE_METHOD_TABLE(JSFloat64ArrayConstructor) };
 
 JSFloat64ArrayConstructor::JSFloat64ArrayConstructor(Structure* structure, JSDOMGlobalObject* globalObject)
     : DOMConstructorObject(structure, globalObject)
@@ -98,7 +101,7 @@ static const HashTable* getJSFloat64ArrayPrototypeTable(ExecState* exec)
     return getHashTableForGlobalData(exec->globalData(), &JSFloat64ArrayPrototypeTable);
 }
 
-const ClassInfo JSFloat64ArrayPrototype::s_info = { "Float64ArrayPrototype", &JSC::JSNonFinalObject::s_info, 0, getJSFloat64ArrayPrototypeTable, CREATE_METHOD_TABLE(JSFloat64ArrayPrototype) };
+const ClassInfo JSFloat64ArrayPrototype::s_info = { "Float64ArrayPrototype", &Base::s_info, 0, getJSFloat64ArrayPrototypeTable, CREATE_METHOD_TABLE(JSFloat64ArrayPrototype) };
 
 JSObject* JSFloat64ArrayPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
 {
@@ -122,7 +125,7 @@ static const HashTable* getJSFloat64ArrayTable(ExecState* exec)
     return getHashTableForGlobalData(exec->globalData(), &JSFloat64ArrayTable);
 }
 
-const ClassInfo JSFloat64Array::s_info = { "Float64Array", &JSArrayBufferView::s_info, 0, getJSFloat64ArrayTable , CREATE_METHOD_TABLE(JSFloat64Array) };
+const ClassInfo JSFloat64Array::s_info = { "Float64Array", &Base::s_info, 0, getJSFloat64ArrayTable , CREATE_METHOD_TABLE(JSFloat64Array) };
 
 JSFloat64Array::JSFloat64Array(Structure* structure, JSDOMGlobalObject* globalObject, PassRefPtr<Float64Array> impl)
     : JSArrayBufferView(structure, globalObject, impl)
@@ -132,7 +135,7 @@ JSFloat64Array::JSFloat64Array(Structure* structure, JSDOMGlobalObject* globalOb
 void JSFloat64Array::finishCreation(JSGlobalData& globalData)
 {
     Base::finishCreation(globalData);
-    TypedArrayDescriptor descriptor(vptr(), OBJECT_OFFSETOF(JSFloat64Array, m_storage), OBJECT_OFFSETOF(JSFloat64Array, m_storageLength));
+    TypedArrayDescriptor descriptor(&JSFloat64Array::s_info, OBJECT_OFFSETOF(JSFloat64Array, m_storage), OBJECT_OFFSETOF(JSFloat64Array, m_storageLength));
     globalData.registerTypedArrayDescriptor(impl(), descriptor);
     m_storage = impl()->data();
     m_storageLength = impl()->length();
index 4400e5e..f80b649 100644 (file)
@@ -33,6 +33,7 @@ using namespace JSC;
 namespace WebCore {
 
 ASSERT_CLASS_FITS_IN_CELL(JSTestEventConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSTestEventConstructor);
 
 /* Hash table for constructor */
 
@@ -53,7 +54,9 @@ static const HashTableValue JSTestEventConstructorConstructorTableValues[] =
 };
 
 static const HashTable JSTestEventConstructorConstructorTable = { 1, 0, JSTestEventConstructorConstructorTableValues, 0 };
-const ClassInfo JSTestEventConstructorConstructor::s_info = { "TestEventConstructorConstructor", &DOMConstructorObject::s_info, &JSTestEventConstructorConstructorTable, 0, CREATE_METHOD_TABLE(JSTestEventConstructorConstructor) };
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSTestEventConstructorConstructor);
+
+const ClassInfo JSTestEventConstructorConstructor::s_info = { "TestEventConstructorConstructor", &Base::s_info, &JSTestEventConstructorConstructorTable, 0, CREATE_METHOD_TABLE(JSTestEventConstructorConstructor) };
 
 JSTestEventConstructorConstructor::JSTestEventConstructorConstructor(Structure* structure, JSDOMGlobalObject* globalObject)
     : DOMConstructorObject(structure, globalObject)
@@ -127,14 +130,14 @@ static const HashTableValue JSTestEventConstructorPrototypeTableValues[] =
 };
 
 static const HashTable JSTestEventConstructorPrototypeTable = { 1, 0, JSTestEventConstructorPrototypeTableValues, 0 };
-const ClassInfo JSTestEventConstructorPrototype::s_info = { "TestEventConstructorPrototype", &JSC::JSNonFinalObject::s_info, &JSTestEventConstructorPrototypeTable, 0, CREATE_METHOD_TABLE(JSTestEventConstructorPrototype) };
+const ClassInfo JSTestEventConstructorPrototype::s_info = { "TestEventConstructorPrototype", &Base::s_info, &JSTestEventConstructorPrototypeTable, 0, CREATE_METHOD_TABLE(JSTestEventConstructorPrototype) };
 
 JSObject* JSTestEventConstructorPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
 {
     return getDOMPrototype<JSTestEventConstructor>(exec, globalObject);
 }
 
-const ClassInfo JSTestEventConstructor::s_info = { "TestEventConstructor", &JSDOMWrapper::s_info, &JSTestEventConstructorTable, 0 , CREATE_METHOD_TABLE(JSTestEventConstructor) };
+const ClassInfo JSTestEventConstructor::s_info = { "TestEventConstructor", &Base::s_info, &JSTestEventConstructorTable, 0 , CREATE_METHOD_TABLE(JSTestEventConstructor) };
 
 JSTestEventConstructor::JSTestEventConstructor(Structure* structure, JSDOMGlobalObject* globalObject, PassRefPtr<TestEventConstructor> impl)
     : JSDOMWrapper(structure, globalObject)
index 0aaa56a..ba22b9f 100644 (file)
@@ -42,6 +42,7 @@ using namespace JSC;
 namespace WebCore {
 
 ASSERT_CLASS_FITS_IN_CELL(JSTestInterface);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSTestInterface);
 
 /* Hash table */
 
@@ -69,7 +70,9 @@ static const HashTableValue JSTestInterfaceConstructorTableValues[] =
 };
 
 static const HashTable JSTestInterfaceConstructorTable = { 1, 0, JSTestInterfaceConstructorTableValues, 0 };
-const ClassInfo JSTestInterfaceConstructor::s_info = { "TestInterfaceConstructor", &DOMConstructorObject::s_info, &JSTestInterfaceConstructorTable, 0, CREATE_METHOD_TABLE(JSTestInterfaceConstructor) };
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSTestInterfaceConstructor);
+
+const ClassInfo JSTestInterfaceConstructor::s_info = { "TestInterfaceConstructor", &Base::s_info, &JSTestInterfaceConstructorTable, 0, CREATE_METHOD_TABLE(JSTestInterfaceConstructor) };
 
 JSTestInterfaceConstructor::JSTestInterfaceConstructor(Structure* structure, JSDOMGlobalObject* globalObject)
     : DOMConstructorObject(structure, globalObject)
@@ -130,14 +133,14 @@ static const HashTableValue JSTestInterfacePrototypeTableValues[] =
 };
 
 static const HashTable JSTestInterfacePrototypeTable = { 1, 0, JSTestInterfacePrototypeTableValues, 0 };
-const ClassInfo JSTestInterfacePrototype::s_info = { "TestInterfacePrototype", &JSC::JSNonFinalObject::s_info, &JSTestInterfacePrototypeTable, 0, CREATE_METHOD_TABLE(JSTestInterfacePrototype) };
+const ClassInfo JSTestInterfacePrototype::s_info = { "TestInterfacePrototype", &Base::s_info, &JSTestInterfacePrototypeTable, 0, CREATE_METHOD_TABLE(JSTestInterfacePrototype) };
 
 JSObject* JSTestInterfacePrototype::self(ExecState* exec, JSGlobalObject* globalObject)
 {
     return getDOMPrototype<JSTestInterface>(exec, globalObject);
 }
 
-const ClassInfo JSTestInterface::s_info = { "TestInterface", &JSDOMWrapper::s_info, &JSTestInterfaceTable, 0 , CREATE_METHOD_TABLE(JSTestInterface) };
+const ClassInfo JSTestInterface::s_info = { "TestInterface", &Base::s_info, &JSTestInterfaceTable, 0 , CREATE_METHOD_TABLE(JSTestInterface) };
 
 JSTestInterface::JSTestInterface(Structure* structure, JSDOMGlobalObject* globalObject, PassRefPtr<TestInterface> impl)
     : JSDOMWrapper(structure, globalObject)
index 6995371..1c34bdb 100644 (file)
@@ -33,6 +33,7 @@ using namespace JSC;
 namespace WebCore {
 
 ASSERT_CLASS_FITS_IN_CELL(JSTestMediaQueryListListener);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSTestMediaQueryListListener);
 
 /* Hash table */