| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 __ InitializeRootRegister(); | 934 __ InitializeRootRegister(); |
| 935 | 935 |
| 936 __ pop(at); // Get continuation, leave pc on stack. | 936 __ pop(at); // Get continuation, leave pc on stack. |
| 937 __ pop(ra); | 937 __ pop(ra); |
| 938 __ Jump(at); | 938 __ Jump(at); |
| 939 __ stop("Unreachable."); | 939 __ stop("Unreachable."); |
| 940 } | 940 } |
| 941 | 941 |
| 942 | 942 |
| 943 // Maximum size of a table entry generated below. | 943 // Maximum size of a table entry generated below. |
| 944 const int Deoptimizer::table_entry_size_ = 12 * Assembler::kInstrSize; | 944 const int Deoptimizer::table_entry_size_ = 9 * Assembler::kInstrSize; |
| 945 | 945 |
| 946 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 946 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |
| 947 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); | 947 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); |
| 948 | 948 |
| 949 // Create a sequence of deoptimization entries. Note that any | 949 // Create a sequence of deoptimization entries. Note that any |
| 950 // registers may be still live. | 950 // registers may be still live. |
| 951 Label table_start; | 951 Label table_start; |
| 952 __ bind(&table_start); | 952 __ bind(&table_start); |
| 953 for (int i = 0; i < count(); i++) { | 953 for (int i = 0; i < count(); i++) { |
| 954 Label start; | 954 Label start; |
| 955 __ bind(&start); | 955 __ bind(&start); |
| 956 if (type() != EAGER) { | 956 if (type() != EAGER) { |
| 957 // Emulate ia32 like call by pushing return address to stack. | 957 // Emulate ia32 like call by pushing return address to stack. |
| 958 __ addiu(sp, sp, -3 * kPointerSize); | 958 __ addiu(sp, sp, -2 * kPointerSize); |
| 959 __ sw(ra, MemOperand(sp, 2 * kPointerSize)); | 959 __ sw(ra, MemOperand(sp, 1 * kPointerSize)); |
| 960 } else { | 960 } else { |
| 961 __ addiu(sp, sp, -2 * kPointerSize); | 961 __ addiu(sp, sp, -1 * kPointerSize); |
| 962 } | 962 } |
| 963 // Using ori makes sure only one instruction is generated. This will work | |
| 964 // as long as the number of deopt entries is below 2^16. | |
| 965 __ ori(at, zero_reg, i); | |
| 966 __ sw(at, MemOperand(sp, kPointerSize)); | |
| 967 __ sw(ra, MemOperand(sp, 0)); | |
| 968 // This branch instruction only jumps over one instruction, and that is | |
| 969 // executed in the delay slot. The result is that execution is linear but | |
| 970 // the ra register is updated. | |
| 971 __ bal(1); | |
| 972 // Jump over the remaining deopt entries (including this one). | 963 // Jump over the remaining deopt entries (including this one). |
| 973 // Only include the remaining part of the current entry in the calculation. | 964 // This code is always reached by calling Jump, which puts the target (label |
| 965 // start) into t9. |
| 974 const int remaining_entries = (count() - i) * table_entry_size_; | 966 const int remaining_entries = (count() - i) * table_entry_size_; |
| 975 const int cur_size = masm()->SizeOfCodeGeneratedSince(&start); | 967 __ Addu(t9, t9, remaining_entries); |
| 976 // ra points to the instruction after the delay slot. Adjust by 4. | 968 // 'at' was clobbered so we can only load the current entry value here. |
| 977 __ Addu(at, ra, remaining_entries - cur_size - Assembler::kInstrSize); | 969 __ li(at, i); |
| 978 __ lw(ra, MemOperand(sp, 0)); | 970 __ jr(t9); // Expose delay slot. |
| 979 __ jr(at); // Expose delay slot. | 971 __ sw(at, MemOperand(sp, 0 * kPointerSize)); // In the delay slot. |
| 980 __ addiu(sp, sp, kPointerSize); // In delay slot. | |
| 981 | 972 |
| 982 // Pad the rest of the code. | 973 // Pad the rest of the code. |
| 983 while (table_entry_size_ > (masm()->SizeOfCodeGeneratedSince(&start))) { | 974 while (table_entry_size_ > (masm()->SizeOfCodeGeneratedSince(&start))) { |
| 984 __ nop(); | 975 __ nop(); |
| 985 } | 976 } |
| 986 | 977 |
| 987 ASSERT_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); | 978 ASSERT_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
| 988 } | 979 } |
| 989 | 980 |
| 990 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | 981 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
| 991 count() * table_entry_size_); | 982 count() * table_entry_size_); |
| 992 } | 983 } |
| 993 | 984 |
| 994 #undef __ | 985 #undef __ |
| 995 | 986 |
| 996 | 987 |
| 997 } } // namespace v8::internal | 988 } } // namespace v8::internal |
| OLD | NEW |