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 |