Chromium Code Reviews| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 | 155 |
| 156 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { | 156 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { |
| 157 if (!frame()->has_adapted_arguments()) return; | 157 if (!frame()->has_adapted_arguments()) return; |
| 158 iterator_.Advance(); | 158 iterator_.Advance(); |
| 159 DCHECK(iterator_.frame()->is_arguments_adaptor()); | 159 DCHECK(iterator_.frame()->is_arguments_adaptor()); |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 // ------------------------------------------------------------------------- | 163 // ------------------------------------------------------------------------- |
| 164 | 164 |
| 165 | |
| 166 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) | 165 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) |
| 167 : JavaScriptFrameIterator(isolate) { | 166 : iterator_(isolate) { |
| 168 if (!done() && !IsValidFrame()) Advance(); | 167 if (!done() && !IsValidFrame(iterator_.frame())) Advance(); |
| 169 } | 168 } |
| 170 | 169 |
| 171 | 170 |
| 172 void StackTraceFrameIterator::Advance() { | 171 void StackTraceFrameIterator::Advance() { |
| 173 while (true) { | 172 do { |
| 174 JavaScriptFrameIterator::Advance(); | 173 iterator_.Advance(); |
| 175 if (done()) return; | 174 } while (!iterator_.done() && !IsValidFrame(iterator_.frame())); |
|
titzer
2016/04/06 09:53:23
might as well be consistent and use done() here in
Clemens Hammacher
2016/04/06 10:18:29
Done.
| |
| 176 if (IsValidFrame()) return; | 175 } |
| 176 | |
| 177 bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const { | |
| 178 if (frame->is_java_script()) { | |
| 179 JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame); | |
| 180 if (!jsFrame->function()->IsJSFunction()) return false; | |
| 181 Object* script = jsFrame->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()); | |
| 177 } | 185 } |
| 186 // apart from javascript, only wasm is valid | |
| 187 return frame->is_wasm(); | |
| 178 } | 188 } |
| 179 | 189 |
| 180 | 190 |
| 181 bool StackTraceFrameIterator::IsValidFrame() { | |
| 182 if (!frame()->function()->IsJSFunction()) return false; | |
| 183 Object* script = frame()->function()->shared()->script(); | |
| 184 // Don't show functions from native scripts to user. | |
| 185 return (script->IsScript() && | |
| 186 Script::TYPE_NATIVE != Script::cast(script)->type()); | |
| 187 } | |
| 188 | |
| 189 | |
| 190 // ------------------------------------------------------------------------- | 191 // ------------------------------------------------------------------------- |
| 191 | 192 |
| 192 | 193 |
| 193 SafeStackFrameIterator::SafeStackFrameIterator( | 194 SafeStackFrameIterator::SafeStackFrameIterator( |
| 194 Isolate* isolate, | 195 Isolate* isolate, |
| 195 Address fp, Address sp, Address js_entry_sp) | 196 Address fp, Address sp, Address js_entry_sp) |
| 196 : StackFrameIteratorBase(isolate, false), | 197 : StackFrameIteratorBase(isolate, false), |
| 197 low_bound_(sp), | 198 low_bound_(sp), |
| 198 high_bound_(js_entry_sp), | 199 high_bound_(js_entry_sp), |
| 199 top_frame_type_(StackFrame::NONE), | 200 top_frame_type_(StackFrame::NONE), |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 state->fp = fp; | 618 state->fp = fp; |
| 618 state->pc_address = ResolveReturnAddressLocation( | 619 state->pc_address = ResolveReturnAddressLocation( |
| 619 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 620 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
| 620 // The constant pool recorded in the exit frame is not associated | 621 // The constant pool recorded in the exit frame is not associated |
| 621 // with the pc in this state (the return address into a C entry | 622 // with the pc in this state (the return address into a C entry |
| 622 // stub). ComputeCallerState will retrieve the constant pool | 623 // stub). ComputeCallerState will retrieve the constant pool |
| 623 // together with the associated caller pc. | 624 // together with the associated caller pc. |
| 624 state->constant_pool_address = NULL; | 625 state->constant_pool_address = NULL; |
| 625 } | 626 } |
| 626 | 627 |
| 628 void StandardFrame::Summarize(List<FrameSummary>* functions) const { | |
| 629 DCHECK(functions->length() == 0); | |
| 630 // default implementation: no summary added | |
| 631 } | |
| 632 | |
| 633 JSFunction* StandardFrame::function() const { | |
| 634 // this default implementation is overridden by JS and WASM frames | |
| 635 return nullptr; | |
| 636 } | |
| 637 | |
| 638 Object* StandardFrame::receiver() const { | |
| 639 return isolate()->heap()->undefined_value(); | |
| 640 } | |
| 627 | 641 |
| 628 Address StandardFrame::GetExpressionAddress(int n) const { | 642 Address StandardFrame::GetExpressionAddress(int n) const { |
| 629 const int offset = StandardFrameConstants::kExpressionsOffset; | 643 const int offset = StandardFrameConstants::kExpressionsOffset; |
| 630 return fp() + offset - n * kPointerSize; | 644 return fp() + offset - n * kPointerSize; |
| 631 } | 645 } |
| 632 | 646 |
| 633 Address InterpretedFrame::GetExpressionAddress(int n) const { | 647 Address InterpretedFrame::GetExpressionAddress(int n) const { |
| 634 const int offset = InterpreterFrameConstants::kExpressionsOffset; | 648 const int offset = InterpreterFrameConstants::kExpressionsOffset; |
| 635 return fp() + offset - n * kPointerSize; | 649 return fp() + offset - n * kPointerSize; |
| 636 } | 650 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 Address JavaScriptFrame::GetCallerStackPointer() const { | 861 Address JavaScriptFrame::GetCallerStackPointer() const { |
| 848 return fp() + StandardFrameConstants::kCallerSPOffset; | 862 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 849 } | 863 } |
| 850 | 864 |
| 851 | 865 |
| 852 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { | 866 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { |
| 853 DCHECK(functions->length() == 0); | 867 DCHECK(functions->length() == 0); |
| 854 functions->Add(function()); | 868 functions->Add(function()); |
| 855 } | 869 } |
| 856 | 870 |
| 857 | 871 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) const { |
| 858 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | |
| 859 DCHECK(functions->length() == 0); | 872 DCHECK(functions->length() == 0); |
| 860 Code* code = LookupCode(); | 873 Code* code = LookupCode(); |
| 861 int offset = static_cast<int>(pc() - code->instruction_start()); | 874 int offset = static_cast<int>(pc() - code->instruction_start()); |
| 862 AbstractCode* abstract_code = AbstractCode::cast(code); | 875 AbstractCode* abstract_code = AbstractCode::cast(code); |
| 863 FrameSummary summary(receiver(), function(), abstract_code, offset, | 876 FrameSummary summary(receiver(), function(), abstract_code, offset, |
| 864 IsConstructor()); | 877 IsConstructor()); |
| 865 functions->Add(summary); | 878 functions->Add(summary); |
| 866 } | 879 } |
| 867 | 880 |
| 881 JSFunction* JavaScriptFrame::function() const { | |
| 882 return JSFunction::cast(function_slot_object()); | |
| 883 } | |
| 884 | |
| 885 Object* JavaScriptFrame::receiver() const { return GetParameter(-1); } | |
| 886 | |
| 868 int JavaScriptFrame::LookupExceptionHandlerInTable( | 887 int JavaScriptFrame::LookupExceptionHandlerInTable( |
| 869 int* stack_depth, HandlerTable::CatchPrediction* prediction) { | 888 int* stack_depth, HandlerTable::CatchPrediction* prediction) { |
| 870 Code* code = LookupCode(); | 889 Code* code = LookupCode(); |
| 871 DCHECK(!code->is_optimized_code()); | 890 DCHECK(!code->is_optimized_code()); |
| 872 HandlerTable* table = HandlerTable::cast(code->handler_table()); | 891 HandlerTable* table = HandlerTable::cast(code->handler_table()); |
| 873 int pc_offset = static_cast<int>(pc() - code->entry()); | 892 int pc_offset = static_cast<int>(pc() - code->entry()); |
| 874 return table->LookupRange(pc_offset, stack_depth, prediction); | 893 return table->LookupRange(pc_offset, stack_depth, prediction); |
| 875 } | 894 } |
| 876 | 895 |
| 877 | 896 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 989 if (code->kind() == Code::OPTIMIZED_FUNCTION) { | 1008 if (code->kind() == Code::OPTIMIZED_FUNCTION) { |
| 990 DCHECK(CannotDeoptFromAsmCode(code, *function())); | 1009 DCHECK(CannotDeoptFromAsmCode(code, *function())); |
| 991 PrintF(" ASM "); | 1010 PrintF(" ASM "); |
| 992 } | 1011 } |
| 993 } else { | 1012 } else { |
| 994 PrintF(" BYTECODE "); | 1013 PrintF(" BYTECODE "); |
| 995 } | 1014 } |
| 996 PrintF("\npc: %d\n", code_offset_); | 1015 PrintF("\npc: %d\n", code_offset_); |
| 997 } | 1016 } |
| 998 | 1017 |
| 999 | 1018 void OptimizedFrame::Summarize(List<FrameSummary>* frames) const { |
| 1000 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { | |
| 1001 DCHECK(frames->length() == 0); | 1019 DCHECK(frames->length() == 0); |
| 1002 DCHECK(is_optimized()); | 1020 DCHECK(is_optimized()); |
| 1003 | 1021 |
| 1004 // Delegate to JS frame in absence of turbofan deoptimization. | 1022 // Delegate to JS frame in absence of turbofan deoptimization. |
| 1005 // TODO(turbofan): Revisit once we support deoptimization across the board. | 1023 // TODO(turbofan): Revisit once we support deoptimization across the board. |
| 1006 Code* code = LookupCode(); | 1024 Code* code = LookupCode(); |
| 1007 if (code->kind() == Code::BUILTIN || | 1025 if (code->kind() == Code::BUILTIN || |
| 1008 CannotDeoptFromAsmCode(code, function())) { | 1026 CannotDeoptFromAsmCode(code, function())) { |
| 1009 return JavaScriptFrame::Summarize(frames); | 1027 return JavaScriptFrame::Summarize(frames); |
| 1010 } | 1028 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1244 } | 1262 } |
| 1245 | 1263 |
| 1246 Object* InterpretedFrame::GetInterpreterRegister(int register_index) const { | 1264 Object* InterpretedFrame::GetInterpreterRegister(int register_index) const { |
| 1247 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex; | 1265 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex; |
| 1248 DCHECK_EQ( | 1266 DCHECK_EQ( |
| 1249 InterpreterFrameConstants::kRegisterFilePointerFromFp, | 1267 InterpreterFrameConstants::kRegisterFilePointerFromFp, |
| 1250 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); | 1268 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); |
| 1251 return GetExpression(index + register_index); | 1269 return GetExpression(index + register_index); |
| 1252 } | 1270 } |
| 1253 | 1271 |
| 1254 void InterpretedFrame::Summarize(List<FrameSummary>* functions) { | 1272 void InterpretedFrame::Summarize(List<FrameSummary>* functions) const { |
| 1255 DCHECK(functions->length() == 0); | 1273 DCHECK(functions->length() == 0); |
| 1256 AbstractCode* abstract_code = | 1274 AbstractCode* abstract_code = |
| 1257 AbstractCode::cast(function()->shared()->bytecode_array()); | 1275 AbstractCode::cast(function()->shared()->bytecode_array()); |
| 1258 FrameSummary summary(receiver(), function(), abstract_code, | 1276 FrameSummary summary(receiver(), function(), abstract_code, |
| 1259 GetBytecodeOffset(), IsConstructor()); | 1277 GetBytecodeOffset(), IsConstructor()); |
| 1260 functions->Add(summary); | 1278 functions->Add(summary); |
| 1261 } | 1279 } |
| 1262 | 1280 |
| 1263 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { | 1281 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { |
| 1264 return Smi::cast(GetExpression(0))->value(); | 1282 return Smi::cast(GetExpression(0))->value(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1301 | 1319 |
| 1302 void WasmFrame::Print(StringStream* accumulator, PrintMode mode, | 1320 void WasmFrame::Print(StringStream* accumulator, PrintMode mode, |
| 1303 int index) const { | 1321 int index) const { |
| 1304 accumulator->Add("wasm frame"); | 1322 accumulator->Add("wasm frame"); |
| 1305 } | 1323 } |
| 1306 | 1324 |
| 1307 Code* WasmFrame::unchecked_code() const { | 1325 Code* WasmFrame::unchecked_code() const { |
| 1308 return static_cast<Code*>(isolate()->FindCodeObject(pc())); | 1326 return static_cast<Code*>(isolate()->FindCodeObject(pc())); |
| 1309 } | 1327 } |
| 1310 | 1328 |
| 1329 JSFunction* WasmFrame::function() const { | |
| 1330 Factory* factory = isolate()->factory(); | |
|
titzer
2016/04/06 09:53:23
Add a TODO here that we need to cache these JSFunc
Clemens Hammacher
2016/04/06 10:18:29
Done.
| |
| 1331 Handle<JSFunction> fun = | |
| 1332 factory->NewFunction(factory->NewStringFromAsciiChecked("<WASM>")); | |
| 1333 return *fun; | |
| 1334 } | |
| 1335 | |
| 1311 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } | 1336 void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } |
| 1312 | 1337 |
| 1313 Address WasmFrame::GetCallerStackPointer() const { | 1338 Address WasmFrame::GetCallerStackPointer() const { |
| 1314 return fp() + ExitFrameConstants::kCallerSPOffset; | 1339 return fp() + ExitFrameConstants::kCallerSPOffset; |
| 1315 } | 1340 } |
| 1316 | 1341 |
| 1317 namespace { | 1342 namespace { |
| 1318 | 1343 |
| 1319 | 1344 |
| 1320 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, | 1345 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1737 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1762 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1738 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1763 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1739 list.Add(frame, zone); | 1764 list.Add(frame, zone); |
| 1740 } | 1765 } |
| 1741 return list.ToVector(); | 1766 return list.ToVector(); |
| 1742 } | 1767 } |
| 1743 | 1768 |
| 1744 | 1769 |
| 1745 } // namespace internal | 1770 } // namespace internal |
| 1746 } // namespace v8 | 1771 } // namespace v8 |
| OLD | NEW |