| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 ASSERT((prev_call_address == NULL) || | 73 ASSERT((prev_call_address == NULL) || |
| 74 (call_address >= prev_call_address + patch_size())); | 74 (call_address >= prev_call_address + patch_size())); |
| 75 ASSERT(call_address + patch_size() <= code->instruction_end()); | 75 ASSERT(call_address + patch_size() <= code->instruction_end()); |
| 76 #ifdef DEBUG | 76 #ifdef DEBUG |
| 77 prev_call_address = call_address; | 77 prev_call_address = call_address; |
| 78 #endif | 78 #endif |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 // The back edge bookkeeping code matches the pattern: | |
| 84 // | |
| 85 // <decrement profiling counter> | |
| 86 // .. .. .. .. b.pl ok | |
| 87 // .. .. .. .. ldr x16, pc+<interrupt stub address> | |
| 88 // .. .. .. .. blr x16 | |
| 89 // ok-label | |
| 90 // | |
| 91 // We patch the code to the following form: | |
| 92 // | |
| 93 // <decrement profiling counter> | |
| 94 // .. .. .. .. mov x0, x0 (NOP) | |
| 95 // .. .. .. .. ldr x16, pc+<on-stack replacement address> | |
| 96 // .. .. .. .. blr x16 | |
| 97 void Deoptimizer::PatchInterruptCodeAt(Code* unoptimized_code, | |
| 98 Address pc_after, | |
| 99 Code* replacement_code) { | |
| 100 // Turn the jump into a nop. | |
| 101 Instruction* jump = Instruction::Cast(pc_after)->preceding(3); | |
| 102 PatchingAssembler patcher(jump, 1); | |
| 103 patcher.nop(Assembler::INTERRUPT_CODE_NOP); | |
| 104 | |
| 105 // Replace the call address. | |
| 106 Instruction* load = Instruction::Cast(pc_after)->preceding(2); | |
| 107 Address interrupt_address_pointer = | |
| 108 reinterpret_cast<Address>(load) + load->ImmPCOffset(); | |
| 109 Memory::uint64_at(interrupt_address_pointer) = | |
| 110 reinterpret_cast<uint64_t>(replacement_code->entry()); | |
| 111 | |
| 112 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( | |
| 113 unoptimized_code, pc_after - 2 * kInstructionSize, replacement_code); | |
| 114 } | |
| 115 | |
| 116 | |
| 117 void Deoptimizer::RevertInterruptCodeAt(Code* unoptimized_code, | |
| 118 Address pc_after, | |
| 119 Code* interrupt_code) { | |
| 120 // Turn the nop into a jump. | |
| 121 Instruction* jump = Instruction::Cast(pc_after)->preceding(3); | |
| 122 PatchingAssembler patcher(jump, 1); | |
| 123 patcher.b(6, pl); // The ok label is 6 instructions later. | |
| 124 | |
| 125 // Replace the call address. | |
| 126 Instruction* load = Instruction::Cast(pc_after)->preceding(2); | |
| 127 Address interrupt_address_pointer = | |
| 128 reinterpret_cast<Address>(load) + load->ImmPCOffset(); | |
| 129 Memory::uint64_at(interrupt_address_pointer) = | |
| 130 reinterpret_cast<uint64_t>(interrupt_code->entry()); | |
| 131 | |
| 132 interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( | |
| 133 unoptimized_code, pc_after - 2 * kInstructionSize, interrupt_code); | |
| 134 } | |
| 135 | |
| 136 | |
| 137 #ifdef DEBUG | |
| 138 Deoptimizer::InterruptPatchState Deoptimizer::GetInterruptPatchState( | |
| 139 Isolate* isolate, | |
| 140 Code* unoptimized_code, | |
| 141 Address pc_after) { | |
| 142 // TODO(jbramley): There should be some extra assertions here (as in the ARM | |
| 143 // back-end), but this function is gone in bleeding_edge so it might not | |
| 144 // matter anyway. | |
| 145 Instruction* jump_or_nop = Instruction::Cast(pc_after)->preceding(3); | |
| 146 return jump_or_nop->IsNop(Assembler::INTERRUPT_CODE_NOP) ? PATCHED_FOR_OSR | |
| 147 : NOT_PATCHED; | |
| 148 } | |
| 149 #endif | |
| 150 | |
| 151 | |
| 152 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 83 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
| 153 // Set the register values. The values are not important as there are no | 84 // Set the register values. The values are not important as there are no |
| 154 // callee saved registers in JavaScript frames, so all registers are | 85 // callee saved registers in JavaScript frames, so all registers are |
| 155 // spilled. Registers fp and sp are set to the correct values though. | 86 // spilled. Registers fp and sp are set to the correct values though. |
| 156 for (int i = 0; i < Register::NumRegisters(); i++) { | 87 for (int i = 0; i < Register::NumRegisters(); i++) { |
| 157 input_->SetRegister(i, 0); | 88 input_->SetRegister(i, 0); |
| 158 } | 89 } |
| 159 | 90 |
| 160 // TODO(all): Do we also need to set a value to csp? | 91 // TODO(all): Do we also need to set a value to csp? |
| 161 input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp())); | 92 input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp())); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 | 365 |
| 435 | 366 |
| 436 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 367 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
| 437 SetFrameSlot(offset, value); | 368 SetFrameSlot(offset, value); |
| 438 } | 369 } |
| 439 | 370 |
| 440 | 371 |
| 441 #undef __ | 372 #undef __ |
| 442 | 373 |
| 443 } } // namespace v8::internal | 374 } } // namespace v8::internal |
| OLD | NEW |