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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 121 |
122 // For each return after a safepoint insert a absolute call to the | 122 // For each return after a safepoint insert a absolute call to the |
123 // corresponding deoptimization entry, or a short call to an absolute | 123 // corresponding deoptimization entry, or a short call to an absolute |
124 // jump if space is short. The absolute jumps are put in a table just | 124 // jump if space is short. The absolute jumps are put in a table just |
125 // before the safepoint table (space was allocated there when the Code | 125 // before the safepoint table (space was allocated there when the Code |
126 // object was created, if necessary). | 126 // object was created, if necessary). |
127 | 127 |
128 Address instruction_start = function->code()->instruction_start(); | 128 Address instruction_start = function->code()->instruction_start(); |
129 Address jump_table_address = | 129 Address jump_table_address = |
130 instruction_start + function->code()->safepoint_table_offset(); | 130 instruction_start + function->code()->safepoint_table_offset(); |
| 131 #ifdef DEBUG |
131 Address previous_pc = instruction_start; | 132 Address previous_pc = instruction_start; |
| 133 #endif |
132 | 134 |
133 SafepointTableDeoptimiztionEntryIterator deoptimizations(function->code()); | 135 SafepointTableDeoptimiztionEntryIterator deoptimizations(function->code()); |
134 Address entry_pc = NULL; | 136 Address entry_pc = NULL; |
135 | 137 |
136 SafepointEntry current_entry = deoptimizations.Next(&entry_pc); | 138 SafepointEntry current_entry = deoptimizations.Next(&entry_pc); |
137 while (current_entry.is_valid()) { | 139 while (current_entry.is_valid()) { |
138 int gap_code_size = current_entry.gap_code_size(); | 140 int gap_code_size = current_entry.gap_code_size(); |
139 unsigned deoptimization_index = current_entry.deoptimization_index(); | 141 unsigned deoptimization_index = current_entry.deoptimization_index(); |
140 | 142 |
141 #ifdef DEBUG | 143 #ifdef DEBUG |
142 // Destroy the code which is not supposed to run again. | 144 // Destroy the code which is not supposed to run again. |
143 ZapCodeRange(previous_pc, entry_pc); | 145 ZapCodeRange(previous_pc, entry_pc); |
144 #endif | 146 #endif |
145 // Position where Call will be patched in. | 147 // Position where Call will be patched in. |
146 Address call_address = entry_pc + gap_code_size; | 148 Address call_address = entry_pc + gap_code_size; |
147 // End of call instruction, if using a direct call to a 64-bit address. | 149 // End of call instruction, if using a direct call to a 64-bit address. |
148 Address call_end_address = | 150 Address call_end_address = |
149 call_address + MacroAssembler::kCallInstructionLength; | 151 call_address + MacroAssembler::kCallInstructionLength; |
150 | 152 |
151 // Find next deoptimization entry, if any. | 153 // Find next deoptimization entry, if any. |
152 Address next_pc = NULL; | 154 Address next_pc = NULL; |
153 SafepointEntry next_entry = deoptimizations.Next(&next_pc); | 155 SafepointEntry next_entry = deoptimizations.Next(&next_pc); |
154 | 156 |
155 if (!next_entry.is_valid() || next_pc >= call_end_address) { | 157 if (!next_entry.is_valid() || next_pc >= call_end_address) { |
156 // Room enough to write a long call instruction. | 158 // Room enough to write a long call instruction. |
157 CodePatcher patcher(call_address, Assembler::kCallInstructionLength); | 159 CodePatcher patcher(call_address, Assembler::kCallInstructionLength); |
158 patcher.masm()->Call(GetDeoptimizationEntry(deoptimization_index, LAZY), | 160 patcher.masm()->Call(GetDeoptimizationEntry(deoptimization_index, LAZY), |
159 RelocInfo::NONE); | 161 RelocInfo::NONE); |
| 162 #ifdef DEBUG |
160 previous_pc = call_end_address; | 163 previous_pc = call_end_address; |
| 164 #endif |
161 } else { | 165 } else { |
162 // Not room enough for a long Call instruction. Write a short call | 166 // Not room enough for a long Call instruction. Write a short call |
163 // instruction to a long jump placed elsewhere in the code. | 167 // instruction to a long jump placed elsewhere in the code. |
| 168 #ifdef DEBUG |
164 Address short_call_end_address = | 169 Address short_call_end_address = |
165 call_address + MacroAssembler::kShortCallInstructionLength; | 170 call_address + MacroAssembler::kShortCallInstructionLength; |
| 171 #endif |
166 ASSERT(next_pc >= short_call_end_address); | 172 ASSERT(next_pc >= short_call_end_address); |
167 | 173 |
168 // Write jump in jump-table. | 174 // Write jump in jump-table. |
169 jump_table_address -= MacroAssembler::kJumpInstructionLength; | 175 jump_table_address -= MacroAssembler::kJumpInstructionLength; |
170 CodePatcher jump_patcher(jump_table_address, | 176 CodePatcher jump_patcher(jump_table_address, |
171 MacroAssembler::kJumpInstructionLength); | 177 MacroAssembler::kJumpInstructionLength); |
172 jump_patcher.masm()->Jump( | 178 jump_patcher.masm()->Jump( |
173 GetDeoptimizationEntry(deoptimization_index, LAZY), | 179 GetDeoptimizationEntry(deoptimization_index, LAZY), |
174 RelocInfo::NONE); | 180 RelocInfo::NONE); |
175 | 181 |
176 // Write call to jump at call_offset. | 182 // Write call to jump at call_offset. |
177 CodePatcher call_patcher(call_address, | 183 CodePatcher call_patcher(call_address, |
178 MacroAssembler::kShortCallInstructionLength); | 184 MacroAssembler::kShortCallInstructionLength); |
179 call_patcher.masm()->call(jump_table_address); | 185 call_patcher.masm()->call(jump_table_address); |
| 186 #ifdef DEBUG |
180 previous_pc = short_call_end_address; | 187 previous_pc = short_call_end_address; |
| 188 #endif |
181 } | 189 } |
182 | 190 |
183 // Continue with next deoptimization entry. | 191 // Continue with next deoptimization entry. |
184 current_entry = next_entry; | 192 current_entry = next_entry; |
185 entry_pc = next_pc; | 193 entry_pc = next_pc; |
186 } | 194 } |
187 | 195 |
188 #ifdef DEBUG | 196 #ifdef DEBUG |
189 // Destroy the code which is not supposed to run again. | 197 // Destroy the code which is not supposed to run again. |
190 ZapCodeRange(previous_pc, jump_table_address); | 198 ZapCodeRange(previous_pc, jump_table_address); |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 } | 840 } |
833 __ bind(&done); | 841 __ bind(&done); |
834 } | 842 } |
835 | 843 |
836 #undef __ | 844 #undef __ |
837 | 845 |
838 | 846 |
839 } } // namespace v8::internal | 847 } } // namespace v8::internal |
840 | 848 |
841 #endif // V8_TARGET_ARCH_X64 | 849 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |