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 |