OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/debug/debug-frames.h" | 5 #include "src/debug/debug-frames.h" |
6 | 6 |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
| 8 #include "src/wasm/wasm-module.h" |
8 | 9 |
9 namespace v8 { | 10 namespace v8 { |
10 namespace internal { | 11 namespace internal { |
11 | 12 |
12 FrameInspector::FrameInspector(StandardFrame* frame, int inlined_jsframe_index, | 13 FrameInspector::FrameInspector(StandardFrame* frame, int inlined_frame_index, |
13 Isolate* isolate) | 14 Isolate* isolate) |
14 : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) { | 15 : frame_(frame), isolate_(isolate) { |
15 JavaScriptFrame* js_frame = | 16 JavaScriptFrame* js_frame = |
16 frame->is_java_script() ? javascript_frame() : nullptr; | 17 frame->is_java_script() ? javascript_frame() : nullptr; |
17 DCHECK(js_frame || frame->is_wasm()); | 18 DCHECK(js_frame || frame->is_wasm()); |
18 has_adapted_arguments_ = js_frame && js_frame->has_adapted_arguments(); | 19 has_adapted_arguments_ = js_frame && js_frame->has_adapted_arguments(); |
19 is_bottommost_ = inlined_jsframe_index == 0; | 20 is_bottommost_ = inlined_frame_index == 0; |
20 is_optimized_ = frame_->is_optimized(); | |
21 is_interpreted_ = frame_->is_interpreted(); | 21 is_interpreted_ = frame_->is_interpreted(); |
22 // Calculate the deoptimized frame. | 22 // Calculate the deoptimized frame. |
23 if (frame->is_optimized()) { | 23 if (frame->is_optimized()) { |
24 DCHECK(js_frame != nullptr); | 24 DCHECK(js_frame != nullptr); |
25 // TODO(turbofan): Revisit once we support deoptimization. | 25 // TODO(turbofan): Revisit once we support deoptimization. |
26 if (js_frame->LookupCode()->is_turbofanned() && | 26 if (js_frame->LookupCode()->is_turbofanned() && |
27 js_frame->function()->shared()->asm_function() && | 27 js_frame->function()->shared()->asm_function() && |
28 !FLAG_turbo_asm_deoptimization) { | 28 !FLAG_turbo_asm_deoptimization) { |
29 is_optimized_ = false; | |
30 return; | 29 return; |
31 } | 30 } |
32 | 31 |
33 deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame( | 32 deoptimized_frame_.reset(Deoptimizer::DebuggerInspectableFrame( |
34 js_frame, inlined_jsframe_index, isolate); | 33 js_frame, inlined_frame_index, isolate)); |
35 } | 34 } else if (frame->is_wasm_interpreted()) { |
36 } | 35 // Get wasm interpreted frame information. |
37 | 36 Handle<JSObject> wasm(JSObject::cast(WasmFrame::cast(frame)->wasm_obj()), |
38 | 37 isolate); |
39 FrameInspector::~FrameInspector() { | 38 wasm::InterpreterFrameIterator frame_it = |
40 // Get rid of the calculated deoptimized frame if any. | 39 wasm::GetDebugInfo(wasm)->GetInterpreterFrameIterator(); |
41 if (deoptimized_frame_ != NULL) { | 40 for (int count = inlined_frame_index; count > 0; --count) frame_it.Next(); |
42 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_); | 41 DCHECK(!frame_it.Done()); |
| 42 wasm_interpreted_frame_.reset( |
| 43 new wasm::InterpreterFrameInfo(frame_it.GetFrameInfo())); |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 | 47 |
47 int FrameInspector::GetParametersCount() { | 48 int FrameInspector::GetParametersCount() { |
48 return is_optimized_ ? deoptimized_frame_->parameters_count() | 49 return deoptimized_frame_ ? deoptimized_frame_->parameters_count() |
49 : frame_->ComputeParametersCount(); | 50 : frame_->ComputeParametersCount(); |
50 } | 51 } |
51 | 52 |
52 Handle<Script> FrameInspector::GetScript() { | 53 Handle<Script> FrameInspector::GetScript() { |
53 Object* script = is_optimized_ | 54 Object* script = deoptimized_frame_ |
54 ? deoptimized_frame_->GetFunction()->shared()->script() | 55 ? deoptimized_frame_->GetFunction()->shared()->script() |
55 : frame_->script(); | 56 : wasm_interpreted_frame_ |
| 57 ? wasm_interpreted_frame_->GetScript() |
| 58 : frame_->script(); |
56 return handle(Script::cast(script), isolate_); | 59 return handle(Script::cast(script), isolate_); |
57 } | 60 } |
58 | 61 |
| 62 bool FrameInspector::HasFunction() { |
| 63 return frame_->is_java_script() || frame_->is_arguments_adaptor(); |
| 64 } |
| 65 |
59 Handle<JSFunction> FrameInspector::GetFunction() { | 66 Handle<JSFunction> FrameInspector::GetFunction() { |
60 DCHECK(!frame_->is_wasm()); | 67 DCHECK(HasFunction()); |
61 return is_optimized_ ? deoptimized_frame_->GetFunction() | 68 return deoptimized_frame_ ? deoptimized_frame_->GetFunction() |
62 : handle(javascript_frame()->function(), isolate_); | 69 : handle(javascript_frame()->function(), isolate_); |
| 70 } |
| 71 |
| 72 Handle<String> FrameInspector::GetFunctionName() { |
| 73 if (!frame_->is_wasm()) return JSFunction::GetDebugName(GetFunction()); |
| 74 Handle<JSObject> wasm_obj(JSObject::cast(WasmFrame::cast(frame_)->wasm_obj()), |
| 75 isolate_); |
| 76 int func_index = wasm_interpreted_frame_ |
| 77 ? wasm_interpreted_frame_->func_index() |
| 78 : WasmCompiledFrame::cast(frame_)->function_index(); |
| 79 return wasm::GetWasmFunctionName(isolate_, wasm_obj, func_index); |
63 } | 80 } |
64 | 81 |
65 Handle<Object> FrameInspector::GetParameter(int index) { | 82 Handle<Object> FrameInspector::GetParameter(int index) { |
66 return is_optimized_ ? deoptimized_frame_->GetParameter(index) | 83 return deoptimized_frame_ ? deoptimized_frame_->GetParameter(index) |
67 : handle(frame_->GetParameter(index), isolate_); | 84 : handle(frame_->GetParameter(index), isolate_); |
68 } | 85 } |
69 | 86 |
70 Handle<Object> FrameInspector::GetExpression(int index) { | 87 Handle<Object> FrameInspector::GetExpression(int index) { |
71 // TODO(turbofan): Revisit once we support deoptimization. | 88 // TODO(turbofan): Revisit once we support deoptimization. |
72 if (frame_->is_java_script() && | 89 if (frame_->is_java_script() && |
73 javascript_frame()->LookupCode()->is_turbofanned() && | 90 javascript_frame()->LookupCode()->is_turbofanned() && |
74 javascript_frame()->function()->shared()->asm_function() && | 91 javascript_frame()->function()->shared()->asm_function() && |
75 !FLAG_turbo_asm_deoptimization) { | 92 !FLAG_turbo_asm_deoptimization) { |
76 return isolate_->factory()->undefined_value(); | 93 return isolate_->factory()->undefined_value(); |
77 } | 94 } |
78 return is_optimized_ ? deoptimized_frame_->GetExpression(index) | 95 return deoptimized_frame_ ? deoptimized_frame_->GetExpression(index) |
79 : handle(frame_->GetExpression(index), isolate_); | 96 : handle(frame_->GetExpression(index), isolate_); |
80 } | 97 } |
81 | 98 |
82 | 99 |
83 int FrameInspector::GetSourcePosition() { | 100 int FrameInspector::GetSourcePosition() { |
84 if (is_optimized_) { | 101 if (deoptimized_frame_) return deoptimized_frame_->GetSourcePosition(); |
85 return deoptimized_frame_->GetSourcePosition(); | 102 if (wasm_interpreted_frame_) return wasm_interpreted_frame_->pc_offset(); |
86 } else if (is_interpreted_) { | 103 if (is_interpreted_) { |
87 InterpretedFrame* frame = reinterpret_cast<InterpretedFrame*>(frame_); | 104 InterpretedFrame* frame = reinterpret_cast<InterpretedFrame*>(frame_); |
88 BytecodeArray* bytecode_array = frame->GetBytecodeArray(); | 105 BytecodeArray* bytecode_array = frame->GetBytecodeArray(); |
89 return bytecode_array->SourcePosition(frame->GetBytecodeOffset()); | 106 return bytecode_array->SourcePosition(frame->GetBytecodeOffset()); |
90 } else { | |
91 Code* code = frame_->LookupCode(); | |
92 int offset = static_cast<int>(frame_->pc() - code->instruction_start()); | |
93 return code->SourcePosition(offset); | |
94 } | 107 } |
| 108 Code* code = frame_->LookupCode(); |
| 109 int offset = static_cast<int>(frame_->pc() - code->instruction_start()); |
| 110 return code->SourcePosition(offset); |
95 } | 111 } |
96 | 112 |
97 | 113 |
98 bool FrameInspector::IsConstructor() { | 114 bool FrameInspector::IsConstructor() { |
99 return is_optimized_ && !is_bottommost_ | 115 return deoptimized_frame_ && !is_bottommost_ |
100 ? deoptimized_frame_->HasConstructStub() | 116 ? deoptimized_frame_->HasConstructStub() |
101 : frame_->IsConstructor(); | 117 : frame_->IsConstructor(); |
102 } | 118 } |
103 | 119 |
104 Handle<Object> FrameInspector::GetContext() { | 120 Handle<Object> FrameInspector::GetContext() { |
105 return is_optimized_ ? deoptimized_frame_->GetContext() | 121 return deoptimized_frame_ ? deoptimized_frame_->GetContext() |
106 : handle(frame_->context(), isolate_); | 122 : handle(frame_->context(), isolate_); |
107 } | 123 } |
108 | 124 |
109 | 125 |
110 // To inspect all the provided arguments the frame might need to be | 126 // To inspect all the provided arguments the frame might need to be |
111 // replaced with the arguments frame. | 127 // replaced with the arguments frame. |
112 void FrameInspector::SetArgumentsFrame(StandardFrame* frame) { | 128 void FrameInspector::SetArgumentsFrame(StandardFrame* frame) { |
113 DCHECK(has_adapted_arguments_); | 129 DCHECK(has_adapted_arguments_); |
114 DCHECK(frame->is_arguments_adaptor()); | 130 DCHECK(frame->is_arguments_adaptor()); |
115 frame_ = frame; | 131 frame_ = frame; |
116 is_optimized_ = frame_->is_optimized(); | 132 DCHECK(!frame_->is_optimized()); |
| 133 deoptimized_frame_ = nullptr; |
117 is_interpreted_ = frame_->is_interpreted(); | 134 is_interpreted_ = frame_->is_interpreted(); |
118 DCHECK(!is_optimized_); | |
119 } | 135 } |
120 | 136 |
121 | 137 |
122 // Create a plain JSObject which materializes the local scope for the specified | 138 // Create a plain JSObject which materializes the local scope for the specified |
123 // frame. | 139 // frame. |
124 void FrameInspector::MaterializeStackLocals(Handle<JSObject> target, | 140 void FrameInspector::MaterializeStackLocals(Handle<JSObject> target, |
125 Handle<ScopeInfo> scope_info) { | 141 Handle<ScopeInfo> scope_info) { |
126 HandleScope scope(isolate_); | 142 HandleScope scope(isolate_); |
127 // First fill all parameters. | 143 // First fill all parameters. |
128 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 144 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 Handle<JSFunction> function) { | 180 Handle<JSFunction> function) { |
165 Handle<SharedFunctionInfo> shared(function->shared()); | 181 Handle<SharedFunctionInfo> shared(function->shared()); |
166 Handle<ScopeInfo> scope_info(shared->scope_info()); | 182 Handle<ScopeInfo> scope_info(shared->scope_info()); |
167 MaterializeStackLocals(target, scope_info); | 183 MaterializeStackLocals(target, scope_info); |
168 } | 184 } |
169 | 185 |
170 | 186 |
171 void FrameInspector::UpdateStackLocalsFromMaterializedObject( | 187 void FrameInspector::UpdateStackLocalsFromMaterializedObject( |
172 Handle<JSObject> target, Handle<ScopeInfo> scope_info) { | 188 Handle<JSObject> target, Handle<ScopeInfo> scope_info) { |
173 // Optimized frames and wasm frames are not supported. Simply give up. | 189 // Optimized frames and wasm frames are not supported. Simply give up. |
174 if (is_optimized_ || frame_->is_wasm()) return; | 190 if (deoptimized_frame_ || frame_->is_wasm()) return; |
175 | 191 |
176 HandleScope scope(isolate_); | 192 HandleScope scope(isolate_); |
177 | 193 |
178 // Parameters. | 194 // Parameters. |
179 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 195 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
180 // Shadowed parameters were not materialized. | 196 // Shadowed parameters were not materialized. |
181 Handle<String> name(scope_info->ParameterName(i)); | 197 Handle<String> name(scope_info->ParameterName(i)); |
182 if (ScopeInfo::VariableIsSynthetic(*name)) continue; | 198 if (ScopeInfo::VariableIsSynthetic(*name)) continue; |
183 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue; | 199 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue; |
184 | 200 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 save = save->prev(); | 233 save = save->prev(); |
218 } | 234 } |
219 DCHECK(save != NULL); | 235 DCHECK(save != NULL); |
220 return save; | 236 return save; |
221 } | 237 } |
222 | 238 |
223 int DebugFrameHelper::FindIndexedNonNativeFrame(StackTraceFrameIterator* it, | 239 int DebugFrameHelper::FindIndexedNonNativeFrame(StackTraceFrameIterator* it, |
224 int index) { | 240 int index) { |
225 int count = -1; | 241 int count = -1; |
226 for (; !it->done(); it->Advance()) { | 242 for (; !it->done(); it->Advance()) { |
227 if (it->is_wasm()) { | |
228 if (++count == index) return 0; | |
229 continue; | |
230 } | |
231 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 243 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
232 it->javascript_frame()->Summarize(&frames); | 244 it->frame()->Summarize(&frames); |
233 for (int i = frames.length() - 1; i >= 0; i--) { | 245 for (int i = frames.length() - 1; i >= 0; i--) { |
234 // Omit functions from native and extension scripts. | 246 // Omit functions from native and extension scripts. |
235 if (!frames[i].function()->shared()->IsSubjectToDebugging()) continue; | 247 if (!frames[i].is_subject_to_debugging()) continue; |
236 if (++count == index) return i; | 248 if (++count == index) return i; |
237 } | 249 } |
238 } | 250 } |
239 return -1; | 251 return -1; |
240 } | 252 } |
241 | 253 |
242 | 254 |
243 } // namespace internal | 255 } // namespace internal |
244 } // namespace v8 | 256 } // namespace v8 |
OLD | NEW |