Ignore:
Timestamp:
Nov 16, 2010, 7:03:34 PM (15 years ago)
Author:
[email protected]
Message:

Bug 49635 - Profiler implementation is fragile

Reviewed by Sam Weinig.

The profile presently requires the exception handling mechanism to explicitly
remove all stack frames that are exited during the exception unwind mechanism.
This is fragile in a number of ways:

  • We have to change bytecode register allocation when compiling code to run when profiling, to preserve the callee function (this is also required to call did_call after the call has returned).
  • In the JIT we have to maintain additional data structures (CodeBlock::RareData::m_functionRegisterInfos) to map back to the register containing the callee.
  • In the interpreter we use 'magic values' to offset into the instruction stream to rediscover the register containing the function.

Instead, move profiling into the head and tail of functions.

  • This correctly accounts the cost of the call itself to the caller.
  • This allows us to access the callee function object from the callframe.
  • This means that at the point a call is made we can track the stack depth on the ProfileNode.
  • When unwinding we can simply report the depth at which the exception is being handled - all call frames above this level are freed.

(JSC::CodeBlock::dump):
(JSC::CodeBlock::shrinkToFit):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::bytecodeOffset):
(JSC::CodeBlock::methodCallLinkInfo):

  • bytecode/Opcode.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitCallVarargs):
(JSC::BytecodeGenerator::emitReturn):
(JSC::BytecodeGenerator::emitConstruct):

  • bytecompiler/BytecodeGenerator.h:

(JSC::CallArguments::count):

  • bytecompiler/NodesCodegen.cpp:

(JSC::CallArguments::CallArguments):

  • interpreter/Interpreter.cpp:

(JSC::ProfileHostCall::ProfileHostCall):
(JSC::ProfileHostCall::~ProfileHostCall):
(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::throwException):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::privateExecute):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_profile_has_called):
(JSC::JIT::emit_op_profile_will_return):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_profile_has_called):
(JSC::JIT::emit_op_profile_will_return):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jit/JITStubs.h:
  • profiler/Profile.cpp:

(JSC::Profile::Profile):

  • profiler/ProfileGenerator.cpp:

(JSC::ProfileGenerator::addParentForConsoleStart):
(JSC::ProfileGenerator::willExecute):
(JSC::ProfileGenerator::didExecute):
(JSC::ProfileGenerator::exceptionUnwind):
(JSC::ProfileGenerator::stopProfiling):

  • profiler/ProfileGenerator.h:
  • profiler/ProfileNode.cpp:

(JSC::ProfileNode::ProfileNode):
(JSC::ProfileNode::willExecute):

  • profiler/ProfileNode.h:

(JSC::ProfileNode::create):
(JSC::ProfileNode::operator==):
(JSC::ProfileNode::exec):

  • profiler/Profiler.cpp:

(JSC::dispatchFunctionToProfiles):
(JSC::Profiler::hasCalled):
(JSC::Profiler::willEvaluate):
(JSC::Profiler::willReturn):
(JSC::Profiler::didEvaluate):
(JSC::Profiler::exceptionUnwind):

  • profiler/Profiler.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/profiler/ProfileNode.h

    r65478 r72160  
    3838namespace JSC {
    3939
     40    class ExecState;
    4041    class ProfileNode;
    4142
     
    4546    class ProfileNode : public RefCounted<ProfileNode> {
    4647    public:
    47         static PassRefPtr<ProfileNode> create(const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
     48        static PassRefPtr<ProfileNode> create(ExecState* exec, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
    4849        {
    49             return adoptRef(new ProfileNode(callIdentifier, headNode, parentNode));
     50            return adoptRef(new ProfileNode(exec, callIdentifier, headNode, parentNode));
    5051        }
    51         static PassRefPtr<ProfileNode> create(ProfileNode* headNode, ProfileNode* node)
     52        static PassRefPtr<ProfileNode> create(ExecState* exec, ProfileNode* headNode, ProfileNode* node)
    5253        {
    53             return adoptRef(new ProfileNode(headNode, node));
     54            return adoptRef(new ProfileNode(exec, headNode, node));
    5455        }
    5556
    56         bool operator==(ProfileNode* node) { return m_callIdentifier == node->callIdentifier(); }
     57        bool operator==(ProfileNode* node) { return m_exec == node->m_exec && m_callIdentifier == node->callIdentifier(); }
    5758
    58         ProfileNode* willExecute(const CallIdentifier&);
     59        ProfileNode* willExecute(ExecState* exec, const CallIdentifier&);
    5960        ProfileNode* didExecute();
    6061
     
    6263
    6364        // CallIdentifier members
     65        const ExecState* exec() const { return m_exec; }
    6466        const CallIdentifier& callIdentifier() const { return m_callIdentifier; }
    6567        const UString& functionName() const { return m_callIdentifier.m_name; }
     
    129131
    130132    private:
    131         ProfileNode(const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
    132         ProfileNode(ProfileNode* headNode, ProfileNode* nodeToCopy);
     133        ProfileNode(ExecState* exec, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
     134        ProfileNode(ExecState* exec, ProfileNode* headNode, ProfileNode* nodeToCopy);
    133135
    134136        void startTimer();
     
    148150        static inline bool functionNameAscendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->functionName() < b->functionName(); }
    149151
     152        ExecState* m_exec;
    150153        CallIdentifier m_callIdentifier;
    151154        ProfileNode* m_head;
Note: See TracChangeset for help on using the changeset viewer.