Index: src/x64/deoptimizer-x64.cc |
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc |
index 0bb02dbe7c49ef760552ad71abf901fc4d4054d9..bae97cd8155e5c5da166986ad243939dc316df8d 100644 |
--- a/src/x64/deoptimizer-x64.cc |
+++ b/src/x64/deoptimizer-x64.cc |
@@ -117,40 +117,39 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( |
static const byte kJnsInstruction = 0x79; |
-static const byte kJnsOffset = 0x1f; |
+static const byte kJnsOffset = 0x1d; |
static const byte kCallInstruction = 0xe8; |
static const byte kNopByteOne = 0x66; |
static const byte kNopByteTwo = 0x90; |
-void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, |
- Address pc_after, |
- Code* check_code, |
- Code* replacement_code) { |
+// The back edge bookkeeping code matches the pattern: |
+// |
+// add <profiling_counter>, <-delta> |
+// jns ok |
+// call <stack guard> |
+// ok: |
+// |
+// We will patch away the branch so the code is: |
+// |
+// add <profiling_counter>, <-delta> ;; Not changed |
+// nop |
+// nop |
+// call <on-stack replacment> |
+// ok: |
+ |
+void Deoptimizer::PatchInterruptCodeAt(Code* unoptimized_code, |
+ Address pc_after, |
+ Code* interrupt_code, |
+ Code* replacement_code) { |
+ ASSERT(!InterruptCodeIsPatched(unoptimized_code, |
+ pc_after, |
+ interrupt_code, |
+ replacement_code)); |
+ // Turn the jump into nops. |
Address call_target_address = pc_after - kIntSize; |
- ASSERT_EQ(check_code->entry(), |
- Assembler::target_address_at(call_target_address)); |
- // The back edge bookkeeping code matches the pattern: |
- // |
- // add <profiling_counter>, <-delta> |
- // jns ok |
- // call <stack guard> |
- // test rax, <loop nesting depth> |
- // ok: ... |
- // |
- // We will patch away the branch so the code is: |
- // |
- // add <profiling_counter>, <-delta> ;; Not changed |
- // nop |
- // nop |
- // call <on-stack replacment> |
- // test rax, <loop nesting depth> |
- // ok: |
- // |
- ASSERT_EQ(kJnsInstruction, *(call_target_address - 3)); |
- ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); |
- ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); |
*(call_target_address - 3) = kNopByteOne; |
*(call_target_address - 2) = kNopByteTwo; |
+ // Replace the call address. |
Assembler::set_target_address_at(call_target_address, |
replacement_code->entry()); |
@@ -159,26 +158,48 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, |
} |
-void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code, |
- Address pc_after, |
- Code* check_code, |
- Code* replacement_code) { |
+void Deoptimizer::RevertInterruptCodeAt(Code* unoptimized_code, |
+ Address pc_after, |
+ Code* interrupt_code, |
+ Code* replacement_code) { |
+ ASSERT(InterruptCodeIsPatched(unoptimized_code, |
+ pc_after, |
+ interrupt_code, |
+ replacement_code)); |
+ // Restore the original jump. |
Address call_target_address = pc_after - kIntSize; |
- ASSERT(replacement_code->entry() == |
- Assembler::target_address_at(call_target_address)); |
- // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to |
- // restore the conditional branch. |
- ASSERT_EQ(kNopByteOne, *(call_target_address - 3)); |
- ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); |
- ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); |
*(call_target_address - 3) = kJnsInstruction; |
*(call_target_address - 2) = kJnsOffset; |
+ // Restore the original call address. |
Assembler::set_target_address_at(call_target_address, |
- check_code->entry()); |
+ interrupt_code->entry()); |
+ |
+ interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
+ unoptimized_code, call_target_address, interrupt_code); |
+} |
+ |
- check_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
- unoptimized_code, call_target_address, check_code); |
+#ifdef DEBUG |
+bool Deoptimizer::InterruptCodeIsPatched(Code* unoptimized_code, |
+ Address pc_after, |
+ Code* interrupt_code, |
+ Code* replacement_code) { |
+ Address call_target_address = pc_after - kIntSize; |
+ ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); |
+ if (*(call_target_address - 3) == kNopByteOne) { |
+ ASSERT(replacement_code->entry() == |
+ Assembler::target_address_at(call_target_address)); |
+ ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); |
+ return true; |
+ } else { |
+ ASSERT_EQ(interrupt_code->entry(), |
+ Assembler::target_address_at(call_target_address)); |
+ ASSERT_EQ(kJnsInstruction, *(call_target_address - 3)); |
+ ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); |
+ return false; |
+ } |
} |
+#endif // DEBUG |
static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) { |