OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/full-codegen.h" | 9 #include "src/full-codegen.h" |
10 #include "src/safepoint-table.h" | 10 #include "src/safepoint-table.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 #endif | 52 #endif |
53 // For each LLazyBailout instruction insert a call to the corresponding | 53 // For each LLazyBailout instruction insert a call to the corresponding |
54 // deoptimization entry. | 54 // deoptimization entry. |
55 for (int i = 0; i < deopt_data->DeoptCount(); i++) { | 55 for (int i = 0; i < deopt_data->DeoptCount(); i++) { |
56 if (deopt_data->Pc(i)->value() == -1) continue; | 56 if (deopt_data->Pc(i)->value() == -1) continue; |
57 Address call_address = code_start_address + deopt_data->Pc(i)->value(); | 57 Address call_address = code_start_address + deopt_data->Pc(i)->value(); |
58 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); | 58 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); |
59 int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, | 59 int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, |
60 RelocInfo::NONE32); | 60 RelocInfo::NONE32); |
61 int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; | 61 int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; |
62 ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); | 62 DCHECK(call_size_in_bytes % Assembler::kInstrSize == 0); |
63 ASSERT(call_size_in_bytes <= patch_size()); | 63 DCHECK(call_size_in_bytes <= patch_size()); |
64 CodePatcher patcher(call_address, call_size_in_words); | 64 CodePatcher patcher(call_address, call_size_in_words); |
65 patcher.masm()->Call(deopt_entry, RelocInfo::NONE32); | 65 patcher.masm()->Call(deopt_entry, RelocInfo::NONE32); |
66 ASSERT(prev_call_address == NULL || | 66 DCHECK(prev_call_address == NULL || |
67 call_address >= prev_call_address + patch_size()); | 67 call_address >= prev_call_address + patch_size()); |
68 ASSERT(call_address + patch_size() <= code->instruction_end()); | 68 DCHECK(call_address + patch_size() <= code->instruction_end()); |
69 | 69 |
70 #ifdef DEBUG | 70 #ifdef DEBUG |
71 prev_call_address = call_address; | 71 prev_call_address = call_address; |
72 #endif | 72 #endif |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 77 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
78 // Set the register values. The values are not important as there are no | 78 // Set the register values. The values are not important as there are no |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); | 193 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); |
194 } | 194 } |
195 | 195 |
196 // Preserve "deoptimizer" object in register v0 and get the input | 196 // Preserve "deoptimizer" object in register v0 and get the input |
197 // frame descriptor pointer to a1 (deoptimizer->input_); | 197 // frame descriptor pointer to a1 (deoptimizer->input_); |
198 // Move deopt-obj to a0 for call to Deoptimizer::ComputeOutputFrames() below. | 198 // Move deopt-obj to a0 for call to Deoptimizer::ComputeOutputFrames() below. |
199 __ mov(a0, v0); | 199 __ mov(a0, v0); |
200 __ ld(a1, MemOperand(v0, Deoptimizer::input_offset())); | 200 __ ld(a1, MemOperand(v0, Deoptimizer::input_offset())); |
201 | 201 |
202 // Copy core registers into FrameDescription::registers_[kNumRegisters]. | 202 // Copy core registers into FrameDescription::registers_[kNumRegisters]. |
203 ASSERT(Register::kNumRegisters == kNumberOfRegisters); | 203 DCHECK(Register::kNumRegisters == kNumberOfRegisters); |
204 for (int i = 0; i < kNumberOfRegisters; i++) { | 204 for (int i = 0; i < kNumberOfRegisters; i++) { |
205 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); | 205 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
206 if ((saved_regs & (1 << i)) != 0) { | 206 if ((saved_regs & (1 << i)) != 0) { |
207 __ ld(a2, MemOperand(sp, i * kPointerSize)); | 207 __ ld(a2, MemOperand(sp, i * kPointerSize)); |
208 __ sd(a2, MemOperand(a1, offset)); | 208 __ sd(a2, MemOperand(a1, offset)); |
209 } else if (FLAG_debug_code) { | 209 } else if (FLAG_debug_code) { |
210 __ li(a2, kDebugZapValue); | 210 __ li(a2, kDebugZapValue); |
211 __ sd(a2, MemOperand(a1, offset)); | 211 __ sd(a2, MemOperand(a1, offset)); |
212 } | 212 } |
213 } | 213 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 __ push(a6); | 294 __ push(a6); |
295 | 295 |
296 __ ld(a6, MemOperand(a2, FrameDescription::pc_offset())); | 296 __ ld(a6, MemOperand(a2, FrameDescription::pc_offset())); |
297 __ push(a6); | 297 __ push(a6); |
298 __ ld(a6, MemOperand(a2, FrameDescription::continuation_offset())); | 298 __ ld(a6, MemOperand(a2, FrameDescription::continuation_offset())); |
299 __ push(a6); | 299 __ push(a6); |
300 | 300 |
301 | 301 |
302 // Technically restoring 'at' should work unless zero_reg is also restored | 302 // Technically restoring 'at' should work unless zero_reg is also restored |
303 // but it's safer to check for this. | 303 // but it's safer to check for this. |
304 ASSERT(!(at.bit() & restored_regs)); | 304 DCHECK(!(at.bit() & restored_regs)); |
305 // Restore the registers from the last output frame. | 305 // Restore the registers from the last output frame. |
306 __ mov(at, a2); | 306 __ mov(at, a2); |
307 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { | 307 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { |
308 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); | 308 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
309 if ((restored_regs & (1 << i)) != 0) { | 309 if ((restored_regs & (1 << i)) != 0) { |
310 __ ld(ToRegister(i), MemOperand(at, offset)); | 310 __ ld(ToRegister(i), MemOperand(at, offset)); |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 __ InitializeRootRegister(); | 314 __ InitializeRootRegister(); |
(...skipping 27 matching lines...) Expand all Loading... |
342 // 'at' was clobbered so we can only load the current entry value here. | 342 // 'at' was clobbered so we can only load the current entry value here. |
343 __ li(t8, i); | 343 __ li(t8, i); |
344 __ jr(t9); // Expose delay slot. | 344 __ jr(t9); // Expose delay slot. |
345 __ sd(t8, MemOperand(sp, 0 * kPointerSize)); // In the delay slot. | 345 __ sd(t8, MemOperand(sp, 0 * kPointerSize)); // In the delay slot. |
346 | 346 |
347 // Pad the rest of the code. | 347 // Pad the rest of the code. |
348 while (table_entry_size_ > (masm()->SizeOfCodeGeneratedSince(&start))) { | 348 while (table_entry_size_ > (masm()->SizeOfCodeGeneratedSince(&start))) { |
349 __ nop(); | 349 __ nop(); |
350 } | 350 } |
351 | 351 |
352 ASSERT_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); | 352 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
353 } | 353 } |
354 | 354 |
355 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | 355 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
356 count() * table_entry_size_); | 356 count() * table_entry_size_); |
357 } | 357 } |
358 | 358 |
359 | 359 |
360 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { | 360 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { |
361 SetFrameSlot(offset, value); | 361 SetFrameSlot(offset, value); |
362 } | 362 } |
363 | 363 |
364 | 364 |
365 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 365 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
366 SetFrameSlot(offset, value); | 366 SetFrameSlot(offset, value); |
367 } | 367 } |
368 | 368 |
369 | 369 |
370 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 370 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
371 // No out-of-line constant pool support. | 371 // No out-of-line constant pool support. |
372 UNREACHABLE(); | 372 UNREACHABLE(); |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 #undef __ | 376 #undef __ |
377 | 377 |
378 | 378 |
379 } } // namespace v8::internal | 379 } } // namespace v8::internal |
OLD | NEW |