Changeset 47641 in webkit for trunk/JavaScriptCore/jit


Ignore:
Timestamp:
Aug 21, 2009, 2:54:20 PM (16 years ago)
Author:
[email protected]
Message:

Restructure Executable types so that host functions do not hold a FunctionExecutable.
https://bugs.webkit.org/show_bug.cgi?id=28621

Reviewed by Oliver Hunt.

All JSFunction objects have a pointer to an Executable*. This is currently always a
FunctionExecutable, however this has a couple of drawbacks. Host functions do not
store a range of information that the FunctionExecutable provides (source, name,
CodeBlock & information presently held on the FunctionBodyNode).

[ * nearly all... see below! ]

Instead, make JSFunctions hold a pointer to an ExecutableBase, move fields specific
to JS sourced executable types (source, node) into a new subclass (ScriptExecutable),
and create a new NativeExecutable type. We now provide a new method in JSFunction
to access & downcast to FunctionExecutable, but in doing so we can make an early
check (with an ASSERT) to ensure that the Executable read from a function will only
be treated as a FunctionExecutable (and thus the JS sepcific fields will only be
accessed) if the JSFunction is not a host function.

There is one JSFunction that currently does not have an Executable, which is the
object created to allow us to read out the vtable pointer. By making this change
we can also add a new Executable type fror this object (VPtrHackExecutable).
Since this means that really all JSFunctions have an Executable we no longer have
to null-check m_executable before us it - particularly in isHostFunction().

This patch removes CacheableEvalExecutable, since all subclasses of ExecutableBase
can now be ref-counted - since both JSFunction holds (and ref-counts) an ExecutableBase
that might be a FunctionExecutable or a NativeExecutable. This does now mean that all
ProgramExecutables and EvalExecutables (unnecessarily) provide an interface to be
ref-counted, however this seems less-bad than host functions unnecessarily providing
interface to access non-host specific information.

The class hierarcy has changed from this:

  • ExecutableBase
    • ProgramExecutable
    • EvalExecutable
      • CacheableEvalExecutable (also RefCounted by multiple-inheritance)
    • FunctionExecutable (also RefCounted by multiple-inheritance, 'special' FunctionExecutable also used for host functions)

To this:

  • RefCounted
    • ExecutableBase
      • NativeExecutable
      • VPtrHackExecutable
      • ScriptExecutable
        • ProgramExecutable
        • EvalExecutable
        • FunctionExecutable

This patch speeds up sunspidey by a couple of ms (presumably due to the changes to isHostFunction()).

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::ownerExecutable):
(JSC::GlobalCodeBlock::GlobalCodeBlock):

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::get):

  • debugger/Debugger.cpp:

(JSC::Debugger::recompileAllJSFunctions):

  • interpreter/CachedCall.h:

(JSC::CachedCall::CachedCall):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::callEval):
(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • profiler/Profiler.cpp:

(JSC::createCallIdentifierFromFunctionImp):

  • runtime/Arguments.h:

(JSC::Arguments::getArgumentsData):
(JSC::Arguments::Arguments):

  • runtime/Executable.cpp:

(JSC::NativeExecutable::~NativeExecutable):
(JSC::VPtrHackExecutable::~VPtrHackExecutable):

  • runtime/Executable.h:

(JSC::ExecutableBase::ExecutableBase):
(JSC::ExecutableBase::~ExecutableBase):
(JSC::ExecutableBase::isHostFunction):
(JSC::NativeExecutable::NativeExecutable):
(JSC::VPtrHackExecutable::VPtrHackExecutable):
(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ScriptExecutable::source):
(JSC::ScriptExecutable::sourceID):
(JSC::ScriptExecutable::sourceURL):
(JSC::ScriptExecutable::lineNo):
(JSC::ScriptExecutable::lastLine):
(JSC::ScriptExecutable::usesEval):
(JSC::ScriptExecutable::usesArguments):
(JSC::ScriptExecutable::needsActivation):
(JSC::EvalExecutable::EvalExecutable):
(JSC::EvalExecutable::create):
(JSC::ProgramExecutable::ProgramExecutable):
(JSC::FunctionExecutable::FunctionExecutable):

  • runtime/FunctionPrototype.cpp:

(JSC::functionProtoFuncToString):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::JSFunction):
(JSC::JSFunction::~JSFunction):
(JSC::JSFunction::markChildren):
(JSC::JSFunction::getCallData):
(JSC::JSFunction::call):
(JSC::JSFunction::lengthGetter):
(JSC::JSFunction::getConstructData):
(JSC::JSFunction::construct):

  • runtime/JSFunction.h:

(JSC::JSFunction::executable):
(JSC::JSFunction::jsExecutable):
(JSC::JSFunction::isHostFunction):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r47597 r47641  
    14811481
    14821482    JSFunction* function = asFunction(stackFrame.args[0].jsValue());
    1483     FunctionExecutable* executable = function->executable();
    1484     ASSERT(!executable->isHostFunction());
     1483    ASSERT(!function->isHostFunction());
     1484    FunctionExecutable* executable = function->jsExecutable();
    14851485    ScopeChainNode* callDataScopeChain = function->scope().node();
    14861486    executable->jitCode(callDataScopeChain);
     
    14951495    CallFrame* callFrame = stackFrame.callFrame;
    14961496    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
    1497     CodeBlock* newCodeBlock = &callee->executable()->generatedBytecode();
     1497    ASSERT(!callee->isHostFunction());
     1498    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecode();
    14981499    int argCount = stackFrame.args[2].int32();
    14991500
     
    15401541    STUB_INIT_STACK_FRAME(stackFrame);
    15411542    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
    1542     FunctionExecutable* executable = callee->executable();
     1543    ExecutableBase* executable = callee->executable();
    15431544    JITCode& jitCode = executable->generatedJITCode();
    15441545   
    15451546    CodeBlock* codeBlock = 0;
    15461547    if (!executable->isHostFunction())
    1547         codeBlock = &executable->bytecode(callee->scope().node());
     1548        codeBlock = &static_cast<FunctionExecutable*>(executable)->bytecode(callee->scope().node());
    15481549    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
    15491550
     
    17151716
    17161717    JSFunction* constructor = asFunction(stackFrame.args[0].jsValue());
    1717     FunctionExecutable* executable = constructor->executable();
    1718     if (executable && executable->isHostFunction()) {
     1718    if (constructor->isHostFunction()) {
    17191719        CallFrame* callFrame = stackFrame.callFrame;
    17201720        CodeBlock* codeBlock = callFrame->codeBlock();
     
    20432043            VM_THROW_EXCEPTION();
    20442044        }
    2045         int32_t expectedParams = callFrame->callee()->executable()->parameterCount();
     2045        int32_t expectedParams = callFrame->callee()->jsExecutable()->parameterCount();
    20462046        int32_t inplaceArgs = min(providedParams, expectedParams);
    20472047       
Note: See TracChangeset for help on using the changeset viewer.