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

Side by Side Diff: src/frames.cc

Issue 2109093003: [wasm] Enable wasm frame inspection for debugging (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 Address StandardFrame::GetExpressionAddress(int n) const { 630 Address StandardFrame::GetExpressionAddress(int n) const {
624 const int offset = StandardFrameConstants::kExpressionsOffset; 631 const int offset = StandardFrameConstants::kExpressionsOffset;
625 return fp() + offset - n * kPointerSize; 632 return fp() + offset - n * kPointerSize;
626 } 633 }
627 634
628 Address InterpretedFrame::GetExpressionAddress(int n) const { 635 Address InterpretedFrame::GetExpressionAddress(int n) const {
629 const int offset = InterpreterFrameConstants::kExpressionsOffset; 636 const int offset = InterpreterFrameConstants::kExpressionsOffset;
630 return fp() + offset - n * kPointerSize; 637 return fp() + offset - n * kPointerSize;
631 } 638 }
632 639
640 Script* StandardFrame::script() const {
641 // This should only be called on frames which override this method.
642 DCHECK(false);
643 return nullptr;
644 }
645
646 Object* StandardFrame::receiver() const {
647 return isolate()->heap()->undefined_value();
648 }
649
650 Object* StandardFrame::context() const {
651 return isolate()->heap()->undefined_value();
652 }
653
633 int StandardFrame::ComputeExpressionsCount() const { 654 int StandardFrame::ComputeExpressionsCount() const {
634 Address base = GetExpressionAddress(0); 655 Address base = GetExpressionAddress(0);
635 Address limit = sp() - kPointerSize; 656 Address limit = sp() - kPointerSize;
636 DCHECK(base >= limit); // stack grows downwards 657 DCHECK(base >= limit); // stack grows downwards
637 // Include register-allocated locals in number of expressions. 658 // Include register-allocated locals in number of expressions.
638 return static_cast<int>((base - limit) / kPointerSize); 659 return static_cast<int>((base - limit) / kPointerSize);
639 } 660 }
640 661
662 Object* StandardFrame::GetParameter(int index) const {
663 // StandardFrame does not define any parameters.
664 UNREACHABLE();
665 return nullptr;
666 }
667
668 int StandardFrame::ComputeParametersCount() const { return 0; }
641 669
642 void StandardFrame::ComputeCallerState(State* state) const { 670 void StandardFrame::ComputeCallerState(State* state) const {
643 state->sp = caller_sp(); 671 state->sp = caller_sp();
644 state->fp = caller_fp(); 672 state->fp = caller_fp();
645 state->pc_address = ResolveReturnAddressLocation( 673 state->pc_address = ResolveReturnAddressLocation(
646 reinterpret_cast<Address*>(ComputePCAddress(fp()))); 674 reinterpret_cast<Address*>(ComputePCAddress(fp())));
647 state->constant_pool_address = 675 state->constant_pool_address =
648 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); 676 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
649 } 677 }
650 678
651 679
652 void StandardFrame::SetCallerFp(Address caller_fp) { 680 void StandardFrame::SetCallerFp(Address caller_fp) {
653 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 681 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
654 caller_fp; 682 caller_fp;
655 } 683 }
656 684
685 bool StandardFrame::IsConstructor() const { return false; }
657 686
658 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 687 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
659 // Make sure that we're not doing "safe" stack frame iteration. We cannot 688 // Make sure that we're not doing "safe" stack frame iteration. We cannot
660 // possibly find pointers in optimized frames in that state. 689 // possibly find pointers in optimized frames in that state.
661 DCHECK(can_access_heap_objects()); 690 DCHECK(can_access_heap_objects());
662 691
663 // Compute the safepoint information. 692 // Compute the safepoint information.
664 unsigned stack_slots = 0; 693 unsigned stack_slots = 0;
665 SafepointEntry safepoint_entry; 694 SafepointEntry safepoint_entry;
666 Code* code = StackFrame::GetSafepointData( 695 Code* code = StackFrame::GetSafepointData(
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 IsConstructor(), mode); 889 IsConstructor(), mode);
861 functions->Add(summary); 890 functions->Add(summary);
862 } 891 }
863 892
864 JSFunction* JavaScriptFrame::function() const { 893 JSFunction* JavaScriptFrame::function() const {
865 return JSFunction::cast(function_slot_object()); 894 return JSFunction::cast(function_slot_object());
866 } 895 }
867 896
868 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); } 897 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
869 898
899 Script* JavaScriptFrame::script() const {
900 return Script::cast(function()->shared()->script());
901 }
902
903 Object* JavaScriptFrame::context() const {
904 const int offset = StandardFrameConstants::kContextOffset;
905 Object* maybe_result = Memory::Object_at(fp() + offset);
906 DCHECK(!maybe_result->IsSmi());
907 return maybe_result;
908 }
909
870 int JavaScriptFrame::LookupExceptionHandlerInTable( 910 int JavaScriptFrame::LookupExceptionHandlerInTable(
871 int* stack_depth, HandlerTable::CatchPrediction* prediction) { 911 int* stack_depth, HandlerTable::CatchPrediction* prediction) {
872 Code* code = LookupCode(); 912 Code* code = LookupCode();
873 DCHECK(!code->is_optimized_code()); 913 DCHECK(!code->is_optimized_code());
874 HandlerTable* table = HandlerTable::cast(code->handler_table()); 914 HandlerTable* table = HandlerTable::cast(code->handler_table());
875 int pc_offset = static_cast<int>(pc() - code->entry()); 915 int pc_offset = static_cast<int>(pc() - code->entry());
876 return table->LookupRange(pc_offset, stack_depth, prediction); 916 return table->LookupRange(pc_offset, stack_depth, prediction);
877 } 917 }
878 918
879 919
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 979
940 980
941 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const { 981 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
942 int operands_count = store->length(); 982 int operands_count = store->length();
943 DCHECK_LE(operands_count, ComputeOperandsCount()); 983 DCHECK_LE(operands_count, ComputeOperandsCount());
944 for (int i = 0; i < operands_count; i++) { 984 for (int i = 0; i < operands_count; i++) {
945 store->set(i, GetOperand(i)); 985 store->set(i, GetOperand(i));
946 } 986 }
947 } 987 }
948 988
989 Object* JavaScriptFrame::GetParameter(int index) const {
990 return Memory::Object_at(GetParameterSlot(index));
991 }
992
993 int JavaScriptFrame::ComputeParametersCount() const {
994 return GetNumberOfIncomingArguments();
995 }
996
949 namespace { 997 namespace {
950 998
951 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) { 999 bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
952 return code->is_turbofanned() && function->shared()->asm_function() && 1000 return code->is_turbofanned() && function->shared()->asm_function() &&
953 !FLAG_turbo_asm_deoptimization; 1001 !FLAG_turbo_asm_deoptimization;
954 } 1002 }
955 1003
956 } // namespace 1004 } // namespace
957 1005
958 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, 1006 FrameSummary::FrameSummary(Object* receiver, JSFunction* function,
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 Code* WasmFrame::unchecked_code() const { 1383 Code* WasmFrame::unchecked_code() const {
1336 return static_cast<Code*>(isolate()->FindCodeObject(pc())); 1384 return static_cast<Code*>(isolate()->FindCodeObject(pc()));
1337 } 1385 }
1338 1386
1339 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } 1387 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); }
1340 1388
1341 Address WasmFrame::GetCallerStackPointer() const { 1389 Address WasmFrame::GetCallerStackPointer() const {
1342 return fp() + ExitFrameConstants::kCallerSPOffset; 1390 return fp() + ExitFrameConstants::kCallerSPOffset;
1343 } 1391 }
1344 1392
1345 Object* WasmFrame::wasm_obj() { 1393 Object* WasmFrame::wasm_obj() const {
1346 FixedArray* deopt_data = LookupCode()->deoptimization_data(); 1394 FixedArray* deopt_data = LookupCode()->deoptimization_data();
1347 DCHECK(deopt_data->length() == 2); 1395 DCHECK(deopt_data->length() == 2);
1348 return deopt_data->get(0); 1396 return deopt_data->get(0);
1349 } 1397 }
1350 1398
1351 uint32_t WasmFrame::function_index() { 1399 uint32_t WasmFrame::function_index() 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 Object* func_index_obj = deopt_data->get(1); 1402 return Smi::cast(deopt_data->get(1))->value();
1355 if (func_index_obj->IsUndefined(isolate())) return static_cast<uint32_t>(-1); 1403 }
1356 if (func_index_obj->IsSmi()) return Smi::cast(func_index_obj)->value(); 1404
1357 DCHECK(func_index_obj->IsHeapNumber()); 1405 Script* WasmFrame::script() const {
1358 uint32_t val = static_cast<uint32_t>(-1); 1406 JSObject* wasm = JSObject::cast(wasm_obj());
1359 func_index_obj->ToUint32(&val); 1407 Handle<wasm::WasmDebugInfo> debug_info(wasm::GetDebugInfo(wasm), isolate());
1360 DCHECK(val != static_cast<uint32_t>(-1)); 1408 return wasm::WasmDebugInfo::GetFunctionScript(debug_info, function_index());
1361 return val;
1362 } 1409 }
1363 1410
1364 namespace { 1411 namespace {
1365 1412
1366 1413
1367 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, 1414 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
1368 Code* code) { 1415 Code* code) {
1369 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1416 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1370 std::ostringstream os; 1417 std::ostringstream os;
1371 os << "--------- s o u r c e c o d e ---------\n" 1418 os << "--------- s o u r c e c o d e ---------\n"
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1838 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1792 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1839 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1793 list.Add(frame, zone); 1840 list.Add(frame, zone);
1794 } 1841 }
1795 return list.ToVector(); 1842 return list.ToVector();
1796 } 1843 }
1797 1844
1798 1845
1799 } // namespace internal 1846 } // namespace internal
1800 } // namespace v8 1847 } // 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