OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/crankshaft/lithium.h" | 5 #include "src/crankshaft/lithium.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_IA32 | 9 #if V8_TARGET_ARCH_IA32 |
10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT | 10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 index = instructions_.length(); | 331 index = instructions_.length(); |
332 instructions_.Add(instr, zone()); | 332 instructions_.Add(instr, zone()); |
333 instructions_.Add(gap, zone()); | 333 instructions_.Add(gap, zone()); |
334 } | 334 } |
335 if (instr->HasPointerMap()) { | 335 if (instr->HasPointerMap()) { |
336 pointer_maps_.Add(instr->pointer_map(), zone()); | 336 pointer_maps_.Add(instr->pointer_map(), zone()); |
337 instr->pointer_map()->set_lithium_position(index); | 337 instr->pointer_map()->set_lithium_position(index); |
338 } | 338 } |
339 } | 339 } |
340 | 340 |
341 | |
342 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { | 341 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
343 return LConstantOperand::Create(constant->id(), zone()); | 342 return LConstantOperand::Create(constant->id(), zone()); |
344 } | 343 } |
345 | 344 |
346 | 345 |
347 int LChunk::GetParameterStackSlot(int index) const { | 346 int LChunk::GetParameterStackSlot(int index) const { |
348 // The receiver is at index 0, the first parameter at index 1, so we | 347 // The receiver is at index 0, the first parameter at index 1, so we |
349 // shift all parameter indexes down by the number of parameters, and | 348 // shift all parameter indexes down by the number of parameters, and |
350 // make sure they end up negative so they are distinguishable from | 349 // make sure they end up negative so they are distinguishable from |
351 // spill slots. | 350 // spill slots. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 info()->AbortOptimization(reason); | 500 info()->AbortOptimization(reason); |
502 status_ = ABORTED; | 501 status_ = ABORTED; |
503 } | 502 } |
504 | 503 |
505 | 504 |
506 void LChunkBuilderBase::Retry(BailoutReason reason) { | 505 void LChunkBuilderBase::Retry(BailoutReason reason) { |
507 info()->RetryOptimization(reason); | 506 info()->RetryOptimization(reason); |
508 status_ = ABORTED; | 507 status_ = ABORTED; |
509 } | 508 } |
510 | 509 |
| 510 void LChunkBuilderBase::CreateLazyBailoutForCall(HBasicBlock* current_block, |
| 511 LInstruction* instr, |
| 512 HInstruction* hydrogen_val) { |
| 513 if (!instr->IsCall()) return; |
| 514 |
| 515 HEnvironment* hydrogen_env = current_block->last_environment(); |
| 516 HValue* hydrogen_value_for_lazy_bailout = hydrogen_val; |
| 517 DCHECK_NOT_NULL(hydrogen_env); |
| 518 if (instr->IsSyntacticTailCall()) { |
| 519 // If it was a syntactic tail call we need to drop the current frame and |
| 520 // all the frames on top of it that are either an arguments adaptor frame |
| 521 // or a tail caller frame. |
| 522 hydrogen_env = hydrogen_env->outer(); |
| 523 while (hydrogen_env != nullptr && |
| 524 (hydrogen_env->frame_type() == ARGUMENTS_ADAPTOR || |
| 525 hydrogen_env->frame_type() == TAIL_CALLER_FUNCTION)) { |
| 526 hydrogen_env = hydrogen_env->outer(); |
| 527 } |
| 528 if (hydrogen_env != nullptr) { |
| 529 if (hydrogen_env->frame_type() == JS_FUNCTION) { |
| 530 // In case an outer frame is a function frame we have to replay |
| 531 // environment manually because |
| 532 // 1) it does not contain a result of inlined function yet, |
| 533 // 2) we can't find the proper simulate that corresponds to the point |
| 534 // after inlined call to do a ReplayEnvironment() on. |
| 535 // So we push return value on top of outer environment. |
| 536 // As for JS_GETTER/JS_SETTER/JS_CONSTRUCT nothing has to be done here, |
| 537 // the deoptimizer ensures that the result of the callee is correctly |
| 538 // propagated to result register during deoptimization. |
| 539 hydrogen_env = hydrogen_env->Copy(); |
| 540 hydrogen_env->Push(hydrogen_val); |
| 541 } |
| 542 } else { |
| 543 // Although we don't need this lazy bailout for normal execution |
| 544 // (because when we tail call from the outermost function we should pop |
| 545 // its frame) we still need it when debugger is on. |
| 546 hydrogen_env = current_block->last_environment(); |
| 547 } |
| 548 } else { |
| 549 if (hydrogen_val->HasObservableSideEffects()) { |
| 550 HSimulate* sim = HSimulate::cast(hydrogen_val->next()); |
| 551 sim->ReplayEnvironment(hydrogen_env); |
| 552 hydrogen_value_for_lazy_bailout = sim; |
| 553 } |
| 554 } |
| 555 LInstruction* bailout = LChunkBuilderBase::AssignEnvironment( |
| 556 new (zone()) LLazyBailout(), hydrogen_env); |
| 557 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); |
| 558 chunk_->AddInstruction(bailout, current_block); |
| 559 } |
| 560 |
511 LInstruction* LChunkBuilderBase::AssignEnvironment(LInstruction* instr, | 561 LInstruction* LChunkBuilderBase::AssignEnvironment(LInstruction* instr, |
512 HEnvironment* hydrogen_env) { | 562 HEnvironment* hydrogen_env) { |
513 int argument_index_accumulator = 0; | 563 int argument_index_accumulator = 0; |
514 ZoneList<HValue*> objects_to_materialize(0, zone()); | 564 ZoneList<HValue*> objects_to_materialize(0, zone()); |
515 DCHECK_NE(TAIL_CALLER_FUNCTION, hydrogen_env->frame_type()); | 565 DCHECK_NE(TAIL_CALLER_FUNCTION, hydrogen_env->frame_type()); |
516 instr->set_environment(CreateEnvironment( | 566 instr->set_environment(CreateEnvironment( |
517 hydrogen_env, &argument_index_accumulator, &objects_to_materialize)); | 567 hydrogen_env, &argument_index_accumulator, &objects_to_materialize)); |
518 return instr; | 568 return instr; |
519 } | 569 } |
520 | 570 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 | 724 |
675 LPhase::~LPhase() { | 725 LPhase::~LPhase() { |
676 if (ShouldProduceTraceOutput()) { | 726 if (ShouldProduceTraceOutput()) { |
677 isolate()->GetHTracer()->TraceLithium(name(), chunk_); | 727 isolate()->GetHTracer()->TraceLithium(name(), chunk_); |
678 } | 728 } |
679 } | 729 } |
680 | 730 |
681 | 731 |
682 } // namespace internal | 732 } // namespace internal |
683 } // namespace v8 | 733 } // namespace v8 |
OLD | NEW |