CallFrame* CallFrame::trueCallerFrame()
{
    // this -> The callee; this is either an inlined callee in which case it already has
    //    a pointer to the true caller. Otherwise it contains current PC in the machine
    //    caller.
    //
    // machineCaller -> The caller according to the machine, which may be zero or
    //    more frames above the true caller due to inlining.
    
    // Am I an inline call frame? If so, we're done.
    if (isInlineCallFrame())
        return callerFrame();
    
    // I am a machine call frame, so the question is: is my caller a machine call frame
    // that has inlines or a machine call frame that doesn't?
    CallFrame* machineCaller = callerFrame()->removeHostCallFrameFlag();
    if (!machineCaller)
        return 0;
    ASSERT(!machineCaller->isInlineCallFrame());
    
    // Figure out how we want to get the current code location.
    if (hasHostCallFrameFlag() || returnAddressIsInCtiTrampoline(returnPC()))
        return machineCaller->trueCallFrameFromVMCode();
    
    return machineCaller->trueCallFrame(returnPC());
}
Exemple #2
0
CallFrame* CallFrame::trueCallerFrameSlow()
{
    // this -> The callee; this is either an inlined callee in which case it already has
    //    a pointer to the true caller. Otherwise it contains current PC in the machine
    //    caller.
    //
    // machineCaller -> The caller according to the machine, which may be zero or
    //    more frames above the true caller due to inlining.
    //
    // trueCaller -> The real caller.
    
    // Am I an inline call frame? If so, we're done.
    if (isInlineCallFrame())
        return callerFrame();
    
    // I am a machine call frame, so the question is: is my caller a machine call frame
    // that has inlines or a machine call frame that doesn't?
    CallFrame* machineCaller = callerFrame()->removeHostCallFrameFlag();
    if (!machineCaller)
        return 0;
    ASSERT(!machineCaller->isInlineCallFrame());
    if (!machineCaller->codeBlock() || !machineCaller->codeBlock()->hasCodeOrigins())
        return machineCaller; // No inlining, so machineCaller == trueCaller
    
    // Figure out where the caller frame would have gone relative to the machine
    // caller, and rematerialize it. Do so for the entire inline stack.
    
    CodeOrigin codeOrigin = machineCaller->codeBlock()->codeOriginForReturn(returnPC());
    
    for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) {
        InlineCallFrame* nextInlineCallFrame = inlineCallFrame = inlineCallFrame->caller.inlineCallFrame;
        
        CallFrame* inlinedCaller = machineCaller + inlineCallFrame->stackOffset;
        
        JSObject* callee = machineCaller->registers()[inlineCallFrame->calleeVR].function();
        JSCell* calleeAsFunctionCell = getJSFunction(callee);
        ASSERT(calleeAsFunctionCell);
        JSFunction* calleeAsFunction = asFunction(calleeAsFunctionCell);
        
        // Fill in the inlinedCaller
        inlinedCaller->setCodeBlock(machineCaller->codeBlock());
        
        inlinedCaller->setScopeChain(calleeAsFunction->scope());
        if (nextInlineCallFrame)
            inlinedCaller->setCallerFrame(machineCaller + nextInlineCallFrame->stackOffset);
        else
            inlinedCaller->setCallerFrame(machineCaller);
        
        inlinedCaller->setInlineCallFrame(inlineCallFrame);
        inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->numArgumentsIncludingThis);
        inlinedCaller->setCallee(callee);
        
        inlineCallFrame = nextInlineCallFrame;
    }
    
    return machineCaller + codeOrigin.inlineCallFrame->stackOffset;
}
Exemple #3
0
void CallFrame::dump(PrintStream& out)
{
    if (CodeBlock* codeBlock = this->codeBlock()) {
        out.print(codeBlock->inferredName(), "#", codeBlock->hashAsStringIfPossible(), " [", codeBlock->jitType(), "]");

        out.print("(");
        thisValue().dumpForBacktrace(out);

        for (size_t i = 0; i < argumentCount(); ++i) {
            out.print(", ");
            JSValue value = argument(i);
            value.dumpForBacktrace(out);
        }

        out.print(")");

        return;
    }

    out.print(returnPC());
}