Source/JavaScriptCore/ChangeLog

 12013-05-24 Mark Lam <mark.lam@apple.com>
 2
 3 Remove Interpreter::retrieveLastCaller().
 4 https://bugs.webkit.org/show_bug.cgi?id=116753.
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This is part of the refactoring effort to get rid of functions walking
 9 the JS stack in their own way.
 10
 11 * API/JSContextRef.cpp:
 12 (JSContextCreateBacktrace):
 13 * interpreter/CallFrame.cpp:
 14 * interpreter/Interpreter.cpp:
 15 (JSC::Interpreter::Interpreter):
 16 (JSC::Interpreter::getStackTrace):
 17 (JSC::Interpreter::addStackTraceIfNecessary):
 18 * interpreter/Interpreter.h:
 19 (StackFrame):
 20 (JSC::StackFrame::StackFrame):
 21 (Interpreter):
 22 * jsc.cpp:
 23 (functionJSCStack):
 24 * profiler/ProfileGenerator.cpp:
 25 (JSC::ProfileGenerator::addParentForConsoleStart):
 26
1272013-05-24 Filip Pizlo <fpizlo@apple.com>
228
329 fourthTier: FTL boolify should support ObjectOrOtherUse
150679

Source/JavaScriptCore/jsc.cpp

@@EncodedJSValue JSC_HOST_CALL functionJSC
327327 trace.appendLiteral("--> Stack trace:\n");
328328
329329 Vector<StackFrame> stackTrace;
330  Interpreter::getStackTrace(&exec->vm(), stackTrace);
 330 exec->interpreter()->getStackTrace(stackTrace);
331331 int i = 0;
332332
333333 for (Vector<StackFrame>::iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) {
150679

Source/JavaScriptCore/API/JSContextRef.cpp

@@JSStringRef JSContextCreateBacktrace(JSC
178178
179179 unsigned count = 0;
180180 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;
196  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);
203  else {
204  // Caller is unknown, but if frame is empty we should still add the frame, because
205  // something called us, and gave us arguments.
206  if (count)
207  break;
208  }
209  unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;
 181 Vector<StackFrame> stackTrace;
 182 exec->interpreter()->getStackTrace(stackTrace, maxStackSize);
 183 for (Vector<StackFrame>::const_iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) {
210184 if (!builder.isEmpty())
211185 builder.append('\n');
212186 builder.append('#');
213  builder.appendNumber(count);
 187 builder.appendNumber(count++);
214188 builder.append(' ');
215  builder.append(functionName);
 189 builder.append(iter->friendlyFunctionName(exec));
216190 builder.appendLiteral("() at ");
217  builder.append(urlString);
 191 builder.append(iter->friendlySourceURL());
218192 builder.append(':');
219  builder.appendNumber(lineNumber);
220  if (!function || ++count == maxStackSize)
221  break;
222  callFrame = callFrame->callerFrame();
 193 builder.appendNumber(iter->friendlyLineNumber());
223194 }
 195
224196 return OpaqueJSString::create(builder.toString()).leakRef();
225197}
226198
150679

Source/JavaScriptCore/interpreter/CallFrame.cpp

