Ignore:
Timestamp:
Apr 5, 2013, 4:53:12 PM (12 years ago)
Author:
[email protected]
Message:

Unify the many and varied stack trace mechanisms, and make the result sane.
https://bugs.webkit.org/show_bug.cgi?id=114072

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Makes JSC::StackFrame record the bytecode offset and other necessary data
rather than requiring us to perform eager evaluation of the line number, etc.
Then remove most of the users of retrieveLastCaller, as most of them were
using it to create a stack trace in a fairly incomplete and inefficient way.

StackFrame now also has a couple of helpers to get the line and column info.

  • API/JSContextRef.cpp:

(JSContextCreateBacktrace):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitDebugHook):

  • interpreter/Interpreter.cpp:

(JSC):
(JSC::Interpreter::dumpRegisters):
(JSC::Interpreter::unwindCallFrame):
(JSC::getBytecodeOffsetForCallFrame):
(JSC::getCallerInfo):
(JSC::StackFrame::line):
(JSC::StackFrame::column):
(JSC::StackFrame::expressionInfo):
(JSC::StackFrame::toString):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::addStackTraceIfNecessary):
(JSC::Interpreter::retrieveCallerFromVMCode):

  • interpreter/Interpreter.h:

(StackFrame):
(Interpreter):

  • runtime/Error.cpp:

(JSC::throwError):

  • runtime/JSGlobalData.h:

(JSC):
(JSGlobalData):

  • runtime/JSGlobalObject.cpp:

(JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):

Source/WebCore:

Now that we've fleshed out the StackFrames from Interpreter::getStackTrace
WebCore can just ask us for a stack trace rather than implementing its own
stack walking.

  • bindings/js/ScriptCallStackFactory.cpp:

(WebCore::createScriptCallStack):

  • inspector/ScriptCallFrame.cpp:

(WebCore::ScriptCallFrame::isEqual):

  • inspector/ScriptCallFrame.h:

(ScriptCallFrame):
(WebCore::ScriptCallFrame::columnNumber):

Tools:

The commandline jsc executable no longer requires arguments, so
I've made run-jsc work without them.

  • Scripts/run-jsc:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSContextRef.cpp

    r141321 r147818  
    3737#include "JSObject.h"
    3838#include "Operations.h"
     39#include "SourceProvider.h"
    3940#include <wtf/text/StringBuilder.h>
    4041#include <wtf/text/StringHash.h>
     
    176177    ExecState* exec = toJS(ctx);
    177178    JSLockHolder lock(exec);
    178 
    179     unsigned count = 0;
    180179    StringBuilder builder;
    181     CallFrame* callFrame = exec;
    182     String functionName;
    183     if (exec->callee()) {
    184         if (asObject(exec->callee())->inherits(&InternalFunction::s_info)) {
    185             functionName = asInternalFunction(exec->callee())->name(exec);
    186             builder.appendLiteral("#0 ");
    187             builder.append(functionName);
    188             builder.appendLiteral("() ");
    189             count++;
    190         }
    191     }
    192     while (true) {
    193         RELEASE_ASSERT(callFrame);
    194         int signedLineNumber;
    195         intptr_t sourceID;
     180    Vector<StackFrame> stackTrace;
     181    Interpreter::getStackTrace(&exec->globalData(), stackTrace, maxStackSize);
     182
     183    for (size_t i = 0; i < stackTrace.size(); i++) {
    196184        String urlString;
    197         JSValue function;
    198 
    199         exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function);
    200 
    201         if (function)
    202             functionName = jsCast<JSFunction*>(function)->name(exec);
     185        String functionName;
     186        StackFrame& frame = stackTrace[i];
     187        JSValue function = frame.callee.get();
     188        if (frame.callee)
     189            functionName = frame.friendlyFunctionName(exec);
    203190        else {
    204191            // Caller is unknown, but if frame is empty we should still add the frame, because
    205192            // something called us, and gave us arguments.
    206             if (count)
     193            if (i)
    207194                break;
    208195        }
    209         unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;
     196        unsigned lineNumber = frame.line();
    210197        if (!builder.isEmpty())
    211198            builder.append('\n');
    212199        builder.append('#');
    213         builder.appendNumber(count);
     200        builder.appendNumber(i);
    214201        builder.append(' ');
    215202        builder.append(functionName);
    216203        builder.appendLiteral("() at ");
    217204        builder.append(urlString);
    218         builder.append(':');
    219         builder.appendNumber(lineNumber);
    220         if (!function || ++count == maxStackSize)
     205        if (frame.codeType != StackFrameNativeCode) {
     206            builder.append(':');
     207            builder.appendNumber(lineNumber);
     208        }
     209        if (!function)
    221210            break;
    222         callFrame = callFrame->callerFrame();
    223211    }
    224212    return OpaqueJSString::create(builder.toString()).leakRef();
Note: See TracChangeset for help on using the changeset viewer.