Ignore:
Timestamp:
Aug 17, 2009, 10:34:52 PM (16 years ago)
Author:
[email protected]
Message:

No, silly runtime, AST nodes are not for you.

Reviewed by Sam Weinig.

We still use AST nodes (ScopeNodes, particularly FunctionBodyNodes) within
the runtime, which means that these nodes must be persisted outside of the
arena, contain both parser & runtime data, etc. This is all a bit of a mess.

Move functionality into a new FunctionExecutable class.

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::markAggregate):
(JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
(JSC::CodeBlock::lineNumberForBytecodeOffset):
(JSC::CodeBlock::shrinkToFit):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::getBytecodeIndex):
(JSC::CodeBlock::discardBytecode):
(JSC::CodeBlock::instructionCount):
(JSC::CodeBlock::getJITCode):
(JSC::CodeBlock::executablePool):
(JSC::CodeBlock::ownerExecutable):
(JSC::CodeBlock::extractExceptionInfo):
(JSC::CodeBlock::addFunctionDecl):
(JSC::CodeBlock::functionDecl):
(JSC::CodeBlock::numberOfFunctionDecls):
(JSC::CodeBlock::addFunctionExpr):
(JSC::CodeBlock::functionExpr):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::ProgramCodeBlock::ProgramCodeBlock):
(JSC::EvalCodeBlock::EvalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
(JSC::NativeCodeBlock::NativeCodeBlock):

  • bytecode/EvalCodeCache.h:
  • bytecode/SamplingTool.cpp:

(JSC::SamplingTool::doRun):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunction):
(JSC::BytecodeGenerator::emitNewFunctionExpression):

  • bytecompiler/BytecodeGenerator.h:
  • debugger/Debugger.cpp:

(JSC::Debugger::recompileAllJSFunctions):

  • interpreter/CachedCall.h:

(JSC::CachedCall::CachedCall):

  • interpreter/CallFrameClosure.h:
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::throwException):
(JSC::Interpreter::execute):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::debug):
(JSC::Interpreter::privateExecute):
(JSC::Interpreter::retrieveLastCaller):

  • interpreter/Interpreter.h:
  • jit/JIT.cpp:

(JSC::JIT::privateCompile):

  • jit/JIT.h:

(JSC::JIT::compile):

  • jit/JITOpcodes.cpp:

(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::emit_op_new_func):
(JSC::JIT::emit_op_new_func_exp):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jit/JITStubs.h:

(JSC::):

  • parser/Nodes.cpp:

(JSC::FunctionBodyNode::reparseDataIfNecessary):

  • parser/Nodes.h:

(JSC::EvalNode::partialDestroyData):

  • parser/Parser.h:
  • profiler/ProfileGenerator.cpp:
  • profiler/Profiler.cpp:

(JSC::Profiler::createCallIdentifier):
(JSC::createCallIdentifierFromFunctionImp):

  • runtime/Arguments.h:

(JSC::Arguments::getArgumentsData):
(JSC::Arguments::Arguments):
(JSC::JSActivation::copyRegisters):

  • runtime/ArrayPrototype.cpp:

(JSC::isNumericCompareFunction):

  • runtime/CallData.h:

(JSC::):

  • runtime/Collector.cpp:

(JSC::Heap::collect):

  • runtime/ConstructData.h:

(JSC::):

  • runtime/ExceptionHelpers.cpp:

(JSC::createUndefinedVariableError):
(JSC::createInvalidParamError):
(JSC::createNotAConstructorError):
(JSC::createNotAFunctionError):
(JSC::createNotAnObjectError):

  • runtime/Executable.cpp: Added.

(JSC::EvalExecutable::generateBytecode):
(JSC::ProgramExecutable::generateBytecode):
(JSC::FunctionExecutable::generateBytecode):
(JSC::EvalExecutable::generateJITCode):
(JSC::ProgramExecutable::generateJITCode):
(JSC::FunctionExecutable::generateJITCode):
(JSC::FunctionExecutable::isHostFunction):
(JSC::FunctionExecutable::markAggregate):
(JSC::FunctionExecutable::reparseExceptionInfo):
(JSC::EvalExecutable::reparseExceptionInfo):
(JSC::FunctionExecutable::recompile):
(JSC::FunctionExecutable::FunctionExecutable):

  • runtime/Executable.h:

