| 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 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 case Translation::REGISTER: | 782 case Translation::REGISTER: |
| 783 case Translation::INT32_REGISTER: | 783 case Translation::INT32_REGISTER: |
| 784 case Translation::UINT32_REGISTER: | 784 case Translation::UINT32_REGISTER: |
| 785 case Translation::DOUBLE_REGISTER: | 785 case Translation::DOUBLE_REGISTER: |
| 786 case Translation::STACK_SLOT: | 786 case Translation::STACK_SLOT: |
| 787 case Translation::INT32_STACK_SLOT: | 787 case Translation::INT32_STACK_SLOT: |
| 788 case Translation::UINT32_STACK_SLOT: | 788 case Translation::UINT32_STACK_SLOT: |
| 789 case Translation::DOUBLE_STACK_SLOT: | 789 case Translation::DOUBLE_STACK_SLOT: |
| 790 case Translation::LITERAL: | 790 case Translation::LITERAL: |
| 791 case Translation::ARGUMENTS_OBJECT: | 791 case Translation::ARGUMENTS_OBJECT: |
| 792 case Translation::DUPLICATE: | |
| 793 default: | 792 default: |
| 794 UNREACHABLE(); | 793 UNREACHABLE(); |
| 795 break; | 794 break; |
| 796 } | 795 } |
| 797 } | 796 } |
| 798 | 797 |
| 799 // Print some helpful diagnostic information. | 798 // Print some helpful diagnostic information. |
| 800 if (trace_) { | 799 if (trace_) { |
| 801 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 800 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
| 802 int index = output_count_ - 1; // Index of the topmost frame. | 801 int index = output_count_ - 1; // Index of the topmost frame. |
| (...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 return "heap number"; | 1717 return "heap number"; |
| 1719 } | 1718 } |
| 1720 | 1719 |
| 1721 | 1720 |
| 1722 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, | 1721 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
| 1723 int object_opcode, | 1722 int object_opcode, |
| 1724 int field_index) { | 1723 int field_index) { |
| 1725 disasm::NameConverter converter; | 1724 disasm::NameConverter converter; |
| 1726 Address object_slot = deferred_objects_.last().slot_address(); | 1725 Address object_slot = deferred_objects_.last().slot_address(); |
| 1727 | 1726 |
| 1728 // Ignore commands marked as duplicate and act on the first non-duplicate. | |
| 1729 Translation::Opcode opcode = | 1727 Translation::Opcode opcode = |
| 1730 static_cast<Translation::Opcode>(iterator->Next()); | 1728 static_cast<Translation::Opcode>(iterator->Next()); |
| 1731 while (opcode == Translation::DUPLICATE) { | |
| 1732 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1733 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | |
| 1734 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1735 } | |
| 1736 | 1729 |
| 1737 switch (opcode) { | 1730 switch (opcode) { |
| 1738 case Translation::BEGIN: | 1731 case Translation::BEGIN: |
| 1739 case Translation::JS_FRAME: | 1732 case Translation::JS_FRAME: |
| 1740 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1733 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 1741 case Translation::CONSTRUCT_STUB_FRAME: | 1734 case Translation::CONSTRUCT_STUB_FRAME: |
| 1742 case Translation::GETTER_STUB_FRAME: | 1735 case Translation::GETTER_STUB_FRAME: |
| 1743 case Translation::SETTER_STUB_FRAME: | 1736 case Translation::SETTER_STUB_FRAME: |
| 1744 case Translation::COMPILED_STUB_FRAME: | 1737 case Translation::COMPILED_STUB_FRAME: |
| 1745 case Translation::ARGUMENTS_OBJECT: | 1738 case Translation::ARGUMENTS_OBJECT: |
| 1746 case Translation::DUPLICATE: | |
| 1747 UNREACHABLE(); | 1739 UNREACHABLE(); |
| 1748 return; | 1740 return; |
| 1749 | 1741 |
| 1750 case Translation::REGISTER: { | 1742 case Translation::REGISTER: { |
| 1751 int input_reg = iterator->Next(); | 1743 int input_reg = iterator->Next(); |
| 1752 intptr_t input_value = input_->GetRegister(input_reg); | 1744 intptr_t input_value = input_->GetRegister(input_reg); |
| 1753 if (trace_) { | 1745 if (trace_) { |
| 1754 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1746 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1755 reinterpret_cast<intptr_t>(object_slot), | 1747 reinterpret_cast<intptr_t>(object_slot), |
| 1756 field_index); | 1748 field_index); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 | 1911 |
| 1920 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 1912 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
| 1921 int frame_index, | 1913 int frame_index, |
| 1922 unsigned output_offset, | 1914 unsigned output_offset, |
| 1923 DeoptimizerTranslatedValueType value_type) { | 1915 DeoptimizerTranslatedValueType value_type) { |
| 1924 disasm::NameConverter converter; | 1916 disasm::NameConverter converter; |
| 1925 // A GC-safe temporary placeholder that we can put in the output frame. | 1917 // A GC-safe temporary placeholder that we can put in the output frame. |
| 1926 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 1918 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1927 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; | 1919 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; |
| 1928 | 1920 |
| 1929 // Ignore commands marked as duplicate and act on the first non-duplicate. | |
| 1930 Translation::Opcode opcode = | 1921 Translation::Opcode opcode = |
| 1931 static_cast<Translation::Opcode>(iterator->Next()); | 1922 static_cast<Translation::Opcode>(iterator->Next()); |
| 1932 while (opcode == Translation::DUPLICATE) { | |
| 1933 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1934 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | |
| 1935 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1936 } | |
| 1937 | 1923 |
| 1938 switch (opcode) { | 1924 switch (opcode) { |
| 1939 case Translation::BEGIN: | 1925 case Translation::BEGIN: |
| 1940 case Translation::JS_FRAME: | 1926 case Translation::JS_FRAME: |
| 1941 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1927 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 1942 case Translation::CONSTRUCT_STUB_FRAME: | 1928 case Translation::CONSTRUCT_STUB_FRAME: |
| 1943 case Translation::GETTER_STUB_FRAME: | 1929 case Translation::GETTER_STUB_FRAME: |
| 1944 case Translation::SETTER_STUB_FRAME: | 1930 case Translation::SETTER_STUB_FRAME: |
| 1945 case Translation::COMPILED_STUB_FRAME: | 1931 case Translation::COMPILED_STUB_FRAME: |
| 1946 case Translation::DUPLICATE: | |
| 1947 UNREACHABLE(); | 1932 UNREACHABLE(); |
| 1948 return; | 1933 return; |
| 1949 | 1934 |
| 1950 case Translation::REGISTER: { | 1935 case Translation::REGISTER: { |
| 1951 int input_reg = iterator->Next(); | 1936 int input_reg = iterator->Next(); |
| 1952 intptr_t input_value = input_->GetRegister(input_reg); | 1937 intptr_t input_value = input_->GetRegister(input_reg); |
| 1953 if (trace_) { | 1938 if (trace_) { |
| 1954 PrintF( | 1939 PrintF( |
| 1955 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 1940 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
| 1956 output_[frame_index]->GetTop() + output_offset, | 1941 output_[frame_index]->GetTop() + output_offset, |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2190 disasm::NameConverter converter; | 2175 disasm::NameConverter converter; |
| 2191 FrameDescription* output = output_[0]; | 2176 FrameDescription* output = output_[0]; |
| 2192 | 2177 |
| 2193 // The input values are all part of the unoptimized frame so they | 2178 // The input values are all part of the unoptimized frame so they |
| 2194 // are all tagged pointers. | 2179 // are all tagged pointers. |
| 2195 uintptr_t input_value = input_->GetFrameSlot(*input_offset); | 2180 uintptr_t input_value = input_->GetFrameSlot(*input_offset); |
| 2196 Object* input_object = reinterpret_cast<Object*>(input_value); | 2181 Object* input_object = reinterpret_cast<Object*>(input_value); |
| 2197 | 2182 |
| 2198 Translation::Opcode opcode = | 2183 Translation::Opcode opcode = |
| 2199 static_cast<Translation::Opcode>(iterator->Next()); | 2184 static_cast<Translation::Opcode>(iterator->Next()); |
| 2200 bool duplicate = (opcode == Translation::DUPLICATE); | |
| 2201 if (duplicate) { | |
| 2202 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 2203 } | |
| 2204 | 2185 |
| 2205 switch (opcode) { | 2186 switch (opcode) { |
| 2206 case Translation::BEGIN: | 2187 case Translation::BEGIN: |
| 2207 case Translation::JS_FRAME: | 2188 case Translation::JS_FRAME: |
| 2208 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 2189 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 2209 case Translation::CONSTRUCT_STUB_FRAME: | 2190 case Translation::CONSTRUCT_STUB_FRAME: |
| 2210 case Translation::GETTER_STUB_FRAME: | 2191 case Translation::GETTER_STUB_FRAME: |
| 2211 case Translation::SETTER_STUB_FRAME: | 2192 case Translation::SETTER_STUB_FRAME: |
| 2212 case Translation::COMPILED_STUB_FRAME: | 2193 case Translation::COMPILED_STUB_FRAME: |
| 2213 case Translation::DUPLICATE: | |
| 2214 UNREACHABLE(); // Malformed input. | 2194 UNREACHABLE(); // Malformed input. |
| 2215 return false; | 2195 return false; |
| 2216 | 2196 |
| 2217 case Translation::REGISTER: { | 2197 case Translation::REGISTER: { |
| 2218 int output_reg = iterator->Next(); | 2198 int output_reg = iterator->Next(); |
| 2219 if (FLAG_trace_osr) { | 2199 if (FLAG_trace_osr) { |
| 2220 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", | 2200 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", |
| 2221 converter.NameOfCPURegister(output_reg), | 2201 converter.NameOfCPURegister(output_reg), |
| 2222 input_value, | 2202 input_value, |
| 2223 *input_offset); | 2203 *input_offset); |
| 2224 } | 2204 } |
| 2225 output->SetRegister(output_reg, input_value); | 2205 output->SetRegister(output_reg, input_value); |
| 2226 break; | 2206 break; |
| 2227 } | 2207 } |
| 2228 | 2208 |
| 2229 case Translation::INT32_REGISTER: { | 2209 case Translation::INT32_REGISTER: { |
| 2230 int32_t int32_value = 0; | 2210 int32_t int32_value = 0; |
| 2231 if (!input_object->ToInt32(&int32_value)) return false; | 2211 if (!input_object->ToInt32(&int32_value)) return false; |
| 2232 | 2212 |
| 2233 int output_reg = iterator->Next(); | 2213 int output_reg = iterator->Next(); |
| 2234 if (FLAG_trace_osr) { | 2214 if (FLAG_trace_osr) { |
| 2235 PrintF(" %s <- %d (int32) ; [sp + %d]\n", | 2215 PrintF(" %s <- %d (int32) ; [sp + %d]\n", |
| 2236 converter.NameOfCPURegister(output_reg), | 2216 converter.NameOfCPURegister(output_reg), |
| 2237 int32_value, | 2217 int32_value, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 case Translation::ARGUMENTS_OBJECT: { | 2342 case Translation::ARGUMENTS_OBJECT: { |
| 2363 // Optimized code assumes that the argument object has not been | 2343 // Optimized code assumes that the argument object has not been |
| 2364 // materialized and so bypasses it when doing arguments access. | 2344 // materialized and so bypasses it when doing arguments access. |
| 2365 // We should have bailed out before starting the frame | 2345 // We should have bailed out before starting the frame |
| 2366 // translation. | 2346 // translation. |
| 2367 UNREACHABLE(); | 2347 UNREACHABLE(); |
| 2368 return false; | 2348 return false; |
| 2369 } | 2349 } |
| 2370 } | 2350 } |
| 2371 | 2351 |
| 2372 if (!duplicate) *input_offset -= kPointerSize; | 2352 *input_offset -= kPointerSize; |
| 2373 return true; | 2353 return true; |
| 2374 } | 2354 } |
| 2375 | 2355 |
| 2376 | 2356 |
| 2377 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, | 2357 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, |
| 2378 Code* interrupt_code, | 2358 Code* interrupt_code, |
| 2379 Code* replacement_code) { | 2359 Code* replacement_code) { |
| 2380 // Iterate over the back edge table and patch every interrupt | 2360 // Iterate over the back edge table and patch every interrupt |
| 2381 // call to an unconditional call to the replacement code. | 2361 // call to an unconditional call to the replacement code. |
| 2382 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 2362 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2816 buffer_->Add(index, zone()); | 2796 buffer_->Add(index, zone()); |
| 2817 } | 2797 } |
| 2818 | 2798 |
| 2819 | 2799 |
| 2820 void Translation::StoreLiteral(int literal_id) { | 2800 void Translation::StoreLiteral(int literal_id) { |
| 2821 buffer_->Add(LITERAL, zone()); | 2801 buffer_->Add(LITERAL, zone()); |
| 2822 buffer_->Add(literal_id, zone()); | 2802 buffer_->Add(literal_id, zone()); |
| 2823 } | 2803 } |
| 2824 | 2804 |
| 2825 | 2805 |
| 2826 void Translation::MarkDuplicate() { | 2806 void Translation::StoreArgumentsObject(bool args_known, |
| 2827 buffer_->Add(DUPLICATE, zone()); | 2807 int args_index, |
| 2808 int args_length) { |
| 2809 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
| 2810 buffer_->Add(args_known, zone()); |
| 2811 buffer_->Add(args_index, zone()); |
| 2812 buffer_->Add(args_length, zone()); |
| 2828 } | 2813 } |
| 2829 | 2814 |
| 2830 | 2815 |
| 2831 int Translation::NumberOfOperandsFor(Opcode opcode) { | 2816 int Translation::NumberOfOperandsFor(Opcode opcode) { |
| 2832 switch (opcode) { | 2817 switch (opcode) { |
| 2833 case DUPLICATE: | |
| 2834 return 0; | |
| 2835 case GETTER_STUB_FRAME: | 2818 case GETTER_STUB_FRAME: |
| 2836 case SETTER_STUB_FRAME: | 2819 case SETTER_STUB_FRAME: |
| 2837 case ARGUMENTS_OBJECT: | 2820 case ARGUMENTS_OBJECT: |
| 2838 case REGISTER: | 2821 case REGISTER: |
| 2839 case INT32_REGISTER: | 2822 case INT32_REGISTER: |
| 2840 case UINT32_REGISTER: | 2823 case UINT32_REGISTER: |
| 2841 case DOUBLE_REGISTER: | 2824 case DOUBLE_REGISTER: |
| 2842 case STACK_SLOT: | 2825 case STACK_SLOT: |
| 2843 case INT32_STACK_SLOT: | 2826 case INT32_STACK_SLOT: |
| 2844 case UINT32_STACK_SLOT: | 2827 case UINT32_STACK_SLOT: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2889 case INT32_STACK_SLOT: | 2872 case INT32_STACK_SLOT: |
| 2890 return "INT32_STACK_SLOT"; | 2873 return "INT32_STACK_SLOT"; |
| 2891 case UINT32_STACK_SLOT: | 2874 case UINT32_STACK_SLOT: |
| 2892 return "UINT32_STACK_SLOT"; | 2875 return "UINT32_STACK_SLOT"; |
| 2893 case DOUBLE_STACK_SLOT: | 2876 case DOUBLE_STACK_SLOT: |
| 2894 return "DOUBLE_STACK_SLOT"; | 2877 return "DOUBLE_STACK_SLOT"; |
| 2895 case LITERAL: | 2878 case LITERAL: |
| 2896 return "LITERAL"; | 2879 return "LITERAL"; |
| 2897 case ARGUMENTS_OBJECT: | 2880 case ARGUMENTS_OBJECT: |
| 2898 return "ARGUMENTS_OBJECT"; | 2881 return "ARGUMENTS_OBJECT"; |
| 2899 case DUPLICATE: | |
| 2900 return "DUPLICATE"; | |
| 2901 } | 2882 } |
| 2902 UNREACHABLE(); | 2883 UNREACHABLE(); |
| 2903 return ""; | 2884 return ""; |
| 2904 } | 2885 } |
| 2905 | 2886 |
| 2906 #endif | 2887 #endif |
| 2907 | 2888 |
| 2908 | 2889 |
| 2909 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { | 2890 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { |
| 2910 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); | 2891 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2942 break; | 2923 break; |
| 2943 | 2924 |
| 2944 case Translation::ARGUMENTS_OBJECT: | 2925 case Translation::ARGUMENTS_OBJECT: |
| 2945 // This can be only emitted for local slots not for argument slots. | 2926 // This can be only emitted for local slots not for argument slots. |
| 2946 break; | 2927 break; |
| 2947 | 2928 |
| 2948 case Translation::REGISTER: | 2929 case Translation::REGISTER: |
| 2949 case Translation::INT32_REGISTER: | 2930 case Translation::INT32_REGISTER: |
| 2950 case Translation::UINT32_REGISTER: | 2931 case Translation::UINT32_REGISTER: |
| 2951 case Translation::DOUBLE_REGISTER: | 2932 case Translation::DOUBLE_REGISTER: |
| 2952 case Translation::DUPLICATE: | |
| 2953 // We are at safepoint which corresponds to call. All registers are | 2933 // We are at safepoint which corresponds to call. All registers are |
| 2954 // saved by caller so there would be no live registers at this | 2934 // saved by caller so there would be no live registers at this |
| 2955 // point. Thus these translation commands should not be used. | 2935 // point. Thus these translation commands should not be used. |
| 2956 break; | 2936 break; |
| 2957 | 2937 |
| 2958 case Translation::STACK_SLOT: { | 2938 case Translation::STACK_SLOT: { |
| 2959 int slot_index = iterator->Next(); | 2939 int slot_index = iterator->Next(); |
| 2960 Address slot_addr = SlotAddress(frame, slot_index); | 2940 Address slot_addr = SlotAddress(frame, slot_index); |
| 2961 return SlotRef(slot_addr, SlotRef::TAGGED); | 2941 return SlotRef(slot_addr, SlotRef::TAGGED); |
| 2962 } | 2942 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 | 3091 |
| 3112 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3092 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 3113 v->VisitPointer(BitCast<Object**>(&function_)); | 3093 v->VisitPointer(BitCast<Object**>(&function_)); |
| 3114 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3094 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 3115 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3095 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 3116 } | 3096 } |
| 3117 | 3097 |
| 3118 #endif // ENABLE_DEBUGGER_SUPPORT | 3098 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3119 | 3099 |
| 3120 } } // namespace v8::internal | 3100 } } // namespace v8::internal |
| OLD | NEW |