| 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 "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" |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 | 153 |
| 154 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { | 154 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { |
| 155 if (!frame()->has_adapted_arguments()) return; | 155 if (!frame()->has_adapted_arguments()) return; |
| 156 iterator_.Advance(); | 156 iterator_.Advance(); |
| 157 DCHECK(iterator_.frame()->is_arguments_adaptor()); | 157 DCHECK(iterator_.frame()->is_arguments_adaptor()); |
| 158 } | 158 } |
| 159 | 159 |
| 160 | 160 |
| 161 // ------------------------------------------------------------------------- | 161 // ------------------------------------------------------------------------- |
| 162 | 162 |
| 163 | |
| 164 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) | 163 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) |
| 165 : JavaScriptFrameIterator(isolate) { | 164 : iterator_(isolate) { |
| 166 if (!done() && !IsValidFrame()) Advance(); | 165 if (!done() && !IsValidFrame(iterator_.frame())) Advance(); |
| 167 } | 166 } |
| 168 | 167 |
| 169 | 168 |
| 170 void StackTraceFrameIterator::Advance() { | 169 void StackTraceFrameIterator::Advance() { |
| 171 while (true) { | 170 do { |
| 172 JavaScriptFrameIterator::Advance(); | 171 iterator_.Advance(); |
| 173 if (done()) return; | 172 } while (!done() && !IsValidFrame(iterator_.frame())); |
| 174 if (IsValidFrame()) return; | 173 } |
| 174 |
| 175 bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const { |
| 176 if (frame->is_java_script()) { |
| 177 JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame); |
| 178 if (!jsFrame->function()->IsJSFunction()) return false; |
| 179 Object* script = jsFrame->function()->shared()->script(); |
| 180 // Don't show functions from native scripts to user. |
| 181 return (script->IsScript() && |
| 182 Script::TYPE_NATIVE != Script::cast(script)->type()); |
| 175 } | 183 } |
| 184 // apart from javascript, only wasm is valid |
| 185 return frame->is_wasm(); |
| 176 } | 186 } |
| 177 | 187 |
| 178 | 188 |
| 179 bool StackTraceFrameIterator::IsValidFrame() { | |
| 180 if (!frame()->function()->IsJSFunction()) return false; | |
| 181 Object* script = frame()->function()->shared()->script(); | |
| 182 // Don't show functions from native scripts to user. | |
| 183 return (script->IsScript() && | |
| 184 Script::TYPE_NATIVE != Script::cast(script)->type()); | |
| 185 } | |
| 186 | |
| 187 | |
| 188 // ------------------------------------------------------------------------- | 189 // ------------------------------------------------------------------------- |
| 189 | 190 |
| 190 | 191 |
| 191 SafeStackFrameIterator::SafeStackFrameIterator( | 192 SafeStackFrameIterator::SafeStackFrameIterator( |
| 192 Isolate* isolate, | 193 Isolate* isolate, |
| 193 Address fp, Address sp, Address js_entry_sp) | 194 Address fp, Address sp, Address js_entry_sp) |
| 194 : StackFrameIteratorBase(isolate, false), | 195 : StackFrameIteratorBase(isolate, false), |
| 195 low_bound_(sp), | 196 low_bound_(sp), |
| 196 high_bound_(js_entry_sp), | 197 high_bound_(js_entry_sp), |
| 197 top_frame_type_(StackFrame::NONE), | 198 top_frame_type_(StackFrame::NONE), |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 state->fp = fp; | 610 state->fp = fp; |
| 610 state->pc_address = ResolveReturnAddressLocation( | 611 state->pc_address = ResolveReturnAddressLocation( |
| 611 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 612 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
| 612 // The constant pool recorded in the exit frame is not associated | 613 // The constant pool recorded in the exit frame is not associated |
| 613 // with the pc in this state (the return address into a C entry | 614 // with the pc in this state (the return address into a C entry |
| 614 // stub). ComputeCallerState will retrieve the constant pool | 615 // stub). ComputeCallerState will retrieve the constant pool |
| 615 // together with the associated caller pc. | 616 // together with the associated caller pc. |
| 616 state->constant_pool_address = NULL; | 617 state->constant_pool_address = NULL; |
| 617 } | 618 } |
| 618 | 619 |
| 620 void StandardFrame::Summarize(List<FrameSummary>* functions) const { |
| 621 DCHECK(functions->length() == 0); |
| 622 // default implementation: no summary added |
| 623 } |
| 624 |
| 625 JSFunction* StandardFrame::function() const { |
| 626 // this default implementation is overridden by JS and WASM frames |
| 627 return nullptr; |
| 628 } |
| 629 |
| 630 Object* StandardFrame::receiver() const { |
| 631 return isolate()->heap()->undefined_value(); |
| 632 } |
| 619 | 633 |
| 620 Address StandardFrame::GetExpressionAddress(int n) const { | 634 Address StandardFrame::GetExpressionAddress(int n) const { |
| 621 const int offset = StandardFrameConstants::kExpressionsOffset; | 635 const int offset = StandardFrameConstants::kExpressionsOffset; |
| 622 return fp() + offset - n * kPointerSize; | 636 return fp() + offset - n * kPointerSize; |
| 623 } | 637 } |
| 624 | 638 |
| 625 Address InterpretedFrame::GetExpressionAddress(int n) const { | 639 Address InterpretedFrame::GetExpressionAddress(int n) const { |
| 626 const int offset = InterpreterFrameConstants::kExpressionsOffset; | 640 const int offset = InterpreterFrameConstants::kExpressionsOffset; |
| 627 return fp() + offset - n * kPointerSize; | 641 return fp() + offset - n * kPointerSize; |
| 628 } | 642 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 Address JavaScriptFrame::GetCallerStackPointer() const { | 853 Address JavaScriptFrame::GetCallerStackPointer() const { |
| 840 return fp() + StandardFrameConstants::kCallerSPOffset; | 854 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 841 } | 855 } |
| 842 | 856 |
| 843 | 857 |
| 844 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { | 858 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { |
| 845 DCHECK(functions->length() == 0); | 859 DCHECK(functions->length() == 0); |
| 846 functions->Add(function()); | 860 functions->Add(function()); |
| 847 } | 861 } |
| 848 | 862 |
| 849 | 863 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) const { |
| 850 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | |
| 851 DCHECK(functions->length() == 0); | 864 DCHECK(functions->length() == 0); |
| 852 Code* code = LookupCode(); | 865 Code* code = LookupCode(); |
| 853 int offset = static_cast<int>(pc() - code->instruction_start()); | 866 int offset = static_cast<int>(pc() - code->instruction_start()); |
| 854 AbstractCode* abstract_code = AbstractCode::cast(code); | 867 AbstractCode* abstract_code = AbstractCode::cast(code); |
| 855 FrameSummary summary(receiver(), function(), abstract_code, offset, | 868 FrameSummary summary(receiver(), function(), abstract_code, offset, |
| 856 IsConstructor()); | 869 IsConstructor()); |
| 857 functions->Add(summary); | 870 functions->Add(summary); |
| 858 } | 871 } |
| 859 | 872 |
| 873 JSFunction* JavaScriptFrame::function() const { |
| 874 return JSFunction::cast(function_slot_object()); |
| 875 } |
| 876 |
| 877 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); } |
| 878 |
| 860 int JavaScriptFrame::LookupExceptionHandlerInTable( | 879 int JavaScriptFrame::LookupExceptionHandlerInTable( |
| 861 int* stack_depth, HandlerTable::CatchPrediction* prediction) { | 880 int* stack_depth, HandlerTable::CatchPrediction* prediction) { |
| 862 Code* code = LookupCode(); | 881 Code* code = LookupCode(); |
| 863 DCHECK(!code->is_optimized_code()); | 882 DCHECK(!code->is_optimized_code()); |
| 864 HandlerTable* table = HandlerTable::cast(code->handler_table()); | 883 HandlerTable* table = HandlerTable::cast(code->handler_table()); |
| 865 int pc_offset = static_cast<int>(pc() - code->entry()); | 884 int pc_offset = static_cast<int>(pc() - code->entry()); |
| 866 return table->LookupRange(pc_offset, stack_depth, prediction); | 885 return table->LookupRange(pc_offset, stack_depth, prediction); |
| 867 } | 886 } |
| 868 | 887 |
| 869 | 888 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 if (code->kind() == Code::OPTIMIZED_FUNCTION) { | 990 if (code->kind() == Code::OPTIMIZED_FUNCTION) { |
| 972 DCHECK(CannotDeoptFromAsmCode(code, *function())); | 991 DCHECK(CannotDeoptFromAsmCode(code, *function())); |
| 973 PrintF(" ASM "); | 992 PrintF(" ASM "); |
| 974 } | 993 } |
| 975 } else { | 994 } else { |
| 976 PrintF(" BYTECODE "); | 995 PrintF(" BYTECODE "); |
| 977 } | 996 } |
| 978 PrintF("\npc: %d\n", code_offset_); | 997 PrintF("\npc: %d\n", code_offset_); |
| 979 } | 998 } |
| 980 | 999 |
| 981 | 1000 void OptimizedFrame::Summarize(List<FrameSummary>* frames) const { |
| 982 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { | |
| 983 DCHECK(frames->length() == 0); | 1001 DCHECK(frames->length() == 0); |
| 984 DCHECK(is_optimized()); | 1002 DCHECK(is_optimized()); |
| 985 | 1003 |
| 986 // Delegate to JS frame in absence of turbofan deoptimization. | 1004 // Delegate to JS frame in absence of turbofan deoptimization. |
| 987 // TODO(turbofan): Revisit once we support deoptimization across the board. | 1005 // TODO(turbofan): Revisit once we support deoptimization across the board. |
| 988 Code* code = LookupCode(); | 1006 Code* code = LookupCode(); |
| 989 if (code->kind() == Code::BUILTIN || | 1007 if (code->kind() == Code::BUILTIN || |
| 990 CannotDeoptFromAsmCode(code, function())) { | 1008 CannotDeoptFromAsmCode(code, function())) { |
| 991 return JavaScriptFrame::Summarize(frames); | 1009 return JavaScriptFrame::Summarize(frames); |
| 992 } | 1010 } |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 } | 1245 } |
| 1228 | 1246 |
| 1229 Object* InterpretedFrame::GetInterpreterRegister(int register_index) const { | 1247 Object* InterpretedFrame::GetInterpreterRegister(int register_index) const { |
| 1230 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex; | 1248 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex; |
| 1231 DCHECK_EQ( | 1249 DCHECK_EQ( |
| 1232 InterpreterFrameConstants::kRegisterFilePointerFromFp, | 1250 InterpreterFrameConstants::kRegisterFilePointerFromFp, |
| 1233 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); | 1251 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); |
| 1234 return GetExpression(index + register_index); | 1252 return GetExpression(index + register_index); |
| 1235 } | 1253 } |
| 1236 | 1254 |
| 1237 void InterpretedFrame::Summarize(List<FrameSummary>* functions) { | 1255 void InterpretedFrame::Summarize(List<FrameSummary>* functions) const { |
| 1238 DCHECK(functions->length() == 0); | 1256 DCHECK(functions->length() == 0); |
| 1239 AbstractCode* abstract_code = | 1257 AbstractCode* abstract_code = |
| 1240 AbstractCode::cast(function()->shared()->bytecode_array()); | 1258 AbstractCode::cast(function()->shared()->bytecode_array()); |
| 1241 FrameSummary summary(receiver(), function(), abstract_code, | 1259 FrameSummary summary(receiver(), function(), abstract_code, |
| 1242 GetBytecodeOffset(), IsConstructor()); | 1260 GetBytecodeOffset(), IsConstructor()); |
| 1243 functions->Add(summary); | 1261 functions->Add(summary); |
| 1244 } | 1262 } |
| 1245 | 1263 |
| 1246 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { | 1264 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { |
| 1247 return Smi::cast(GetExpression(0))->value(); | 1265 return Smi::cast(GetExpression(0))->value(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 | 1302 |
| 1285 void WasmFrame::Print(StringStream* accumulator, PrintMode mode, | 1303 void WasmFrame::Print(StringStream* accumulator, PrintMode mode, |
| 1286 int index) const { | 1304 int index) const { |
| 1287 accumulator->Add("wasm frame"); | 1305 accumulator->Add("wasm frame"); |
| 1288 } | 1306 } |
| 1289 | 1307 |
| 1290 Code* WasmFrame::unchecked_code() const { | 1308 Code* WasmFrame::unchecked_code() const { |
| 1291 return static_cast<Code*>(isolate()->FindCodeObject(pc())); | 1309 return static_cast<Code*>(isolate()->FindCodeObject(pc())); |
| 1292 } | 1310 } |
| 1293 | 1311 |
| 1312 JSFunction* WasmFrame::function() const { |
| 1313 // TODO(clemensh): generate the right JSFunctions once per wasm function and |
| 1314 // cache them |
| 1315 Factory* factory = isolate()->factory(); |
| 1316 Handle<JSFunction> fun = |
| 1317 factory->NewFunction(factory->NewStringFromAsciiChecked("<WASM>")); |
| 1318 return *fun; |
| 1319 } |
| 1320 |
| 1294 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } | 1321 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } |
| 1295 | 1322 |
| 1296 Address WasmFrame::GetCallerStackPointer() const { | 1323 Address WasmFrame::GetCallerStackPointer() const { |
| 1297 return fp() + ExitFrameConstants::kCallerSPOffset; | 1324 return fp() + ExitFrameConstants::kCallerSPOffset; |
| 1298 } | 1325 } |
| 1299 | 1326 |
| 1300 namespace { | 1327 namespace { |
| 1301 | 1328 |
| 1302 | 1329 |
| 1303 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, | 1330 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1720 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1747 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1721 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1748 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1722 list.Add(frame, zone); | 1749 list.Add(frame, zone); |
| 1723 } | 1750 } |
| 1724 return list.ToVector(); | 1751 return list.ToVector(); |
| 1725 } | 1752 } |
| 1726 | 1753 |
| 1727 | 1754 |
| 1728 } // namespace internal | 1755 } // namespace internal |
| 1729 } // namespace v8 | 1756 } // namespace v8 |
| OLD | NEW |