(JSC::ExecutableBase::~ExecutableBase):
(JSC::ExecutableBase::ExecutableBase):
(JSC::ExecutableBase::source):
(JSC::ExecutableBase::sourceID):
(JSC::ExecutableBase::lastLine):
(JSC::ExecutableBase::usesEval):
(JSC::ExecutableBase::usesArguments):
(JSC::ExecutableBase::needsActivation):
(JSC::ExecutableBase::astNode):
(JSC::ExecutableBase::generatedJITCode):
(JSC::ExecutableBase::getExecutablePool):
(JSC::EvalExecutable::EvalExecutable):
(JSC::EvalExecutable::bytecode):
(JSC::EvalExecutable::varStack):
(JSC::EvalExecutable::evalNode):
(JSC::EvalExecutable::jitCode):
(JSC::ProgramExecutable::ProgramExecutable):
(JSC::ProgramExecutable::reparseExceptionInfo):
(JSC::ProgramExecutable::bytecode):
(JSC::ProgramExecutable::programNode):
(JSC::ProgramExecutable::jitCode):
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::name):
(JSC::FunctionExecutable::bytecode):
(JSC::FunctionExecutable::generatedBytecode):
(JSC::FunctionExecutable::usesEval):
(JSC::FunctionExecutable::usesArguments):
(JSC::FunctionExecutable::parameterCount):
(JSC::FunctionExecutable::paramString):
(JSC::FunctionExecutable::isGenerated):
(JSC::FunctionExecutable::body):
(JSC::FunctionExecutable::jitCode):
(JSC::FunctionExecutable::createNativeThunk):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):

  • runtime/FunctionPrototype.cpp:

(JSC::functionProtoFuncToString):

  • runtime/JSActivation.cpp:

(JSC::JSActivation::JSActivation):
(JSC::JSActivation::markChildren):
(JSC::JSActivation::isDynamicScope):
(JSC::JSActivation::argumentsGetter):

  • runtime/JSActivation.h:

