Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: src/frames.cc

Issue 2069823003: [wasm] Enable wasm frame inspection for debugging (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@split-wasm-debug
Patch Set: address yang's comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "src/frames.h" 5 #include "src/frames.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/ast/ast.h" 9 #include "src/ast/ast.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
11 #include "src/base/bits.h" 11 #include "src/base/bits.h"
12 #include "src/deoptimizer.h" 12 #include "src/deoptimizer.h"
13 #include "src/frames-inl.h" 13 #include "src/frames-inl.h"
14 #include "src/full-codegen/full-codegen.h" 14 #include "src/full-codegen/full-codegen.h"
15 #include "src/register-configuration.h" 15 #include "src/register-configuration.h"
16 #include "src/safepoint-table.h" 16 #include "src/safepoint-table.h"
17 #include "src/string-stream.h" 17 #include "src/string-stream.h"
18 #include "src/vm-state-inl.h" 18 #include "src/vm-state-inl.h"
19 #include "src/wasm/wasm-debug.h"
20 #include "src/wasm/wasm-module.h"
19 21
20 namespace v8 { 22 namespace v8 {
21 namespace internal { 23 namespace internal {
22 24
23 ReturnAddressLocationResolver 25 ReturnAddressLocationResolver
24 StackFrame::return_address_location_resolver_ = NULL; 26 StackFrame::return_address_location_resolver_ = NULL;
25 27
26 28
27 // Iterator that supports traversing the stack handlers of a 29 // Iterator that supports traversing the stack handlers of a
28 // particular frame. Needs to know the top of the handler chain. 30 // particular frame. Needs to know the top of the handler chain.
(...skipping 27 matching lines...) Expand all
56 #define INITIALIZE_SINGLETON(type, field) field##_(this), 58 #define INITIALIZE_SINGLETON(type, field) field##_(this),
57 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate, 59 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
58 bool can_access_heap_objects) 60 bool can_access_heap_objects)
59 : isolate_(isolate), 61 : isolate_(isolate),
60 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 62 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
61 frame_(NULL), handler_(NULL), 63 frame_(NULL), handler_(NULL),
62 can_access_heap_objects_(can_access_heap_objects) { 64 can_access_heap_objects_(can_access_heap_objects) {
63 } 65 }
64 #undef INITIALIZE_SINGLETON 66 #undef INITIALIZE_SINGLETON
65 67
66
67 StackFrameIterator::StackFrameIterator(Isolate* isolate) 68 StackFrameIterator::StackFrameIterator(Isolate* isolate)
68 : StackFrameIteratorBase(isolate, true) { 69 : StackFrameIterator(isolate, isolate->thread_local_top()) {}
69 Reset(isolate->thread_local_top());
70 }
71
72 70
73 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) 71 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
74 : StackFrameIteratorBase(isolate, true) { 72 : StackFrameIteratorBase(isolate, true) {
75 Reset(t); 73 Reset(t);
76 } 74 }
77 75
78
79 void StackFrameIterator::Advance() { 76 void StackFrameIterator::Advance() {
80 DCHECK(!done()); 77 DCHECK(!done());
81 // Compute the state of the calling frame before restoring 78 // Compute the state of the calling frame before restoring
82 // callee-saved registers and unwinding handlers. This allows the 79 // callee-saved registers and unwinding handlers. This allows the
83 // frame code that computes the caller state to access the top 80 // frame code that computes the caller state to access the top
84 // handler and the value of any callee-saved register if needed. 81 // handler and the value of any callee-saved register if needed.
85 StackFrame::State state; 82 StackFrame::State state;
86 StackFrame::Type type = frame_->GetCallerState(&state); 83 StackFrame::Type type = frame_->GetCallerState(&state);
87 84
88 // Unwind handlers corresponding to the current frame. 85 // Unwind handlers corresponding to the current frame.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } 155 }
159 156
160 157
161 // ------------------------------------------------------------------------- 158 // -------------------------------------------------------------------------
162 159
163 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 160 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
164 : iterator_(isolate) { 161 : iterator_(isolate) {
165 if (!done() && !IsValidFrame(iterator_.frame())) Advance(); 162 if (!done() && !IsValidFrame(iterator_.frame())) Advance();
166 } 163 }
167 164
165 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
166 StackFrame::Id id)
167 : StackTraceFrameIterator(isolate) {
168 while (!done() && frame()->id() != id) Advance();
169 }
168 170
169 void StackTraceFrameIterator::Advance() { 171 void StackTraceFrameIterator::Advance() {
170 do { 172 do {
171 iterator_.Advance(); 173 iterator_.Advance();
172 } while (!done() && !IsValidFrame(iterator_.frame())); 174 } while (!done() && !IsValidFrame(iterator_.frame()));
173 } 175 }
174 176
175 bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const { 177 bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
176 if (frame->is_java_script()) { 178 if (frame->is_java_script()) {
177 JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame); 179 JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
178 if (!jsFrame->function()->IsJSFunction()) return false; 180 if (!jsFrame->function()->IsJSFunction()) return false;
179 Object* script = jsFrame->function()->shared()->script(); 181 Object* script = jsFrame->function()->shared()->script();
180 // Don't show functions from native scripts to user. 182 // Don't show functions from native scripts to user.
181 return (script->IsScript() && 183 return (script->IsScript() &&
182 Script::TYPE_NATIVE != Script::cast(script)->type()); 184 Script::TYPE_NATIVE != Script::cast(script)->type());
183 } 185 }
184 // apart from javascript, only wasm is valid 186 // apart from javascript, only wasm is valid
185 return frame->is_wasm(); 187 return frame->is_wasm();
186 } 188 }
187 189
190 void StackTraceFrameIterator::AdvanceToArgumentsFrame() {
191 if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return;
192 iterator_.Advance();
193 DCHECK(iterator_.frame()->is_arguments_adaptor());
194 }
188 195
189 // ------------------------------------------------------------------------- 196 // -------------------------------------------------------------------------
190 197
191 198
192 SafeStackFrameIterator::SafeStackFrameIterator( 199 SafeStackFrameIterator::SafeStackFrameIterator(
193 Isolate* isolate, 200 Isolate* isolate,
194 Address fp, Address sp, Address js_entry_sp) 201 Address fp, Address sp, Address js_entry_sp)
195 : StackFrameIteratorBase(isolate, false), 202 : StackFrameIteratorBase(isolate, false),
196 low_bound_(sp), 203 low_bound_(sp),
197 high_bound_(js_entry_sp), 204 high_bound_(js_entry_sp),
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 Address StandardFrame::GetExpressionAddress(int n) const { 631 Address StandardFrame::GetExpressionAddress(int n) const {
625 const int offset = StandardFrameConstants::kExpressionsOffset; 632 const int offset = StandardFrameConstants::kExpressionsOffset;
626 return fp() + offset - n * kPointerSize; 633 return fp() + offset - n * kPointerSize;
627 } 634 }
628 635
629 Address InterpretedFrame::GetExpressionAddress(int n) const { 636 Address InterpretedFrame::GetExpressionAddress(int n) const {
630 const int offset = InterpreterFrameConstants::kExpressionsOffset; 637 const int offset = InterpreterFrameConstants::kExpressionsOffset;
631 return fp() + offset - n * kPointerSize; 638 return fp() + offset - n * kPointerSize;
632 } 639 }
633 640
641 Script* StandardFrame::script() const {
642 // This should only be called on frames which override this method.
643 DCHECK(false);
644 return nullptr;
645 }
646
647 Object* StandardFrame::context() const {
648 return isolate()->heap()->undefined_value();
649 }
650
634 int StandardFrame::ComputeExpressionsCount() const { 651 int StandardFrame::ComputeExpressionsCount() const {
635 Address base = GetExpressionAddress(0); 652 Address base = GetExpressionAddress(0);
636 Address limit = sp() - kPointerSize; 653 Address limit = sp() - kPointerSize;
637 DCHECK(base >= limit); // stack grows downwards 654 DCHECK(base >= limit); // stack grows downwards
638 // Include register-allocated locals in number of expressions. 655 // Include register-allocated locals in number of expressions.
639 return static_cast<int>((base - limit) / kPointerSize); 656 return static_cast<int>((base - limit) / kPointerSize);
640 } 657 }
641 658
659 Object* StandardFrame::GetParameter(int index) const {
660 // StandardFrame does not define any parameters.
661 UNREACHABLE();
662 return nullptr;
663 }
664
665 int StandardFrame::ComputeParametersCount() const { return 0; }
642 666
643 void StandardFrame::ComputeCallerState(State* state) const { 667 void StandardFrame::ComputeCallerState(State* state) const {
644 state->sp = caller_sp(); 668 state->sp = caller_sp();
645 state->fp = caller_fp(); 669 state->fp = caller_fp();
646 state->pc_address = ResolveReturnAddressLocation( 670 state->pc_address = ResolveReturnAddressLocation(
647 reinterpret_cast<Address*>(ComputePCAddress(fp()))); 671 reinterpret_cast<Address*>(ComputePCAddress(fp())));
648 state->constant_pool_address = 672 state->constant_pool_address =
649 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); 673 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
650 } 674 }
651 675
652 676
653 void StandardFrame::SetCallerFp(Address caller_fp) { 677 void StandardFrame::SetCallerFp(Address caller_fp) {
654 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 678 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
655 caller_fp; 679 caller_fp;
656 } 680 }
657 681
682 bool StandardFrame::IsConstructor() const { return false; }
658 683
659 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 684 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
660 // Make sure that we're not doing "safe" stack frame iteration. We cannot 685 // Make sure that we're not doing "safe" stack frame iteration. We cannot
661 // possibly find pointers in optimized frames in that state. 686 // possibly find pointers in optimized frames in that state.
662 DCHECK(can_access_heap_objects()); 687 DCHECK(can_access_heap_objects());
663 688
664 // Compute the safepoint information. 689 // Compute the safepoint information.
665 unsigned stack_slots = 0; 690 unsigned stack_slots = 0;
666 SafepointEntry safepoint_entry; 691 SafepointEntry safepoint_entry;
667 Code* code = StackFrame::GetSafepointData( 692 Code* code = StackFrame::GetSafepointData(
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 IsConstructor(), mode); 886 IsConstructor(), mode);
862 functions->Add(summary); 887 functions->Add(summary);
863 } 888 }
864 889
865 JSFunction* JavaScriptFrame::function() const { 890 JSFunction* JavaScriptFrame::function() const {
866 return JSFunction::cast(function_slot_object()); 891 return JSFunction::cast(function_slot_object());
867 } 892 }
868 893
869 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); } 894 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
870 895
896 Script* JavaScriptFrame::script() const {
897 return Script::cast(function()->shared()->script());
898 }
899
900 Object* JavaScriptFrame::context() const {
901 const int offset = StandardFrameConstants::kContextOffset;
902 Object* maybe_result = Memory::Object_at(fp() + offset);
903 DCHECK(!maybe_result->IsSmi());
904 return maybe_result;
905 }
906
871 int JavaScriptFrame::LookupExceptionHandlerInTable( 907 int JavaScriptFrame::LookupExceptionHandlerInTable(
872 int* stack_depth, HandlerTable::CatchPrediction* prediction) { 908 int* stack_depth, HandlerTable::CatchPrediction* prediction) {
873 Code* code = LookupCode(); 909 Code* code = LookupCode();
874 DCHECK(!code->is_optimized_code()); 910 DCHECK(!code->is_optimized_code());
875 HandlerTable* table = HandlerTable::cast(code->handler_table()); 911 HandlerTable* table = HandlerTable::cast(code->handler_table());
876 int pc_offset = static_cast<int>(pc() - code->entry()); 912 int pc_offset = static_cast<int>(pc() - code->entry());
877 return table->LookupRange(pc_offset, stack_depth, prediction); 913 return table->LookupRange(pc_offset, stack_depth, prediction);
878 } 914 }
879 915
880 916
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 976
941 977
942 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const { 978 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
943 int operands_count = store->length(); 979 int operands_count = store->length();
944 DCHECK_LE(operands_count, ComputeOperandsCount()); 980 DCHECK_LE(operands_count, ComputeOperandsCount());
945 for (int i = 0; i < operands_count; i++) { 981 for (int i = 0; i < operands_count; i++) {
946 store->set(i, GetOperand(i)); 982 store->set(i, GetOperand(i));
947 } 983 }
948 } 984 }
949 985
986 Object* JavaScriptFrame::GetParameter(int index) const {
987 return Memory::Object_at(GetParameterSlot(index));
988 }
989
990 int JavaScriptFrame::ComputeParametersCount() const {
991 return GetNumberOfIncomingArguments();
992 }
993
950 namespace { 994 namespace {
951 995
952 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) { 996 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
953 return code->is_turbofanned() && function->shared()->asm_function() && 997 return code->is_turbofanned() && function->shared()->asm_function() &&
954 !FLAG_turbo_asm_deoptimization; 998 !FLAG_turbo_asm_deoptimization;
955 } 999 }
956 1000
957 } // namespace 1001 } // namespace
958 1002
959 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, 1003 FrameSummary::FrameSummary(Object* receiver, JSFunction* function,
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 Code* WasmFrame::unchecked_code() const { 1376 Code* WasmFrame::unchecked_code() const {
1333 return static_cast<Code*>(isolate()->FindCodeObject(pc())); 1377 return static_cast<Code*>(isolate()->FindCodeObject(pc()));
1334 } 1378 }
1335 1379
1336 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } 1380 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); }
1337 1381
1338 Address WasmFrame::GetCallerStackPointer() const { 1382 Address WasmFrame::GetCallerStackPointer() const {
1339 return fp() + ExitFrameConstants::kCallerSPOffset; 1383 return fp() + ExitFrameConstants::kCallerSPOffset;
1340 } 1384 }
1341 1385
1342 Object* WasmFrame::wasm_obj() { 1386 Object* WasmFrame::wasm_obj() const {
1343 FixedArray* deopt_data = LookupCode()->deoptimization_data(); 1387 FixedArray* deopt_data = LookupCode()->deoptimization_data();
1344 DCHECK(deopt_data->length() == 2); 1388 DCHECK(deopt_data->length() == 2);
1345 return deopt_data->get(0); 1389 return deopt_data->get(0);
1346 } 1390 }
1347 1391
1348 uint32_t WasmFrame::function_index() { 1392 uint32_t WasmFrame::function_index() const {
1349 FixedArray* deopt_data = LookupCode()->deoptimization_data(); 1393 FixedArray* deopt_data = LookupCode()->deoptimization_data();
1350 DCHECK(deopt_data->length() == 2); 1394 DCHECK(deopt_data->length() == 2);
1351 Object* func_index_obj = deopt_data->get(1); 1395 return Smi::cast(deopt_data->get(1))->value();
1352 if (func_index_obj->IsUndefined(isolate())) return static_cast<uint32_t>(-1); 1396 }
1353 if (func_index_obj->IsSmi()) return Smi::cast(func_index_obj)->value(); 1397
1354 DCHECK(func_index_obj->IsHeapNumber()); 1398 Script* WasmFrame::script() const {
1355 uint32_t val = static_cast<uint32_t>(-1); 1399 JSObject* wasm = JSObject::cast(wasm_obj());
1356 func_index_obj->ToUint32(&val); 1400 int func_index = function_index();
1357 DCHECK(val != static_cast<uint32_t>(-1)); 1401 return wasm::GetDebugInfo(wasm)->GetFunctionScript(func_index);
1358 return val;
1359 } 1402 }
1360 1403
1361 namespace { 1404 namespace {
1362 1405
1363 1406
1364 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, 1407 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
1365 Code* code) { 1408 Code* code) {
1366 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1409 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1367 std::ostringstream os; 1410 std::ostringstream os;
1368 os << "--------- s o u r c e c o d e ---------\n" 1411 os << "--------- s o u r c e c o d e ---------\n"
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1831 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1789 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1832 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1790 list.Add(frame, zone); 1833 list.Add(frame, zone);
1791 } 1834 }
1792 return list.ToVector(); 1835 return list.ToVector();
1793 } 1836 }
1794 1837
1795 1838
1796 } // namespace internal 1839 } // namespace internal
1797 } // namespace v8 1840 } // namespace v8
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | src/wasm/wasm-debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698