Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index fb40d5e73e3c3dd85b15165c88487f6d893cbd5f..add954138d2ded3ca4ebe4fc7664431a8a5e8329 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -12876,47 +12876,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) { |
} |
-// Determines whether the given stack frame should be displayed in |
-// a stack trace. The caller is the error constructor that asked |
-// for the stack trace to be collected. The first time a construct |
-// call to this function is encountered it is skipped. The seen_caller |
-// in/out parameter is used to remember if the caller has been seen |
-// yet. |
-static bool ShowFrameInStackTrace(StackFrame* raw_frame, |
- Object* caller, |
- bool* seen_caller) { |
- // Only display JS frames. |
- if (!raw_frame->is_java_script()) { |
- return false; |
- } |
- JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
- Object* raw_fun = frame->function(); |
- // Not sure when this can happen but skip it just in case. |
- if (!raw_fun->IsJSFunction()) { |
- return false; |
- } |
- if ((raw_fun == caller) && !(*seen_caller)) { |
- *seen_caller = true; |
- return false; |
- } |
- // Skip all frames until we've seen the caller. |
- if (!(*seen_caller)) return false; |
- // Also, skip non-visible built-in functions and any call with the builtins |
- // object as receiver, so as to not reveal either the builtins object or |
- // an internal function. |
- // The --builtins-in-stack-traces command line flag allows including |
- // internal call sites in the stack trace for debugging purposes. |
- if (!FLAG_builtins_in_stack_traces) { |
- JSFunction* fun = JSFunction::cast(raw_fun); |
- if (frame->receiver()->IsJSBuiltinsObject() || |
- (fun->IsBuiltin() && !fun->shared()->native())) { |
- return false; |
- } |
- } |
- return true; |
-} |
- |
- |
// Collect the raw data for a stack trace. Returns an array of 4 |
// element segments each containing a receiver, function, code and |
// native code offset. |
@@ -12927,57 +12886,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) { |
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); |
HandleScope scope(isolate); |
- Factory* factory = isolate->factory(); |
+ // Optionally capture a more detailed stack trace for the message. |
+ isolate->CaptureAndSetDetailedStackTrace(error_object); |
+ // Capture a simple stack trace for the stack property. |
+ return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); |
+} |
- limit = Max(limit, 0); // Ensure that limit is not negative. |
- int initial_size = Min(limit, 10); |
- Handle<FixedArray> elements = |
- factory->NewFixedArrayWithHoles(initial_size * 4); |
- StackFrameIterator iter(isolate); |
- // If the caller parameter is a function we skip frames until we're |
- // under it before starting to collect. |
- bool seen_caller = !caller->IsJSFunction(); |
- int cursor = 0; |
- int frames_seen = 0; |
- while (!iter.done() && frames_seen < limit) { |
- StackFrame* raw_frame = iter.frame(); |
- if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { |
- frames_seen++; |
- JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
- // Set initial size to the maximum inlining level + 1 for the outermost |
- // function. |
- List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1); |
- frame->Summarize(&frames); |
- for (int i = frames.length() - 1; i >= 0; i--) { |
- if (cursor + 4 > elements->length()) { |
- int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
- Handle<FixedArray> new_elements = |
- factory->NewFixedArrayWithHoles(new_capacity); |
- for (int i = 0; i < cursor; i++) { |
- new_elements->set(i, elements->get(i)); |
- } |
- elements = new_elements; |
- } |
- ASSERT(cursor + 4 <= elements->length()); |
- |
- Handle<Object> recv = frames[i].receiver(); |
- Handle<JSFunction> fun = frames[i].function(); |
- Handle<Code> code = frames[i].code(); |
- Handle<Smi> offset(Smi::FromInt(frames[i].offset())); |
- elements->set(cursor++, *recv); |
- elements->set(cursor++, *fun); |
- elements->set(cursor++, *code); |
- elements->set(cursor++, *offset); |
- } |
- } |
- iter.Advance(); |
- } |
- Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
- // Capture and attach a more detailed stack trace if necessary. |
- isolate->CaptureAndSetCurrentStackTraceFor(error_object); |
- result->set_length(Smi::FromInt(cursor)); |
- return *result; |
+// Retrieve the raw stack trace collected on stack overflow and delete |
+// it since it is used only once to avoid keeping it alive. |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedRawStackTrace) { |
+ ASSERT_EQ(args.length(), 1); |
+ CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
+ String* key = isolate->heap()->hidden_stack_trace_symbol(); |
+ Object* result = error_object->GetHiddenProperty(key); |
+ RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined()); |
+ error_object->DeleteHiddenProperty(key); |
+ return result; |
} |