(JSC::JSActivation::JSActivationData::JSActivationData):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::isHostFunction):
(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::FunctionExecutable::make):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::numericCompareFunction):

  • runtime/JSGlobalData.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Executable.h

    r47405 r47412  
    3131namespace JSC {
    3232
    33     template<class ASTNodeType, class CodeBlockType>
    34     class TemplateExecutable {
    35     public:
    36         TemplateExecutable(const SourceCode& source)
     33    class CodeBlock;
     34    class EvalCodeBlock;
     35    class ProgramCodeBlock;
     36    class ScopeChainNode;
     37
     38    struct ExceptionInfo;
     39
     40    class ExecutableBase {
     41        friend class JIT;
     42    public:
     43        virtual ~ExecutableBase() {}
     44
     45        ExecutableBase(const SourceCode& source)
    3746            : m_source(source)
    3847        {
    3948        }
    4049
    41         void markAggregate(MarkStack& markStack)
    42         {
    43             m_node->markAggregate(markStack);
    44         }
    45 
     50        const SourceCode& source() { return m_source; }
     51        intptr_t sourceID() const { return m_node->sourceID(); }
    4652        const UString& sourceURL() const { return m_node->sourceURL(); }
    4753        int lineNo() const { return m_node->lineNo(); }
    48         CodeBlockType& bytecode(ScopeChainNode* scopeChainNode) { return m_node->bytecode(scopeChainNode); }
    49 
    50 #if ENABLE(JIT)
    51         JITCode& jitCode(ScopeChainNode* scopeChainNode) { return m_node->jitCode(scopeChainNode); }
    52 #endif
     54        int lastLine() const { return m_node->lastLine(); }
     55
     56        bool usesEval() const { return m_node->usesEval(); }
     57        bool usesArguments() const { return m_node->usesArguments(); }
     58        bool needsActivation() const { return m_node->needsActivation(); }
     59
     60        virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
     61
     62        ScopeNode* astNode() { return m_node.get(); }
    5363
    5464    protected:
    55         RefPtr<ASTNodeType> m_node;
     65        RefPtr<ScopeNode> m_node;
    5666        SourceCode m_source;
    57     };
    58 
    59     class EvalExecutable : public TemplateExecutable<EvalNode, EvalCodeBlock> {
     67
     68    private:
     69        // For use making native thunk.
     70        friend class FunctionExecutable;
     71        ExecutableBase()
     72        {
     73        }
     74
     75#if ENABLE(JIT)
     76    public:
     77        JITCode& generatedJITCode()
     78        {
     79            ASSERT(m_jitCode);
     80            return m_jitCode;
     81        }
     82
     83        ExecutablePool* getExecutablePool()
     84        {
     85            return m_jitCode.getExecutablePool();
     86        }
     87
     88    protected:
     89        JITCode m_jitCode;
     90#endif
     91    };
     92
     93    class EvalExecutable : public ExecutableBase {
    6094    public:
    6195        EvalExecutable(const SourceCode& source)
    62             : TemplateExecutable<EvalNode, EvalCodeBlock>(source)
    63         {
    64         }
     96            : ExecutableBase(source)
     97            , m_evalCodeBlock(0)
     98        {
     99        }
     100
     101        ~EvalExecutable();
    65102
    66103        JSObject* parse(ExecState* exec, bool allowDebug = true);
     104
     105        EvalCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     106        {
     107            if (!m_evalCodeBlock)
     108                generateBytecode(scopeChainNode);
     109            return *m_evalCodeBlock;
     110        }
     111
     112        DeclarationStacks::VarStack& varStack() { return m_node->varStack(); }
     113
     114        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
     115
     116    private:
     117        EvalNode* evalNode() { return static_cast<EvalNode*>(m_node.get()); }
     118
     119        void generateBytecode(ScopeChainNode*);
     120
     121        EvalCodeBlock* m_evalCodeBlock;
     122
     123#if ENABLE(JIT)
     124    public:
     125        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     126        {
     127            if (!m_jitCode)
     128                generateJITCode(scopeChainNode);
     129            return m_jitCode;
     130        }
     131
     132    private:
     133        void generateJITCode(ScopeChainNode*);
     134#endif
    67135    };
    68136
     
    78146    };
    79147
    80     class ProgramExecutable : public TemplateExecutable<ProgramNode, ProgramCodeBlock> {
     148    class ProgramExecutable : public ExecutableBase {
    81149    public:
    82150        ProgramExecutable(const SourceCode& source)
    83             : TemplateExecutable<ProgramNode, ProgramCodeBlock>(source)
    84         {
    85         }
     151            : ExecutableBase(source)
     152            , m_programCodeBlock(0)
     153        {
     154        }
     155       
     156        ~ProgramExecutable();
    86157
    87158        JSObject* parse(ExecState* exec, bool allowDebug = true);
     159
     160        // CodeBlocks for program code are transient and therefore to not gain from from throwing out there exception information.
     161        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
     162
     163        ProgramCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     164        {
     165            if (!m_programCodeBlock)
     166                generateBytecode(scopeChainNode);
     167            return *m_programCodeBlock;
     168        }
     169
     170    private:
     171        ProgramNode* programNode() { return static_cast<ProgramNode*>(m_node.get()); }
     172
     173        void generateBytecode(ScopeChainNode*);
     174
     175        ProgramCodeBlock* m_programCodeBlock;
     176
     177#if ENABLE(JIT)
     178    public:
     179        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     180        {
     181            if (!m_jitCode)
     182                generateJITCode(scopeChainNode);
     183            return m_jitCode;
     184        }
     185
     186    private:
     187        void generateJITCode(ScopeChainNode*);
     188#endif
     189    };
     190
     191    class FunctionExecutable : public ExecutableBase, public RefCounted<FunctionExecutable> {
     192        friend class JIT;
     193    public:
     194        FunctionExecutable(const Identifier& name, FunctionBodyNode* body)
     195            : ExecutableBase(body->source())
     196            , m_codeBlock(0)
     197            , m_name(name)
     198        {
     199            m_node = body;
     200        }
     201
     202        ~FunctionExecutable();
     203
     204        const Identifier& name() { return m_name; }
     205
     206        JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain);
     207
     208        CodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     209        {
     210            ASSERT(scopeChainNode);
     211            if (!m_codeBlock)
     212                generateBytecode(scopeChainNode);
     213            return *m_codeBlock;
     214        }
     215        CodeBlock& generatedBytecode()
     216        {
     217            ASSERT(m_codeBlock);
     218            return *m_codeBlock;
     219        }
     220
     221        bool usesEval() const { return body()->usesEval(); }
     222        bool usesArguments() const { return body()->usesArguments(); }
     223        size_t parameterCount() const { return body()->parameterCount(); }
     224        UString paramString() const { return body()->paramString(); }
     225
     226        bool isHostFunction() const;
     227        bool isGenerated() const
     228        {
     229            return m_codeBlock;
     230        }
     231
     232        void recompile(ExecState* exec);
     233
     234        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
     235
     236        void markAggregate(MarkStack& markStack);
     237
     238    private:
     239        FunctionBodyNode* body() const { return static_cast<FunctionBodyNode*>(m_node.get()); }
     240
     241        void generateBytecode(ScopeChainNode*);
     242
     243        CodeBlock* m_codeBlock;
     244        const Identifier& m_name;
     245
     246#if ENABLE(JIT)
     247    public:
     248        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     249        {
     250            if (!m_jitCode)
     251                generateJITCode(scopeChainNode);
     252            return m_jitCode;
     253        }
     254
     255        static PassRefPtr<FunctionExecutable> createNativeThunk(ExecState* exec)
     256        {
     257            return adoptRef(new FunctionExecutable(exec));
     258        }
     259
     260    private:
     261        FunctionExecutable(ExecState* exec);
     262        void generateJITCode(ScopeChainNode*);
     263#endif
    88264    };
    89265
Note: See TracChangeset for help on using the changeset viewer.