OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 if (sp_slot_delta < 0) { | 353 if (sp_slot_delta < 0) { |
354 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); | 354 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); |
355 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 355 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
356 } | 356 } |
357 if (frame()->needs_frame()) { | 357 if (frame()->needs_frame()) { |
358 __ mov(ebp, MemOperand(ebp, 0)); | 358 __ mov(ebp, MemOperand(ebp, 0)); |
359 } | 359 } |
360 frame_access_state()->SetFrameAccessToSP(); | 360 frame_access_state()->SetFrameAccessToSP(); |
361 } | 361 } |
362 | 362 |
| 363 thread_local bool is_handler_entry_point = false; |
| 364 static void DoEnsureSpaceForLazyDeopt(CompilationInfo* info, |
| 365 MacroAssembler* masm, |
| 366 int last_lazy_deopt_pc) { |
| 367 if (!info->ShouldEnsureSpaceForLazyDeopt()) { |
| 368 return; |
| 369 } |
| 370 |
| 371 int space_needed = Deoptimizer::patch_size(); |
| 372 // Ensure that we have enough space after the previous lazy-bailout |
| 373 // instruction for patching the code here. |
| 374 int current_pc = masm->pc_offset(); |
| 375 if (current_pc < last_lazy_deopt_pc + space_needed) { |
| 376 int padding_size = last_lazy_deopt_pc + space_needed - current_pc; |
| 377 masm->Nop(padding_size); |
| 378 } |
| 379 } |
363 | 380 |
364 // Assembles an instruction after register allocation, producing machine code. | 381 // Assembles an instruction after register allocation, producing machine code. |
365 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 382 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
366 X87OperandConverter i(this, instr); | 383 X87OperandConverter i(this, instr); |
| 384 if (is_handler_entry_point) { |
| 385 // Lazy Bailout entry, need to re-initialize FPU state. |
| 386 __ fninit(); |
| 387 __ fld1(); |
| 388 is_handler_entry_point = false; |
| 389 } |
367 | 390 |
368 switch (ArchOpcodeField::decode(instr->opcode())) { | 391 switch (ArchOpcodeField::decode(instr->opcode())) { |
369 case kArchCallCodeObject: { | 392 case kArchCallCodeObject: { |
| 393 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
370 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 394 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
371 __ VerifyX87StackDepth(1); | 395 __ VerifyX87StackDepth(1); |
372 } | 396 } |
373 __ fstp(0); | 397 __ fstp(0); |
374 EnsureSpaceForLazyDeopt(); | |
375 if (HasImmediateInput(instr, 0)) { | 398 if (HasImmediateInput(instr, 0)) { |
376 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 399 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
377 __ call(code, RelocInfo::CODE_TARGET); | 400 __ call(code, RelocInfo::CODE_TARGET); |
378 } else { | 401 } else { |
379 Register reg = i.InputRegister(0); | 402 Register reg = i.InputRegister(0); |
380 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 403 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
381 __ call(reg); | 404 __ call(reg); |
382 } | 405 } |
383 RecordCallPosition(instr); | 406 RecordCallPosition(instr); |
384 bool double_result = | 407 bool double_result = |
(...skipping 24 matching lines...) Expand all Loading... |
409 __ jmp(code, RelocInfo::CODE_TARGET); | 432 __ jmp(code, RelocInfo::CODE_TARGET); |
410 } else { | 433 } else { |
411 Register reg = i.InputRegister(0); | 434 Register reg = i.InputRegister(0); |
412 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 435 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
413 __ jmp(reg); | 436 __ jmp(reg); |
414 } | 437 } |
415 frame_access_state()->ClearSPDelta(); | 438 frame_access_state()->ClearSPDelta(); |
416 break; | 439 break; |
417 } | 440 } |
418 case kArchCallJSFunction: { | 441 case kArchCallJSFunction: { |
419 EnsureSpaceForLazyDeopt(); | 442 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
420 Register func = i.InputRegister(0); | 443 Register func = i.InputRegister(0); |
421 if (FLAG_debug_code) { | 444 if (FLAG_debug_code) { |
422 // Check the function's context matches the context argument. | 445 // Check the function's context matches the context argument. |
423 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); | 446 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
424 __ Assert(equal, kWrongFunctionContext); | 447 __ Assert(equal, kWrongFunctionContext); |
425 } | 448 } |
426 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 449 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
427 __ VerifyX87StackDepth(1); | 450 __ VerifyX87StackDepth(1); |
428 } | 451 } |
429 __ fstp(0); | 452 __ fstp(0); |
(...skipping 26 matching lines...) Expand all Loading... |
456 __ VerifyX87StackDepth(1); | 479 __ VerifyX87StackDepth(1); |
457 } | 480 } |
458 __ fstp(0); | 481 __ fstp(0); |
459 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 482 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
460 AssembleDeconstructActivationRecord(stack_param_delta); | 483 AssembleDeconstructActivationRecord(stack_param_delta); |
461 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 484 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
462 frame_access_state()->ClearSPDelta(); | 485 frame_access_state()->ClearSPDelta(); |
463 break; | 486 break; |
464 } | 487 } |
465 case kArchLazyBailout: { | 488 case kArchLazyBailout: { |
466 EnsureSpaceForLazyDeopt(); | 489 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
467 RecordCallPosition(instr); | 490 RecordCallPosition(instr); |
468 // Lazy Bailout entry, need to re-initialize FPU state. | 491 // Lazy Bailout entry, need to re-initialize FPU state. |
469 __ fninit(); | 492 __ fninit(); |
470 __ fld1(); | 493 __ fld1(); |
471 break; | 494 break; |
472 } | 495 } |
473 case kArchPrepareCallCFunction: { | 496 case kArchPrepareCallCFunction: { |
474 // Frame alignment requires using FP-relative frame addressing. | 497 // Frame alignment requires using FP-relative frame addressing. |
475 frame_access_state()->SetFrameAccessToFP(); | 498 frame_access_state()->SetFrameAccessToFP(); |
476 int const num_parameters = MiscField::decode(instr->opcode()); | 499 int const num_parameters = MiscField::decode(instr->opcode()); |
(...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 for (size_t index = 0; index < target_count; ++index) { | 2172 for (size_t index = 0; index < target_count; ++index) { |
2150 __ dd(targets[index]); | 2173 __ dd(targets[index]); |
2151 } | 2174 } |
2152 } | 2175 } |
2153 | 2176 |
2154 | 2177 |
2155 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } | 2178 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } |
2156 | 2179 |
2157 | 2180 |
2158 void CodeGenerator::EnsureSpaceForLazyDeopt() { | 2181 void CodeGenerator::EnsureSpaceForLazyDeopt() { |
2159 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { | 2182 is_handler_entry_point = true; |
2160 return; | 2183 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
2161 } | |
2162 | |
2163 int space_needed = Deoptimizer::patch_size(); | |
2164 // Ensure that we have enough space after the previous lazy-bailout | |
2165 // instruction for patching the code here. | |
2166 int current_pc = masm()->pc_offset(); | |
2167 if (current_pc < last_lazy_deopt_pc_ + space_needed) { | |
2168 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | |
2169 __ Nop(padding_size); | |
2170 } | |
2171 } | 2184 } |
2172 | 2185 |
2173 #undef __ | 2186 #undef __ |
2174 | 2187 |
2175 } // namespace compiler | 2188 } // namespace compiler |
2176 } // namespace internal | 2189 } // namespace internal |
2177 } // namespace v8 | 2190 } // namespace v8 |
OLD | NEW |