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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 factory->NewByteArray(reloc_length + padding, TENURED); | 109 factory->NewByteArray(reloc_length + padding, TENURED); |
110 memcpy(new_reloc->GetDataStartAddress() + padding, | 110 memcpy(new_reloc->GetDataStartAddress() + padding, |
111 code->relocation_info()->GetDataStartAddress(), | 111 code->relocation_info()->GetDataStartAddress(), |
112 reloc_length); | 112 reloc_length); |
113 // Create a relocation writer to write the comments in the padding | 113 // Create a relocation writer to write the comments in the padding |
114 // space. Use position 0 for everything to ensure short encoding. | 114 // space. Use position 0 for everything to ensure short encoding. |
115 RelocInfoWriter reloc_info_writer( | 115 RelocInfoWriter reloc_info_writer( |
116 new_reloc->GetDataStartAddress() + padding, 0); | 116 new_reloc->GetDataStartAddress() + padding, 0); |
117 intptr_t comment_string | 117 intptr_t comment_string |
118 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); | 118 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); |
119 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string); | 119 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string, NULL); |
120 for (int i = 0; i < additional_comments; ++i) { | 120 for (int i = 0; i < additional_comments; ++i) { |
121 #ifdef DEBUG | 121 #ifdef DEBUG |
122 byte* pos_before = reloc_info_writer.pos(); | 122 byte* pos_before = reloc_info_writer.pos(); |
123 #endif | 123 #endif |
124 reloc_info_writer.Write(&rinfo); | 124 reloc_info_writer.Write(&rinfo); |
125 ASSERT(RelocInfo::kMinRelocCommentSize == | 125 ASSERT(RelocInfo::kMinRelocCommentSize == |
126 pos_before - reloc_info_writer.pos()); | 126 pos_before - reloc_info_writer.pos()); |
127 } | 127 } |
128 // Replace relocation information on the code object. | 128 // Replace relocation information on the code object. |
129 code->set_relocation_info(*new_reloc); | 129 code->set_relocation_info(*new_reloc); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 // The gap code is needed to get to the state expected at the bailout. | 167 // The gap code is needed to get to the state expected at the bailout. |
168 curr_address += safepoint_entry.gap_code_size(); | 168 curr_address += safepoint_entry.gap_code_size(); |
169 | 169 |
170 CodePatcher patcher(curr_address, patch_size()); | 170 CodePatcher patcher(curr_address, patch_size()); |
171 Address deopt_entry = GetDeoptimizationEntry(deoptimization_index, LAZY); | 171 Address deopt_entry = GetDeoptimizationEntry(deoptimization_index, LAZY); |
172 patcher.masm()->call(deopt_entry, RelocInfo::NONE); | 172 patcher.masm()->call(deopt_entry, RelocInfo::NONE); |
173 | 173 |
174 // We use RUNTIME_ENTRY for deoptimization bailouts. | 174 // We use RUNTIME_ENTRY for deoptimization bailouts. |
175 RelocInfo rinfo(curr_address + 1, // 1 after the call opcode. | 175 RelocInfo rinfo(curr_address + 1, // 1 after the call opcode. |
176 RelocInfo::RUNTIME_ENTRY, | 176 RelocInfo::RUNTIME_ENTRY, |
177 reinterpret_cast<intptr_t>(deopt_entry)); | 177 reinterpret_cast<intptr_t>(deopt_entry), |
| 178 NULL); |
178 reloc_info_writer.Write(&rinfo); | 179 reloc_info_writer.Write(&rinfo); |
179 ASSERT_GE(reloc_info_writer.pos(), | 180 ASSERT_GE(reloc_info_writer.pos(), |
180 reloc_info->address() + ByteArray::kHeaderSize); | 181 reloc_info->address() + ByteArray::kHeaderSize); |
181 curr_address += patch_size(); | 182 curr_address += patch_size(); |
182 } | 183 } |
183 prev_address = curr_address; | 184 prev_address = curr_address; |
184 } | 185 } |
185 ZapCodeRange(prev_address, | 186 ZapCodeRange(prev_address, |
186 code_start_address + code->safepoint_table_offset()); | 187 code_start_address + code->safepoint_table_offset()); |
187 | 188 |
(...skipping 26 matching lines...) Expand all Loading... |
214 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); | 215 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); |
215 #ifdef DEBUG | 216 #ifdef DEBUG |
216 if (FLAG_print_code) { | 217 if (FLAG_print_code) { |
217 code->PrintLn(); | 218 code->PrintLn(); |
218 } | 219 } |
219 #endif | 220 #endif |
220 } | 221 } |
221 } | 222 } |
222 | 223 |
223 | 224 |
224 void Deoptimizer::PatchStackCheckCodeAt(Address pc_after, | 225 void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, |
| 226 Address pc_after, |
225 Code* check_code, | 227 Code* check_code, |
226 Code* replacement_code) { | 228 Code* replacement_code) { |
227 Address call_target_address = pc_after - kIntSize; | 229 Address call_target_address = pc_after - kIntSize; |
228 ASSERT(check_code->entry() == | 230 ASSERT(check_code->entry() == |
229 Assembler::target_address_at(call_target_address)); | 231 Assembler::target_address_at(call_target_address)); |
230 // The stack check code matches the pattern: | 232 // The stack check code matches the pattern: |
231 // | 233 // |
232 // cmp esp, <limit> | 234 // cmp esp, <limit> |
233 // jae ok | 235 // jae ok |
234 // call <stack guard> | 236 // call <stack guard> |
235 // test eax, <loop nesting depth> | 237 // test eax, <loop nesting depth> |
236 // ok: ... | 238 // ok: ... |
237 // | 239 // |
238 // We will patch away the branch so the code is: | 240 // We will patch away the branch so the code is: |
239 // | 241 // |
240 // cmp esp, <limit> ;; Not changed | 242 // cmp esp, <limit> ;; Not changed |
241 // nop | 243 // nop |
242 // nop | 244 // nop |
243 // call <on-stack replacment> | 245 // call <on-stack replacment> |
244 // test eax, <loop nesting depth> | 246 // test eax, <loop nesting depth> |
245 // ok: | 247 // ok: |
246 ASSERT(*(call_target_address - 3) == 0x73 && // jae | 248 ASSERT(*(call_target_address - 3) == 0x73 && // jae |
247 *(call_target_address - 2) == 0x07 && // offset | 249 *(call_target_address - 2) == 0x07 && // offset |
248 *(call_target_address - 1) == 0xe8); // call | 250 *(call_target_address - 1) == 0xe8); // call |
249 *(call_target_address - 3) = 0x90; // nop | 251 *(call_target_address - 3) = 0x90; // nop |
250 *(call_target_address - 2) = 0x90; // nop | 252 *(call_target_address - 2) = 0x90; // nop |
251 Assembler::set_target_address_at(call_target_address, | 253 Assembler::set_target_address_at(call_target_address, |
252 replacement_code->entry()); | 254 replacement_code->entry()); |
| 255 |
| 256 RelocInfo rinfo(call_target_address, |
| 257 RelocInfo::CODE_TARGET, |
| 258 NULL, |
| 259 unoptimized_code); |
| 260 unoptimized_code->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 261 unoptimized_code, &rinfo, replacement_code); |
253 } | 262 } |
254 | 263 |
255 | 264 |
256 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after, | 265 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after, |
257 Code* check_code, | 266 Code* check_code, |
258 Code* replacement_code) { | 267 Code* replacement_code) { |
259 Address call_target_address = pc_after - kIntSize; | 268 Address call_target_address = pc_after - kIntSize; |
260 ASSERT(replacement_code->entry() == | 269 ASSERT(replacement_code->entry() == |
261 Assembler::target_address_at(call_target_address)); | 270 Assembler::target_address_at(call_target_address)); |
262 // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to | 271 // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to |
263 // restore the conditional branch. | 272 // restore the conditional branch. |
264 ASSERT(*(call_target_address - 3) == 0x90 && // nop | 273 ASSERT(*(call_target_address - 3) == 0x90 && // nop |
265 *(call_target_address - 2) == 0x90 && // nop | 274 *(call_target_address - 2) == 0x90 && // nop |
266 *(call_target_address - 1) == 0xe8); // call | 275 *(call_target_address - 1) == 0xe8); // call |
267 *(call_target_address - 3) = 0x73; // jae | 276 *(call_target_address - 3) = 0x73; // jae |
268 *(call_target_address - 2) = 0x07; // offset | 277 *(call_target_address - 2) = 0x07; // offset |
269 Assembler::set_target_address_at(call_target_address, | 278 Assembler::set_target_address_at(call_target_address, |
270 check_code->entry()); | 279 check_code->entry()); |
| 280 |
| 281 check_code->GetHeap()->incremental_marking()-> |
| 282 RecordCodeTargetPatch(call_target_address, check_code); |
271 } | 283 } |
272 | 284 |
273 | 285 |
274 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) { | 286 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) { |
275 ByteArray* translations = data->TranslationByteArray(); | 287 ByteArray* translations = data->TranslationByteArray(); |
276 int length = data->DeoptCount(); | 288 int length = data->DeoptCount(); |
277 for (int i = 0; i < length; i++) { | 289 for (int i = 0; i < length; i++) { |
278 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) { | 290 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) { |
279 TranslationIterator it(translations, data->TranslationIndex(i)->value()); | 291 TranslationIterator it(translations, data->TranslationIndex(i)->value()); |
280 int value = it.Next(); | 292 int value = it.Next(); |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 } | 808 } |
797 __ bind(&done); | 809 __ bind(&done); |
798 } | 810 } |
799 | 811 |
800 #undef __ | 812 #undef __ |
801 | 813 |
802 | 814 |
803 } } // namespace v8::internal | 815 } } // namespace v8::internal |
804 | 816 |
805 #endif // V8_TARGET_ARCH_IA32 | 817 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |