OLD | NEW |
1 | 1 |
2 // Copyright 2011 the V8 project authors. All rights reserved. | 2 // Copyright 2011 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include "src/v8.h" | 6 #include "src/v8.h" |
7 | 7 |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen.h" | 10 #include "src/full-codegen.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 #endif | 53 #endif |
54 // For each LLazyBailout instruction insert a call to the corresponding | 54 // For each LLazyBailout instruction insert a call to the corresponding |
55 // deoptimization entry. | 55 // deoptimization entry. |
56 for (int i = 0; i < deopt_data->DeoptCount(); i++) { | 56 for (int i = 0; i < deopt_data->DeoptCount(); i++) { |
57 if (deopt_data->Pc(i)->value() == -1) continue; | 57 if (deopt_data->Pc(i)->value() == -1) continue; |
58 Address call_address = code_start_address + deopt_data->Pc(i)->value(); | 58 Address call_address = code_start_address + deopt_data->Pc(i)->value(); |
59 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); | 59 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); |
60 int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, | 60 int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, |
61 RelocInfo::NONE32); | 61 RelocInfo::NONE32); |
62 int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; | 62 int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; |
63 ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); | 63 DCHECK(call_size_in_bytes % Assembler::kInstrSize == 0); |
64 ASSERT(call_size_in_bytes <= patch_size()); | 64 DCHECK(call_size_in_bytes <= patch_size()); |
65 CodePatcher patcher(call_address, call_size_in_words); | 65 CodePatcher patcher(call_address, call_size_in_words); |
66 patcher.masm()->Call(deopt_entry, RelocInfo::NONE32); | 66 patcher.masm()->Call(deopt_entry, RelocInfo::NONE32); |
67 ASSERT(prev_call_address == NULL || | 67 DCHECK(prev_call_address == NULL || |
68 call_address >= prev_call_address + patch_size()); | 68 call_address >= prev_call_address + patch_size()); |
69 ASSERT(call_address + patch_size() <= code->instruction_end()); | 69 DCHECK(call_address + patch_size() <= code->instruction_end()); |
70 | 70 |
71 #ifdef DEBUG | 71 #ifdef DEBUG |
72 prev_call_address = call_address; | 72 prev_call_address = call_address; |
73 #endif | 73 #endif |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 78 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
79 // Set the register values. The values are not important as there are no | 79 // Set the register values. The values are not important as there are no |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); | 188 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); |
189 } | 189 } |
190 | 190 |
191 // Preserve "deoptimizer" object in register v0 and get the input | 191 // Preserve "deoptimizer" object in register v0 and get the input |
192 // frame descriptor pointer to a1 (deoptimizer->input_); | 192 // frame descriptor pointer to a1 (deoptimizer->input_); |
193 // Move deopt-obj to a0 for call to Deoptimizer::ComputeOutputFrames() below. | 193 // Move deopt-obj to a0 for call to Deoptimizer::ComputeOutputFrames() below. |
194 __ mov(a0, v0); | 194 __ mov(a0, v0); |
195 __ lw(a1, MemOperand(v0, Deoptimizer::input_offset())); | 195 __ lw(a1, MemOperand(v0, Deoptimizer::input_offset())); |
196 | 196 |
197 // Copy core registers into FrameDescription::registers_[kNumRegisters]. | 197 // Copy core registers into FrameDescription::registers_[kNumRegisters]. |
198 ASSERT(Register::kNumRegisters == kNumberOfRegisters); | 198 DCHECK(Register::kNumRegisters == kNumberOfRegisters); |
199 for (int i = 0; i < kNumberOfRegisters; i++) { | 199 for (int i = 0; i < kNumberOfRegisters; i++) { |
200 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); | 200 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
201 if ((saved_regs & (1 << i)) != 0) { | 201 if ((saved_regs & (1 << i)) != 0) { |
202 __ lw(a2, MemOperand(sp, i * kPointerSize)); | 202 __ lw(a2, MemOperand(sp, i * kPointerSize)); |
203 __ sw(a2, MemOperand(a1, offset)); | 203 __ sw(a2, MemOperand(a1, offset)); |
204 } else if (FLAG_debug_code) { | 204 } else if (FLAG_debug_code) { |
205 __ li(a2, kDebugZapValue); | 205 __ li(a2, kDebugZapValue); |
206 __ sw(a2, MemOperand(a1, offset)); | 206 __ sw(a2, MemOperand(a1, offset)); |
207 } | 207 } |
208 } | 208 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 __ push(t2); | 290 __ push(t2); |
291 | 291 |
292 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset())); | 292 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset())); |
293 __ push(t2); | 293 __ push(t2); |
294 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset())); | 294 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset())); |
295 __ push(t2); | 295 __ push(t2); |
296 | 296 |
297 | 297 |
298 // Technically restoring 'at' should work unless zero_reg is also restored | 298 // Technically restoring 'at' should work unless zero_reg is also restored |
299 // but it's safer to check for this. | 299 // but it's safer to check for this. |
300 ASSERT(!(at.bit() & restored_regs)); | 300 DCHECK(!(at.bit() & restored_regs)); |
301 // Restore the registers from the last output frame. | 301 // Restore the registers from the last output frame. |
302 __ mov(at, a2); | 302 __ mov(at, a2); |
303 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { | 303 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { |
304 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); | 304 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
305 if ((restored_regs & (1 << i)) != 0) { | 305 if ((restored_regs & (1 << i)) != 0) { |
306 __ lw(ToRegister(i), MemOperand(at, offset)); | 306 __ lw(ToRegister(i), MemOperand(at, offset)); |
307 } | 307 } |
308 } | 308 } |
309 | 309 |
310 __ InitializeRootRegister(); | 310 __ InitializeRootRegister(); |
(...skipping 11 matching lines...) Expand all Loading... |
322 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 322 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |
323 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); | 323 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); |
324 | 324 |
325 // Create a sequence of deoptimization entries. | 325 // Create a sequence of deoptimization entries. |
326 // Note that registers are still live when jumping to an entry. | 326 // Note that registers are still live when jumping to an entry. |
327 Label table_start, done; | 327 Label table_start, done; |
328 __ bind(&table_start); | 328 __ bind(&table_start); |
329 for (int i = 0; i < count(); i++) { | 329 for (int i = 0; i < count(); i++) { |
330 Label start; | 330 Label start; |
331 __ bind(&start); | 331 __ bind(&start); |
332 ASSERT(is_int16(i)); | 332 DCHECK(is_int16(i)); |
333 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. | 333 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. |
334 __ li(at, i); // In the delay slot. | 334 __ li(at, i); // In the delay slot. |
335 | 335 |
336 ASSERT_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); | 336 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
337 } | 337 } |
338 | 338 |
339 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | 339 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
340 count() * table_entry_size_); | 340 count() * table_entry_size_); |
341 __ bind(&done); | 341 __ bind(&done); |
342 __ Push(at); | 342 __ Push(at); |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { | 346 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { |
347 SetFrameSlot(offset, value); | 347 SetFrameSlot(offset, value); |
348 } | 348 } |
349 | 349 |
350 | 350 |
351 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 351 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
352 SetFrameSlot(offset, value); | 352 SetFrameSlot(offset, value); |
353 } | 353 } |
354 | 354 |
355 | 355 |
356 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 356 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
357 // No out-of-line constant pool support. | 357 // No out-of-line constant pool support. |
358 UNREACHABLE(); | 358 UNREACHABLE(); |
359 } | 359 } |
360 | 360 |
361 | 361 |
362 #undef __ | 362 #undef __ |
363 | 363 |
364 | 364 |
365 } } // namespace v8::internal | 365 } } // namespace v8::internal |
OLD | NEW |