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

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: Add two DCHECKs 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
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 Address StandardFrame::GetExpressionAddress(int n) const { 635 Address StandardFrame::GetExpressionAddress(int n) const {
629 const int offset = StandardFrameConstants::kExpressionsOffset; 636 const int offset = StandardFrameConstants::kExpressionsOffset;
630 return fp() + offset - n * kPointerSize; 637 return fp() + offset - n * kPointerSize;
631 } 638 }
632 639
633 Address InterpretedFrame::GetExpressionAddress(int n) const { 640 Address InterpretedFrame::GetExpressionAddress(int n) const {
634 const int offset = InterpreterFrameConstants::kExpressionsOffset; 641 const int offset = InterpreterFrameConstants::kExpressionsOffset;
635 return fp() + offset - n * kPointerSize; 642 return fp() + offset - n * kPointerSize;
636 } 643 }
637 644
645 Script* StandardFrame::script() const {
646 // This should only be called on frames which override this method.
647 DCHECK(false);
648 return nullptr;
649 }
650
651 Object* StandardFrame::receiver() const {
652 return isolate()->heap()->undefined_value();
653 }
654
655 Object* StandardFrame::context() const {
656 return isolate()->heap()->undefined_value();
657 }
658
638 int StandardFrame::ComputeExpressionsCount() const { 659 int StandardFrame::ComputeExpressionsCount() const {
639 Address base = GetExpressionAddress(0); 660 Address base = GetExpressionAddress(0);
640 Address limit = sp() - kPointerSize; 661 Address limit = sp() - kPointerSize;
641 DCHECK(base >= limit); // stack grows downwards 662 DCHECK(base >= limit); // stack grows downwards
642 // Include register-allocated locals in number of expressions. 663 // Include register-allocated locals in number of expressions.
643 return static_cast<int>((base - limit) / kPointerSize); 664 return static_cast<int>((base - limit) / kPointerSize);
644 } 665 }
645 666
667 Object* StandardFrame::GetParameter(int index) const {
668 // StandardFrame does not define any parameters.
669 UNREACHABLE();
670 return nullptr;
671 }
672
673 int StandardFrame::ComputeParametersCount() const { return 0; }
646 674
647 void StandardFrame::ComputeCallerState(State* state) const { 675 void StandardFrame::ComputeCallerState(State* state) const {
648 state->sp = caller_sp(); 676 state->sp = caller_sp();
649 state->fp = caller_fp(); 677 state->fp = caller_fp();
650 state->pc_address = ResolveReturnAddressLocation( 678 state->pc_address = ResolveReturnAddressLocation(
651 reinterpret_cast<Address*>(ComputePCAddress(fp()))); 679 reinterpret_cast<Address*>(ComputePCAddress(fp())));
652 state->constant_pool_address = 680 state->constant_pool_address =
653 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); 681 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
654 } 682 }
655 683
656 684
657 void StandardFrame::SetCallerFp(Address caller_fp) { 685 void StandardFrame::SetCallerFp(Address caller_fp) {
658 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 686 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
659 caller_fp; 687 caller_fp;
660 } 688 }
661 689
690 bool StandardFrame::IsConstructor() const { return false; }
662 691
663 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 692 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
664 // Make sure that we're not doing "safe" stack frame iteration. We cannot 693 // Make sure that we're not doing "safe" stack frame iteration. We cannot
665 // possibly find pointers in optimized frames in that state. 694 // possibly find pointers in optimized frames in that state.
666 DCHECK(can_access_heap_objects()); 695 DCHECK(can_access_heap_objects());
667 696
668 // Compute the safepoint information. 697 // Compute the safepoint information.
669 unsigned stack_slots = 0; 698 unsigned stack_slots = 0;
670 SafepointEntry safepoint_entry; 699 SafepointEntry safepoint_entry;
671 Code* code = StackFrame::GetSafepointData( 700 Code* code = StackFrame::GetSafepointData(
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 IsConstructor(), mode); 895 IsConstructor(), mode);
867 functions->Add(summary); 896 functions->Add(summary);
868 } 897 }
869 898
870 JSFunction* JavaScriptFrame::function() const { 899 JSFunction* JavaScriptFrame::function() const {
871 return JSFunction::cast(function_slot_object()); 900 return JSFunction::cast(function_slot_object());
872 } 901 }
873 902
874 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); } 903 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
875 904
905 Script* JavaScriptFrame::script() const {
906 return Script::cast(function()->shared()->script());
907 }
908
909 Object* JavaScriptFrame::context() const {
910 const int offset = StandardFrameConstants::kContextOffset;
911 Object* maybe_result = Memory::Object_at(fp() + offset);
912 DCHECK(!maybe_result->IsSmi());
913 return maybe_result;
914 }
915
876 int JavaScriptFrame::LookupExceptionHandlerInTable( 916 int JavaScriptFrame::LookupExceptionHandlerInTable(
877 int* stack_depth, HandlerTable::CatchPrediction* prediction) { 917 int* stack_depth, HandlerTable::CatchPrediction* prediction) {
878 Code* code = LookupCode(); 918 Code* code = LookupCode();
879 DCHECK(!code->is_optimized_code()); 919 DCHECK(!code->is_optimized_code());
880 HandlerTable* table = HandlerTable::cast(code->handler_table()); 920 HandlerTable* table = HandlerTable::cast(code->handler_table());
881 int pc_offset = static_cast<int>(pc() - code->entry()); 921 int pc_offset = static_cast<int>(pc() - code->entry());
882 return table->LookupRange(pc_offset, stack_depth, prediction); 922 return table->LookupRange(pc_offset, stack_depth, prediction);
883 } 923 }
884 924
885 925
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 985
946 986
947 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const { 987 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
948 int operands_count = store->length(); 988 int operands_count = store->length();
949 DCHECK_LE(operands_count, ComputeOperandsCount()); 989 DCHECK_LE(operands_count, ComputeOperandsCount());
950 for (int i = 0; i < operands_count; i++) { 990 for (int i = 0; i < operands_count; i++) {
951 store->set(i, GetOperand(i)); 991 store->set(i, GetOperand(i));
952 } 992 }
953 } 993 }
954 994
995 Object* JavaScriptFrame::GetParameter(int index) const {
996 return Memory::Object_at(GetParameterSlot(index));
997 }
998
999 int JavaScriptFrame::ComputeParametersCount() const {
1000 return GetNumberOfIncomingArguments();
1001 }
1002
955 namespace { 1003 namespace {
956 1004
957 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) { 1005 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
958 return code->is_turbofanned() && function->shared()->asm_function() && 1006 return code->is_turbofanned() && function->shared()->asm_function() &&
959 !FLAG_turbo_asm_deoptimization; 1007 !FLAG_turbo_asm_deoptimization;
960 } 1008 }
961 1009
962 } // namespace 1010 } // namespace
963 1011
964 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, 1012 FrameSummary::FrameSummary(Object* receiver, JSFunction* function,
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 Code* WasmFrame::unchecked_code() const { 1389 Code* WasmFrame::unchecked_code() const {
1342 return static_cast<Code*>(isolate()->FindCodeObject(pc())); 1390 return static_cast<Code*>(isolate()->FindCodeObject(pc()));
1343 } 1391 }
1344 1392
1345 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } 1393 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); }
1346 1394
1347 Address WasmFrame::GetCallerStackPointer() const { 1395 Address WasmFrame::GetCallerStackPointer() const {
1348 return fp() + ExitFrameConstants::kCallerSPOffset; 1396 return fp() + ExitFrameConstants::kCallerSPOffset;
1349 } 1397 }
1350 1398
1351 Object* WasmFrame::wasm_obj() { 1399 Object* WasmFrame::wasm_obj() const {
1352 FixedArray* deopt_data = LookupCode()->deoptimization_data(); 1400 FixedArray* deopt_data = LookupCode()->deoptimization_data();
1353 DCHECK(deopt_data->length() == 2); 1401 DCHECK(deopt_data->length() == 2);
1354 return deopt_data->get(0); 1402 return deopt_data->get(0);
1355 } 1403 }
1356 1404
1357 uint32_t WasmFrame::function_index() { 1405 uint32_t WasmFrame::function_index() const {
1358 FixedArray* deopt_data = LookupCode()->deoptimization_data(); 1406 FixedArray* deopt_data = LookupCode()->deoptimization_data();
1359 DCHECK(deopt_data->length() == 2); 1407 DCHECK(deopt_data->length() == 2);
1360 Object* func_index_obj = deopt_data->get(1); 1408 return Smi::cast(deopt_data->get(1))->value();
1361 if (func_index_obj->IsUndefined(isolate())) return static_cast<uint32_t>(-1); 1409 }
1362 if (func_index_obj->IsSmi()) return Smi::cast(func_index_obj)->value(); 1410
1363 DCHECK(func_index_obj->IsHeapNumber()); 1411 Script* WasmFrame::script() const {
1364 uint32_t val = static_cast<uint32_t>(-1); 1412 JSObject* wasm = JSObject::cast(wasm_obj());
1365 func_index_obj->ToUint32(&val); 1413 Handle<wasm::WasmDebugInfo> debug_info(wasm::GetDebugInfo(wasm), isolate());
1366 DCHECK(val != static_cast<uint32_t>(-1)); 1414 return wasm::WasmDebugInfo::GetFunctionScript(debug_info, function_index());
1367 return val;
1368 } 1415 }
1369 1416
1370 namespace { 1417 namespace {
1371 1418
1372 1419
1373 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, 1420 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
1374 Code* code) { 1421 Code* code) {
1375 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1422 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1376 std::ostringstream os; 1423 std::ostringstream os;
1377 os << "--------- s o u r c e c o d e ---------\n" 1424 os << "--------- s o u r c e c o d e ---------\n"
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1844 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1798 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1845 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1799 list.Add(frame, zone); 1846 list.Add(frame, zone);
1800 } 1847 }
1801 return list.ToVector(); 1848 return list.ToVector();
1802 } 1849 }
1803 1850
1804 1851
1805 } // namespace internal 1852 } // namespace internal
1806 } // namespace v8 1853 } // namespace v8
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698