| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "lithium-allocator-inl.h" |
| 28 #include "arm/lithium-arm.h" | 29 #include "arm/lithium-arm.h" |
| 29 #include "arm/lithium-codegen-arm.h" | 30 #include "arm/lithium-codegen-arm.h" |
| 30 | 31 |
| 31 namespace v8 { | 32 namespace v8 { |
| 32 namespace internal { | 33 namespace internal { |
| 33 | 34 |
| 34 #define DEFINE_COMPILE(type) \ | 35 #define DEFINE_COMPILE(type) \ |
| 35 void L##type::CompileToNative(LCodeGen* generator) { \ | 36 void L##type::CompileToNative(LCodeGen* generator) { \ |
| 36 generator->Do##type(this); \ | 37 generator->Do##type(this); \ |
| 37 } | 38 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 49 | 50 |
| 50 | 51 |
| 51 void LOsrEntry::MarkSpilledRegister(int allocation_index, | 52 void LOsrEntry::MarkSpilledRegister(int allocation_index, |
| 52 LOperand* spill_operand) { | 53 LOperand* spill_operand) { |
| 53 ASSERT(spill_operand->IsStackSlot()); | 54 ASSERT(spill_operand->IsStackSlot()); |
| 54 ASSERT(register_spills_[allocation_index] == NULL); | 55 ASSERT(register_spills_[allocation_index] == NULL); |
| 55 register_spills_[allocation_index] = spill_operand; | 56 register_spills_[allocation_index] = spill_operand; |
| 56 } | 57 } |
| 57 | 58 |
| 58 | 59 |
| 60 #ifdef DEBUG |
| 61 void LInstruction::VerifyCall() { |
| 62 // Call instructions can use only fixed registers as |
| 63 // temporaries and outputs because all registers |
| 64 // are blocked by the calling convention. |
| 65 // Inputs can use either fixed register or have a short lifetime (be |
| 66 // used at start of the instruction). |
| 67 ASSERT(Output() == NULL || |
| 68 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 69 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 70 for (UseIterator it(this); it.HasNext(); it.Advance()) { |
| 71 LOperand* operand = it.Next(); |
| 72 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 73 LUnallocated::cast(operand)->IsUsedAtStart() || |
| 74 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 75 } |
| 76 for (TempIterator it(this); it.HasNext(); it.Advance()) { |
| 77 LOperand* operand = it.Next(); |
| 78 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 79 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 80 } |
| 81 } |
| 82 #endif |
| 83 |
| 84 |
| 59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, | 85 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, |
| 60 LOperand* spill_operand) { | 86 LOperand* spill_operand) { |
| 61 ASSERT(spill_operand->IsDoubleStackSlot()); | 87 ASSERT(spill_operand->IsDoubleStackSlot()); |
| 62 ASSERT(double_register_spills_[allocation_index] == NULL); | 88 ASSERT(double_register_spills_[allocation_index] == NULL); |
| 63 double_register_spills_[allocation_index] = spill_operand; | 89 double_register_spills_[allocation_index] = spill_operand; |
| 64 } | 90 } |
| 65 | 91 |
| 66 | 92 |
| 67 void LInstruction::PrintTo(StringStream* stream) { | 93 void LInstruction::PrintTo(StringStream* stream) { |
| 68 stream->Add("%s ", this->Mnemonic()); | 94 stream->Add("%s ", this->Mnemonic()); |
| 69 if (HasResult()) { | 95 |
| 70 PrintOutputOperandTo(stream); | 96 PrintOutputOperandTo(stream); |
| 71 } | |
| 72 | 97 |
| 73 PrintDataTo(stream); | 98 PrintDataTo(stream); |
| 74 | 99 |
| 75 if (HasEnvironment()) { | 100 if (HasEnvironment()) { |
| 76 stream->Add(" "); | 101 stream->Add(" "); |
| 77 environment()->PrintTo(stream); | 102 environment()->PrintTo(stream); |
| 78 } | 103 } |
| 79 | 104 |
| 80 if (HasPointerMap()) { | 105 if (HasPointerMap()) { |
| 81 stream->Add(" "); | 106 stream->Add(" "); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 } | 176 } |
| 152 | 177 |
| 153 | 178 |
| 154 const char* LArithmeticT::Mnemonic() const { | 179 const char* LArithmeticT::Mnemonic() const { |
| 155 switch (op()) { | 180 switch (op()) { |
| 156 case Token::ADD: return "add-t"; | 181 case Token::ADD: return "add-t"; |
| 157 case Token::SUB: return "sub-t"; | 182 case Token::SUB: return "sub-t"; |
| 158 case Token::MUL: return "mul-t"; | 183 case Token::MUL: return "mul-t"; |
| 159 case Token::MOD: return "mod-t"; | 184 case Token::MOD: return "mod-t"; |
| 160 case Token::DIV: return "div-t"; | 185 case Token::DIV: return "div-t"; |
| 186 case Token::BIT_AND: return "bit-and-t"; |
| 187 case Token::BIT_OR: return "bit-or-t"; |
| 188 case Token::BIT_XOR: return "bit-xor-t"; |
| 161 default: | 189 default: |
| 162 UNREACHABLE(); | 190 UNREACHABLE(); |
| 163 return NULL; | 191 return NULL; |
| 164 } | 192 } |
| 165 } | 193 } |
| 166 | 194 |
| 167 | 195 |
| 168 void LGoto::PrintDataTo(StringStream* stream) { | 196 void LGoto::PrintDataTo(StringStream* stream) { |
| 169 stream->Add("B%d", block_id()); | 197 stream->Add("B%d", block_id()); |
| 170 } | 198 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 } | 279 } |
| 252 | 280 |
| 253 | 281 |
| 254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { | 282 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 255 stream->Add("/%s ", hydrogen()->OpName()); | 283 stream->Add("/%s ", hydrogen()->OpName()); |
| 256 InputAt(0)->PrintTo(stream); | 284 InputAt(0)->PrintTo(stream); |
| 257 } | 285 } |
| 258 | 286 |
| 259 | 287 |
| 260 void LLoadContextSlot::PrintDataTo(StringStream* stream) { | 288 void LLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 261 stream->Add("(%d, %d)", context_chain_length(), slot_index()); | 289 InputAt(0)->PrintTo(stream); |
| 290 stream->Add("[%d]", slot_index()); |
| 291 } |
| 292 |
| 293 |
| 294 void LStoreContextSlot::PrintDataTo(StringStream* stream) { |
| 295 InputAt(0)->PrintTo(stream); |
| 296 stream->Add("[%d] <- ", slot_index()); |
| 297 InputAt(1)->PrintTo(stream); |
| 262 } | 298 } |
| 263 | 299 |
| 264 | 300 |
| 265 void LCallKeyed::PrintDataTo(StringStream* stream) { | 301 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 266 stream->Add("[r2] #%d / ", arity()); | 302 stream->Add("[r2] #%d / ", arity()); |
| 267 } | 303 } |
| 268 | 304 |
| 269 | 305 |
| 270 void LCallNamed::PrintDataTo(StringStream* stream) { | 306 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 271 SmartPointer<char> name_string = name()->ToCString(); | 307 SmartPointer<char> name_string = name()->ToCString(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 419 |
| 384 if (can_eliminate) { | 420 if (can_eliminate) { |
| 385 label->set_replacement(GetLabel(goto_instr->block_id())); | 421 label->set_replacement(GetLabel(goto_instr->block_id())); |
| 386 } | 422 } |
| 387 } | 423 } |
| 388 } | 424 } |
| 389 } | 425 } |
| 390 } | 426 } |
| 391 | 427 |
| 392 | 428 |
| 393 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 429 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 394 LGap* gap = new LGap(block); | 430 LGap* gap = new LGap(block); |
| 395 int index = -1; | 431 int index = -1; |
| 396 if (instr->IsControl()) { | 432 if (instr->IsControl()) { |
| 397 instructions_.Add(gap); | 433 instructions_.Add(gap); |
| 398 index = instructions_.length(); | 434 index = instructions_.length(); |
| 399 instructions_.Add(instr); | 435 instructions_.Add(instr); |
| 400 } else { | 436 } else { |
| 401 index = instructions_.length(); | 437 index = instructions_.length(); |
| 402 instructions_.Add(instr); | 438 instructions_.Add(instr); |
| 403 instructions_.Add(gap); | 439 instructions_.Add(gap); |
| 404 } | 440 } |
| 405 if (instr->HasPointerMap()) { | 441 if (instr->HasPointerMap()) { |
| 406 pointer_maps_.Add(instr->pointer_map()); | 442 pointer_maps_.Add(instr->pointer_map()); |
| 407 instr->pointer_map()->set_lithium_position(index); | 443 instr->pointer_map()->set_lithium_position(index); |
| 408 } | 444 } |
| 409 return index; | |
| 410 } | 445 } |
| 411 | 446 |
| 412 | 447 |
| 413 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { | 448 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
| 414 return LConstantOperand::Create(constant->id()); | 449 return LConstantOperand::Create(constant->id()); |
| 415 } | 450 } |
| 416 | 451 |
| 417 | 452 |
| 418 int LChunk::GetParameterStackSlot(int index) const { | 453 int LChunk::GetParameterStackSlot(int index) const { |
| 419 // The receiver is at index 0, the first parameter at index 1, so we | 454 // The receiver is at index 0, the first parameter at index 1, so we |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 | 683 |
| 649 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 684 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
| 650 HEnvironment* hydrogen_env = current_block_->last_environment(); | 685 HEnvironment* hydrogen_env = current_block_->last_environment(); |
| 651 instr->set_environment(CreateEnvironment(hydrogen_env)); | 686 instr->set_environment(CreateEnvironment(hydrogen_env)); |
| 652 return instr; | 687 return instr; |
| 653 } | 688 } |
| 654 | 689 |
| 655 | 690 |
| 656 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( | 691 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( |
| 657 LInstruction* instr, int ast_id) { | 692 LInstruction* instr, int ast_id) { |
| 658 ASSERT(instructions_pending_deoptimization_environment_ == NULL); | 693 ASSERT(instruction_pending_deoptimization_environment_ == NULL); |
| 659 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); | 694 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); |
| 660 instructions_pending_deoptimization_environment_ = instr; | 695 instruction_pending_deoptimization_environment_ = instr; |
| 661 pending_deoptimization_ast_id_ = ast_id; | 696 pending_deoptimization_ast_id_ = ast_id; |
| 662 return instr; | 697 return instr; |
| 663 } | 698 } |
| 664 | 699 |
| 665 | 700 |
| 666 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { | 701 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { |
| 667 instructions_pending_deoptimization_environment_ = NULL; | 702 instruction_pending_deoptimization_environment_ = NULL; |
| 668 pending_deoptimization_ast_id_ = AstNode::kNoNumber; | 703 pending_deoptimization_ast_id_ = AstNode::kNoNumber; |
| 669 } | 704 } |
| 670 | 705 |
| 671 | 706 |
| 672 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, | 707 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, |
| 673 HInstruction* hinstr, | 708 HInstruction* hinstr, |
| 674 CanDeoptimize can_deoptimize) { | 709 CanDeoptimize can_deoptimize) { |
| 675 allocator_->MarkAsCall(); | 710 #ifdef DEBUG |
| 711 instr->VerifyCall(); |
| 712 #endif |
| 713 instr->MarkAsCall(); |
| 676 instr = AssignPointerMap(instr); | 714 instr = AssignPointerMap(instr); |
| 677 | 715 |
| 678 if (hinstr->HasSideEffects()) { | 716 if (hinstr->HasSideEffects()) { |
| 679 ASSERT(hinstr->next()->IsSimulate()); | 717 ASSERT(hinstr->next()->IsSimulate()); |
| 680 HSimulate* sim = HSimulate::cast(hinstr->next()); | 718 HSimulate* sim = HSimulate::cast(hinstr->next()); |
| 681 instr = SetInstructionPendingDeoptimizationEnvironment( | 719 instr = SetInstructionPendingDeoptimizationEnvironment( |
| 682 instr, sim->ast_id()); | 720 instr, sim->ast_id()); |
| 683 } | 721 } |
| 684 | 722 |
| 685 // If instruction does not have side-effects lazy deoptimization | 723 // If instruction does not have side-effects lazy deoptimization |
| 686 // after the call will try to deoptimize to the point before the call. | 724 // after the call will try to deoptimize to the point before the call. |
| 687 // Thus we still need to attach environment to this call even if | 725 // Thus we still need to attach environment to this call even if |
| 688 // call sequence can not deoptimize eagerly. | 726 // call sequence can not deoptimize eagerly. |
| 689 bool needs_environment = | 727 bool needs_environment = |
| 690 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); | 728 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); |
| 691 if (needs_environment && !instr->HasEnvironment()) { | 729 if (needs_environment && !instr->HasEnvironment()) { |
| 692 instr = AssignEnvironment(instr); | 730 instr = AssignEnvironment(instr); |
| 693 } | 731 } |
| 694 | 732 |
| 695 return instr; | 733 return instr; |
| 696 } | 734 } |
| 697 | 735 |
| 698 | 736 |
| 699 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { | 737 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { |
| 700 allocator_->MarkAsSaveDoubles(); | 738 instr->MarkAsSaveDoubles(); |
| 701 return instr; | 739 return instr; |
| 702 } | 740 } |
| 703 | 741 |
| 704 | 742 |
| 705 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 743 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 706 ASSERT(!instr->HasPointerMap()); | 744 ASSERT(!instr->HasPointerMap()); |
| 707 instr->set_pointer_map(new LPointerMap(position_)); | 745 instr->set_pointer_map(new LPointerMap(position_)); |
| 708 return instr; | 746 return instr; |
| 709 } | 747 } |
| 710 | 748 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 735 } | 773 } |
| 736 | 774 |
| 737 | 775 |
| 738 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 776 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 739 return AssignEnvironment(new LDeoptimize); | 777 return AssignEnvironment(new LDeoptimize); |
| 740 } | 778 } |
| 741 | 779 |
| 742 | 780 |
| 743 LInstruction* LChunkBuilder::DoBit(Token::Value op, | 781 LInstruction* LChunkBuilder::DoBit(Token::Value op, |
| 744 HBitwiseBinaryOperation* instr) { | 782 HBitwiseBinaryOperation* instr) { |
| 745 ASSERT(instr->representation().IsInteger32()); | 783 if (instr->representation().IsInteger32()) { |
| 746 ASSERT(instr->left()->representation().IsInteger32()); | 784 ASSERT(instr->left()->representation().IsInteger32()); |
| 747 ASSERT(instr->right()->representation().IsInteger32()); | 785 ASSERT(instr->right()->representation().IsInteger32()); |
| 748 | 786 |
| 749 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 787 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 750 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); | 788 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 751 return DefineSameAsFirst(new LBitI(op, left, right)); | 789 return DefineSameAsFirst(new LBitI(op, left, right)); |
| 790 } else { |
| 791 ASSERT(instr->representation().IsTagged()); |
| 792 ASSERT(instr->left()->representation().IsTagged()); |
| 793 ASSERT(instr->right()->representation().IsTagged()); |
| 794 |
| 795 LOperand* left = UseFixed(instr->left(), r1); |
| 796 LOperand* right = UseFixed(instr->right(), r0); |
| 797 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 798 return MarkAsCall(DefineFixed(result, r0), instr); |
| 799 } |
| 752 } | 800 } |
| 753 | 801 |
| 754 | 802 |
| 755 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 803 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 756 HBitwiseBinaryOperation* instr) { | 804 HBitwiseBinaryOperation* instr) { |
| 757 ASSERT(instr->representation().IsInteger32()); | 805 ASSERT(instr->representation().IsInteger32()); |
| 758 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); | 806 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); |
| 759 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); | 807 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); |
| 760 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); | 808 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); |
| 761 | 809 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 } | 928 } |
| 881 block->set_argument_count(argument_count_); | 929 block->set_argument_count(argument_count_); |
| 882 next_block_ = NULL; | 930 next_block_ = NULL; |
| 883 current_block_ = NULL; | 931 current_block_ = NULL; |
| 884 } | 932 } |
| 885 | 933 |
| 886 | 934 |
| 887 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 935 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 888 HInstruction* old_current = current_instruction_; | 936 HInstruction* old_current = current_instruction_; |
| 889 current_instruction_ = current; | 937 current_instruction_ = current; |
| 890 allocator_->BeginInstruction(); | |
| 891 if (current->has_position()) position_ = current->position(); | 938 if (current->has_position()) position_ = current->position(); |
| 892 LInstruction* instr = current->CompileToLithium(this); | 939 LInstruction* instr = current->CompileToLithium(this); |
| 893 | 940 |
| 894 if (instr != NULL) { | 941 if (instr != NULL) { |
| 895 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 942 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 896 instr = AssignPointerMap(instr); | 943 instr = AssignPointerMap(instr); |
| 897 } | 944 } |
| 898 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 945 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 899 instr = AssignEnvironment(instr); | 946 instr = AssignEnvironment(instr); |
| 900 } | 947 } |
| 901 if (current->IsTest() && !instr->IsGoto()) { | 948 if (current->IsTest() && !instr->IsGoto()) { |
| 902 ASSERT(instr->IsControl()); | 949 ASSERT(instr->IsControl()); |
| 903 HTest* test = HTest::cast(current); | 950 HTest* test = HTest::cast(current); |
| 904 instr->set_hydrogen_value(test->value()); | 951 instr->set_hydrogen_value(test->value()); |
| 905 HBasicBlock* first = test->FirstSuccessor(); | 952 HBasicBlock* first = test->FirstSuccessor(); |
| 906 HBasicBlock* second = test->SecondSuccessor(); | 953 HBasicBlock* second = test->SecondSuccessor(); |
| 907 ASSERT(first != NULL && second != NULL); | 954 ASSERT(first != NULL && second != NULL); |
| 908 instr->SetBranchTargets(first->block_id(), second->block_id()); | 955 instr->SetBranchTargets(first->block_id(), second->block_id()); |
| 909 } else { | 956 } else { |
| 910 instr->set_hydrogen_value(current); | 957 instr->set_hydrogen_value(current); |
| 911 } | 958 } |
| 912 | 959 |
| 913 int index = chunk_->AddInstruction(instr, current_block_); | 960 chunk_->AddInstruction(instr, current_block_); |
| 914 allocator_->SummarizeInstruction(index); | |
| 915 } else { | |
| 916 // This instruction should be omitted. | |
| 917 allocator_->OmitInstruction(); | |
| 918 } | 961 } |
| 919 current_instruction_ = old_current; | 962 current_instruction_ = old_current; |
| 920 } | 963 } |
| 921 | 964 |
| 922 | 965 |
| 923 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { | 966 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { |
| 924 if (hydrogen_env == NULL) return NULL; | 967 if (hydrogen_env == NULL) return NULL; |
| 925 | 968 |
| 926 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); | 969 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); |
| 927 int ast_id = hydrogen_env->ast_id(); | 970 int ast_id = hydrogen_env->ast_id(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 | 1064 |
| 1022 LOperand* temp = TempRegister(); | 1065 LOperand* temp = TempRegister(); |
| 1023 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp); | 1066 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp); |
| 1024 } else if (v->IsCompareJSObjectEq()) { | 1067 } else if (v->IsCompareJSObjectEq()) { |
| 1025 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1068 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 1026 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1069 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 1027 UseRegisterAtStart(compare->right())); | 1070 UseRegisterAtStart(compare->right())); |
| 1028 } else if (v->IsInstanceOf()) { | 1071 } else if (v->IsInstanceOf()) { |
| 1029 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1072 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 1030 LInstruction* result = | 1073 LInstruction* result = |
| 1031 new LInstanceOfAndBranch(Use(instance_of->left()), | 1074 new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0), |
| 1032 Use(instance_of->right())); | 1075 UseFixed(instance_of->right(), r1)); |
| 1033 return MarkAsCall(result, instr); | 1076 return MarkAsCall(result, instr); |
| 1034 } else if (v->IsTypeofIs()) { | 1077 } else if (v->IsTypeofIs()) { |
| 1035 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1078 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 1036 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | 1079 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1080 } else if (v->IsIsConstructCall()) { |
| 1081 return new LIsConstructCallAndBranch(TempRegister()); |
| 1037 } else { | 1082 } else { |
| 1038 if (v->IsConstant()) { | 1083 if (v->IsConstant()) { |
| 1039 if (HConstant::cast(v)->handle()->IsTrue()) { | 1084 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 1040 return new LGoto(instr->FirstSuccessor()->block_id()); | 1085 return new LGoto(instr->FirstSuccessor()->block_id()); |
| 1041 } else if (HConstant::cast(v)->handle()->IsFalse()) { | 1086 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
| 1042 return new LGoto(instr->SecondSuccessor()->block_id()); | 1087 return new LGoto(instr->SecondSuccessor()->block_id()); |
| 1043 } | 1088 } |
| 1044 } | 1089 } |
| 1045 Abort("Undefined compare before branch"); | 1090 Abort("Undefined compare before branch"); |
| 1046 return NULL; | 1091 return NULL; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 } | 1143 } |
| 1099 | 1144 |
| 1100 | 1145 |
| 1101 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1146 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1102 ++argument_count_; | 1147 ++argument_count_; |
| 1103 LOperand* argument = Use(instr->argument()); | 1148 LOperand* argument = Use(instr->argument()); |
| 1104 return new LPushArgument(argument); | 1149 return new LPushArgument(argument); |
| 1105 } | 1150 } |
| 1106 | 1151 |
| 1107 | 1152 |
| 1153 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1154 return DefineAsRegister(new LContext); |
| 1155 } |
| 1156 |
| 1157 |
| 1158 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1159 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1160 return DefineAsRegister(new LOuterContext(context)); |
| 1161 } |
| 1162 |
| 1163 |
| 1108 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1164 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 1109 return DefineAsRegister(new LGlobalObject); | 1165 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1166 return DefineAsRegister(new LGlobalObject(context)); |
| 1110 } | 1167 } |
| 1111 | 1168 |
| 1112 | 1169 |
| 1113 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1170 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1114 return DefineAsRegister(new LGlobalReceiver); | 1171 LOperand* global_object = UseRegisterAtStart(instr->value()); |
| 1172 return DefineAsRegister(new LGlobalReceiver(global_object)); |
| 1115 } | 1173 } |
| 1116 | 1174 |
| 1117 | 1175 |
| 1118 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1176 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1119 HCallConstantFunction* instr) { | 1177 HCallConstantFunction* instr) { |
| 1120 argument_count_ -= instr->argument_count(); | 1178 argument_count_ -= instr->argument_count(); |
| 1121 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); | 1179 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); |
| 1122 } | 1180 } |
| 1123 | 1181 |
| 1124 | 1182 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 | 1299 |
| 1242 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1300 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1243 if (instr->representation().IsDouble()) { | 1301 if (instr->representation().IsDouble()) { |
| 1244 return DoArithmeticD(Token::DIV, instr); | 1302 return DoArithmeticD(Token::DIV, instr); |
| 1245 } else if (instr->representation().IsInteger32()) { | 1303 } else if (instr->representation().IsInteger32()) { |
| 1246 // TODO(1042) The fixed register allocation | 1304 // TODO(1042) The fixed register allocation |
| 1247 // is needed because we call GenericBinaryOpStub from | 1305 // is needed because we call GenericBinaryOpStub from |
| 1248 // the generated code, which requires registers r0 | 1306 // the generated code, which requires registers r0 |
| 1249 // and r1 to be used. We should remove that | 1307 // and r1 to be used. We should remove that |
| 1250 // when we provide a native implementation. | 1308 // when we provide a native implementation. |
| 1251 LOperand* value = UseFixed(instr->left(), r0); | 1309 LOperand* dividend = UseFixed(instr->left(), r0); |
| 1252 LOperand* divisor = UseFixed(instr->right(), r1); | 1310 LOperand* divisor = UseFixed(instr->right(), r1); |
| 1253 return AssignEnvironment(AssignPointerMap( | 1311 return AssignEnvironment(AssignPointerMap( |
| 1254 DefineFixed(new LDivI(value, divisor), r0))); | 1312 DefineFixed(new LDivI(dividend, divisor), r0))); |
| 1255 } else { | 1313 } else { |
| 1256 return DoArithmeticT(Token::DIV, instr); | 1314 return DoArithmeticT(Token::DIV, instr); |
| 1257 } | 1315 } |
| 1258 } | 1316 } |
| 1259 | 1317 |
| 1260 | 1318 |
| 1261 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1319 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1262 if (instr->representation().IsInteger32()) { | 1320 if (instr->representation().IsInteger32()) { |
| 1263 // TODO(1042) The fixed register allocation | 1321 // TODO(1042) The fixed register allocation |
| 1264 // is needed because we call GenericBinaryOpStub from | 1322 // is needed because we call GenericBinaryOpStub from |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 return AssignEnvironment(DefineSameAsFirst(result)); | 1514 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1457 } | 1515 } |
| 1458 | 1516 |
| 1459 | 1517 |
| 1460 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1518 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1461 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1519 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1462 UseRegister(instr->length()))); | 1520 UseRegister(instr->length()))); |
| 1463 } | 1521 } |
| 1464 | 1522 |
| 1465 | 1523 |
| 1524 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1525 // The control instruction marking the end of a block that completed |
| 1526 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1527 return NULL; |
| 1528 } |
| 1529 |
| 1530 |
| 1466 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1531 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1467 LOperand* value = UseFixed(instr->value(), r0); | 1532 LOperand* value = UseFixed(instr->value(), r0); |
| 1468 return MarkAsCall(new LThrow(value), instr); | 1533 return MarkAsCall(new LThrow(value), instr); |
| 1469 } | 1534 } |
| 1470 | 1535 |
| 1471 | 1536 |
| 1472 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1537 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1473 Representation from = instr->from(); | 1538 Representation from = instr->from(); |
| 1474 Representation to = instr->to(); | 1539 Representation to = instr->to(); |
| 1475 if (from.IsTagged()) { | 1540 if (from.IsTagged()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1500 | 1565 |
| 1501 // Make sure that the temp and result_temp registers are | 1566 // Make sure that the temp and result_temp registers are |
| 1502 // different. | 1567 // different. |
| 1503 LUnallocated* result_temp = TempRegister(); | 1568 LUnallocated* result_temp = TempRegister(); |
| 1504 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); | 1569 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); |
| 1505 Define(result, result_temp); | 1570 Define(result, result_temp); |
| 1506 return AssignPointerMap(result); | 1571 return AssignPointerMap(result); |
| 1507 } else { | 1572 } else { |
| 1508 ASSERT(to.IsInteger32()); | 1573 ASSERT(to.IsInteger32()); |
| 1509 LOperand* value = UseRegister(instr->value()); | 1574 LOperand* value = UseRegister(instr->value()); |
| 1510 LDoubleToI* res = new LDoubleToI(value); | 1575 LDoubleToI* res = new LDoubleToI(value, TempRegister()); |
| 1511 return AssignEnvironment(DefineAsRegister(res)); | 1576 return AssignEnvironment(DefineAsRegister(res)); |
| 1512 } | 1577 } |
| 1513 } else if (from.IsInteger32()) { | 1578 } else if (from.IsInteger32()) { |
| 1514 if (to.IsTagged()) { | 1579 if (to.IsTagged()) { |
| 1515 HValue* val = instr->value(); | 1580 HValue* val = instr->value(); |
| 1516 LOperand* value = UseRegister(val); | 1581 LOperand* value = UseRegister(val); |
| 1517 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1582 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1518 return DefineSameAsFirst(new LSmiTag(value)); | 1583 return DefineSameAsFirst(new LSmiTag(value)); |
| 1519 } else { | 1584 } else { |
| 1520 LNumberTagI* result = new LNumberTagI(value); | 1585 LNumberTagI* result = new LNumberTagI(value); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 | 1637 |
| 1573 | 1638 |
| 1574 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1639 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1575 return new LReturn(UseFixed(instr->value(), r0)); | 1640 return new LReturn(UseFixed(instr->value(), r0)); |
| 1576 } | 1641 } |
| 1577 | 1642 |
| 1578 | 1643 |
| 1579 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1644 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1580 Representation r = instr->representation(); | 1645 Representation r = instr->representation(); |
| 1581 if (r.IsInteger32()) { | 1646 if (r.IsInteger32()) { |
| 1582 int32_t value = instr->Integer32Value(); | 1647 return DefineAsRegister(new LConstantI); |
| 1583 return DefineAsRegister(new LConstantI(value)); | |
| 1584 } else if (r.IsDouble()) { | 1648 } else if (r.IsDouble()) { |
| 1585 double value = instr->DoubleValue(); | 1649 return DefineAsRegister(new LConstantD); |
| 1586 return DefineAsRegister(new LConstantD(value)); | |
| 1587 } else if (r.IsTagged()) { | 1650 } else if (r.IsTagged()) { |
| 1588 return DefineAsRegister(new LConstantT(instr->handle())); | 1651 return DefineAsRegister(new LConstantT); |
| 1589 } else { | 1652 } else { |
| 1590 UNREACHABLE(); | 1653 UNREACHABLE(); |
| 1591 return NULL; | 1654 return NULL; |
| 1592 } | 1655 } |
| 1593 } | 1656 } |
| 1594 | 1657 |
| 1595 | 1658 |
| 1596 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1659 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
| 1597 LLoadGlobal* result = new LLoadGlobal(); | 1660 LLoadGlobal* result = new LLoadGlobal(); |
| 1598 return instr->check_hole_value() | 1661 return instr->check_hole_value() |
| 1599 ? AssignEnvironment(DefineAsRegister(result)) | 1662 ? AssignEnvironment(DefineAsRegister(result)) |
| 1600 : DefineAsRegister(result); | 1663 : DefineAsRegister(result); |
| 1601 } | 1664 } |
| 1602 | 1665 |
| 1603 | 1666 |
| 1604 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1667 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1605 return new LStoreGlobal(UseRegisterAtStart(instr->value())); | 1668 if (instr->check_hole_value()) { |
| 1669 LOperand* temp = TempRegister(); |
| 1670 LOperand* value = UseRegister(instr->value()); |
| 1671 return AssignEnvironment(new LStoreGlobal(value, temp)); |
| 1672 } else { |
| 1673 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1674 return new LStoreGlobal(value, NULL); |
| 1675 } |
| 1606 } | 1676 } |
| 1607 | 1677 |
| 1608 | 1678 |
| 1609 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 1679 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1610 return DefineAsRegister(new LLoadContextSlot); | 1680 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1681 return DefineAsRegister(new LLoadContextSlot(context)); |
| 1682 } |
| 1683 |
| 1684 |
| 1685 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
| 1686 LOperand* context = UseTempRegister(instr->context()); |
| 1687 LOperand* value; |
| 1688 if (instr->NeedsWriteBarrier()) { |
| 1689 value = UseTempRegister(instr->value()); |
| 1690 } else { |
| 1691 value = UseRegister(instr->value()); |
| 1692 } |
| 1693 return new LStoreContextSlot(context, value); |
| 1611 } | 1694 } |
| 1612 | 1695 |
| 1613 | 1696 |
| 1614 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1697 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1615 return DefineAsRegister( | 1698 return DefineAsRegister( |
| 1616 new LLoadNamedField(UseRegisterAtStart(instr->object()))); | 1699 new LLoadNamedField(UseRegisterAtStart(instr->object()))); |
| 1617 } | 1700 } |
| 1618 | 1701 |
| 1619 | 1702 |
| 1620 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1703 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1883 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 1801 LTypeof* result = new LTypeof(UseRegisterAtStart(instr->value())); | 1884 LTypeof* result = new LTypeof(UseRegisterAtStart(instr->value())); |
| 1802 return MarkAsCall(DefineFixed(result, r0), instr); | 1885 return MarkAsCall(DefineFixed(result, r0), instr); |
| 1803 } | 1886 } |
| 1804 | 1887 |
| 1805 | 1888 |
| 1806 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1889 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 1807 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 1890 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
| 1808 } | 1891 } |
| 1809 | 1892 |
| 1893 |
| 1894 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { |
| 1895 return DefineAsRegister(new LIsConstructCall()); |
| 1896 } |
| 1897 |
| 1898 |
| 1810 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1899 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1811 HEnvironment* env = current_block_->last_environment(); | 1900 HEnvironment* env = current_block_->last_environment(); |
| 1812 ASSERT(env != NULL); | 1901 ASSERT(env != NULL); |
| 1813 | 1902 |
| 1814 env->set_ast_id(instr->ast_id()); | 1903 env->set_ast_id(instr->ast_id()); |
| 1815 | 1904 |
| 1816 env->Drop(instr->pop_count()); | 1905 env->Drop(instr->pop_count()); |
| 1817 for (int i = 0; i < instr->values()->length(); ++i) { | 1906 for (int i = 0; i < instr->values()->length(); ++i) { |
| 1818 HValue* value = instr->values()->at(i); | 1907 HValue* value = instr->values()->at(i); |
| 1819 if (instr->HasAssignedIndexAt(i)) { | 1908 if (instr->HasAssignedIndexAt(i)) { |
| 1820 env->Bind(instr->GetAssignedIndexAt(i), value); | 1909 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 1821 } else { | 1910 } else { |
| 1822 env->Push(value); | 1911 env->Push(value); |
| 1823 } | 1912 } |
| 1824 } | 1913 } |
| 1825 | 1914 |
| 1826 ASSERT(env->length() == instr->environment_length()); | 1915 ASSERT(env->length() == instr->environment_length()); |
| 1827 | 1916 |
| 1828 // If there is an instruction pending deoptimization environment create a | 1917 // If there is an instruction pending deoptimization environment create a |
| 1829 // lazy bailout instruction to capture the environment. | 1918 // lazy bailout instruction to capture the environment. |
| 1830 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 1919 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 1831 LInstruction* result = new LLazyBailout; | 1920 LInstruction* result = new LLazyBailout; |
| 1832 result = AssignEnvironment(result); | 1921 result = AssignEnvironment(result); |
| 1833 instructions_pending_deoptimization_environment_-> | 1922 instruction_pending_deoptimization_environment_-> |
| 1834 set_deoptimization_environment(result->environment()); | 1923 set_deoptimization_environment(result->environment()); |
| 1835 ClearInstructionPendingDeoptimizationEnvironment(); | 1924 ClearInstructionPendingDeoptimizationEnvironment(); |
| 1836 return result; | 1925 return result; |
| 1837 } | 1926 } |
| 1838 | 1927 |
| 1839 return NULL; | 1928 return NULL; |
| 1840 } | 1929 } |
| 1841 | 1930 |
| 1842 | 1931 |
| 1843 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 1932 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1859 | 1948 |
| 1860 | 1949 |
| 1861 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1950 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1862 HEnvironment* outer = current_block_->last_environment()->outer(); | 1951 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1863 current_block_->UpdateEnvironment(outer); | 1952 current_block_->UpdateEnvironment(outer); |
| 1864 return NULL; | 1953 return NULL; |
| 1865 } | 1954 } |
| 1866 | 1955 |
| 1867 | 1956 |
| 1868 } } // namespace v8::internal | 1957 } } // namespace v8::internal |
| OLD | NEW |