Changeset 147818 in webkit
- Timestamp:
- Apr 5, 2013 4:53:12 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSContextRef.cpp
r141321 r147818 37 37 #include "JSObject.h" 38 38 #include "Operations.h" 39 #include "SourceProvider.h" 39 40 #include <wtf/text/StringBuilder.h> 40 41 #include <wtf/text/StringHash.h> … … 176 177 ExecState* exec = toJS(ctx); 177 178 JSLockHolder lock(exec); 178 179 unsigned count = 0;180 179 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++) { 196 184 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); 203 190 else { 204 191 // Caller is unknown, but if frame is empty we should still add the frame, because 205 192 // something called us, and gave us arguments. 206 if ( count)193 if (i) 207 194 break; 208 195 } 209 unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;196 unsigned lineNumber = frame.line(); 210 197 if (!builder.isEmpty()) 211 198 builder.append('\n'); 212 199 builder.append('#'); 213 builder.appendNumber( count);200 builder.appendNumber(i); 214 201 builder.append(' '); 215 202 builder.append(functionName); 216 203 builder.appendLiteral("() at "); 217 204 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) 221 210 break; 222 callFrame = callFrame->callerFrame();223 211 } 224 212 return OpaqueJSString::create(builder.toString()).leakRef(); -
trunk/Source/JavaScriptCore/ChangeLog
r147816 r147818 1 2013-04-05 Oliver Hunt <oliver@apple.com> 2 3 Unify the many and varied stack trace mechanisms, and make the result sane. 4 https://bugs.webkit.org/show_bug.cgi?id=114072 5 6 Reviewed by Filip Pizlo. 7 8 Makes JSC::StackFrame record the bytecode offset and other necessary data 9 rather than requiring us to perform eager evaluation of the line number, etc. 10 Then remove most of the users of retrieveLastCaller, as most of them were 11 using it to create a stack trace in a fairly incomplete and inefficient way. 12 13 StackFrame now also has a couple of helpers to get the line and column info. 14 15 * API/JSContextRef.cpp: 16 (JSContextCreateBacktrace): 17 * bytecompiler/BytecodeGenerator.cpp: 18 (JSC::BytecodeGenerator::emitDebugHook): 19 * interpreter/Interpreter.cpp: 20 (JSC): 21 (JSC::Interpreter::dumpRegisters): 22 (JSC::Interpreter::unwindCallFrame): 23 (JSC::getBytecodeOffsetForCallFrame): 24 (JSC::getCallerInfo): 25 (JSC::StackFrame::line): 26 (JSC::StackFrame::column): 27 (JSC::StackFrame::expressionInfo): 28 (JSC::StackFrame::toString): 29 (JSC::Interpreter::getStackTrace): 30 (JSC::Interpreter::addStackTraceIfNecessary): 31 (JSC::Interpreter::retrieveCallerFromVMCode): 32 * interpreter/Interpreter.h: 33 (StackFrame): 34 (Interpreter): 35 * runtime/Error.cpp: 36 (JSC::throwError): 37 * runtime/JSGlobalData.h: 38 (JSC): 39 (JSGlobalData): 40 * runtime/JSGlobalObject.cpp: 41 (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): 42 1 43 2013-04-05 Mark Hahnenberg <mhahnenberg@apple.com> 2 44 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r147669 r147818 2056 2056 return; 2057 2057 #endif 2058 emitExpressionInfo(charPosition, 0, 0); 2058 2059 emitOpcode(op_debug); 2059 2060 instructions().append(debugHookID); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r147798 r147818 200 200 201 201 202 static CallFrame* getCallerInfo(JSGlobalData*, CallFrame*, int& lineNumber,unsigned& bytecodeOffset, CodeBlock*& callerOut);202 static CallFrame* getCallerInfo(JSGlobalData*, CallFrame*, unsigned& bytecodeOffset, CodeBlock*& callerOut); 203 203 204 204 // Returns the depth of the scope chain within a given call frame. … … 423 423 unsigned bytecodeOffset = 0; 424 424 int line = 0; 425 CodeBlock* unusedCallerCodeBlock = 0; 426 getCallerInfo(&callFrame->globalData(), callFrame, line, bytecodeOffset, unusedCallerCodeBlock); 425 CodeBlock* callerCodeBlock = 0; 426 getCallerInfo(&callFrame->globalData(), callFrame, bytecodeOffset, callerCodeBlock); 427 line = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset); 427 428 dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", it, bytecodeOffset, line); 428 429 ++it; … … 508 509 if (callerFrame->hasHostCallFrameFlag()) 509 510 return false; 510 int unusedLineNumber = 0; 511 callFrame = getCallerInfo(&callFrame->globalData(), callFrame, unusedLineNumber, bytecodeOffset, codeBlock); 511 callFrame = getCallerInfo(&callFrame->globalData(), callFrame, bytecodeOffset, codeBlock); 512 512 return true; 513 513 } … … 565 565 } 566 566 567 static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFrame) 568 { 569 UNUSED_PARAM(globalData); 567 static unsigned getBytecodeOffsetForCallFrame(CallFrame* callFrame) 568 { 570 569 callFrame = callFrame->removeHostCallFrameFlag(); 571 570 CodeBlock* codeBlock = callFrame->codeBlock(); 572 571 if (!codeBlock) 573 572 return -1; 574 #if ENABLE(JIT) || ENABLE(LLINT)573 #if ENABLE(JIT) 575 574 #if ENABLE(DFG_JIT) 576 575 if (codeBlock->getJITType() == JITCode::DFGJIT) 577 return codeBlock-> lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);578 #endif 579 return c odeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());580 #endif 581 } 582 583 static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber,unsigned& bytecodeOffset, CodeBlock*& caller)576 return codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex; 577 #endif 578 return callFrame->bytecodeOffsetForNonDFGCode(); 579 #endif 580 } 581 582 static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, unsigned& bytecodeOffset, CodeBlock*& caller) 584 583 { 585 584 ASSERT_UNUSED(globalData, globalData); 586 585 bytecodeOffset = 0; 587 lineNumber = -1;588 586 ASSERT(!callFrame->hasHostCallFrameFlag()); 589 587 CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag(); … … 655 653 RELEASE_ASSERT(callerCodeBlock); 656 654 caller = callerCodeBlock; 657 lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);658 655 return callerFrame; 659 656 } … … 681 678 } 682 679 683 void Interpreter::getStackTrace(JSGlobalData* globalData, Vector<StackFrame>& results) 680 unsigned StackFrame::line() 681 { 682 return codeBlock ? codeBlock->lineNumberForBytecodeOffset(bytecodeOffset) + lineOffset : 0; 683 } 684 685 unsigned StackFrame::column() 686 { 687 if (!code) 688 return 0; 689 int divot = 0; 690 int unusedStartOffset = 0; 691 int unusedEndOffset = 0; 692 expressionInfo(divot, unusedStartOffset, unusedEndOffset); 693 return code->charPositionToColumnNumber(divot); 694 } 695 696 void StackFrame::expressionInfo(int& divot, int& startOffset, int& endOffset) 697 { 698 codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset); 699 divot += startOffset; 700 } 701 702 String StackFrame::toString(CallFrame* callFrame) 703 { 704 StringBuilder traceBuild; 705 String functionName = friendlyFunctionName(callFrame); 706 String sourceURL = friendlySourceURL(); 707 traceBuild.append(functionName); 708 if (!sourceURL.isEmpty()) { 709 if (!functionName.isEmpty()) 710 traceBuild.append('@'); 711 traceBuild.append(sourceURL); 712 if (codeType != StackFrameNativeCode) { 713 traceBuild.append(':'); 714 traceBuild.appendNumber(line()); 715 } 716 } 717 return traceBuild.toString().impl(); 718 } 719 720 void Interpreter::getStackTrace(JSGlobalData* globalData, Vector<StackFrame>& results, size_t maxStackSize) 684 721 { 685 722 CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag(); 686 723 if (!callFrame || callFrame == CallFrame::noCaller()) 687 724 return; 688 int line = getLineNumberForCallFrame(globalData, callFrame); 689 725 unsigned bytecodeOffset = getBytecodeOffsetForCallFrame(callFrame); 690 726 callFrame = callFrame->trueCallFrameFromVMCode(); 691 727 if (!callFrame) 692 728 return; 693 694 while (callFrame && callFrame != CallFrame::noCaller()) { 729 CodeBlock* callerCodeBlock = callFrame->codeBlock(); 730 731 while (callFrame && callFrame != CallFrame::noCaller() && maxStackSize--) { 695 732 String sourceURL; 696 if (call Frame->codeBlock()) {733 if (callerCodeBlock) { 697 734 sourceURL = getSourceURLFromCallFrame(callFrame); 698 StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL}; 735 StackFrame s = { 736 Strong<JSObject>(*globalData, callFrame->callee()), 737 getStackFrameCodeType(callFrame), 738 Strong<ExecutableBase>(*globalData, callerCodeBlock->ownerExecutable()), 739 Strong<UnlinkedCodeBlock>(*globalData, callerCodeBlock->unlinkedCodeBlock()), 740 callerCodeBlock->source(), 741 callerCodeBlock->ownerExecutable()->lineNo(), 742 callerCodeBlock->sourceOffset(), 743 bytecodeOffset, 744 sourceURL 745 }; 699 746 results.append(s); 700 747 } else { 701 StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, String()};748 StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, String()}; 702 749 results.append(s); 703 750 } 704 unsigned unusedBytecodeOffset = 0; 705 CodeBlock* unusedCallerCodeBlock = 0; 706 callFrame = getCallerInfo(globalData, callFrame, line, unusedBytecodeOffset, unusedCallerCodeBlock); 707 } 708 } 709 710 void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSObject* error) 751 callFrame = getCallerInfo(globalData, callFrame, bytecodeOffset, callerCodeBlock); 752 } 753 } 754 755 void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSValue error) 711 756 { 712 757 JSGlobalData* globalData = &callFrame->globalData(); 713 758 ASSERT(callFrame == globalData->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec()); 714 if (error->hasProperty(callFrame, globalData->propertyNames->stack))715 return;716 759 717 760 Vector<StackFrame> stackTrace; 718 761 getStackTrace(&callFrame->globalData(), stackTrace); 719 762 720 if (stackTrace.isEmpty() )763 if (stackTrace.isEmpty() || !error.isObject()) 721 764 return; 722 765 JSObject* errorObject = asObject(error); 723 766 JSGlobalObject* globalObject = 0; 724 767 if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error)) 725 768 globalObject = globalData->dynamicGlobalObject; 726 769 else 727 globalObject = error ->globalObject();770 globalObject = errorObject->globalObject(); 728 771 729 772 // FIXME: JSStringJoiner could be more efficient than StringBuilder here. … … 734 777 builder.append('\n'); 735 778 } 736 737 error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, builder.toString()), ReadOnly | DontDelete); 779 780 if (errorObject->hasProperty(callFrame, globalData->propertyNames->stack)) 781 return; 782 errorObject->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, builder.toString()), ReadOnly | DontDelete); 738 783 } 739 784 … … 1378 1423 return jsNull(); 1379 1424 1380 int lineNumber;1381 1425 unsigned bytecodeOffset; 1382 1426 CodeBlock* unusedCallerCodeBlock = 0; 1383 CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber,bytecodeOffset, unusedCallerCodeBlock);1427 CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, bytecodeOffset, unusedCallerCodeBlock); 1384 1428 if (!callerFrame) 1385 1429 return jsNull(); … … 1391 1435 ASSERT(caller.isObject()); 1392 1436 while (asObject(caller)->inherits(&JSBoundFunction::s_info)) { 1393 callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber,bytecodeOffset, unusedCallerCodeBlock);1437 callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, bytecodeOffset, unusedCallerCodeBlock); 1394 1438 if (!callerFrame) 1395 1439 return jsNull(); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r146552 r147818 80 80 StackFrameCodeType codeType; 81 81 Strong<ExecutableBase> executable; 82 int line; 82 Strong<UnlinkedCodeBlock> codeBlock; 83 RefPtr<SourceProvider> code; 84 int lineOffset; 85 unsigned characterOffset; 86 unsigned bytecodeOffset; 83 87 String sourceURL; 84 String toString(CallFrame* callFrame) const 85 { 86 StringBuilder traceBuild; 87 String functionName = friendlyFunctionName(callFrame); 88 String sourceURL = friendlySourceURL(); 89 traceBuild.append(functionName); 90 if (!sourceURL.isEmpty()) { 91 if (!functionName.isEmpty()) 92 traceBuild.append('@'); 93 traceBuild.append(sourceURL); 94 if (line > -1) { 95 traceBuild.append(':'); 96 traceBuild.appendNumber(line); 97 } 98 } 99 return traceBuild.toString().impl(); 100 } 88 JS_EXPORT_PRIVATE String toString(CallFrame*); 101 89 String friendlySourceURL() const 102 90 { … … 138 126 return traceLine.isNull() ? emptyString() : traceLine; 139 127 } 140 unsigned friendlyLineNumber() const 141 { 142 return line > -1 ? line : 0; 143 } 128 JS_EXPORT_PRIVATE unsigned line(); 129 JS_EXPORT_PRIVATE unsigned column(); 130 JS_EXPORT_PRIVATE void expressionInfo(int& divot, int& startOffset, int& endOffset); 144 131 }; 145 132 … … 233 220 NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column); 234 221 static const String getTraceLine(CallFrame*, StackFrameCodeType, const String&, int); 235 JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector<StackFrame>& results );236 static void addStackTraceIfNecessary(CallFrame*, JS Object*error);222 JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max()); 223 static void addStackTraceIfNecessary(CallFrame*, JSValue error); 237 224 238 225 void dumpSampleData(ExecState* exec); -
trunk/Source/JavaScriptCore/runtime/Error.cpp
r139541 r147818 156 156 JSValue throwError(ExecState* exec, JSValue error) 157 157 { 158 if (error.isObject()) 159 return throwError(exec, asObject(error)); 158 Interpreter::addStackTraceIfNecessary(exec, error); 160 159 exec->globalData().exception = error; 161 160 return error; -
trunk/Source/JavaScriptCore/runtime/JSGlobalData.h
r146682 r147818 55 55 #include <wtf/Forward.h> 56 56 #include <wtf/HashMap.h> 57 #include <wtf/RefCountedArray.h> 57 58 #include <wtf/SimpleStats.h> 58 59 #include <wtf/ThreadSafeRefCounted.h> … … 82 83 class SourceProvider; 83 84 class SourceProviderCache; 85 struct StackFrame; 84 86 class Stringifier; 85 87 class Structure; … … 329 331 330 332 JSValue exception; 333 RefCountedArray<StackFrame> exceptionStack; 331 334 332 335 const ClassInfo* const jsArrayClassInfo; -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r146494 r147818 598 598 globalData.resetDateCache(); 599 599 } 600 // Clear the exception stack between entries 601 globalData.exceptionStack = RefCountedArray<StackFrame>(); 600 602 } 601 603 -
trunk/Source/WebCore/ChangeLog
r147806 r147818 1 2013-04-05 Oliver Hunt <oliver@apple.com> 2 3 Unify the many and varied stack trace mechanisms, and make the result sane. 4 https://bugs.webkit.org/show_bug.cgi?id=114072 5 6 Reviewed by Filip Pizlo. 7 8 Now that we've fleshed out the StackFrames from Interpreter::getStackTrace 9 WebCore can just ask us for a stack trace rather than implementing its own 10 stack walking. 11 12 * bindings/js/ScriptCallStackFactory.cpp: 13 (WebCore::createScriptCallStack): 14 * inspector/ScriptCallFrame.cpp: 15 (WebCore::ScriptCallFrame::isEqual): 16 * inspector/ScriptCallFrame.h: 17 (ScriptCallFrame): 18 (WebCore::ScriptCallFrame::columnNumber): 19 1 20 2013-04-05 Beth Dakin <bdakin@apple.com> 2 21 -
trunk/Source/WebCore/bindings/js/ScriptCallStackFactory.cpp
r140718 r147818 59 59 if (JSC::ExecState* exec = JSMainThreadExecState::currentState()) { 60 60 Vector<StackFrame> stackTrace; 61 Interpreter::getStackTrace(&exec->globalData(), stackTrace); 62 for (Vector<StackFrame>::const_iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) { 63 frames.append(ScriptCallFrame(iter->friendlyFunctionName(exec), iter->friendlySourceURL(), iter->friendlyLineNumber())); 64 if (frames.size() >= maxStackSize) 65 break; 66 } 61 Interpreter::getStackTrace(&exec->globalData(), stackTrace, maxStackSize); 62 for (size_t i = 0; i < stackTrace.size(); i++) 63 frames.append(ScriptCallFrame(stackTrace[i].friendlyFunctionName(exec), stackTrace[i].friendlySourceURL(), stackTrace[i].line(), stackTrace[i].column())); 67 64 } 68 65 if (frames.isEmpty() && !emptyIsAllowed) { … … 70 67 // a bound function is called from native code for example. 71 68 // Fallback to setting lineNumber to 0, and source and function name to "undefined". 72 frames.append(ScriptCallFrame("undefined", "undefined", 0 ));69 frames.append(ScriptCallFrame("undefined", "undefined", 0, 0)); 73 70 } 74 71 return ScriptCallStack::create(frames); … … 78 75 { 79 76 Vector<ScriptCallFrame> frames; 80 CallFrame* callFrame = exec; 81 while (true) { 82 ASSERT(callFrame); 83 int signedLineNumber; 84 intptr_t sourceID; 85 String urlString; 86 JSValue function; 77 Vector<StackFrame> stackTrace; 78 Interpreter::getStackTrace(&exec->globalData(), stackTrace, maxStackSize + 1); 79 for (size_t i = 1; i < stackTrace.size(); i++) { 80 // This early exit is necessary to maintain our old behaviour 81 // but the stack trace we produce now is complete and handles all 82 // ways in which code may be running 83 if (!stackTrace[i].callee && frames.size()) 84 break; 85 String functionName = stackTrace[i].friendlyFunctionName(exec); 86 frames.append(ScriptCallFrame(functionName, stackTrace[i].sourceURL, stackTrace[i].line(), stackTrace[i].column())); 87 } 87 88 88 exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function);89 String functionName;90 if (function)91 functionName = jsCast<JSFunction*>(function)->name(exec);92 else {93 // Caller is unknown, but if frames is empty we should still add the frame, because94 // something called us, and gave us arguments.95 if (!frames.isEmpty())96 break;97 }98 unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;99 frames.append(ScriptCallFrame(functionName, urlString, lineNumber));100 if (!function || frames.size() == maxStackSize)101 break;102 callFrame = callFrame->callerFrame();103 }104 89 return ScriptCallStack::create(frames); 105 90 } -
trunk/Source/WebCore/inspector/ScriptCallFrame.cpp
r115965 r147818 54 54 return m_functionName == o.m_functionName 55 55 && m_scriptName == o.m_scriptName 56 && m_lineNumber == o.m_lineNumber; 56 && m_lineNumber == o.m_lineNumber 57 && m_column == o.m_column; 57 58 } 58 59 -
trunk/Source/WebCore/inspector/ScriptCallFrame.h
r127757 r147818 45 45 class ScriptCallFrame { 46 46 public: 47 ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column = 0);47 ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column); 48 48 ~ScriptCallFrame(); 49 49 … … 51 51 const String& sourceURL() const { return m_scriptName; } 52 52 unsigned lineNumber() const { return m_lineNumber; } 53 unsigned columnNumber() const { return m_column; } 53 54 54 55 bool isEqual(const ScriptCallFrame&) const; -
trunk/Tools/ChangeLog
r147802 r147818 1 2013-04-05 Oliver Hunt <oliver@apple.com> 2 3 Unify the many and varied stack trace mechanisms, and make the result sane. 4 https://bugs.webkit.org/show_bug.cgi?id=114072 5 6 Reviewed by Filip Pizlo. 7 8 The commandline jsc executable no longer requires arguments, so 9 I've made run-jsc work without them. 10 11 * Scripts/run-jsc: 12 1 13 2013-04-05 Chris Fleizach <cfleizach@apple.com> 2 14 -
trunk/Tools/Scripts/run-jsc
r50080 r147818 43 43 GetOptions("count|c=i" => \$count, 44 44 "verbose|v" => \$verbose); 45 die "$usage\n" if (@ARGV < 1);46 45 47 46 my $jsc = jscProductDir() . "/jsc @ARGV";
Note: See TracChangeset
for help on using the changeset viewer.