OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 11030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11041 | 11041 |
11042 // Count all frames which are relevant to debugging stack trace. | 11042 // Count all frames which are relevant to debugging stack trace. |
11043 int n = 0; | 11043 int n = 0; |
11044 StackFrame::Id id = isolate->debug()->break_frame_id(); | 11044 StackFrame::Id id = isolate->debug()->break_frame_id(); |
11045 if (id == StackFrame::NO_ID) { | 11045 if (id == StackFrame::NO_ID) { |
11046 // If there is no JavaScript stack frame count is 0. | 11046 // If there is no JavaScript stack frame count is 0. |
11047 return Smi::FromInt(0); | 11047 return Smi::FromInt(0); |
11048 } | 11048 } |
11049 | 11049 |
11050 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) { | 11050 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) { |
11051 n += it.frame()->GetInlineCount(); | 11051 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 11052 it.frame()->Summarize(&frames); |
| 11053 for (int i = frames.length() - 1; i >= 0; i--) { |
| 11054 // Omit functions from native scripts. |
| 11055 if (!frames[i].function()->IsFromNativeScript()) n++; |
| 11056 } |
11052 } | 11057 } |
11053 return Smi::FromInt(n); | 11058 return Smi::FromInt(n); |
11054 } | 11059 } |
11055 | 11060 |
11056 | 11061 |
11057 class FrameInspector { | 11062 class FrameInspector { |
11058 public: | 11063 public: |
11059 FrameInspector(JavaScriptFrame* frame, | 11064 FrameInspector(JavaScriptFrame* frame, |
11060 int inlined_jsframe_index, | 11065 int inlined_jsframe_index, |
11061 Isolate* isolate) | 11066 Isolate* isolate) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11156 | 11161 |
11157 RUNTIME_FUNCTION(Runtime_IsOptimized) { | 11162 RUNTIME_FUNCTION(Runtime_IsOptimized) { |
11158 SealHandleScope shs(isolate); | 11163 SealHandleScope shs(isolate); |
11159 DCHECK(args.length() == 0); | 11164 DCHECK(args.length() == 0); |
11160 JavaScriptFrameIterator it(isolate); | 11165 JavaScriptFrameIterator it(isolate); |
11161 JavaScriptFrame* frame = it.frame(); | 11166 JavaScriptFrame* frame = it.frame(); |
11162 return isolate->heap()->ToBoolean(frame->is_optimized()); | 11167 return isolate->heap()->ToBoolean(frame->is_optimized()); |
11163 } | 11168 } |
11164 | 11169 |
11165 | 11170 |
| 11171 // Advances the iterator to the frame that matches the index and returns the |
| 11172 // inlined frame index, or -1 if not found. Skips native JS functions. |
| 11173 static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) { |
| 11174 int count = -1; |
| 11175 for (; !it->done(); it->Advance()) { |
| 11176 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 11177 it->frame()->Summarize(&frames); |
| 11178 for (int i = frames.length() - 1; i >= 0; i--) { |
| 11179 // Omit functions from native scripts. |
| 11180 if (frames[i].function()->IsFromNativeScript()) continue; |
| 11181 if (++count == index) return i; |
| 11182 } |
| 11183 } |
| 11184 return -1; |
| 11185 } |
| 11186 |
| 11187 |
11166 // Return an array with frame details | 11188 // Return an array with frame details |
11167 // args[0]: number: break id | 11189 // args[0]: number: break id |
11168 // args[1]: number: frame index | 11190 // args[1]: number: frame index |
11169 // | 11191 // |
11170 // The array returned contains the following information: | 11192 // The array returned contains the following information: |
11171 // 0: Frame id | 11193 // 0: Frame id |
11172 // 1: Receiver | 11194 // 1: Receiver |
11173 // 2: Function | 11195 // 2: Function |
11174 // 3: Argument count | 11196 // 3: Argument count |
11175 // 4: Local count | 11197 // 4: Local count |
(...skipping 13 matching lines...) Expand all Loading... |
11189 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 11211 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
11190 Heap* heap = isolate->heap(); | 11212 Heap* heap = isolate->heap(); |
11191 | 11213 |
11192 // Find the relevant frame with the requested index. | 11214 // Find the relevant frame with the requested index. |
11193 StackFrame::Id id = isolate->debug()->break_frame_id(); | 11215 StackFrame::Id id = isolate->debug()->break_frame_id(); |
11194 if (id == StackFrame::NO_ID) { | 11216 if (id == StackFrame::NO_ID) { |
11195 // If there are no JavaScript stack frames return undefined. | 11217 // If there are no JavaScript stack frames return undefined. |
11196 return heap->undefined_value(); | 11218 return heap->undefined_value(); |
11197 } | 11219 } |
11198 | 11220 |
11199 int count = 0; | |
11200 JavaScriptFrameIterator it(isolate, id); | 11221 JavaScriptFrameIterator it(isolate, id); |
11201 for (; !it.done(); it.Advance()) { | 11222 // Inlined frame index in optimized frame, starting from outer function. |
11202 if (index < count + it.frame()->GetInlineCount()) break; | 11223 int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index); |
11203 count += it.frame()->GetInlineCount(); | 11224 if (inlined_jsframe_index == -1) return heap->undefined_value(); |
11204 } | |
11205 if (it.done()) return heap->undefined_value(); | |
11206 | 11225 |
| 11226 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); |
11207 bool is_optimized = it.frame()->is_optimized(); | 11227 bool is_optimized = it.frame()->is_optimized(); |
11208 | 11228 |
11209 int inlined_jsframe_index = 0; // Inlined frame index in optimized frame. | |
11210 if (is_optimized) { | |
11211 inlined_jsframe_index = | |
11212 it.frame()->GetInlineCount() - (index - count) - 1; | |
11213 } | |
11214 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); | |
11215 | |
11216 // Traverse the saved contexts chain to find the active context for the | 11229 // Traverse the saved contexts chain to find the active context for the |
11217 // selected frame. | 11230 // selected frame. |
11218 SaveContext* save = FindSavedContextForFrame(isolate, it.frame()); | 11231 SaveContext* save = FindSavedContextForFrame(isolate, it.frame()); |
11219 | 11232 |
11220 // Get the frame id. | 11233 // Get the frame id. |
11221 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); | 11234 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); |
11222 | 11235 |
11223 // Find source position in unoptimized code. | 11236 // Find source position in unoptimized code. |
11224 int position = frame_inspector.GetSourcePosition(); | 11237 int position = frame_inspector.GetSourcePosition(); |
11225 | 11238 |
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13578 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 13591 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
13579 Heap* heap = isolate->heap(); | 13592 Heap* heap = isolate->heap(); |
13580 | 13593 |
13581 // Find the relevant frame with the requested index. | 13594 // Find the relevant frame with the requested index. |
13582 StackFrame::Id id = isolate->debug()->break_frame_id(); | 13595 StackFrame::Id id = isolate->debug()->break_frame_id(); |
13583 if (id == StackFrame::NO_ID) { | 13596 if (id == StackFrame::NO_ID) { |
13584 // If there are no JavaScript stack frames return undefined. | 13597 // If there are no JavaScript stack frames return undefined. |
13585 return heap->undefined_value(); | 13598 return heap->undefined_value(); |
13586 } | 13599 } |
13587 | 13600 |
13588 int count = 0; | |
13589 JavaScriptFrameIterator it(isolate, id); | 13601 JavaScriptFrameIterator it(isolate, id); |
13590 for (; !it.done(); it.Advance()) { | 13602 int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index); |
13591 if (index < count + it.frame()->GetInlineCount()) break; | 13603 if (inlined_jsframe_index == -1) return heap->undefined_value(); |
13592 count += it.frame()->GetInlineCount(); | 13604 // We don't really care what the inlined frame index is, since we are |
13593 } | 13605 // throwing away the entire frame anyways. |
13594 if (it.done()) return heap->undefined_value(); | |
13595 | |
13596 const char* error_message = LiveEdit::RestartFrame(it.frame()); | 13606 const char* error_message = LiveEdit::RestartFrame(it.frame()); |
13597 if (error_message) { | 13607 if (error_message) { |
13598 return *(isolate->factory()->InternalizeUtf8String(error_message)); | 13608 return *(isolate->factory()->InternalizeUtf8String(error_message)); |
13599 } | 13609 } |
13600 return heap->true_value(); | 13610 return heap->true_value(); |
13601 } | 13611 } |
13602 | 13612 |
13603 | 13613 |
13604 // A testing entry. Returns statement position which is the closest to | 13614 // A testing entry. Returns statement position which is the closest to |
13605 // source_position. | 13615 // source_position. |
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15570 } | 15580 } |
15571 return NULL; | 15581 return NULL; |
15572 } | 15582 } |
15573 | 15583 |
15574 | 15584 |
15575 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15585 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15576 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15586 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15577 } | 15587 } |
15578 | 15588 |
15579 } } // namespace v8::internal | 15589 } } // namespace v8::internal |
OLD | NEW |