| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 199 | 199 | 
| 200   if (FLAG_trace_deopt) { | 200   if (FLAG_trace_deopt) { | 
| 201     PrintF("[forced deoptimization: "); | 201     PrintF("[forced deoptimization: "); | 
| 202     function->PrintName(); | 202     function->PrintName(); | 
| 203     PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); | 203     PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); | 
| 204   } | 204   } | 
| 205 } | 205 } | 
| 206 | 206 | 
| 207 | 207 | 
| 208 static const byte kJnsInstruction = 0x79; | 208 static const byte kJnsInstruction = 0x79; | 
| 209 static const byte kJnsOffset = 0x11; | 209 static const byte kJnsOffset = 0x13; | 
| 210 static const byte kJaeInstruction = 0x73; | 210 static const byte kJaeInstruction = 0x73; | 
| 211 static const byte kJaeOffset = 0x07; | 211 static const byte kJaeOffset = 0x07; | 
| 212 static const byte kCallInstruction = 0xe8; | 212 static const byte kCallInstruction = 0xe8; | 
| 213 static const byte kNopByteOne = 0x66; | 213 static const byte kNopByteOne = 0x66; | 
| 214 static const byte kNopByteTwo = 0x90; | 214 static const byte kNopByteTwo = 0x90; | 
| 215 | 215 | 
| 216 | 216 | 
| 217 void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, | 217 void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, | 
| 218                                         Address pc_after, | 218                                         Address pc_after, | 
| 219                                         Code* check_code, | 219                                         Code* check_code, | 
| 220                                         Code* replacement_code) { | 220                                         Code* replacement_code) { | 
| 221   Address call_target_address = pc_after - kIntSize; | 221   Address call_target_address = pc_after - kIntSize; | 
| 222   ASSERT(check_code->entry() == | 222   ASSERT_EQ(check_code->entry(), | 
| 223          Assembler::target_address_at(call_target_address)); | 223             Assembler::target_address_at(call_target_address)); | 
| 224   // The stack check code matches the pattern: | 224   // The stack check code matches the pattern: | 
| 225   // | 225   // | 
| 226   //     cmp esp, <limit> | 226   //     cmp esp, <limit> | 
| 227   //     jae ok | 227   //     jae ok | 
| 228   //     call <stack guard> | 228   //     call <stack guard> | 
| 229   //     test eax, <loop nesting depth> | 229   //     test eax, <loop nesting depth> | 
| 230   // ok: ... | 230   // ok: ... | 
| 231   // | 231   // | 
| 232   // We will patch away the branch so the code is: | 232   // We will patch away the branch so the code is: | 
| 233   // | 233   // | 
| 234   //     cmp esp, <limit>  ;; Not changed | 234   //     cmp esp, <limit>  ;; Not changed | 
| 235   //     nop | 235   //     nop | 
| 236   //     nop | 236   //     nop | 
| 237   //     call <on-stack replacment> | 237   //     call <on-stack replacment> | 
| 238   //     test eax, <loop nesting depth> | 238   //     test eax, <loop nesting depth> | 
| 239   // ok: | 239   // ok: | 
| 240 | 240 | 
| 241   if (FLAG_count_based_interrupts) { | 241   if (FLAG_count_based_interrupts) { | 
| 242     ASSERT(*(call_target_address - 3) == kJnsInstruction); | 242     ASSERT_EQ(*(call_target_address - 3), kJnsInstruction); | 
| 243     ASSERT(*(call_target_address - 2) == kJnsOffset); | 243     ASSERT_EQ(*(call_target_address - 2), kJnsOffset); | 
| 244   } else { | 244   } else { | 
| 245     ASSERT(*(call_target_address - 3) == kJaeInstruction); | 245     ASSERT_EQ(*(call_target_address - 3), kJaeInstruction); | 
| 246     ASSERT(*(call_target_address - 2) == kJaeOffset); | 246     ASSERT_EQ(*(call_target_address - 2), kJaeOffset); | 
| 247   } | 247   } | 
| 248   ASSERT(*(call_target_address - 1) == kCallInstruction); | 248   ASSERT_EQ(*(call_target_address - 1), kCallInstruction); | 
| 249   *(call_target_address - 3) = kNopByteOne; | 249   *(call_target_address - 3) = kNopByteOne; | 
| 250   *(call_target_address - 2) = kNopByteTwo; | 250   *(call_target_address - 2) = kNopByteTwo; | 
| 251   Assembler::set_target_address_at(call_target_address, | 251   Assembler::set_target_address_at(call_target_address, | 
| 252                                    replacement_code->entry()); | 252                                    replacement_code->entry()); | 
| 253 | 253 | 
| 254   unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( | 254   unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( | 
| 255       unoptimized_code, call_target_address, replacement_code); | 255       unoptimized_code, call_target_address, replacement_code); | 
| 256 } | 256 } | 
| 257 | 257 | 
| 258 | 258 | 
| 259 void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code, | 259 void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code, | 
| 260                                          Address pc_after, | 260                                          Address pc_after, | 
| 261                                          Code* check_code, | 261                                          Code* check_code, | 
| 262                                          Code* replacement_code) { | 262                                          Code* replacement_code) { | 
| 263   Address call_target_address = pc_after - kIntSize; | 263   Address call_target_address = pc_after - kIntSize; | 
| 264   ASSERT(replacement_code->entry() == | 264   ASSERT_EQ(replacement_code->entry(), | 
| 265          Assembler::target_address_at(call_target_address)); | 265             Assembler::target_address_at(call_target_address)); | 
| 266 | 266 | 
| 267   // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to | 267   // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to | 
| 268   // restore the conditional branch. | 268   // restore the conditional branch. | 
| 269   ASSERT(*(call_target_address - 3) == kNopByteOne && | 269   ASSERT_EQ(*(call_target_address - 3), kNopByteOne); | 
| 270          *(call_target_address - 2) == kNopByteTwo && | 270   ASSERT_EQ(*(call_target_address - 2), kNopByteTwo); | 
| 271          *(call_target_address - 1) == kCallInstruction); | 271   ASSERT_EQ(*(call_target_address - 1), kCallInstruction); | 
| 272   if (FLAG_count_based_interrupts) { | 272   if (FLAG_count_based_interrupts) { | 
| 273     *(call_target_address - 3) = kJnsInstruction; | 273     *(call_target_address - 3) = kJnsInstruction; | 
| 274     *(call_target_address - 2) = kJnsOffset; | 274     *(call_target_address - 2) = kJnsOffset; | 
| 275   } else { | 275   } else { | 
| 276     *(call_target_address - 3) = kJaeInstruction; | 276     *(call_target_address - 3) = kJaeInstruction; | 
| 277     *(call_target_address - 2) = kJaeOffset; | 277     *(call_target_address - 2) = kJaeOffset; | 
| 278   } | 278   } | 
| 279   Assembler::set_target_address_at(call_target_address, | 279   Assembler::set_target_address_at(call_target_address, | 
| 280                                    check_code->entry()); | 280                                    check_code->entry()); | 
| 281 | 281 | 
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1035   } | 1035   } | 
| 1036   __ bind(&done); | 1036   __ bind(&done); | 
| 1037 } | 1037 } | 
| 1038 | 1038 | 
| 1039 #undef __ | 1039 #undef __ | 
| 1040 | 1040 | 
| 1041 | 1041 | 
| 1042 } }  // namespace v8::internal | 1042 } }  // namespace v8::internal | 
| 1043 | 1043 | 
| 1044 #endif  // V8_TARGET_ARCH_IA32 | 1044 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|