OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 output_[index]->GetPc(), | 814 output_[index]->GetPc(), |
815 FullCodeGenerator::State2String( | 815 FullCodeGenerator::State2String( |
816 static_cast<FullCodeGenerator::State>( | 816 static_cast<FullCodeGenerator::State>( |
817 output_[index]->GetState()->value())), | 817 output_[index]->GetState()->value())), |
818 has_alignment_padding_ ? "with padding" : "no padding", | 818 has_alignment_padding_ ? "with padding" : "no padding", |
819 ms); | 819 ms); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 | 823 |
| 824 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, |
| 825 int frame_index) { |
| 826 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 827 unsigned height = iterator->Next(); |
| 828 unsigned height_in_bytes = height * kPointerSize; |
| 829 if (trace_) { |
| 830 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); |
| 831 } |
| 832 |
| 833 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; |
| 834 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 835 |
| 836 // Allocate and store the output frame description. |
| 837 FrameDescription* output_frame = |
| 838 new(output_frame_size) FrameDescription(output_frame_size, function); |
| 839 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
| 840 |
| 841 // Arguments adaptor can not be topmost or bottommost. |
| 842 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); |
| 843 ASSERT(output_[frame_index] == NULL); |
| 844 output_[frame_index] = output_frame; |
| 845 |
| 846 // The top address of the frame is computed from the previous |
| 847 // frame's top and this frame's size. |
| 848 intptr_t top_address; |
| 849 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 850 output_frame->SetTop(top_address); |
| 851 |
| 852 // Compute the incoming parameter translation. |
| 853 int parameter_count = height; |
| 854 unsigned output_offset = output_frame_size; |
| 855 for (int i = 0; i < parameter_count; ++i) { |
| 856 output_offset -= kPointerSize; |
| 857 DoTranslateCommand(iterator, frame_index, output_offset); |
| 858 } |
| 859 |
| 860 // Read caller's PC from the previous frame. |
| 861 output_offset -= kPointerSize; |
| 862 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
| 863 output_frame->SetFrameSlot(output_offset, callers_pc); |
| 864 if (trace_) { |
| 865 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 866 V8PRIxPTR " ; caller's pc\n", |
| 867 top_address + output_offset, output_offset, callers_pc); |
| 868 } |
| 869 |
| 870 // Read caller's FP from the previous frame, and set this frame's FP. |
| 871 output_offset -= kPointerSize; |
| 872 intptr_t value = output_[frame_index - 1]->GetFp(); |
| 873 output_frame->SetFrameSlot(output_offset, value); |
| 874 intptr_t fp_value = top_address + output_offset; |
| 875 output_frame->SetFp(fp_value); |
| 876 if (trace_) { |
| 877 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 878 V8PRIxPTR " ; caller's fp\n", |
| 879 fp_value, output_offset, value); |
| 880 } |
| 881 |
| 882 // A marker value is used in place of the context. |
| 883 output_offset -= kPointerSize; |
| 884 intptr_t context = reinterpret_cast<intptr_t>( |
| 885 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 886 output_frame->SetFrameSlot(output_offset, context); |
| 887 if (trace_) { |
| 888 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 889 V8PRIxPTR " ; context (adaptor sentinel)\n", |
| 890 top_address + output_offset, output_offset, context); |
| 891 } |
| 892 |
| 893 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. |
| 894 output_offset -= kPointerSize; |
| 895 value = reinterpret_cast<intptr_t>(function); |
| 896 output_frame->SetFrameSlot(output_offset, value); |
| 897 if (trace_) { |
| 898 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 899 V8PRIxPTR " ; function\n", |
| 900 top_address + output_offset, output_offset, value); |
| 901 } |
| 902 |
| 903 // Number of incoming arguments. |
| 904 output_offset -= kPointerSize; |
| 905 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); |
| 906 output_frame->SetFrameSlot(output_offset, value); |
| 907 if (trace_) { |
| 908 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 909 V8PRIxPTR " ; argc (%d)\n", |
| 910 top_address + output_offset, output_offset, value, height - 1); |
| 911 } |
| 912 |
| 913 ASSERT(0 == output_offset); |
| 914 |
| 915 Builtins* builtins = isolate_->builtins(); |
| 916 Code* adaptor_trampoline = |
| 917 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); |
| 918 intptr_t pc_value = reinterpret_cast<intptr_t>( |
| 919 adaptor_trampoline->instruction_start() + |
| 920 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); |
| 921 output_frame->SetPc(pc_value); |
| 922 } |
| 923 |
| 924 |
| 925 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, |
| 926 int frame_index, |
| 927 bool is_setter_stub_frame) { |
| 928 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 929 // The receiver (and the implicit return value, if any) are expected in |
| 930 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
| 931 // frame. This means that we have to use a height of 0. |
| 932 unsigned height = 0; |
| 933 unsigned height_in_bytes = height * kPointerSize; |
| 934 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
| 935 if (trace_) { |
| 936 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); |
| 937 } |
| 938 |
| 939 // We need 1 stack entry for the return address + 4 stack entries from |
| 940 // StackFrame::INTERNAL (FP, context, frame type, code object, see |
| 941 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional |
| 942 // entry for the implicit return value, see |
| 943 // StoreStubCompiler::CompileStoreViaSetter. |
| 944 unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); |
| 945 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; |
| 946 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 947 |
| 948 // Allocate and store the output frame description. |
| 949 FrameDescription* output_frame = |
| 950 new(output_frame_size) FrameDescription(output_frame_size, accessor); |
| 951 output_frame->SetFrameType(StackFrame::INTERNAL); |
| 952 |
| 953 // A frame for an accessor stub can not be the topmost or bottommost one. |
| 954 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); |
| 955 ASSERT(output_[frame_index] == NULL); |
| 956 output_[frame_index] = output_frame; |
| 957 |
| 958 // The top address of the frame is computed from the previous frame's top and |
| 959 // this frame's size. |
| 960 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 961 output_frame->SetTop(top_address); |
| 962 |
| 963 unsigned output_offset = output_frame_size; |
| 964 |
| 965 // Read caller's PC from the previous frame. |
| 966 output_offset -= kPointerSize; |
| 967 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
| 968 output_frame->SetFrameSlot(output_offset, callers_pc); |
| 969 if (trace_) { |
| 970 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 971 " ; caller's pc\n", |
| 972 top_address + output_offset, output_offset, callers_pc); |
| 973 } |
| 974 |
| 975 // Read caller's FP from the previous frame, and set this frame's FP. |
| 976 output_offset -= kPointerSize; |
| 977 intptr_t value = output_[frame_index - 1]->GetFp(); |
| 978 output_frame->SetFrameSlot(output_offset, value); |
| 979 intptr_t fp_value = top_address + output_offset; |
| 980 output_frame->SetFp(fp_value); |
| 981 if (trace_) { |
| 982 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 983 " ; caller's fp\n", |
| 984 fp_value, output_offset, value); |
| 985 } |
| 986 |
| 987 // The context can be gotten from the previous frame. |
| 988 output_offset -= kPointerSize; |
| 989 value = output_[frame_index - 1]->GetContext(); |
| 990 output_frame->SetFrameSlot(output_offset, value); |
| 991 if (trace_) { |
| 992 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 993 " ; context\n", |
| 994 top_address + output_offset, output_offset, value); |
| 995 } |
| 996 |
| 997 // A marker value is used in place of the function. |
| 998 output_offset -= kPointerSize; |
| 999 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); |
| 1000 output_frame->SetFrameSlot(output_offset, value); |
| 1001 if (trace_) { |
| 1002 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1003 " ; function (%s sentinel)\n", |
| 1004 top_address + output_offset, output_offset, value, kind); |
| 1005 } |
| 1006 |
| 1007 // Get Code object from accessor stub. |
| 1008 output_offset -= kPointerSize; |
| 1009 Builtins::Name name = is_setter_stub_frame ? |
| 1010 Builtins::kStoreIC_Setter_ForDeopt : |
| 1011 Builtins::kLoadIC_Getter_ForDeopt; |
| 1012 Code* accessor_stub = isolate_->builtins()->builtin(name); |
| 1013 value = reinterpret_cast<intptr_t>(accessor_stub); |
| 1014 output_frame->SetFrameSlot(output_offset, value); |
| 1015 if (trace_) { |
| 1016 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1017 " ; code object\n", |
| 1018 top_address + output_offset, output_offset, value); |
| 1019 } |
| 1020 |
| 1021 // Skip receiver. |
| 1022 Translation::Opcode opcode = |
| 1023 static_cast<Translation::Opcode>(iterator->Next()); |
| 1024 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
| 1025 |
| 1026 if (is_setter_stub_frame) { |
| 1027 // The implicit return value was part of the artificial setter stub |
| 1028 // environment. |
| 1029 output_offset -= kPointerSize; |
| 1030 DoTranslateCommand(iterator, frame_index, output_offset); |
| 1031 } |
| 1032 |
| 1033 ASSERT(0 == output_offset); |
| 1034 |
| 1035 Smi* offset = is_setter_stub_frame ? |
| 1036 isolate_->heap()->setter_stub_deopt_pc_offset() : |
| 1037 isolate_->heap()->getter_stub_deopt_pc_offset(); |
| 1038 intptr_t pc = reinterpret_cast<intptr_t>( |
| 1039 accessor_stub->instruction_start() + offset->value()); |
| 1040 output_frame->SetPc(pc); |
| 1041 } |
| 1042 |
| 1043 |
824 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 1044 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
825 ASSERT_NE(DEBUGGER, bailout_type_); | 1045 ASSERT_NE(DEBUGGER, bailout_type_); |
826 | 1046 |
827 // Handlify all argument object values before triggering any allocation. | 1047 // Handlify all argument object values before triggering any allocation. |
828 List<Handle<Object> > values(deferred_arguments_objects_values_.length()); | 1048 List<Handle<Object> > values(deferred_arguments_objects_values_.length()); |
829 for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) { | 1049 for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) { |
830 values.Add(Handle<Object>(deferred_arguments_objects_values_[i], | 1050 values.Add(Handle<Object>(deferred_arguments_objects_values_[i], |
831 isolate_)); | 1051 isolate_)); |
832 } | 1052 } |
833 | 1053 |
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 | 2366 |
2147 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2367 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
2148 v->VisitPointer(BitCast<Object**>(&function_)); | 2368 v->VisitPointer(BitCast<Object**>(&function_)); |
2149 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2369 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
2150 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2370 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
2151 } | 2371 } |
2152 | 2372 |
2153 #endif // ENABLE_DEBUGGER_SUPPORT | 2373 #endif // ENABLE_DEBUGGER_SUPPORT |
2154 | 2374 |
2155 } } // namespace v8::internal | 2375 } } // namespace v8::internal |
OLD | NEW |