| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 while (true) { | 198 while (true) { |
| 199 JavaScriptFrameIterator::Advance(); | 199 JavaScriptFrameIterator::Advance(); |
| 200 if (done()) return; | 200 if (done()) return; |
| 201 if (IsValidFrame()) return; | 201 if (IsValidFrame()) return; |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 bool StackTraceFrameIterator::IsValidFrame() { | 206 bool StackTraceFrameIterator::IsValidFrame() { |
| 207 if (!frame()->function()->IsJSFunction()) return false; | 207 if (!frame()->function()->IsJSFunction()) return false; |
| 208 Object* script = JSFunction::cast(frame()->function())->shared()->script(); | 208 Object* script = frame()->function()->shared()->script(); |
| 209 // Don't show functions from native scripts to user. | 209 // Don't show functions from native scripts to user. |
| 210 return (script->IsScript() && | 210 return (script->IsScript() && |
| 211 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); | 211 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); |
| 212 } | 212 } |
| 213 | 213 |
| 214 | 214 |
| 215 // ------------------------------------------------------------------------- | 215 // ------------------------------------------------------------------------- |
| 216 | 216 |
| 217 | 217 |
| 218 SafeStackFrameIterator::SafeStackFrameIterator( | 218 SafeStackFrameIterator::SafeStackFrameIterator( |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 // If there is an arguments adaptor frame get the arguments length from it. | 717 // If there is an arguments adaptor frame get the arguments length from it. |
| 718 if (has_adapted_arguments()) { | 718 if (has_adapted_arguments()) { |
| 719 return Smi::cast(GetExpression(caller_fp(), 0))->value(); | 719 return Smi::cast(GetExpression(caller_fp(), 0))->value(); |
| 720 } else { | 720 } else { |
| 721 return GetNumberOfIncomingArguments(); | 721 return GetNumberOfIncomingArguments(); |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 | 724 |
| 725 | 725 |
| 726 Code* JavaScriptFrame::unchecked_code() const { | 726 Code* JavaScriptFrame::unchecked_code() const { |
| 727 JSFunction* function = JSFunction::cast(this->function()); | 727 return function()->code(); |
| 728 return function->code(); | |
| 729 } | 728 } |
| 730 | 729 |
| 731 | 730 |
| 732 int JavaScriptFrame::GetNumberOfIncomingArguments() const { | 731 int JavaScriptFrame::GetNumberOfIncomingArguments() const { |
| 733 ASSERT(can_access_heap_objects() && | 732 ASSERT(can_access_heap_objects() && |
| 734 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); | 733 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); |
| 735 | 734 |
| 736 JSFunction* function = JSFunction::cast(this->function()); | 735 return function()->shared()->formal_parameter_count(); |
| 737 return function->shared()->formal_parameter_count(); | |
| 738 } | 736 } |
| 739 | 737 |
| 740 | 738 |
| 741 Address JavaScriptFrame::GetCallerStackPointer() const { | 739 Address JavaScriptFrame::GetCallerStackPointer() const { |
| 742 return fp() + StandardFrameConstants::kCallerSPOffset; | 740 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 743 } | 741 } |
| 744 | 742 |
| 745 | 743 |
| 746 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { | 744 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { |
| 747 ASSERT(functions->length() == 0); | 745 ASSERT(functions->length() == 0); |
| 748 functions->Add(JSFunction::cast(function())); | 746 functions->Add(function()); |
| 749 } | 747 } |
| 750 | 748 |
| 751 | 749 |
| 752 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 750 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
| 753 ASSERT(functions->length() == 0); | 751 ASSERT(functions->length() == 0); |
| 754 Code* code_pointer = LookupCode(); | 752 Code* code_pointer = LookupCode(); |
| 755 int offset = static_cast<int>(pc() - code_pointer->address()); | 753 int offset = static_cast<int>(pc() - code_pointer->address()); |
| 756 FrameSummary summary(receiver(), | 754 FrameSummary summary(receiver(), |
| 757 JSFunction::cast(function()), | 755 function(), |
| 758 code_pointer, | 756 code_pointer, |
| 759 offset, | 757 offset, |
| 760 IsConstructor()); | 758 IsConstructor()); |
| 761 functions->Add(summary); | 759 functions->Add(summary); |
| 762 } | 760 } |
| 763 | 761 |
| 764 | 762 |
| 765 void JavaScriptFrame::PrintTop(Isolate* isolate, | 763 void JavaScriptFrame::PrintTop(Isolate* isolate, |
| 766 FILE* file, | 764 FILE* file, |
| 767 bool print_args, | 765 bool print_args, |
| 768 bool print_line_number) { | 766 bool print_line_number) { |
| 769 // constructor calls | 767 // constructor calls |
| 770 HandleScope scope(isolate); | 768 HandleScope scope(isolate); |
| 771 DisallowHeapAllocation no_allocation; | 769 DisallowHeapAllocation no_allocation; |
| 772 JavaScriptFrameIterator it(isolate); | 770 JavaScriptFrameIterator it(isolate); |
| 773 while (!it.done()) { | 771 while (!it.done()) { |
| 774 if (it.frame()->is_java_script()) { | 772 if (it.frame()->is_java_script()) { |
| 775 JavaScriptFrame* frame = it.frame(); | 773 JavaScriptFrame* frame = it.frame(); |
| 776 if (frame->IsConstructor()) PrintF(file, "new "); | 774 if (frame->IsConstructor()) PrintF(file, "new "); |
| 777 // function name | 775 // function name |
| 778 Object* maybe_fun = frame->function(); | 776 JSFunction* fun = frame->function(); |
| 779 if (maybe_fun->IsJSFunction()) { | 777 fun->PrintName(); |
| 780 JSFunction* fun = JSFunction::cast(maybe_fun); | 778 Code* js_code = frame->unchecked_code(); |
| 781 fun->PrintName(); | 779 Address pc = frame->pc(); |
| 782 Code* js_code = frame->unchecked_code(); | 780 int code_offset = |
| 783 Address pc = frame->pc(); | 781 static_cast<int>(pc - js_code->instruction_start()); |
| 784 int code_offset = | 782 PrintF("+%d", code_offset); |
| 785 static_cast<int>(pc - js_code->instruction_start()); | 783 SharedFunctionInfo* shared = fun->shared(); |
| 786 PrintF("+%d", code_offset); | 784 if (print_line_number) { |
| 787 SharedFunctionInfo* shared = fun->shared(); | 785 Code* code = Code::cast( |
| 788 if (print_line_number) { | 786 v8::internal::Isolate::Current()->heap()->FindCodeObject(pc)); |
| 789 Code* code = Code::cast( | 787 int source_pos = code->SourcePosition(pc); |
| 790 v8::internal::Isolate::Current()->heap()->FindCodeObject(pc)); | 788 Object* maybe_script = shared->script(); |
| 791 int source_pos = code->SourcePosition(pc); | 789 if (maybe_script->IsScript()) { |
| 792 Object* maybe_script = shared->script(); | 790 Handle<Script> script(Script::cast(maybe_script)); |
| 793 if (maybe_script->IsScript()) { | 791 int line = GetScriptLineNumberSafe(script, source_pos) + 1; |
| 794 Handle<Script> script(Script::cast(maybe_script)); | 792 Object* script_name_raw = script->name(); |
| 795 int line = GetScriptLineNumberSafe(script, source_pos) + 1; | 793 if (script_name_raw->IsString()) { |
| 796 Object* script_name_raw = script->name(); | 794 String* script_name = String::cast(script->name()); |
| 797 if (script_name_raw->IsString()) { | 795 SmartArrayPointer<char> c_script_name = |
| 798 String* script_name = String::cast(script->name()); | 796 script_name->ToCString(DISALLOW_NULLS, |
| 799 SmartArrayPointer<char> c_script_name = | 797 ROBUST_STRING_TRAVERSAL); |
| 800 script_name->ToCString(DISALLOW_NULLS, | 798 PrintF(file, " at %s:%d", *c_script_name, line); |
| 801 ROBUST_STRING_TRAVERSAL); | |
| 802 PrintF(file, " at %s:%d", *c_script_name, line); | |
| 803 } else { | |
| 804 PrintF(file, " at <unknown>:%d", line); | |
| 805 } | |
| 806 } else { | 799 } else { |
| 807 PrintF(file, " at <unknown>:<unknown>"); | 800 PrintF(file, " at <unknown>:%d", line); |
| 808 } | 801 } |
| 802 } else { |
| 803 PrintF(file, " at <unknown>:<unknown>"); |
| 809 } | 804 } |
| 810 } else { | |
| 811 PrintF("<unknown>"); | |
| 812 } | 805 } |
| 813 | 806 |
| 814 if (print_args) { | 807 if (print_args) { |
| 815 // function arguments | 808 // function arguments |
| 816 // (we are intentionally only printing the actually | 809 // (we are intentionally only printing the actually |
| 817 // supplied parameters, not all parameters required) | 810 // supplied parameters, not all parameters required) |
| 818 PrintF(file, "(this="); | 811 PrintF(file, "(this="); |
| 819 frame->receiver()->ShortPrint(file); | 812 frame->receiver()->ShortPrint(file); |
| 820 const int length = frame->ComputeParametersCount(); | 813 const int length = frame->ComputeParametersCount(); |
| 821 for (int i = 0; i < length; i++) { | 814 for (int i = 0; i < length; i++) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 code_->ShortPrint(); | 899 code_->ShortPrint(); |
| 907 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); | 900 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); |
| 908 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); | 901 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); |
| 909 PrintF("\npc: %d\n", offset_); | 902 PrintF("\npc: %d\n", offset_); |
| 910 } | 903 } |
| 911 | 904 |
| 912 | 905 |
| 913 JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array, | 906 JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array, |
| 914 int literal_id) { | 907 int literal_id) { |
| 915 if (literal_id == Translation::kSelfLiteralId) { | 908 if (literal_id == Translation::kSelfLiteralId) { |
| 916 return JSFunction::cast(function()); | 909 return function(); |
| 917 } | 910 } |
| 918 | 911 |
| 919 return JSFunction::cast(literal_array->get(literal_id)); | 912 return JSFunction::cast(literal_array->get(literal_id)); |
| 920 } | 913 } |
| 921 | 914 |
| 922 | 915 |
| 923 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { | 916 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { |
| 924 ASSERT(frames->length() == 0); | 917 ASSERT(frames->length() == 0); |
| 925 ASSERT(is_optimized()); | 918 ASSERT(is_optimized()); |
| 926 | 919 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 } | 1004 } |
| 1012 } | 1005 } |
| 1013 ASSERT(!is_constructor); | 1006 ASSERT(!is_constructor); |
| 1014 } | 1007 } |
| 1015 | 1008 |
| 1016 | 1009 |
| 1017 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( | 1010 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( |
| 1018 int* deopt_index) { | 1011 int* deopt_index) { |
| 1019 ASSERT(is_optimized()); | 1012 ASSERT(is_optimized()); |
| 1020 | 1013 |
| 1021 JSFunction* opt_function = JSFunction::cast(function()); | 1014 JSFunction* opt_function = function(); |
| 1022 Code* code = opt_function->code(); | 1015 Code* code = opt_function->code(); |
| 1023 | 1016 |
| 1024 // The code object may have been replaced by lazy deoptimization. Fall | 1017 // The code object may have been replaced by lazy deoptimization. Fall |
| 1025 // back to a slow search in this case to find the original optimized | 1018 // back to a slow search in this case to find the original optimized |
| 1026 // code object. | 1019 // code object. |
| 1027 if (!code->contains(pc())) { | 1020 if (!code->contains(pc())) { |
| 1028 code = isolate()->inner_pointer_to_code_cache()-> | 1021 code = isolate()->inner_pointer_to_code_cache()-> |
| 1029 GcSafeFindCodeForInnerPointer(pc()); | 1022 GcSafeFindCodeForInnerPointer(pc()); |
| 1030 } | 1023 } |
| 1031 ASSERT(code != NULL); | 1024 ASSERT(code != NULL); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 int index) { | 1118 int index) { |
| 1126 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); | 1119 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); |
| 1127 } | 1120 } |
| 1128 | 1121 |
| 1129 | 1122 |
| 1130 void JavaScriptFrame::Print(StringStream* accumulator, | 1123 void JavaScriptFrame::Print(StringStream* accumulator, |
| 1131 PrintMode mode, | 1124 PrintMode mode, |
| 1132 int index) const { | 1125 int index) const { |
| 1133 HandleScope scope(isolate()); | 1126 HandleScope scope(isolate()); |
| 1134 Object* receiver = this->receiver(); | 1127 Object* receiver = this->receiver(); |
| 1135 Object* function = this->function(); | 1128 JSFunction* function = this->function(); |
| 1136 | 1129 |
| 1137 accumulator->PrintSecurityTokenIfChanged(function); | 1130 accumulator->PrintSecurityTokenIfChanged(function); |
| 1138 PrintIndex(accumulator, mode, index); | 1131 PrintIndex(accumulator, mode, index); |
| 1139 Code* code = NULL; | 1132 Code* code = NULL; |
| 1140 if (IsConstructor()) accumulator->Add("new "); | 1133 if (IsConstructor()) accumulator->Add("new "); |
| 1141 accumulator->PrintFunction(function, receiver, &code); | 1134 accumulator->PrintFunction(function, receiver, &code); |
| 1142 | 1135 |
| 1143 // Get scope information for nicer output, if possible. If code is NULL, or | 1136 // Get scope information for nicer output, if possible. If code is NULL, or |
| 1144 // doesn't contain scope info, scope_info will return 0 for the number of | 1137 // doesn't contain scope info, scope_info will return 0 for the number of |
| 1145 // parameters, stack local variables, context local variables, stack slots, | 1138 // parameters, stack local variables, context local variables, stack slots, |
| 1146 // or context slots. | 1139 // or context slots. |
| 1147 Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate())); | 1140 Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate())); |
| 1148 | 1141 |
| 1149 if (function->IsJSFunction()) { | 1142 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1150 Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared()); | 1143 scope_info = Handle<ScopeInfo>(shared->scope_info()); |
| 1151 scope_info = Handle<ScopeInfo>(shared->scope_info()); | 1144 Object* script_obj = shared->script(); |
| 1152 Object* script_obj = shared->script(); | 1145 if (script_obj->IsScript()) { |
| 1153 if (script_obj->IsScript()) { | 1146 Handle<Script> script(Script::cast(script_obj)); |
| 1154 Handle<Script> script(Script::cast(script_obj)); | 1147 accumulator->Add(" ["); |
| 1155 accumulator->Add(" ["); | 1148 accumulator->PrintName(script->name()); |
| 1156 accumulator->PrintName(script->name()); | |
| 1157 | 1149 |
| 1158 Address pc = this->pc(); | 1150 Address pc = this->pc(); |
| 1159 if (code != NULL && code->kind() == Code::FUNCTION && | 1151 if (code != NULL && code->kind() == Code::FUNCTION && |
| 1160 pc >= code->instruction_start() && pc < code->instruction_end()) { | 1152 pc >= code->instruction_start() && pc < code->instruction_end()) { |
| 1161 int source_pos = code->SourcePosition(pc); | 1153 int source_pos = code->SourcePosition(pc); |
| 1162 int line = GetScriptLineNumberSafe(script, source_pos) + 1; | 1154 int line = GetScriptLineNumberSafe(script, source_pos) + 1; |
| 1163 accumulator->Add(":%d", line); | 1155 accumulator->Add(":%d", line); |
| 1164 } else { | 1156 } else { |
| 1165 int function_start_pos = shared->start_position(); | 1157 int function_start_pos = shared->start_position(); |
| 1166 int line = GetScriptLineNumberSafe(script, function_start_pos) + 1; | 1158 int line = GetScriptLineNumberSafe(script, function_start_pos) + 1; |
| 1167 accumulator->Add(":~%d", line); | 1159 accumulator->Add(":~%d", line); |
| 1168 } | 1160 } |
| 1169 | 1161 |
| 1170 accumulator->Add("] "); | 1162 accumulator->Add("] "); |
| 1171 } | |
| 1172 } | 1163 } |
| 1173 | 1164 |
| 1174 accumulator->Add("(this=%o", receiver); | 1165 accumulator->Add("(this=%o", receiver); |
| 1175 | 1166 |
| 1176 // Print the parameters. | 1167 // Print the parameters. |
| 1177 int parameters_count = ComputeParametersCount(); | 1168 int parameters_count = ComputeParametersCount(); |
| 1178 for (int i = 0; i < parameters_count; i++) { | 1169 for (int i = 0; i < parameters_count; i++) { |
| 1179 accumulator->Add(","); | 1170 accumulator->Add(","); |
| 1180 // If we have a name for the parameter we print it. Nameless | 1171 // If we have a name for the parameter we print it. Nameless |
| 1181 // parameters are either because we have more actual parameters | 1172 // parameters are either because we have more actual parameters |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 if (expressions_start < expressions_count) { | 1242 if (expressions_start < expressions_count) { |
| 1252 accumulator->Add(" // expression stack (top to bottom)\n"); | 1243 accumulator->Add(" // expression stack (top to bottom)\n"); |
| 1253 } | 1244 } |
| 1254 for (int i = expressions_count - 1; i >= expressions_start; i--) { | 1245 for (int i = expressions_count - 1; i >= expressions_start; i--) { |
| 1255 if (IsExpressionInsideHandler(i)) continue; | 1246 if (IsExpressionInsideHandler(i)) continue; |
| 1256 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); | 1247 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); |
| 1257 } | 1248 } |
| 1258 | 1249 |
| 1259 // Print details about the function. | 1250 // Print details about the function. |
| 1260 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { | 1251 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { |
| 1261 SharedFunctionInfo* shared = JSFunction::cast(function)->shared(); | 1252 SharedFunctionInfo* shared = function->shared(); |
| 1262 accumulator->Add("--------- s o u r c e c o d e ---------\n"); | 1253 accumulator->Add("--------- s o u r c e c o d e ---------\n"); |
| 1263 shared->SourceCodePrint(accumulator, FLAG_max_stack_trace_source_length); | 1254 shared->SourceCodePrint(accumulator, FLAG_max_stack_trace_source_length); |
| 1264 accumulator->Add("\n-----------------------------------------\n"); | 1255 accumulator->Add("\n-----------------------------------------\n"); |
| 1265 } | 1256 } |
| 1266 | 1257 |
| 1267 accumulator->Add("}\n\n"); | 1258 accumulator->Add("}\n\n"); |
| 1268 } | 1259 } |
| 1269 | 1260 |
| 1270 | 1261 |
| 1271 void ArgumentsAdaptorFrame::Print(StringStream* accumulator, | 1262 void ArgumentsAdaptorFrame::Print(StringStream* accumulator, |
| 1272 PrintMode mode, | 1263 PrintMode mode, |
| 1273 int index) const { | 1264 int index) const { |
| 1274 int actual = ComputeParametersCount(); | 1265 int actual = ComputeParametersCount(); |
| 1275 int expected = -1; | 1266 int expected = -1; |
| 1276 Object* function = this->function(); | 1267 JSFunction* function = this->function(); |
| 1277 if (function->IsJSFunction()) { | 1268 expected = function->shared()->formal_parameter_count(); |
| 1278 expected = JSFunction::cast(function)->shared()->formal_parameter_count(); | |
| 1279 } | |
| 1280 | 1269 |
| 1281 PrintIndex(accumulator, mode, index); | 1270 PrintIndex(accumulator, mode, index); |
| 1282 accumulator->Add("arguments adaptor frame: %d->%d", actual, expected); | 1271 accumulator->Add("arguments adaptor frame: %d->%d", actual, expected); |
| 1283 if (mode == OVERVIEW) { | 1272 if (mode == OVERVIEW) { |
| 1284 accumulator->Add("\n"); | 1273 accumulator->Add("\n"); |
| 1285 return; | 1274 return; |
| 1286 } | 1275 } |
| 1287 accumulator->Add(" {\n"); | 1276 accumulator->Add(" {\n"); |
| 1288 | 1277 |
| 1289 // Print actual arguments. | 1278 // Print actual arguments. |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 ZoneList<StackFrame*> list(10, zone); | 1596 ZoneList<StackFrame*> list(10, zone); |
| 1608 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1597 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1609 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1598 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1610 list.Add(frame, zone); | 1599 list.Add(frame, zone); |
| 1611 } | 1600 } |
| 1612 return list.ToVector(); | 1601 return list.ToVector(); |
| 1613 } | 1602 } |
| 1614 | 1603 |
| 1615 | 1604 |
| 1616 } } // namespace v8::internal | 1605 } } // namespace v8::internal |
| OLD | NEW |