| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arm/lithium-codegen-arm.h" | 7 #include "src/arm/lithium-codegen-arm.h" |
| 8 #include "src/hydrogen-osr.h" | 8 #include "src/hydrogen-osr.h" |
| 9 #include "src/lithium-inl.h" | 9 #include "src/lithium-inl.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 #define DEFINE_COMPILE(type) \ | 14 #define DEFINE_COMPILE(type) \ |
| 15 void L##type::CompileToNative(LCodeGen* generator) { \ | 15 void L##type::CompileToNative(LCodeGen* generator) { \ |
| 16 generator->Do##type(this); \ | 16 generator->Do##type(this); \ |
| 17 } | 17 } |
| 18 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 18 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 19 #undef DEFINE_COMPILE | 19 #undef DEFINE_COMPILE |
| 20 | 20 |
| 21 #ifdef DEBUG | 21 #ifdef DEBUG |
| 22 void LInstruction::VerifyCall() { | 22 void LInstruction::VerifyCall() { |
| 23 // Call instructions can use only fixed registers as temporaries and | 23 // Call instructions can use only fixed registers as temporaries and |
| 24 // outputs because all registers are blocked by the calling convention. | 24 // outputs because all registers are blocked by the calling convention. |
| 25 // Inputs operands must use a fixed register or use-at-start policy or | 25 // Inputs operands must use a fixed register or use-at-start policy or |
| 26 // a non-register policy. | 26 // a non-register policy. |
| 27 ASSERT(Output() == NULL || | 27 DCHECK(Output() == NULL || |
| 28 LUnallocated::cast(Output())->HasFixedPolicy() || | 28 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 29 !LUnallocated::cast(Output())->HasRegisterPolicy()); | 29 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 30 for (UseIterator it(this); !it.Done(); it.Advance()) { | 30 for (UseIterator it(this); !it.Done(); it.Advance()) { |
| 31 LUnallocated* operand = LUnallocated::cast(it.Current()); | 31 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 32 ASSERT(operand->HasFixedPolicy() || | 32 DCHECK(operand->HasFixedPolicy() || |
| 33 operand->IsUsedAtStart()); | 33 operand->IsUsedAtStart()); |
| 34 } | 34 } |
| 35 for (TempIterator it(this); !it.Done(); it.Advance()) { | 35 for (TempIterator it(this); !it.Done(); it.Advance()) { |
| 36 LUnallocated* operand = LUnallocated::cast(it.Current()); | 36 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 37 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); | 37 DCHECK(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); |
| 38 } | 38 } |
| 39 } | 39 } |
| 40 #endif | 40 #endif |
| 41 | 41 |
| 42 | 42 |
| 43 void LInstruction::PrintTo(StringStream* stream) { | 43 void LInstruction::PrintTo(StringStream* stream) { |
| 44 stream->Add("%s ", this->Mnemonic()); | 44 stream->Add("%s ", this->Mnemonic()); |
| 45 | 45 |
| 46 PrintOutputOperandTo(stream); | 46 PrintOutputOperandTo(stream); |
| 47 | 47 |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 elements()->PrintTo(stream); | 348 elements()->PrintTo(stream); |
| 349 stream->Add("["); | 349 stream->Add("["); |
| 350 key()->PrintTo(stream); | 350 key()->PrintTo(stream); |
| 351 if (hydrogen()->IsDehoisted()) { | 351 if (hydrogen()->IsDehoisted()) { |
| 352 stream->Add(" + %d] <-", base_offset()); | 352 stream->Add(" + %d] <-", base_offset()); |
| 353 } else { | 353 } else { |
| 354 stream->Add("] <- "); | 354 stream->Add("] <- "); |
| 355 } | 355 } |
| 356 | 356 |
| 357 if (value() == NULL) { | 357 if (value() == NULL) { |
| 358 ASSERT(hydrogen()->IsConstantHoleStore() && | 358 DCHECK(hydrogen()->IsConstantHoleStore() && |
| 359 hydrogen()->value()->representation().IsDouble()); | 359 hydrogen()->value()->representation().IsDouble()); |
| 360 stream->Add("<the hole(nan)>"); | 360 stream->Add("<the hole(nan)>"); |
| 361 } else { | 361 } else { |
| 362 value()->PrintTo(stream); | 362 value()->PrintTo(stream); |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 | 366 |
| 367 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { | 367 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 368 object()->PrintTo(stream); | 368 object()->PrintTo(stream); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 384 if (kind == DOUBLE_REGISTERS) spill_slot_count_++; | 384 if (kind == DOUBLE_REGISTERS) spill_slot_count_++; |
| 385 return spill_slot_count_++; | 385 return spill_slot_count_++; |
| 386 } | 386 } |
| 387 | 387 |
| 388 | 388 |
| 389 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { | 389 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 390 int index = GetNextSpillIndex(kind); | 390 int index = GetNextSpillIndex(kind); |
| 391 if (kind == DOUBLE_REGISTERS) { | 391 if (kind == DOUBLE_REGISTERS) { |
| 392 return LDoubleStackSlot::Create(index, zone()); | 392 return LDoubleStackSlot::Create(index, zone()); |
| 393 } else { | 393 } else { |
| 394 ASSERT(kind == GENERAL_REGISTERS); | 394 DCHECK(kind == GENERAL_REGISTERS); |
| 395 return LStackSlot::Create(index, zone()); | 395 return LStackSlot::Create(index, zone()); |
| 396 } | 396 } |
| 397 } | 397 } |
| 398 | 398 |
| 399 | 399 |
| 400 LPlatformChunk* LChunkBuilder::Build() { | 400 LPlatformChunk* LChunkBuilder::Build() { |
| 401 ASSERT(is_unused()); | 401 DCHECK(is_unused()); |
| 402 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 402 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
| 403 LPhase phase("L_Building chunk", chunk_); | 403 LPhase phase("L_Building chunk", chunk_); |
| 404 status_ = BUILDING; | 404 status_ = BUILDING; |
| 405 | 405 |
| 406 // If compiling for OSR, reserve space for the unoptimized frame, | 406 // If compiling for OSR, reserve space for the unoptimized frame, |
| 407 // which will be subsumed into this frame. | 407 // which will be subsumed into this frame. |
| 408 if (graph()->has_osr()) { | 408 if (graph()->has_osr()) { |
| 409 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 409 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 410 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 410 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 411 } | 411 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 instr = AssignEnvironment(instr); | 602 instr = AssignEnvironment(instr); |
| 603 // We can't really figure out if the environment is needed or not. | 603 // We can't really figure out if the environment is needed or not. |
| 604 instr->environment()->set_has_been_used(); | 604 instr->environment()->set_has_been_used(); |
| 605 } | 605 } |
| 606 | 606 |
| 607 return instr; | 607 return instr; |
| 608 } | 608 } |
| 609 | 609 |
| 610 | 610 |
| 611 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 611 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 612 ASSERT(!instr->HasPointerMap()); | 612 DCHECK(!instr->HasPointerMap()); |
| 613 instr->set_pointer_map(new(zone()) LPointerMap(zone())); | 613 instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
| 614 return instr; | 614 return instr; |
| 615 } | 615 } |
| 616 | 616 |
| 617 | 617 |
| 618 LUnallocated* LChunkBuilder::TempRegister() { | 618 LUnallocated* LChunkBuilder::TempRegister() { |
| 619 LUnallocated* operand = | 619 LUnallocated* operand = |
| 620 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 620 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
| 621 int vreg = allocator_->GetVirtualRegister(); | 621 int vreg = allocator_->GetVirtualRegister(); |
| 622 if (!allocator_->AllocationOk()) { | 622 if (!allocator_->AllocationOk()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 636 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 636 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
| 637 vreg = 0; | 637 vreg = 0; |
| 638 } | 638 } |
| 639 operand->set_virtual_register(vreg); | 639 operand->set_virtual_register(vreg); |
| 640 return operand; | 640 return operand; |
| 641 } | 641 } |
| 642 | 642 |
| 643 | 643 |
| 644 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 644 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
| 645 LUnallocated* operand = ToUnallocated(reg); | 645 LUnallocated* operand = ToUnallocated(reg); |
| 646 ASSERT(operand->HasFixedPolicy()); | 646 DCHECK(operand->HasFixedPolicy()); |
| 647 return operand; | 647 return operand; |
| 648 } | 648 } |
| 649 | 649 |
| 650 | 650 |
| 651 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { | 651 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { |
| 652 LUnallocated* operand = ToUnallocated(reg); | 652 LUnallocated* operand = ToUnallocated(reg); |
| 653 ASSERT(operand->HasFixedPolicy()); | 653 DCHECK(operand->HasFixedPolicy()); |
| 654 return operand; | 654 return operand; |
| 655 } | 655 } |
| 656 | 656 |
| 657 | 657 |
| 658 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { | 658 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { |
| 659 return new(zone()) LLabel(instr->block()); | 659 return new(zone()) LLabel(instr->block()); |
| 660 } | 660 } |
| 661 | 661 |
| 662 | 662 |
| 663 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 663 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
| 664 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 664 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { | 668 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { |
| 669 UNREACHABLE(); | 669 UNREACHABLE(); |
| 670 return NULL; | 670 return NULL; |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 674 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 675 return AssignEnvironment(new(zone()) LDeoptimize); | 675 return AssignEnvironment(new(zone()) LDeoptimize); |
| 676 } | 676 } |
| 677 | 677 |
| 678 | 678 |
| 679 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 679 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 680 HBitwiseBinaryOperation* instr) { | 680 HBitwiseBinaryOperation* instr) { |
| 681 if (instr->representation().IsSmiOrInteger32()) { | 681 if (instr->representation().IsSmiOrInteger32()) { |
| 682 ASSERT(instr->left()->representation().Equals(instr->representation())); | 682 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 683 ASSERT(instr->right()->representation().Equals(instr->representation())); | 683 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 684 LOperand* left = UseRegisterAtStart(instr->left()); | 684 LOperand* left = UseRegisterAtStart(instr->left()); |
| 685 | 685 |
| 686 HValue* right_value = instr->right(); | 686 HValue* right_value = instr->right(); |
| 687 LOperand* right = NULL; | 687 LOperand* right = NULL; |
| 688 int constant_value = 0; | 688 int constant_value = 0; |
| 689 bool does_deopt = false; | 689 bool does_deopt = false; |
| 690 if (right_value->IsConstant()) { | 690 if (right_value->IsConstant()) { |
| 691 HConstant* constant = HConstant::cast(right_value); | 691 HConstant* constant = HConstant::cast(right_value); |
| 692 right = chunk_->DefineConstantOperand(constant); | 692 right = chunk_->DefineConstantOperand(constant); |
| 693 constant_value = constant->Integer32Value() & 0x1f; | 693 constant_value = constant->Integer32Value() & 0x1f; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 714 DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); | 714 DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); |
| 715 return does_deopt ? AssignEnvironment(result) : result; | 715 return does_deopt ? AssignEnvironment(result) : result; |
| 716 } else { | 716 } else { |
| 717 return DoArithmeticT(op, instr); | 717 return DoArithmeticT(op, instr); |
| 718 } | 718 } |
| 719 } | 719 } |
| 720 | 720 |
| 721 | 721 |
| 722 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 722 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 723 HArithmeticBinaryOperation* instr) { | 723 HArithmeticBinaryOperation* instr) { |
| 724 ASSERT(instr->representation().IsDouble()); | 724 DCHECK(instr->representation().IsDouble()); |
| 725 ASSERT(instr->left()->representation().IsDouble()); | 725 DCHECK(instr->left()->representation().IsDouble()); |
| 726 ASSERT(instr->right()->representation().IsDouble()); | 726 DCHECK(instr->right()->representation().IsDouble()); |
| 727 if (op == Token::MOD) { | 727 if (op == Token::MOD) { |
| 728 LOperand* left = UseFixedDouble(instr->left(), d0); | 728 LOperand* left = UseFixedDouble(instr->left(), d0); |
| 729 LOperand* right = UseFixedDouble(instr->right(), d1); | 729 LOperand* right = UseFixedDouble(instr->right(), d1); |
| 730 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 730 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 731 return MarkAsCall(DefineFixedDouble(result, d0), instr); | 731 return MarkAsCall(DefineFixedDouble(result, d0), instr); |
| 732 } else { | 732 } else { |
| 733 LOperand* left = UseRegisterAtStart(instr->left()); | 733 LOperand* left = UseRegisterAtStart(instr->left()); |
| 734 LOperand* right = UseRegisterAtStart(instr->right()); | 734 LOperand* right = UseRegisterAtStart(instr->right()); |
| 735 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 735 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 736 return DefineAsRegister(result); | 736 return DefineAsRegister(result); |
| 737 } | 737 } |
| 738 } | 738 } |
| 739 | 739 |
| 740 | 740 |
| 741 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 741 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 742 HBinaryOperation* instr) { | 742 HBinaryOperation* instr) { |
| 743 HValue* left = instr->left(); | 743 HValue* left = instr->left(); |
| 744 HValue* right = instr->right(); | 744 HValue* right = instr->right(); |
| 745 ASSERT(left->representation().IsTagged()); | 745 DCHECK(left->representation().IsTagged()); |
| 746 ASSERT(right->representation().IsTagged()); | 746 DCHECK(right->representation().IsTagged()); |
| 747 LOperand* context = UseFixed(instr->context(), cp); | 747 LOperand* context = UseFixed(instr->context(), cp); |
| 748 LOperand* left_operand = UseFixed(left, r1); | 748 LOperand* left_operand = UseFixed(left, r1); |
| 749 LOperand* right_operand = UseFixed(right, r0); | 749 LOperand* right_operand = UseFixed(right, r0); |
| 750 LArithmeticT* result = | 750 LArithmeticT* result = |
| 751 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 751 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 752 return MarkAsCall(DefineFixed(result, r0), instr); | 752 return MarkAsCall(DefineFixed(result, r0), instr); |
| 753 } | 753 } |
| 754 | 754 |
| 755 | 755 |
| 756 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 756 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 757 ASSERT(is_building()); | 757 DCHECK(is_building()); |
| 758 current_block_ = block; | 758 current_block_ = block; |
| 759 next_block_ = next_block; | 759 next_block_ = next_block; |
| 760 if (block->IsStartBlock()) { | 760 if (block->IsStartBlock()) { |
| 761 block->UpdateEnvironment(graph_->start_environment()); | 761 block->UpdateEnvironment(graph_->start_environment()); |
| 762 argument_count_ = 0; | 762 argument_count_ = 0; |
| 763 } else if (block->predecessors()->length() == 1) { | 763 } else if (block->predecessors()->length() == 1) { |
| 764 // We have a single predecessor => copy environment and outgoing | 764 // We have a single predecessor => copy environment and outgoing |
| 765 // argument count from the predecessor. | 765 // argument count from the predecessor. |
| 766 ASSERT(block->phis()->length() == 0); | 766 DCHECK(block->phis()->length() == 0); |
| 767 HBasicBlock* pred = block->predecessors()->at(0); | 767 HBasicBlock* pred = block->predecessors()->at(0); |
| 768 HEnvironment* last_environment = pred->last_environment(); | 768 HEnvironment* last_environment = pred->last_environment(); |
| 769 ASSERT(last_environment != NULL); | 769 DCHECK(last_environment != NULL); |
| 770 // Only copy the environment, if it is later used again. | 770 // Only copy the environment, if it is later used again. |
| 771 if (pred->end()->SecondSuccessor() == NULL) { | 771 if (pred->end()->SecondSuccessor() == NULL) { |
| 772 ASSERT(pred->end()->FirstSuccessor() == block); | 772 DCHECK(pred->end()->FirstSuccessor() == block); |
| 773 } else { | 773 } else { |
| 774 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || | 774 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
| 775 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { | 775 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
| 776 last_environment = last_environment->Copy(); | 776 last_environment = last_environment->Copy(); |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 block->UpdateEnvironment(last_environment); | 779 block->UpdateEnvironment(last_environment); |
| 780 ASSERT(pred->argument_count() >= 0); | 780 DCHECK(pred->argument_count() >= 0); |
| 781 argument_count_ = pred->argument_count(); | 781 argument_count_ = pred->argument_count(); |
| 782 } else { | 782 } else { |
| 783 // We are at a state join => process phis. | 783 // We are at a state join => process phis. |
| 784 HBasicBlock* pred = block->predecessors()->at(0); | 784 HBasicBlock* pred = block->predecessors()->at(0); |
| 785 // No need to copy the environment, it cannot be used later. | 785 // No need to copy the environment, it cannot be used later. |
| 786 HEnvironment* last_environment = pred->last_environment(); | 786 HEnvironment* last_environment = pred->last_environment(); |
| 787 for (int i = 0; i < block->phis()->length(); ++i) { | 787 for (int i = 0; i < block->phis()->length(); ++i) { |
| 788 HPhi* phi = block->phis()->at(i); | 788 HPhi* phi = block->phis()->at(i); |
| 789 if (phi->HasMergedIndex()) { | 789 if (phi->HasMergedIndex()) { |
| 790 last_environment->SetValueAt(phi->merged_index(), phi); | 790 last_environment->SetValueAt(phi->merged_index(), phi); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 822 |
| 823 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 823 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 824 HInstruction* old_current = current_instruction_; | 824 HInstruction* old_current = current_instruction_; |
| 825 current_instruction_ = current; | 825 current_instruction_ = current; |
| 826 | 826 |
| 827 LInstruction* instr = NULL; | 827 LInstruction* instr = NULL; |
| 828 if (current->CanReplaceWithDummyUses()) { | 828 if (current->CanReplaceWithDummyUses()) { |
| 829 if (current->OperandCount() == 0) { | 829 if (current->OperandCount() == 0) { |
| 830 instr = DefineAsRegister(new(zone()) LDummy()); | 830 instr = DefineAsRegister(new(zone()) LDummy()); |
| 831 } else { | 831 } else { |
| 832 ASSERT(!current->OperandAt(0)->IsControlInstruction()); | 832 DCHECK(!current->OperandAt(0)->IsControlInstruction()); |
| 833 instr = DefineAsRegister(new(zone()) | 833 instr = DefineAsRegister(new(zone()) |
| 834 LDummyUse(UseAny(current->OperandAt(0)))); | 834 LDummyUse(UseAny(current->OperandAt(0)))); |
| 835 } | 835 } |
| 836 for (int i = 1; i < current->OperandCount(); ++i) { | 836 for (int i = 1; i < current->OperandCount(); ++i) { |
| 837 if (current->OperandAt(i)->IsControlInstruction()) continue; | 837 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 838 LInstruction* dummy = | 838 LInstruction* dummy = |
| 839 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 839 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 840 dummy->set_hydrogen_value(current); | 840 dummy->set_hydrogen_value(current); |
| 841 chunk_->AddInstruction(dummy, current_block_); | 841 chunk_->AddInstruction(dummy, current_block_); |
| 842 } | 842 } |
| 843 } else { | 843 } else { |
| 844 HBasicBlock* successor; | 844 HBasicBlock* successor; |
| 845 if (current->IsControlInstruction() && | 845 if (current->IsControlInstruction() && |
| 846 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && | 846 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 847 successor != NULL) { | 847 successor != NULL) { |
| 848 instr = new(zone()) LGoto(successor); | 848 instr = new(zone()) LGoto(successor); |
| 849 } else { | 849 } else { |
| 850 instr = current->CompileToLithium(this); | 850 instr = current->CompileToLithium(this); |
| 851 } | 851 } |
| 852 } | 852 } |
| 853 | 853 |
| 854 argument_count_ += current->argument_delta(); | 854 argument_count_ += current->argument_delta(); |
| 855 ASSERT(argument_count_ >= 0); | 855 DCHECK(argument_count_ >= 0); |
| 856 | 856 |
| 857 if (instr != NULL) { | 857 if (instr != NULL) { |
| 858 AddInstruction(instr, current); | 858 AddInstruction(instr, current); |
| 859 } | 859 } |
| 860 | 860 |
| 861 current_instruction_ = old_current; | 861 current_instruction_ = old_current; |
| 862 } | 862 } |
| 863 | 863 |
| 864 | 864 |
| 865 void LChunkBuilder::AddInstruction(LInstruction* instr, | 865 void LChunkBuilder::AddInstruction(LInstruction* instr, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 887 LUnallocated* operand = LUnallocated::cast(it.Current()); | 887 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 888 if (operand->IsUsedAtStart()) ++used_at_start; | 888 if (operand->IsUsedAtStart()) ++used_at_start; |
| 889 } | 889 } |
| 890 if (instr->Output() != NULL) { | 890 if (instr->Output() != NULL) { |
| 891 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 891 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 892 } | 892 } |
| 893 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 893 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 894 LUnallocated* operand = LUnallocated::cast(it.Current()); | 894 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 895 if (operand->HasFixedPolicy()) ++fixed; | 895 if (operand->HasFixedPolicy()) ++fixed; |
| 896 } | 896 } |
| 897 ASSERT(fixed == 0 || used_at_start == 0); | 897 DCHECK(fixed == 0 || used_at_start == 0); |
| 898 } | 898 } |
| 899 #endif | 899 #endif |
| 900 | 900 |
| 901 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 901 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 902 instr = AssignPointerMap(instr); | 902 instr = AssignPointerMap(instr); |
| 903 } | 903 } |
| 904 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 904 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 905 instr = AssignEnvironment(instr); | 905 instr = AssignEnvironment(instr); |
| 906 } | 906 } |
| 907 chunk_->AddInstruction(instr, current_block_); | 907 chunk_->AddInstruction(instr, current_block_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 return branch; | 951 return branch; |
| 952 } | 952 } |
| 953 | 953 |
| 954 | 954 |
| 955 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 955 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
| 956 return new(zone()) LDebugBreak(); | 956 return new(zone()) LDebugBreak(); |
| 957 } | 957 } |
| 958 | 958 |
| 959 | 959 |
| 960 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 960 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 961 ASSERT(instr->value()->representation().IsTagged()); | 961 DCHECK(instr->value()->representation().IsTagged()); |
| 962 LOperand* value = UseRegisterAtStart(instr->value()); | 962 LOperand* value = UseRegisterAtStart(instr->value()); |
| 963 LOperand* temp = TempRegister(); | 963 LOperand* temp = TempRegister(); |
| 964 return new(zone()) LCmpMapAndBranch(value, temp); | 964 return new(zone()) LCmpMapAndBranch(value, temp); |
| 965 } | 965 } |
| 966 | 966 |
| 967 | 967 |
| 968 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) { | 968 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) { |
| 969 info()->MarkAsRequiresFrame(); | 969 info()->MarkAsRequiresFrame(); |
| 970 LOperand* value = UseRegister(instr->value()); | 970 LOperand* value = UseRegister(instr->value()); |
| 971 return DefineAsRegister(new(zone()) LArgumentsLength(value)); | 971 return DefineAsRegister(new(zone()) LArgumentsLength(value)); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 LOperand* input = UseRegister(instr->value()); | 1164 LOperand* input = UseRegister(instr->value()); |
| 1165 LInstruction* result = | 1165 LInstruction* result = |
| 1166 DefineAsRegister(new(zone()) LMathAbs(context, input)); | 1166 DefineAsRegister(new(zone()) LMathAbs(context, input)); |
| 1167 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); | 1167 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); |
| 1168 if (!r.IsDouble()) result = AssignEnvironment(result); | 1168 if (!r.IsDouble()) result = AssignEnvironment(result); |
| 1169 return result; | 1169 return result; |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 | 1172 |
| 1173 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1173 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
| 1174 ASSERT(instr->representation().IsDouble()); | 1174 DCHECK(instr->representation().IsDouble()); |
| 1175 ASSERT(instr->value()->representation().IsDouble()); | 1175 DCHECK(instr->value()->representation().IsDouble()); |
| 1176 LOperand* input = UseFixedDouble(instr->value(), d0); | 1176 LOperand* input = UseFixedDouble(instr->value(), d0); |
| 1177 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr); | 1177 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr); |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 | 1180 |
| 1181 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { | 1181 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
| 1182 LOperand* input = UseRegisterAtStart(instr->value()); | 1182 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1183 LMathClz32* result = new(zone()) LMathClz32(input); | 1183 LMathClz32* result = new(zone()) LMathClz32(input); |
| 1184 return DefineAsRegister(result); | 1184 return DefineAsRegister(result); |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 | 1187 |
| 1188 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1188 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
| 1189 ASSERT(instr->representation().IsDouble()); | 1189 DCHECK(instr->representation().IsDouble()); |
| 1190 ASSERT(instr->value()->representation().IsDouble()); | 1190 DCHECK(instr->value()->representation().IsDouble()); |
| 1191 LOperand* input = UseRegister(instr->value()); | 1191 LOperand* input = UseRegister(instr->value()); |
| 1192 LOperand* temp1 = TempRegister(); | 1192 LOperand* temp1 = TempRegister(); |
| 1193 LOperand* temp2 = TempRegister(); | 1193 LOperand* temp2 = TempRegister(); |
| 1194 LOperand* double_temp = TempDoubleRegister(); | 1194 LOperand* double_temp = TempDoubleRegister(); |
| 1195 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); | 1195 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); |
| 1196 return DefineAsRegister(result); | 1196 return DefineAsRegister(result); |
| 1197 } | 1197 } |
| 1198 | 1198 |
| 1199 | 1199 |
| 1200 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1200 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 | 1258 |
| 1259 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1259 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
| 1260 return DoShift(Token::SHL, instr); | 1260 return DoShift(Token::SHL, instr); |
| 1261 } | 1261 } |
| 1262 | 1262 |
| 1263 | 1263 |
| 1264 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1264 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 1265 if (instr->representation().IsSmiOrInteger32()) { | 1265 if (instr->representation().IsSmiOrInteger32()) { |
| 1266 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1266 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1267 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1267 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1268 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); | 1268 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); |
| 1269 | 1269 |
| 1270 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1270 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1271 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1271 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1272 return DefineAsRegister(new(zone()) LBitI(left, right)); | 1272 return DefineAsRegister(new(zone()) LBitI(left, right)); |
| 1273 } else { | 1273 } else { |
| 1274 return DoArithmeticT(instr->op(), instr); | 1274 return DoArithmeticT(instr->op(), instr); |
| 1275 } | 1275 } |
| 1276 } | 1276 } |
| 1277 | 1277 |
| 1278 | 1278 |
| 1279 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1279 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
| 1280 ASSERT(instr->representation().IsSmiOrInteger32()); | 1280 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1281 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1281 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1282 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1282 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1283 LOperand* dividend = UseRegister(instr->left()); | 1283 LOperand* dividend = UseRegister(instr->left()); |
| 1284 int32_t divisor = instr->right()->GetInteger32Constant(); | 1284 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1285 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( | 1285 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
| 1286 dividend, divisor)); | 1286 dividend, divisor)); |
| 1287 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1287 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1288 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || | 1288 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
| 1289 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1289 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1290 divisor != 1 && divisor != -1)) { | 1290 divisor != 1 && divisor != -1)) { |
| 1291 result = AssignEnvironment(result); | 1291 result = AssignEnvironment(result); |
| 1292 } | 1292 } |
| 1293 return result; | 1293 return result; |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 | 1296 |
| 1297 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { | 1297 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1298 ASSERT(instr->representation().IsInteger32()); | 1298 DCHECK(instr->representation().IsInteger32()); |
| 1299 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1299 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1300 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1300 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1301 LOperand* dividend = UseRegister(instr->left()); | 1301 LOperand* dividend = UseRegister(instr->left()); |
| 1302 int32_t divisor = instr->right()->GetInteger32Constant(); | 1302 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1303 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( | 1303 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( |
| 1304 dividend, divisor)); | 1304 dividend, divisor)); |
| 1305 if (divisor == 0 || | 1305 if (divisor == 0 || |
| 1306 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1306 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1307 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1307 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1308 result = AssignEnvironment(result); | 1308 result = AssignEnvironment(result); |
| 1309 } | 1309 } |
| 1310 return result; | 1310 return result; |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 | 1313 |
| 1314 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { | 1314 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { |
| 1315 ASSERT(instr->representation().IsSmiOrInteger32()); | 1315 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1316 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1316 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1317 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1317 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1318 LOperand* dividend = UseRegister(instr->left()); | 1318 LOperand* dividend = UseRegister(instr->left()); |
| 1319 LOperand* divisor = UseRegister(instr->right()); | 1319 LOperand* divisor = UseRegister(instr->right()); |
| 1320 LOperand* temp = | 1320 LOperand* temp = |
| 1321 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); | 1321 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
| 1322 LInstruction* result = | 1322 LInstruction* result = |
| 1323 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); | 1323 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); |
| 1324 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1324 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1325 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1325 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1326 (instr->CheckFlag(HValue::kCanOverflow) && | 1326 (instr->CheckFlag(HValue::kCanOverflow) && |
| 1327 (!CpuFeatures::IsSupported(SUDIV) || | 1327 (!CpuFeatures::IsSupported(SUDIV) || |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1358 dividend, divisor)); | 1358 dividend, divisor)); |
| 1359 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1359 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1360 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { | 1360 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
| 1361 result = AssignEnvironment(result); | 1361 result = AssignEnvironment(result); |
| 1362 } | 1362 } |
| 1363 return result; | 1363 return result; |
| 1364 } | 1364 } |
| 1365 | 1365 |
| 1366 | 1366 |
| 1367 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { | 1367 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1368 ASSERT(instr->representation().IsInteger32()); | 1368 DCHECK(instr->representation().IsInteger32()); |
| 1369 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1369 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1370 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1370 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1371 LOperand* dividend = UseRegister(instr->left()); | 1371 LOperand* dividend = UseRegister(instr->left()); |
| 1372 int32_t divisor = instr->right()->GetInteger32Constant(); | 1372 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1373 LOperand* temp = | 1373 LOperand* temp = |
| 1374 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || | 1374 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || |
| 1375 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? | 1375 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? |
| 1376 NULL : TempRegister(); | 1376 NULL : TempRegister(); |
| 1377 LInstruction* result = DefineAsRegister( | 1377 LInstruction* result = DefineAsRegister( |
| 1378 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); | 1378 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); |
| 1379 if (divisor == 0 || | 1379 if (divisor == 0 || |
| 1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { | 1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { |
| 1381 result = AssignEnvironment(result); | 1381 result = AssignEnvironment(result); |
| 1382 } | 1382 } |
| 1383 return result; | 1383 return result; |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 | 1386 |
| 1387 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1387 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
| 1388 ASSERT(instr->representation().IsSmiOrInteger32()); | 1388 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1389 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1389 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1390 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1390 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1391 LOperand* dividend = UseRegister(instr->left()); | 1391 LOperand* dividend = UseRegister(instr->left()); |
| 1392 LOperand* divisor = UseRegister(instr->right()); | 1392 LOperand* divisor = UseRegister(instr->right()); |
| 1393 LOperand* temp = | 1393 LOperand* temp = |
| 1394 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); | 1394 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
| 1395 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp); | 1395 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp); |
| 1396 return AssignEnvironment(DefineAsRegister(div)); | 1396 return AssignEnvironment(DefineAsRegister(div)); |
| 1397 } | 1397 } |
| 1398 | 1398 |
| 1399 | 1399 |
| 1400 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1400 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1401 if (instr->RightIsPowerOf2()) { | 1401 if (instr->RightIsPowerOf2()) { |
| 1402 return DoFlooringDivByPowerOf2I(instr); | 1402 return DoFlooringDivByPowerOf2I(instr); |
| 1403 } else if (instr->right()->IsConstant()) { | 1403 } else if (instr->right()->IsConstant()) { |
| 1404 return DoFlooringDivByConstI(instr); | 1404 return DoFlooringDivByConstI(instr); |
| 1405 } else { | 1405 } else { |
| 1406 return DoFlooringDivI(instr); | 1406 return DoFlooringDivI(instr); |
| 1407 } | 1407 } |
| 1408 } | 1408 } |
| 1409 | 1409 |
| 1410 | 1410 |
| 1411 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1411 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
| 1412 ASSERT(instr->representation().IsSmiOrInteger32()); | 1412 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1413 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1413 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1414 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1414 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1415 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1415 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1416 int32_t divisor = instr->right()->GetInteger32Constant(); | 1416 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1417 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( | 1417 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
| 1418 dividend, divisor)); | 1418 dividend, divisor)); |
| 1419 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && | 1419 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && |
| 1420 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1420 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1421 result = AssignEnvironment(result); | 1421 result = AssignEnvironment(result); |
| 1422 } | 1422 } |
| 1423 return result; | 1423 return result; |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 | 1426 |
| 1427 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { | 1427 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1428 ASSERT(instr->representation().IsSmiOrInteger32()); | 1428 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1429 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1429 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1430 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1430 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1431 LOperand* dividend = UseRegister(instr->left()); | 1431 LOperand* dividend = UseRegister(instr->left()); |
| 1432 int32_t divisor = instr->right()->GetInteger32Constant(); | 1432 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1433 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( | 1433 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( |
| 1434 dividend, divisor)); | 1434 dividend, divisor)); |
| 1435 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1435 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1436 result = AssignEnvironment(result); | 1436 result = AssignEnvironment(result); |
| 1437 } | 1437 } |
| 1438 return result; | 1438 return result; |
| 1439 } | 1439 } |
| 1440 | 1440 |
| 1441 | 1441 |
| 1442 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1442 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
| 1443 ASSERT(instr->representation().IsSmiOrInteger32()); | 1443 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1444 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1444 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1445 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1445 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1446 LOperand* dividend = UseRegister(instr->left()); | 1446 LOperand* dividend = UseRegister(instr->left()); |
| 1447 LOperand* divisor = UseRegister(instr->right()); | 1447 LOperand* divisor = UseRegister(instr->right()); |
| 1448 LOperand* temp = | 1448 LOperand* temp = |
| 1449 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); | 1449 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
| 1450 LOperand* temp2 = | 1450 LOperand* temp2 = |
| 1451 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); | 1451 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
| 1452 LInstruction* result = DefineAsRegister(new(zone()) LModI( | 1452 LInstruction* result = DefineAsRegister(new(zone()) LModI( |
| 1453 dividend, divisor, temp, temp2)); | 1453 dividend, divisor, temp, temp2)); |
| 1454 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1454 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1455 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1455 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1471 } else if (instr->representation().IsDouble()) { | 1471 } else if (instr->representation().IsDouble()) { |
| 1472 return DoArithmeticD(Token::MOD, instr); | 1472 return DoArithmeticD(Token::MOD, instr); |
| 1473 } else { | 1473 } else { |
| 1474 return DoArithmeticT(Token::MOD, instr); | 1474 return DoArithmeticT(Token::MOD, instr); |
| 1475 } | 1475 } |
| 1476 } | 1476 } |
| 1477 | 1477 |
| 1478 | 1478 |
| 1479 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1479 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1480 if (instr->representation().IsSmiOrInteger32()) { | 1480 if (instr->representation().IsSmiOrInteger32()) { |
| 1481 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1481 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1482 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1482 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1483 HValue* left = instr->BetterLeftOperand(); | 1483 HValue* left = instr->BetterLeftOperand(); |
| 1484 HValue* right = instr->BetterRightOperand(); | 1484 HValue* right = instr->BetterRightOperand(); |
| 1485 LOperand* left_op; | 1485 LOperand* left_op; |
| 1486 LOperand* right_op; | 1486 LOperand* right_op; |
| 1487 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1487 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1488 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); | 1488 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1489 | 1489 |
| 1490 if (right->IsConstant()) { | 1490 if (right->IsConstant()) { |
| 1491 HConstant* constant = HConstant::cast(right); | 1491 HConstant* constant = HConstant::cast(right); |
| 1492 int32_t constant_value = constant->Integer32Value(); | 1492 int32_t constant_value = constant->Integer32Value(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 | 1541 |
| 1542 return DoArithmeticD(Token::MUL, instr); | 1542 return DoArithmeticD(Token::MUL, instr); |
| 1543 } else { | 1543 } else { |
| 1544 return DoArithmeticT(Token::MUL, instr); | 1544 return DoArithmeticT(Token::MUL, instr); |
| 1545 } | 1545 } |
| 1546 } | 1546 } |
| 1547 | 1547 |
| 1548 | 1548 |
| 1549 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1549 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1550 if (instr->representation().IsSmiOrInteger32()) { | 1550 if (instr->representation().IsSmiOrInteger32()) { |
| 1551 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1551 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1552 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1552 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1553 | 1553 |
| 1554 if (instr->left()->IsConstant()) { | 1554 if (instr->left()->IsConstant()) { |
| 1555 // If lhs is constant, do reverse subtraction instead. | 1555 // If lhs is constant, do reverse subtraction instead. |
| 1556 return DoRSub(instr); | 1556 return DoRSub(instr); |
| 1557 } | 1557 } |
| 1558 | 1558 |
| 1559 LOperand* left = UseRegisterAtStart(instr->left()); | 1559 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1560 LOperand* right = UseOrConstantAtStart(instr->right()); | 1560 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1561 LSubI* sub = new(zone()) LSubI(left, right); | 1561 LSubI* sub = new(zone()) LSubI(left, right); |
| 1562 LInstruction* result = DefineAsRegister(sub); | 1562 LInstruction* result = DefineAsRegister(sub); |
| 1563 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1563 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1564 result = AssignEnvironment(result); | 1564 result = AssignEnvironment(result); |
| 1565 } | 1565 } |
| 1566 return result; | 1566 return result; |
| 1567 } else if (instr->representation().IsDouble()) { | 1567 } else if (instr->representation().IsDouble()) { |
| 1568 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { | 1568 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { |
| 1569 return DoMultiplySub(instr->left(), HMul::cast(instr->right())); | 1569 return DoMultiplySub(instr->left(), HMul::cast(instr->right())); |
| 1570 } | 1570 } |
| 1571 | 1571 |
| 1572 return DoArithmeticD(Token::SUB, instr); | 1572 return DoArithmeticD(Token::SUB, instr); |
| 1573 } else { | 1573 } else { |
| 1574 return DoArithmeticT(Token::SUB, instr); | 1574 return DoArithmeticT(Token::SUB, instr); |
| 1575 } | 1575 } |
| 1576 } | 1576 } |
| 1577 | 1577 |
| 1578 | 1578 |
| 1579 LInstruction* LChunkBuilder::DoRSub(HSub* instr) { | 1579 LInstruction* LChunkBuilder::DoRSub(HSub* instr) { |
| 1580 ASSERT(instr->representation().IsSmiOrInteger32()); | 1580 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1581 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1581 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1582 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1582 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1583 | 1583 |
| 1584 // Note: The lhs of the subtraction becomes the rhs of the | 1584 // Note: The lhs of the subtraction becomes the rhs of the |
| 1585 // reverse-subtraction. | 1585 // reverse-subtraction. |
| 1586 LOperand* left = UseRegisterAtStart(instr->right()); | 1586 LOperand* left = UseRegisterAtStart(instr->right()); |
| 1587 LOperand* right = UseOrConstantAtStart(instr->left()); | 1587 LOperand* right = UseOrConstantAtStart(instr->left()); |
| 1588 LRSubI* rsb = new(zone()) LRSubI(left, right); | 1588 LRSubI* rsb = new(zone()) LRSubI(left, right); |
| 1589 LInstruction* result = DefineAsRegister(rsb); | 1589 LInstruction* result = DefineAsRegister(rsb); |
| 1590 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1590 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1591 result = AssignEnvironment(result); | 1591 result = AssignEnvironment(result); |
| 1592 } | 1592 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1609 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); | 1609 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); |
| 1610 | 1610 |
| 1611 return DefineSameAsFirst(new(zone()) LMultiplySubD(minuend_op, | 1611 return DefineSameAsFirst(new(zone()) LMultiplySubD(minuend_op, |
| 1612 multiplier_op, | 1612 multiplier_op, |
| 1613 multiplicand_op)); | 1613 multiplicand_op)); |
| 1614 } | 1614 } |
| 1615 | 1615 |
| 1616 | 1616 |
| 1617 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1617 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 1618 if (instr->representation().IsSmiOrInteger32()) { | 1618 if (instr->representation().IsSmiOrInteger32()) { |
| 1619 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1619 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1620 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1620 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1621 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1621 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1622 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1622 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1623 LAddI* add = new(zone()) LAddI(left, right); | 1623 LAddI* add = new(zone()) LAddI(left, right); |
| 1624 LInstruction* result = DefineAsRegister(add); | 1624 LInstruction* result = DefineAsRegister(add); |
| 1625 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1625 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1626 result = AssignEnvironment(result); | 1626 result = AssignEnvironment(result); |
| 1627 } | 1627 } |
| 1628 return result; | 1628 return result; |
| 1629 } else if (instr->representation().IsExternal()) { | 1629 } else if (instr->representation().IsExternal()) { |
| 1630 ASSERT(instr->left()->representation().IsExternal()); | 1630 DCHECK(instr->left()->representation().IsExternal()); |
| 1631 ASSERT(instr->right()->representation().IsInteger32()); | 1631 DCHECK(instr->right()->representation().IsInteger32()); |
| 1632 ASSERT(!instr->CheckFlag(HValue::kCanOverflow)); | 1632 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); |
| 1633 LOperand* left = UseRegisterAtStart(instr->left()); | 1633 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1634 LOperand* right = UseOrConstantAtStart(instr->right()); | 1634 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1635 LAddI* add = new(zone()) LAddI(left, right); | 1635 LAddI* add = new(zone()) LAddI(left, right); |
| 1636 LInstruction* result = DefineAsRegister(add); | 1636 LInstruction* result = DefineAsRegister(add); |
| 1637 return result; | 1637 return result; |
| 1638 } else if (instr->representation().IsDouble()) { | 1638 } else if (instr->representation().IsDouble()) { |
| 1639 if (instr->left()->IsMul() && instr->left()->HasOneUse()) { | 1639 if (instr->left()->IsMul() && instr->left()->HasOneUse()) { |
| 1640 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); | 1640 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); |
| 1641 } | 1641 } |
| 1642 | 1642 |
| 1643 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { | 1643 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { |
| 1644 ASSERT(!instr->left()->IsMul() || !instr->left()->HasOneUse()); | 1644 DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse()); |
| 1645 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); | 1645 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); |
| 1646 } | 1646 } |
| 1647 | 1647 |
| 1648 return DoArithmeticD(Token::ADD, instr); | 1648 return DoArithmeticD(Token::ADD, instr); |
| 1649 } else { | 1649 } else { |
| 1650 return DoArithmeticT(Token::ADD, instr); | 1650 return DoArithmeticT(Token::ADD, instr); |
| 1651 } | 1651 } |
| 1652 } | 1652 } |
| 1653 | 1653 |
| 1654 | 1654 |
| 1655 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1655 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1656 LOperand* left = NULL; | 1656 LOperand* left = NULL; |
| 1657 LOperand* right = NULL; | 1657 LOperand* right = NULL; |
| 1658 if (instr->representation().IsSmiOrInteger32()) { | 1658 if (instr->representation().IsSmiOrInteger32()) { |
| 1659 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1659 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1660 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1660 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1661 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1661 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1662 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1662 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1663 } else { | 1663 } else { |
| 1664 ASSERT(instr->representation().IsDouble()); | 1664 DCHECK(instr->representation().IsDouble()); |
| 1665 ASSERT(instr->left()->representation().IsDouble()); | 1665 DCHECK(instr->left()->representation().IsDouble()); |
| 1666 ASSERT(instr->right()->representation().IsDouble()); | 1666 DCHECK(instr->right()->representation().IsDouble()); |
| 1667 left = UseRegisterAtStart(instr->left()); | 1667 left = UseRegisterAtStart(instr->left()); |
| 1668 right = UseRegisterAtStart(instr->right()); | 1668 right = UseRegisterAtStart(instr->right()); |
| 1669 } | 1669 } |
| 1670 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1670 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 | 1673 |
| 1674 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1674 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1675 ASSERT(instr->representation().IsDouble()); | 1675 DCHECK(instr->representation().IsDouble()); |
| 1676 // We call a C function for double power. It can't trigger a GC. | 1676 // We call a C function for double power. It can't trigger a GC. |
| 1677 // We need to use fixed result register for the call. | 1677 // We need to use fixed result register for the call. |
| 1678 Representation exponent_type = instr->right()->representation(); | 1678 Representation exponent_type = instr->right()->representation(); |
| 1679 ASSERT(instr->left()->representation().IsDouble()); | 1679 DCHECK(instr->left()->representation().IsDouble()); |
| 1680 LOperand* left = UseFixedDouble(instr->left(), d0); | 1680 LOperand* left = UseFixedDouble(instr->left(), d0); |
| 1681 LOperand* right = exponent_type.IsDouble() ? | 1681 LOperand* right = exponent_type.IsDouble() ? |
| 1682 UseFixedDouble(instr->right(), d1) : | 1682 UseFixedDouble(instr->right(), d1) : |
| 1683 UseFixed(instr->right(), r2); | 1683 UseFixed(instr->right(), r2); |
| 1684 LPower* result = new(zone()) LPower(left, right); | 1684 LPower* result = new(zone()) LPower(left, right); |
| 1685 return MarkAsCall(DefineFixedDouble(result, d2), | 1685 return MarkAsCall(DefineFixedDouble(result, d2), |
| 1686 instr, | 1686 instr, |
| 1687 CAN_DEOPTIMIZE_EAGERLY); | 1687 CAN_DEOPTIMIZE_EAGERLY); |
| 1688 } | 1688 } |
| 1689 | 1689 |
| 1690 | 1690 |
| 1691 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1691 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1692 ASSERT(instr->left()->representation().IsTagged()); | 1692 DCHECK(instr->left()->representation().IsTagged()); |
| 1693 ASSERT(instr->right()->representation().IsTagged()); | 1693 DCHECK(instr->right()->representation().IsTagged()); |
| 1694 LOperand* context = UseFixed(instr->context(), cp); | 1694 LOperand* context = UseFixed(instr->context(), cp); |
| 1695 LOperand* left = UseFixed(instr->left(), r1); | 1695 LOperand* left = UseFixed(instr->left(), r1); |
| 1696 LOperand* right = UseFixed(instr->right(), r0); | 1696 LOperand* right = UseFixed(instr->right(), r0); |
| 1697 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1697 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1698 return MarkAsCall(DefineFixed(result, r0), instr); | 1698 return MarkAsCall(DefineFixed(result, r0), instr); |
| 1699 } | 1699 } |
| 1700 | 1700 |
| 1701 | 1701 |
| 1702 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1702 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1703 HCompareNumericAndBranch* instr) { | 1703 HCompareNumericAndBranch* instr) { |
| 1704 Representation r = instr->representation(); | 1704 Representation r = instr->representation(); |
| 1705 if (r.IsSmiOrInteger32()) { | 1705 if (r.IsSmiOrInteger32()) { |
| 1706 ASSERT(instr->left()->representation().Equals(r)); | 1706 DCHECK(instr->left()->representation().Equals(r)); |
| 1707 ASSERT(instr->right()->representation().Equals(r)); | 1707 DCHECK(instr->right()->representation().Equals(r)); |
| 1708 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1708 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1709 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1709 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
| 1710 return new(zone()) LCompareNumericAndBranch(left, right); | 1710 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1711 } else { | 1711 } else { |
| 1712 ASSERT(r.IsDouble()); | 1712 DCHECK(r.IsDouble()); |
| 1713 ASSERT(instr->left()->representation().IsDouble()); | 1713 DCHECK(instr->left()->representation().IsDouble()); |
| 1714 ASSERT(instr->right()->representation().IsDouble()); | 1714 DCHECK(instr->right()->representation().IsDouble()); |
| 1715 LOperand* left = UseRegisterAtStart(instr->left()); | 1715 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1716 LOperand* right = UseRegisterAtStart(instr->right()); | 1716 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1717 return new(zone()) LCompareNumericAndBranch(left, right); | 1717 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1718 } | 1718 } |
| 1719 } | 1719 } |
| 1720 | 1720 |
| 1721 | 1721 |
| 1722 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1722 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1723 HCompareObjectEqAndBranch* instr) { | 1723 HCompareObjectEqAndBranch* instr) { |
| 1724 LOperand* left = UseRegisterAtStart(instr->left()); | 1724 LOperand* left = UseRegisterAtStart(instr->left()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1736 | 1736 |
| 1737 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1737 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1738 HCompareMinusZeroAndBranch* instr) { | 1738 HCompareMinusZeroAndBranch* instr) { |
| 1739 LOperand* value = UseRegister(instr->value()); | 1739 LOperand* value = UseRegister(instr->value()); |
| 1740 LOperand* scratch = TempRegister(); | 1740 LOperand* scratch = TempRegister(); |
| 1741 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1741 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
| 1742 } | 1742 } |
| 1743 | 1743 |
| 1744 | 1744 |
| 1745 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1745 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1746 ASSERT(instr->value()->representation().IsTagged()); | 1746 DCHECK(instr->value()->representation().IsTagged()); |
| 1747 LOperand* value = UseRegisterAtStart(instr->value()); | 1747 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1748 LOperand* temp = TempRegister(); | 1748 LOperand* temp = TempRegister(); |
| 1749 return new(zone()) LIsObjectAndBranch(value, temp); | 1749 return new(zone()) LIsObjectAndBranch(value, temp); |
| 1750 } | 1750 } |
| 1751 | 1751 |
| 1752 | 1752 |
| 1753 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1753 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
| 1754 ASSERT(instr->value()->representation().IsTagged()); | 1754 DCHECK(instr->value()->representation().IsTagged()); |
| 1755 LOperand* value = UseRegisterAtStart(instr->value()); | 1755 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1756 LOperand* temp = TempRegister(); | 1756 LOperand* temp = TempRegister(); |
| 1757 return new(zone()) LIsStringAndBranch(value, temp); | 1757 return new(zone()) LIsStringAndBranch(value, temp); |
| 1758 } | 1758 } |
| 1759 | 1759 |
| 1760 | 1760 |
| 1761 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { | 1761 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
| 1762 ASSERT(instr->value()->representation().IsTagged()); | 1762 DCHECK(instr->value()->representation().IsTagged()); |
| 1763 return new(zone()) LIsSmiAndBranch(Use(instr->value())); | 1763 return new(zone()) LIsSmiAndBranch(Use(instr->value())); |
| 1764 } | 1764 } |
| 1765 | 1765 |
| 1766 | 1766 |
| 1767 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( | 1767 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
| 1768 HIsUndetectableAndBranch* instr) { | 1768 HIsUndetectableAndBranch* instr) { |
| 1769 ASSERT(instr->value()->representation().IsTagged()); | 1769 DCHECK(instr->value()->representation().IsTagged()); |
| 1770 LOperand* value = UseRegisterAtStart(instr->value()); | 1770 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1771 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); | 1771 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); |
| 1772 } | 1772 } |
| 1773 | 1773 |
| 1774 | 1774 |
| 1775 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1775 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 1776 HStringCompareAndBranch* instr) { | 1776 HStringCompareAndBranch* instr) { |
| 1777 ASSERT(instr->left()->representation().IsTagged()); | 1777 DCHECK(instr->left()->representation().IsTagged()); |
| 1778 ASSERT(instr->right()->representation().IsTagged()); | 1778 DCHECK(instr->right()->representation().IsTagged()); |
| 1779 LOperand* context = UseFixed(instr->context(), cp); | 1779 LOperand* context = UseFixed(instr->context(), cp); |
| 1780 LOperand* left = UseFixed(instr->left(), r1); | 1780 LOperand* left = UseFixed(instr->left(), r1); |
| 1781 LOperand* right = UseFixed(instr->right(), r0); | 1781 LOperand* right = UseFixed(instr->right(), r0); |
| 1782 LStringCompareAndBranch* result = | 1782 LStringCompareAndBranch* result = |
| 1783 new(zone()) LStringCompareAndBranch(context, left, right); | 1783 new(zone()) LStringCompareAndBranch(context, left, right); |
| 1784 return MarkAsCall(result, instr); | 1784 return MarkAsCall(result, instr); |
| 1785 } | 1785 } |
| 1786 | 1786 |
| 1787 | 1787 |
| 1788 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1788 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1789 HHasInstanceTypeAndBranch* instr) { | 1789 HHasInstanceTypeAndBranch* instr) { |
| 1790 ASSERT(instr->value()->representation().IsTagged()); | 1790 DCHECK(instr->value()->representation().IsTagged()); |
| 1791 LOperand* value = UseRegisterAtStart(instr->value()); | 1791 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1792 return new(zone()) LHasInstanceTypeAndBranch(value); | 1792 return new(zone()) LHasInstanceTypeAndBranch(value); |
| 1793 } | 1793 } |
| 1794 | 1794 |
| 1795 | 1795 |
| 1796 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1796 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1797 HGetCachedArrayIndex* instr) { | 1797 HGetCachedArrayIndex* instr) { |
| 1798 ASSERT(instr->value()->representation().IsTagged()); | 1798 DCHECK(instr->value()->representation().IsTagged()); |
| 1799 LOperand* value = UseRegisterAtStart(instr->value()); | 1799 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1800 | 1800 |
| 1801 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); | 1801 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); |
| 1802 } | 1802 } |
| 1803 | 1803 |
| 1804 | 1804 |
| 1805 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( | 1805 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
| 1806 HHasCachedArrayIndexAndBranch* instr) { | 1806 HHasCachedArrayIndexAndBranch* instr) { |
| 1807 ASSERT(instr->value()->representation().IsTagged()); | 1807 DCHECK(instr->value()->representation().IsTagged()); |
| 1808 return new(zone()) LHasCachedArrayIndexAndBranch( | 1808 return new(zone()) LHasCachedArrayIndexAndBranch( |
| 1809 UseRegisterAtStart(instr->value())); | 1809 UseRegisterAtStart(instr->value())); |
| 1810 } | 1810 } |
| 1811 | 1811 |
| 1812 | 1812 |
| 1813 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1813 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1814 HClassOfTestAndBranch* instr) { | 1814 HClassOfTestAndBranch* instr) { |
| 1815 ASSERT(instr->value()->representation().IsTagged()); | 1815 DCHECK(instr->value()->representation().IsTagged()); |
| 1816 LOperand* value = UseRegister(instr->value()); | 1816 LOperand* value = UseRegister(instr->value()); |
| 1817 return new(zone()) LClassOfTestAndBranch(value, TempRegister()); | 1817 return new(zone()) LClassOfTestAndBranch(value, TempRegister()); |
| 1818 } | 1818 } |
| 1819 | 1819 |
| 1820 | 1820 |
| 1821 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1821 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1822 LOperand* map = UseRegisterAtStart(instr->value()); | 1822 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1823 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1823 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1824 } | 1824 } |
| 1825 | 1825 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1908 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); | 1908 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); |
| 1909 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1909 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1910 return result; | 1910 return result; |
| 1911 } else if (to.IsSmi()) { | 1911 } else if (to.IsSmi()) { |
| 1912 LOperand* value = UseRegister(val); | 1912 LOperand* value = UseRegister(val); |
| 1913 if (val->type().IsSmi()) { | 1913 if (val->type().IsSmi()) { |
| 1914 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1914 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
| 1915 } | 1915 } |
| 1916 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1916 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1917 } else { | 1917 } else { |
| 1918 ASSERT(to.IsInteger32()); | 1918 DCHECK(to.IsInteger32()); |
| 1919 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1919 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1920 LOperand* value = UseRegisterAtStart(val); | 1920 LOperand* value = UseRegisterAtStart(val); |
| 1921 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); | 1921 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
| 1922 } else { | 1922 } else { |
| 1923 LOperand* value = UseRegister(val); | 1923 LOperand* value = UseRegister(val); |
| 1924 LOperand* temp1 = TempRegister(); | 1924 LOperand* temp1 = TempRegister(); |
| 1925 LOperand* temp2 = TempDoubleRegister(); | 1925 LOperand* temp2 = TempDoubleRegister(); |
| 1926 LInstruction* result = | 1926 LInstruction* result = |
| 1927 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); | 1927 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); |
| 1928 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1928 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1929 return result; | 1929 return result; |
| 1930 } | 1930 } |
| 1931 } | 1931 } |
| 1932 } else if (from.IsDouble()) { | 1932 } else if (from.IsDouble()) { |
| 1933 if (to.IsTagged()) { | 1933 if (to.IsTagged()) { |
| 1934 info()->MarkAsDeferredCalling(); | 1934 info()->MarkAsDeferredCalling(); |
| 1935 LOperand* value = UseRegister(val); | 1935 LOperand* value = UseRegister(val); |
| 1936 LOperand* temp1 = TempRegister(); | 1936 LOperand* temp1 = TempRegister(); |
| 1937 LOperand* temp2 = TempRegister(); | 1937 LOperand* temp2 = TempRegister(); |
| 1938 LUnallocated* result_temp = TempRegister(); | 1938 LUnallocated* result_temp = TempRegister(); |
| 1939 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); | 1939 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); |
| 1940 return AssignPointerMap(Define(result, result_temp)); | 1940 return AssignPointerMap(Define(result, result_temp)); |
| 1941 } else if (to.IsSmi()) { | 1941 } else if (to.IsSmi()) { |
| 1942 LOperand* value = UseRegister(val); | 1942 LOperand* value = UseRegister(val); |
| 1943 return AssignEnvironment( | 1943 return AssignEnvironment( |
| 1944 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1944 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
| 1945 } else { | 1945 } else { |
| 1946 ASSERT(to.IsInteger32()); | 1946 DCHECK(to.IsInteger32()); |
| 1947 LOperand* value = UseRegister(val); | 1947 LOperand* value = UseRegister(val); |
| 1948 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); | 1948 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); |
| 1949 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); | 1949 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); |
| 1950 return result; | 1950 return result; |
| 1951 } | 1951 } |
| 1952 } else if (from.IsInteger32()) { | 1952 } else if (from.IsInteger32()) { |
| 1953 info()->MarkAsDeferredCalling(); | 1953 info()->MarkAsDeferredCalling(); |
| 1954 if (to.IsTagged()) { | 1954 if (to.IsTagged()) { |
| 1955 if (!instr->CheckFlag(HValue::kCanOverflow)) { | 1955 if (!instr->CheckFlag(HValue::kCanOverflow)) { |
| 1956 LOperand* value = UseRegisterAtStart(val); | 1956 LOperand* value = UseRegisterAtStart(val); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1969 return AssignPointerMap(DefineAsRegister(result)); | 1969 return AssignPointerMap(DefineAsRegister(result)); |
| 1970 } | 1970 } |
| 1971 } else if (to.IsSmi()) { | 1971 } else if (to.IsSmi()) { |
| 1972 LOperand* value = UseRegister(val); | 1972 LOperand* value = UseRegister(val); |
| 1973 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); | 1973 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); |
| 1974 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1974 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1975 result = AssignEnvironment(result); | 1975 result = AssignEnvironment(result); |
| 1976 } | 1976 } |
| 1977 return result; | 1977 return result; |
| 1978 } else { | 1978 } else { |
| 1979 ASSERT(to.IsDouble()); | 1979 DCHECK(to.IsDouble()); |
| 1980 if (val->CheckFlag(HInstruction::kUint32)) { | 1980 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1981 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); | 1981 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); |
| 1982 } else { | 1982 } else { |
| 1983 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); | 1983 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); |
| 1984 } | 1984 } |
| 1985 } | 1985 } |
| 1986 } | 1986 } |
| 1987 UNREACHABLE(); | 1987 UNREACHABLE(); |
| 1988 return NULL; | 1988 return NULL; |
| 1989 } | 1989 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2032 | 2032 |
| 2033 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 2033 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| 2034 HValue* value = instr->value(); | 2034 HValue* value = instr->value(); |
| 2035 Representation input_rep = value->representation(); | 2035 Representation input_rep = value->representation(); |
| 2036 LOperand* reg = UseRegister(value); | 2036 LOperand* reg = UseRegister(value); |
| 2037 if (input_rep.IsDouble()) { | 2037 if (input_rep.IsDouble()) { |
| 2038 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); | 2038 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); |
| 2039 } else if (input_rep.IsInteger32()) { | 2039 } else if (input_rep.IsInteger32()) { |
| 2040 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); | 2040 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); |
| 2041 } else { | 2041 } else { |
| 2042 ASSERT(input_rep.IsSmiOrTagged()); | 2042 DCHECK(input_rep.IsSmiOrTagged()); |
| 2043 // Register allocator doesn't (yet) support allocation of double | 2043 // Register allocator doesn't (yet) support allocation of double |
| 2044 // temps. Reserve d1 explicitly. | 2044 // temps. Reserve d1 explicitly. |
| 2045 LClampTToUint8* result = | 2045 LClampTToUint8* result = |
| 2046 new(zone()) LClampTToUint8(reg, TempDoubleRegister()); | 2046 new(zone()) LClampTToUint8(reg, TempDoubleRegister()); |
| 2047 return AssignEnvironment(DefineAsRegister(result)); | 2047 return AssignEnvironment(DefineAsRegister(result)); |
| 2048 } | 2048 } |
| 2049 } | 2049 } |
| 2050 | 2050 |
| 2051 | 2051 |
| 2052 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2052 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 2053 HValue* value = instr->value(); | 2053 HValue* value = instr->value(); |
| 2054 ASSERT(value->representation().IsDouble()); | 2054 DCHECK(value->representation().IsDouble()); |
| 2055 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2055 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 2056 } | 2056 } |
| 2057 | 2057 |
| 2058 | 2058 |
| 2059 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { | 2059 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
| 2060 LOperand* lo = UseRegister(instr->lo()); | 2060 LOperand* lo = UseRegister(instr->lo()); |
| 2061 LOperand* hi = UseRegister(instr->hi()); | 2061 LOperand* hi = UseRegister(instr->hi()); |
| 2062 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); | 2062 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); |
| 2063 } | 2063 } |
| 2064 | 2064 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2179 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); | 2179 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 2180 } | 2180 } |
| 2181 | 2181 |
| 2182 | 2182 |
| 2183 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 2183 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
| 2184 return DefineAsRegister(new(zone()) LLoadRoot); | 2184 return DefineAsRegister(new(zone()) LLoadRoot); |
| 2185 } | 2185 } |
| 2186 | 2186 |
| 2187 | 2187 |
| 2188 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2188 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2189 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 2189 DCHECK(instr->key()->representation().IsSmiOrInteger32()); |
| 2190 ElementsKind elements_kind = instr->elements_kind(); | 2190 ElementsKind elements_kind = instr->elements_kind(); |
| 2191 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2191 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2192 LInstruction* result = NULL; | 2192 LInstruction* result = NULL; |
| 2193 | 2193 |
| 2194 if (!instr->is_typed_elements()) { | 2194 if (!instr->is_typed_elements()) { |
| 2195 LOperand* obj = NULL; | 2195 LOperand* obj = NULL; |
| 2196 if (instr->representation().IsDouble()) { | 2196 if (instr->representation().IsDouble()) { |
| 2197 obj = UseRegister(instr->elements()); | 2197 obj = UseRegister(instr->elements()); |
| 2198 } else { | 2198 } else { |
| 2199 ASSERT(instr->representation().IsSmiOrTagged()); | 2199 DCHECK(instr->representation().IsSmiOrTagged()); |
| 2200 obj = UseRegisterAtStart(instr->elements()); | 2200 obj = UseRegisterAtStart(instr->elements()); |
| 2201 } | 2201 } |
| 2202 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); | 2202 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); |
| 2203 } else { | 2203 } else { |
| 2204 ASSERT( | 2204 DCHECK( |
| 2205 (instr->representation().IsInteger32() && | 2205 (instr->representation().IsInteger32() && |
| 2206 !IsDoubleOrFloatElementsKind(elements_kind)) || | 2206 !IsDoubleOrFloatElementsKind(elements_kind)) || |
| 2207 (instr->representation().IsDouble() && | 2207 (instr->representation().IsDouble() && |
| 2208 IsDoubleOrFloatElementsKind(elements_kind))); | 2208 IsDoubleOrFloatElementsKind(elements_kind))); |
| 2209 LOperand* backing_store = UseRegister(instr->elements()); | 2209 LOperand* backing_store = UseRegister(instr->elements()); |
| 2210 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); | 2210 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); |
| 2211 } | 2211 } |
| 2212 | 2212 |
| 2213 if ((instr->is_external() || instr->is_fixed_typed_array()) ? | 2213 if ((instr->is_external() || instr->is_fixed_typed_array()) ? |
| 2214 // see LCodeGen::DoLoadKeyedExternalArray | 2214 // see LCodeGen::DoLoadKeyedExternalArray |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2235 | 2235 |
| 2236 LInstruction* result = | 2236 LInstruction* result = |
| 2237 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key, vector), | 2237 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key, vector), |
| 2238 r0); | 2238 r0); |
| 2239 return MarkAsCall(result, instr); | 2239 return MarkAsCall(result, instr); |
| 2240 } | 2240 } |
| 2241 | 2241 |
| 2242 | 2242 |
| 2243 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2243 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2244 if (!instr->is_typed_elements()) { | 2244 if (!instr->is_typed_elements()) { |
| 2245 ASSERT(instr->elements()->representation().IsTagged()); | 2245 DCHECK(instr->elements()->representation().IsTagged()); |
| 2246 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2246 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2247 LOperand* object = NULL; | 2247 LOperand* object = NULL; |
| 2248 LOperand* key = NULL; | 2248 LOperand* key = NULL; |
| 2249 LOperand* val = NULL; | 2249 LOperand* val = NULL; |
| 2250 | 2250 |
| 2251 if (instr->value()->representation().IsDouble()) { | 2251 if (instr->value()->representation().IsDouble()) { |
| 2252 object = UseRegisterAtStart(instr->elements()); | 2252 object = UseRegisterAtStart(instr->elements()); |
| 2253 val = UseRegister(instr->value()); | 2253 val = UseRegister(instr->value()); |
| 2254 key = UseRegisterOrConstantAtStart(instr->key()); | 2254 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2255 } else { | 2255 } else { |
| 2256 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 2256 DCHECK(instr->value()->representation().IsSmiOrTagged()); |
| 2257 if (needs_write_barrier) { | 2257 if (needs_write_barrier) { |
| 2258 object = UseTempRegister(instr->elements()); | 2258 object = UseTempRegister(instr->elements()); |
| 2259 val = UseTempRegister(instr->value()); | 2259 val = UseTempRegister(instr->value()); |
| 2260 key = UseTempRegister(instr->key()); | 2260 key = UseTempRegister(instr->key()); |
| 2261 } else { | 2261 } else { |
| 2262 object = UseRegisterAtStart(instr->elements()); | 2262 object = UseRegisterAtStart(instr->elements()); |
| 2263 val = UseRegisterAtStart(instr->value()); | 2263 val = UseRegisterAtStart(instr->value()); |
| 2264 key = UseRegisterOrConstantAtStart(instr->key()); | 2264 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2265 } | 2265 } |
| 2266 } | 2266 } |
| 2267 | 2267 |
| 2268 return new(zone()) LStoreKeyed(object, key, val); | 2268 return new(zone()) LStoreKeyed(object, key, val); |
| 2269 } | 2269 } |
| 2270 | 2270 |
| 2271 ASSERT( | 2271 DCHECK( |
| 2272 (instr->value()->representation().IsInteger32() && | 2272 (instr->value()->representation().IsInteger32() && |
| 2273 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || | 2273 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || |
| 2274 (instr->value()->representation().IsDouble() && | 2274 (instr->value()->representation().IsDouble() && |
| 2275 IsDoubleOrFloatElementsKind(instr->elements_kind()))); | 2275 IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
| 2276 ASSERT((instr->is_fixed_typed_array() && | 2276 DCHECK((instr->is_fixed_typed_array() && |
| 2277 instr->elements()->representation().IsTagged()) || | 2277 instr->elements()->representation().IsTagged()) || |
| 2278 (instr->is_external() && | 2278 (instr->is_external() && |
| 2279 instr->elements()->representation().IsExternal())); | 2279 instr->elements()->representation().IsExternal())); |
| 2280 LOperand* val = UseRegister(instr->value()); | 2280 LOperand* val = UseRegister(instr->value()); |
| 2281 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2281 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2282 LOperand* backing_store = UseRegister(instr->elements()); | 2282 LOperand* backing_store = UseRegister(instr->elements()); |
| 2283 return new(zone()) LStoreKeyed(backing_store, key, val); | 2283 return new(zone()) LStoreKeyed(backing_store, key, val); |
| 2284 } | 2284 } |
| 2285 | 2285 |
| 2286 | 2286 |
| 2287 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2287 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2288 LOperand* context = UseFixed(instr->context(), cp); | 2288 LOperand* context = UseFixed(instr->context(), cp); |
| 2289 LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister()); | 2289 LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister()); |
| 2290 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); | 2290 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); |
| 2291 LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); | 2291 LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); |
| 2292 | 2292 |
| 2293 ASSERT(instr->object()->representation().IsTagged()); | 2293 DCHECK(instr->object()->representation().IsTagged()); |
| 2294 ASSERT(instr->key()->representation().IsTagged()); | 2294 DCHECK(instr->key()->representation().IsTagged()); |
| 2295 ASSERT(instr->value()->representation().IsTagged()); | 2295 DCHECK(instr->value()->representation().IsTagged()); |
| 2296 | 2296 |
| 2297 return MarkAsCall( | 2297 return MarkAsCall( |
| 2298 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); | 2298 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); |
| 2299 } | 2299 } |
| 2300 | 2300 |
| 2301 | 2301 |
| 2302 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2302 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2303 HTransitionElementsKind* instr) { | 2303 HTransitionElementsKind* instr) { |
| 2304 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2304 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| 2305 LOperand* object = UseRegister(instr->object()); | 2305 LOperand* object = UseRegister(instr->object()); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2418 | 2418 |
| 2419 | 2419 |
| 2420 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2420 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2421 LOperand* context = UseFixed(instr->context(), cp); | 2421 LOperand* context = UseFixed(instr->context(), cp); |
| 2422 return MarkAsCall( | 2422 return MarkAsCall( |
| 2423 DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); | 2423 DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); |
| 2424 } | 2424 } |
| 2425 | 2425 |
| 2426 | 2426 |
| 2427 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2427 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2428 ASSERT(argument_count_ == 0); | 2428 DCHECK(argument_count_ == 0); |
| 2429 allocator_->MarkAsOsrEntry(); | 2429 allocator_->MarkAsOsrEntry(); |
| 2430 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2430 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2431 return AssignEnvironment(new(zone()) LOsrEntry); | 2431 return AssignEnvironment(new(zone()) LOsrEntry); |
| 2432 } | 2432 } |
| 2433 | 2433 |
| 2434 | 2434 |
| 2435 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2435 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 2436 LParameter* result = new(zone()) LParameter; | 2436 LParameter* result = new(zone()) LParameter; |
| 2437 if (instr->kind() == HParameter::STACK_PARAMETER) { | 2437 if (instr->kind() == HParameter::STACK_PARAMETER) { |
| 2438 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2438 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 2439 return DefineAsSpilled(result, spill_index); | 2439 return DefineAsSpilled(result, spill_index); |
| 2440 } else { | 2440 } else { |
| 2441 ASSERT(info()->IsStub()); | 2441 DCHECK(info()->IsStub()); |
| 2442 CodeStubInterfaceDescriptor* descriptor = | 2442 CodeStubInterfaceDescriptor* descriptor = |
| 2443 info()->code_stub()->GetInterfaceDescriptor(); | 2443 info()->code_stub()->GetInterfaceDescriptor(); |
| 2444 int index = static_cast<int>(instr->index()); | 2444 int index = static_cast<int>(instr->index()); |
| 2445 Register reg = descriptor->GetEnvironmentParameterRegister(index); | 2445 Register reg = descriptor->GetEnvironmentParameterRegister(index); |
| 2446 return DefineFixed(result, reg); | 2446 return DefineFixed(result, reg); |
| 2447 } | 2447 } |
| 2448 } | 2448 } |
| 2449 | 2449 |
| 2450 | 2450 |
| 2451 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2451 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 instr->ReplayEnvironment(current_block_->last_environment()); | 2527 instr->ReplayEnvironment(current_block_->last_environment()); |
| 2528 return NULL; | 2528 return NULL; |
| 2529 } | 2529 } |
| 2530 | 2530 |
| 2531 | 2531 |
| 2532 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2532 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2533 if (instr->is_function_entry()) { | 2533 if (instr->is_function_entry()) { |
| 2534 LOperand* context = UseFixed(instr->context(), cp); | 2534 LOperand* context = UseFixed(instr->context(), cp); |
| 2535 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2535 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2536 } else { | 2536 } else { |
| 2537 ASSERT(instr->is_backwards_branch()); | 2537 DCHECK(instr->is_backwards_branch()); |
| 2538 LOperand* context = UseAny(instr->context()); | 2538 LOperand* context = UseAny(instr->context()); |
| 2539 return AssignEnvironment( | 2539 return AssignEnvironment( |
| 2540 AssignPointerMap(new(zone()) LStackCheck(context))); | 2540 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2541 } | 2541 } |
| 2542 } | 2542 } |
| 2543 | 2543 |
| 2544 | 2544 |
| 2545 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2545 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2546 HEnvironment* outer = current_block_->last_environment(); | 2546 HEnvironment* outer = current_block_->last_environment(); |
| 2547 outer->set_ast_id(instr->ReturnId()); | 2547 outer->set_ast_id(instr->ReturnId()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2563 | 2563 |
| 2564 | 2564 |
| 2565 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2565 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2566 LInstruction* pop = NULL; | 2566 LInstruction* pop = NULL; |
| 2567 | 2567 |
| 2568 HEnvironment* env = current_block_->last_environment(); | 2568 HEnvironment* env = current_block_->last_environment(); |
| 2569 | 2569 |
| 2570 if (env->entry()->arguments_pushed()) { | 2570 if (env->entry()->arguments_pushed()) { |
| 2571 int argument_count = env->arguments_environment()->parameter_count(); | 2571 int argument_count = env->arguments_environment()->parameter_count(); |
| 2572 pop = new(zone()) LDrop(argument_count); | 2572 pop = new(zone()) LDrop(argument_count); |
| 2573 ASSERT(instr->argument_delta() == -argument_count); | 2573 DCHECK(instr->argument_delta() == -argument_count); |
| 2574 } | 2574 } |
| 2575 | 2575 |
| 2576 HEnvironment* outer = current_block_->last_environment()-> | 2576 HEnvironment* outer = current_block_->last_environment()-> |
| 2577 DiscardInlined(false); | 2577 DiscardInlined(false); |
| 2578 current_block_->UpdateEnvironment(outer); | 2578 current_block_->UpdateEnvironment(outer); |
| 2579 | 2579 |
| 2580 return pop; | 2580 return pop; |
| 2581 } | 2581 } |
| 2582 | 2582 |
| 2583 | 2583 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2620 LInstruction* LChunkBuilder::DoAllocateBlockContext( | 2620 LInstruction* LChunkBuilder::DoAllocateBlockContext( |
| 2621 HAllocateBlockContext* instr) { | 2621 HAllocateBlockContext* instr) { |
| 2622 LOperand* context = UseFixed(instr->context(), cp); | 2622 LOperand* context = UseFixed(instr->context(), cp); |
| 2623 LOperand* function = UseRegisterAtStart(instr->function()); | 2623 LOperand* function = UseRegisterAtStart(instr->function()); |
| 2624 LAllocateBlockContext* result = | 2624 LAllocateBlockContext* result = |
| 2625 new(zone()) LAllocateBlockContext(context, function); | 2625 new(zone()) LAllocateBlockContext(context, function); |
| 2626 return MarkAsCall(DefineFixed(result, cp), instr); | 2626 return MarkAsCall(DefineFixed(result, cp), instr); |
| 2627 } | 2627 } |
| 2628 | 2628 |
| 2629 } } // namespace v8::internal | 2629 } } // namespace v8::internal |
| OLD | NEW |