| 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 |