OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 7390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7401 static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller, | 7401 static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller, |
7402 bool* seen_caller) { | 7402 bool* seen_caller) { |
7403 // Only display JS frames. | 7403 // Only display JS frames. |
7404 if (!raw_frame->is_java_script()) | 7404 if (!raw_frame->is_java_script()) |
7405 return false; | 7405 return false; |
7406 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 7406 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
7407 Object* raw_fun = frame->function(); | 7407 Object* raw_fun = frame->function(); |
7408 // Not sure when this can happen but skip it just in case. | 7408 // Not sure when this can happen but skip it just in case. |
7409 if (!raw_fun->IsJSFunction()) | 7409 if (!raw_fun->IsJSFunction()) |
7410 return false; | 7410 return false; |
7411 if ((raw_fun == caller) && !(*seen_caller) && frame->IsConstructor()) { | 7411 if ((raw_fun == caller) && !(*seen_caller)) { |
7412 *seen_caller = true; | 7412 *seen_caller = true; |
7413 return false; | 7413 return false; |
7414 } | 7414 } |
7415 // Skip the most obvious builtin calls. Some builtin calls (such as | 7415 // Skip all frames until we've seen the caller. Also, skip the most |
7416 // Number.ADD which is invoked using 'call') are very difficult to | 7416 // obvious builtin calls. Some builtin calls (such as Number.ADD |
7417 // recognize so we're leaving them in for now. | 7417 // which is invoked using 'call') are very difficult to recognize |
7418 return !frame->receiver()->IsJSBuiltinsObject(); | 7418 // so we're leaving them in for now. |
| 7419 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); |
7419 } | 7420 } |
7420 | 7421 |
7421 | 7422 |
7422 // Collect the raw data for a stack trace. Returns an array of three | 7423 // Collect the raw data for a stack trace. Returns an array of three |
7423 // element segments each containing a receiver, function and native | 7424 // element segments each containing a receiver, function and native |
7424 // code offset. | 7425 // code offset. |
7425 static Object* Runtime_CollectStackTrace(Arguments args) { | 7426 static Object* Runtime_CollectStackTrace(Arguments args) { |
7426 ASSERT_EQ(args.length(), 2); | 7427 ASSERT_EQ(args.length(), 2); |
7427 Object* caller = args[0]; | 7428 Object* caller = args[0]; |
7428 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); | 7429 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); |
7429 | 7430 |
7430 HandleScope scope; | 7431 HandleScope scope; |
7431 | 7432 |
7432 int initial_size = limit < 10 ? limit : 10; | 7433 int initial_size = limit < 10 ? limit : 10; |
7433 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); | 7434 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); |
7434 | 7435 |
7435 StackFrameIterator iter; | 7436 StackFrameIterator iter; |
7436 bool seen_caller = false; | 7437 // If the caller parameter is a function we skip frames until we're |
| 7438 // under it before starting to collect. |
| 7439 bool seen_caller = !caller->IsJSFunction(); |
7437 int cursor = 0; | 7440 int cursor = 0; |
7438 int frames_seen = 0; | 7441 int frames_seen = 0; |
7439 while (!iter.done() && frames_seen < limit) { | 7442 while (!iter.done() && frames_seen < limit) { |
7440 StackFrame* raw_frame = iter.frame(); | 7443 StackFrame* raw_frame = iter.frame(); |
7441 if (ShowFrameInStackTrace(raw_frame, caller, &seen_caller)) { | 7444 if (ShowFrameInStackTrace(raw_frame, caller, &seen_caller)) { |
7442 frames_seen++; | 7445 frames_seen++; |
7443 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 7446 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
7444 Object* recv = frame->receiver(); | 7447 Object* recv = frame->receiver(); |
7445 Object* fun = frame->function(); | 7448 Object* fun = frame->function(); |
7446 Address pc = frame->pc(); | 7449 Address pc = frame->pc(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7559 } else { | 7562 } else { |
7560 // Handle last resort GC and make sure to allow future allocations | 7563 // Handle last resort GC and make sure to allow future allocations |
7561 // to grow the heap without causing GCs (if possible). | 7564 // to grow the heap without causing GCs (if possible). |
7562 Counters::gc_last_resort_from_js.Increment(); | 7565 Counters::gc_last_resort_from_js.Increment(); |
7563 Heap::CollectAllGarbage(); | 7566 Heap::CollectAllGarbage(); |
7564 } | 7567 } |
7565 } | 7568 } |
7566 | 7569 |
7567 | 7570 |
7568 } } // namespace v8::internal | 7571 } } // namespace v8::internal |
OLD | NEW |