3333namespace JSC {
3434
3535#ifndef NDEBUG
36 void CallFrame::dumpCaller()
37 {
38  int signedLineNumber;
39  intptr_t sourceID;
40  String urlString;
41  JSValue function;
42 
43  interpreter()->retrieveLastCaller(this, signedLineNumber, sourceID, urlString, function);
44  dataLogF("Callpoint => %s:%d\n", urlString.utf8().data(), signedLineNumber);
45 }
46 
4736JSStack* CallFrame::stack()
4837{
4938 return &interpreter()->stack();
150679

Source/JavaScriptCore/interpreter/Interpreter.cpp

@@CallFrame* loadVarargs(CallFrame* callFr
339339
340340Interpreter::Interpreter(VM& vm)
341341 : m_sampleEntryDepth(0)
 342 , m_vm(vm)
342343 , m_stack(vm)
343344 , m_errorHandlingModeReentry(0)
344345#if !ASSERT_DISABLED

@@static StackFrameCodeType getStackFrameC
684685 return StackFrameGlobalCode;
685686}
686687
687 void Interpreter::getStackTrace(VM* vm, Vector<StackFrame>& results)
 688void Interpreter::getStackTrace(Vector<StackFrame>& results, unsigned maxStackSize)
688689{
689  CallFrame* callFrame = vm->topCallFrame->removeHostCallFrameFlag();
 690 VM& vm = m_vm;
 691 CallFrame* callFrame = vm.topCallFrame->removeHostCallFrameFlag();
690692 if (!callFrame || callFrame == CallFrame::noCaller())
691693 return;
692  int line = getLineNumberForCallFrame(vm, callFrame);
 694 int line = getLineNumberForCallFrame(&vm, callFrame);
693695
694696 callFrame = callFrame->trueCallFrameFromVMCode();
695697
696  while (callFrame && callFrame != CallFrame::noCaller()) {
 698 while (callFrame && callFrame != CallFrame::noCaller() && maxStackSize--) {
697699 String sourceURL;
698700 if (callFrame->codeBlock()) {
699701 sourceURL = getSourceURLFromCallFrame(callFrame);
700  StackFrame s = { Strong<JSObject>(*vm, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*vm, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
 702 StackFrame s(Strong<JSObject>(vm, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(vm, callFrame->codeBlock()->ownerExecutable()), line, sourceURL);
701703 results.append(s);
702704 } else {
703  StackFrame s = { Strong<JSObject>(*vm, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, String()};
 705 StackFrame s(Strong<JSObject>(vm, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, String());
704706 results.append(s);
705707 }
706708 unsigned unusedBytecodeOffset = 0;
707  callFrame = getCallerInfo(vm, callFrame, line, unusedBytecodeOffset);
 709 callFrame = getCallerInfo(&vm, callFrame, line, unusedBytecodeOffset);
708710 }
709711}
710712

@@void Interpreter::addStackTraceIfNecessa
716718 return;
717719
718720 Vector<StackFrame> stackTrace;
719  getStackTrace(&callFrame->vm(), stackTrace);
 721 vm->interpreter->getStackTrace(stackTrace);
720722
721723 if (stackTrace.isEmpty())
722724 return;

@@JSValue Interpreter::retrieveCallerFromV
14131415 return caller;
14141416}
14151417
1416 void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, String& sourceURL, JSValue& function) const
1417 {
1418  function = JSValue();
1419  lineNumber = -1;
1420  sourceURL = String();
1421 
1422  CallFrame* callerFrame = callFrame->callerFrame();
1423  if (callerFrame->hasHostCallFrameFlag())
1424  return;
1425 
1426  CodeBlock* callerCodeBlock = callerFrame->codeBlock();
1427  if (!callerCodeBlock)
1428  return;
1429  unsigned bytecodeOffset = 0;
1430  bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
1431  lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
1432  sourceID = callerCodeBlock->ownerExecutable()->sourceID();
1433  sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
1434  function = callerFrame->callee();
1435 }
1436 
14371418CallFrame* Interpreter::findFunctionCallFrameFromVMCode(CallFrame* callFrame, JSFunction* function)
14381419{
14391420 for (CallFrame* candidate = callFrame->trueCallFrameFromVMCode(); candidate; candidate = candidate->trueCallerFrame()) {
150679

Source/JavaScriptCore/interpreter/Interpreter.h

@@namespace JSC {
8181 Strong<ExecutableBase> executable;
8282 int line;
8383 String sourceURL;
 84
 85 StackFrame()
 86 : codeType(StackFrameNativeCode)
 87 , line(0)
 88 {
 89 }
 90
 91 StackFrame(Strong<JSObject> otherCallee, StackFrameCodeType otherCodeType, Strong<ExecutableBase> otherExecutable, int otherLine, String otherSourceURL)
 92 : callee(otherCallee)
 93 , codeType(otherCodeType)
 94 , executable(otherExecutable)
 95 , line(otherLine)
 96 , sourceURL(otherSourceURL)
 97 {
 98 }
 99
84100 String toString(CallFrame* callFrame) const
85101 {
86102 StringBuilder traceBuild;

@@namespace JSC {
223239
224240 JSValue retrieveArgumentsFromVMCode(CallFrame*, JSFunction*) const;
225241 JSValue retrieveCallerFromVMCode(CallFrame*, JSFunction*) const;
226  JS_EXPORT_PRIVATE void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, String& sourceURL, JSValue& function) const;
227242
228243 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
229244

@@namespace JSC {
232247 NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
233248 NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int charPosition);
234249 static const String getTraceLine(CallFrame*, StackFrameCodeType, const String&, int);
235  JS_EXPORT_PRIVATE static void getStackTrace(VM*, Vector<StackFrame>& results);
 250 JS_EXPORT_PRIVATE void getStackTrace(Vector<StackFrame>& results, unsigned maxStackSize = INT_MAX);
236251 static void addStackTraceIfNecessary(CallFrame*, JSObject* error);
237252
238253 void dumpSampleData(ExecState* exec);

@@namespace JSC {
270285 int m_sampleEntryDepth;
271286 OwnPtr<SamplingTool> m_sampler;
272287
 288 VM& m_vm;
273289 JSStack m_stack;
274290 int m_errorHandlingModeReentry;
275291
150679

Source/JavaScriptCore/profiler/ProfileGenerator.cpp

@@ProfileGenerator::ProfileGenerator(ExecS
5858
5959void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
6060{
61  int lineNumber;
62  intptr_t sourceID;
63  String sourceURL;
64  JSValue function;
 61 Vector<StackFrame> stackTrace;
 62 exec->interpreter()->getStackTrace(stackTrace, 2);
6563
66  exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
67  m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, function, sourceURL, lineNumber), m_head.get(), m_head.get());
 64 m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, stackTrace[1].callee.get(), stackTrace[1].sourceURL, stackTrace[1].line), m_head.get(), m_head.get());
6865 m_head->insertNode(m_currentNode.get());
6966}
7067
150679

Source/WebCore/ChangeLog

 12013-05-24 Mark Lam <mark.lam@apple.com>
 2
 3 Remove Interpreter::retrieveLastCaller().
 4 https://bugs.webkit.org/show_bug.cgi?id=116753.
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This is part of the refactoring effort to get rid of functions walking
 9 the JS stack in their own way.
 10
 11 No new tests.
 12
 13 * bindings/js/JSXMLHttpRequestCustom.cpp:
 14 (WebCore::JSXMLHttpRequest::send):
 15 * bindings/js/ScriptCallStackFactory.cpp:
 16 (WebCore::createScriptCallStack):
 17
1182013-05-06 Geoffrey Garen <ggaren@apple.com>
219
320 Cherry-pick merged some patches to the FTL branch.
150679

Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp

@@JSValue JSXMLHttpRequest::send(ExecState
133133 impl()->send(val.toString(exec)->value(exec), ec);
134134 }
135135
136  int signedLineNumber;
137  intptr_t sourceID;
138  String sourceURL;
139  JSValue function;
140  exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function);
141  impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0);
142  impl()->setLastSendURL(sourceURL);
 136 Vector<StackFrame> stackTrace;
 137 exec->interpreter()->getStackTrace(stackTrace, 2);
 138 impl()->setLastSendLineNumber(stackTrace[1].line);
 139 impl()->setLastSendURL(stackTrace[1].sourceURL);
143140
144141 setDOMException(exec, ec);
145142 return jsUndefined();
150679

Source/WebCore/bindings/js/ScriptCallStackFactory.cpp

@@PassRefPtr<ScriptCallStack> createScript
5858 Vector<ScriptCallFrame> frames;
5959 if (JSC::ExecState* exec = JSMainThreadExecState::currentState()) {
6060 Vector<StackFrame> stackTrace;
61  Interpreter::getStackTrace(&exec->vm(), stackTrace);
 61 exec->interpreter()->getStackTrace(stackTrace);
6262 for (Vector<StackFrame>::const_iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) {
6363 frames.append(ScriptCallFrame(iter->friendlyFunctionName(exec), iter->friendlySourceURL(), iter->friendlyLineNumber()));
6464 if (frames.size() >= maxStackSize)

@@PassRefPtr<ScriptCallStack> createScript
7777PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
7878{
7979 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;
87 
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, because
94  // 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)
 80 Vector<StackFrame> stackTrace;
 81 exec->interpreter()->getStackTrace(stackTrace);
 82 Vector<StackFrame>::const_iterator iter = stackTrace.begin();
 83 iter++;
 84 for (; iter < stackTrace.end(); iter++) {
 85 frames.append(ScriptCallFrame(iter->friendlyFunctionName(exec), iter->friendlySourceURL(), iter->friendlyLineNumber()));
 86 if (frames.size() >= maxStackSize)
10187 break;
102  callFrame = callFrame->callerFrame();
10388 }
10489 return ScriptCallStack::create(frames);
10590}
150679