| 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 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/hydrogen-osr.h" | 9 #include "src/hydrogen-osr.h" |
| 10 #include "src/lithium-inl.h" | 10 #include "src/lithium-inl.h" |
| 11 #include "src/x87/lithium-codegen-x87.h" | 11 #include "src/x87/lithium-codegen-x87.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 #define DEFINE_COMPILE(type) \ | 16 #define DEFINE_COMPILE(type) \ |
| 17 void L##type::CompileToNative(LCodeGen* generator) { \ | 17 void L##type::CompileToNative(LCodeGen* generator) { \ |
| 18 generator->Do##type(this); \ | 18 generator->Do##type(this); \ |
| 19 } | 19 } |
| 20 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 20 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 21 #undef DEFINE_COMPILE | 21 #undef DEFINE_COMPILE |
| 22 | 22 |
| 23 | 23 |
| 24 #ifdef DEBUG | 24 #ifdef DEBUG |
| 25 void LInstruction::VerifyCall() { | 25 void LInstruction::VerifyCall() { |
| 26 // Call instructions can use only fixed registers as temporaries and | 26 // Call instructions can use only fixed registers as temporaries and |
| 27 // outputs because all registers are blocked by the calling convention. | 27 // outputs because all registers are blocked by the calling convention. |
| 28 // Inputs operands must use a fixed register or use-at-start policy or | 28 // Inputs operands must use a fixed register or use-at-start policy or |
| 29 // a non-register policy. | 29 // a non-register policy. |
| 30 ASSERT(Output() == NULL || | 30 DCHECK(Output() == NULL || |
| 31 LUnallocated::cast(Output())->HasFixedPolicy() || | 31 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 32 !LUnallocated::cast(Output())->HasRegisterPolicy()); | 32 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 33 for (UseIterator it(this); !it.Done(); it.Advance()) { | 33 for (UseIterator it(this); !it.Done(); it.Advance()) { |
| 34 LUnallocated* operand = LUnallocated::cast(it.Current()); | 34 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 35 ASSERT(operand->HasFixedPolicy() || | 35 DCHECK(operand->HasFixedPolicy() || |
| 36 operand->IsUsedAtStart()); | 36 operand->IsUsedAtStart()); |
| 37 } | 37 } |
| 38 for (TempIterator it(this); !it.Done(); it.Advance()) { | 38 for (TempIterator it(this); !it.Done(); it.Advance()) { |
| 39 LUnallocated* operand = LUnallocated::cast(it.Current()); | 39 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 40 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); | 40 DCHECK(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 #endif | 43 #endif |
| 44 | 44 |
| 45 | 45 |
| 46 bool LInstruction::HasDoubleRegisterResult() { | 46 bool LInstruction::HasDoubleRegisterResult() { |
| 47 return HasResult() && result()->IsDoubleRegister(); | 47 return HasResult() && result()->IsDoubleRegister(); |
| 48 } | 48 } |
| 49 | 49 |
| 50 | 50 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 361 } |
| 362 return spill_slot_count_++; | 362 return spill_slot_count_++; |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { | 366 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 367 int index = GetNextSpillIndex(kind); | 367 int index = GetNextSpillIndex(kind); |
| 368 if (kind == DOUBLE_REGISTERS) { | 368 if (kind == DOUBLE_REGISTERS) { |
| 369 return LDoubleStackSlot::Create(index, zone()); | 369 return LDoubleStackSlot::Create(index, zone()); |
| 370 } else { | 370 } else { |
| 371 ASSERT(kind == GENERAL_REGISTERS); | 371 DCHECK(kind == GENERAL_REGISTERS); |
| 372 return LStackSlot::Create(index, zone()); | 372 return LStackSlot::Create(index, zone()); |
| 373 } | 373 } |
| 374 } | 374 } |
| 375 | 375 |
| 376 | 376 |
| 377 void LStoreNamedField::PrintDataTo(StringStream* stream) { | 377 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
| 378 object()->PrintTo(stream); | 378 object()->PrintTo(stream); |
| 379 OStringStream os; | 379 OStringStream os; |
| 380 os << hydrogen()->access() << " <- "; | 380 os << hydrogen()->access() << " <- "; |
| 381 stream->Add(os.c_str()); | 381 stream->Add(os.c_str()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 408 elements()->PrintTo(stream); | 408 elements()->PrintTo(stream); |
| 409 stream->Add("["); | 409 stream->Add("["); |
| 410 key()->PrintTo(stream); | 410 key()->PrintTo(stream); |
| 411 if (hydrogen()->IsDehoisted()) { | 411 if (hydrogen()->IsDehoisted()) { |
| 412 stream->Add(" + %d] <-", base_offset()); | 412 stream->Add(" + %d] <-", base_offset()); |
| 413 } else { | 413 } else { |
| 414 stream->Add("] <- "); | 414 stream->Add("] <- "); |
| 415 } | 415 } |
| 416 | 416 |
| 417 if (value() == NULL) { | 417 if (value() == NULL) { |
| 418 ASSERT(hydrogen()->IsConstantHoleStore() && | 418 DCHECK(hydrogen()->IsConstantHoleStore() && |
| 419 hydrogen()->value()->representation().IsDouble()); | 419 hydrogen()->value()->representation().IsDouble()); |
| 420 stream->Add("<the hole(nan)>"); | 420 stream->Add("<the hole(nan)>"); |
| 421 } else { | 421 } else { |
| 422 value()->PrintTo(stream); | 422 value()->PrintTo(stream); |
| 423 } | 423 } |
| 424 } | 424 } |
| 425 | 425 |
| 426 | 426 |
| 427 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { | 427 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 428 object()->PrintTo(stream); | 428 object()->PrintTo(stream); |
| 429 stream->Add("["); | 429 stream->Add("["); |
| 430 key()->PrintTo(stream); | 430 key()->PrintTo(stream); |
| 431 stream->Add("] <- "); | 431 stream->Add("] <- "); |
| 432 value()->PrintTo(stream); | 432 value()->PrintTo(stream); |
| 433 } | 433 } |
| 434 | 434 |
| 435 | 435 |
| 436 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { | 436 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { |
| 437 object()->PrintTo(stream); | 437 object()->PrintTo(stream); |
| 438 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); | 438 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); |
| 439 } | 439 } |
| 440 | 440 |
| 441 | 441 |
| 442 LPlatformChunk* LChunkBuilder::Build() { | 442 LPlatformChunk* LChunkBuilder::Build() { |
| 443 ASSERT(is_unused()); | 443 DCHECK(is_unused()); |
| 444 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 444 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
| 445 LPhase phase("L_Building chunk", chunk_); | 445 LPhase phase("L_Building chunk", chunk_); |
| 446 status_ = BUILDING; | 446 status_ = BUILDING; |
| 447 | 447 |
| 448 // Reserve the first spill slot for the state of dynamic alignment. | 448 // Reserve the first spill slot for the state of dynamic alignment. |
| 449 if (info()->IsOptimizing()) { | 449 if (info()->IsOptimizing()) { |
| 450 int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 450 int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 451 ASSERT_EQ(alignment_state_index, 0); | 451 DCHECK_EQ(alignment_state_index, 0); |
| 452 USE(alignment_state_index); | 452 USE(alignment_state_index); |
| 453 } | 453 } |
| 454 | 454 |
| 455 // If compiling for OSR, reserve space for the unoptimized frame, | 455 // If compiling for OSR, reserve space for the unoptimized frame, |
| 456 // which will be subsumed into this frame. | 456 // which will be subsumed into this frame. |
| 457 if (graph()->has_osr()) { | 457 if (graph()->has_osr()) { |
| 458 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 458 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 459 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 459 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 460 } | 460 } |
| 461 } | 461 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 instr = AssignEnvironment(instr); | 649 instr = AssignEnvironment(instr); |
| 650 // We can't really figure out if the environment is needed or not. | 650 // We can't really figure out if the environment is needed or not. |
| 651 instr->environment()->set_has_been_used(); | 651 instr->environment()->set_has_been_used(); |
| 652 } | 652 } |
| 653 | 653 |
| 654 return instr; | 654 return instr; |
| 655 } | 655 } |
| 656 | 656 |
| 657 | 657 |
| 658 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 658 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 659 ASSERT(!instr->HasPointerMap()); | 659 DCHECK(!instr->HasPointerMap()); |
| 660 instr->set_pointer_map(new(zone()) LPointerMap(zone())); | 660 instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
| 661 return instr; | 661 return instr; |
| 662 } | 662 } |
| 663 | 663 |
| 664 | 664 |
| 665 LUnallocated* LChunkBuilder::TempRegister() { | 665 LUnallocated* LChunkBuilder::TempRegister() { |
| 666 LUnallocated* operand = | 666 LUnallocated* operand = |
| 667 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 667 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
| 668 int vreg = allocator_->GetVirtualRegister(); | 668 int vreg = allocator_->GetVirtualRegister(); |
| 669 if (!allocator_->AllocationOk()) { | 669 if (!allocator_->AllocationOk()) { |
| 670 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 670 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
| 671 vreg = 0; | 671 vreg = 0; |
| 672 } | 672 } |
| 673 operand->set_virtual_register(vreg); | 673 operand->set_virtual_register(vreg); |
| 674 return operand; | 674 return operand; |
| 675 } | 675 } |
| 676 | 676 |
| 677 | 677 |
| 678 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 678 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
| 679 LUnallocated* operand = ToUnallocated(reg); | 679 LUnallocated* operand = ToUnallocated(reg); |
| 680 ASSERT(operand->HasFixedPolicy()); | 680 DCHECK(operand->HasFixedPolicy()); |
| 681 return operand; | 681 return operand; |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { | 685 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { |
| 686 return new(zone()) LLabel(instr->block()); | 686 return new(zone()) LLabel(instr->block()); |
| 687 } | 687 } |
| 688 | 688 |
| 689 | 689 |
| 690 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 690 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
| 691 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 691 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
| 692 } | 692 } |
| 693 | 693 |
| 694 | 694 |
| 695 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { | 695 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { |
| 696 UNREACHABLE(); | 696 UNREACHABLE(); |
| 697 return NULL; | 697 return NULL; |
| 698 } | 698 } |
| 699 | 699 |
| 700 | 700 |
| 701 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 701 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 702 return AssignEnvironment(new(zone()) LDeoptimize); | 702 return AssignEnvironment(new(zone()) LDeoptimize); |
| 703 } | 703 } |
| 704 | 704 |
| 705 | 705 |
| 706 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 706 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 707 HBitwiseBinaryOperation* instr) { | 707 HBitwiseBinaryOperation* instr) { |
| 708 if (instr->representation().IsSmiOrInteger32()) { | 708 if (instr->representation().IsSmiOrInteger32()) { |
| 709 ASSERT(instr->left()->representation().Equals(instr->representation())); | 709 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 710 ASSERT(instr->right()->representation().Equals(instr->representation())); | 710 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 711 LOperand* left = UseRegisterAtStart(instr->left()); | 711 LOperand* left = UseRegisterAtStart(instr->left()); |
| 712 | 712 |
| 713 HValue* right_value = instr->right(); | 713 HValue* right_value = instr->right(); |
| 714 LOperand* right = NULL; | 714 LOperand* right = NULL; |
| 715 int constant_value = 0; | 715 int constant_value = 0; |
| 716 bool does_deopt = false; | 716 bool does_deopt = false; |
| 717 if (right_value->IsConstant()) { | 717 if (right_value->IsConstant()) { |
| 718 HConstant* constant = HConstant::cast(right_value); | 718 HConstant* constant = HConstant::cast(right_value); |
| 719 right = chunk_->DefineConstantOperand(constant); | 719 right = chunk_->DefineConstantOperand(constant); |
| 720 constant_value = constant->Integer32Value() & 0x1f; | 720 constant_value = constant->Integer32Value() & 0x1f; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 741 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); | 741 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); |
| 742 return does_deopt ? AssignEnvironment(result) : result; | 742 return does_deopt ? AssignEnvironment(result) : result; |
| 743 } else { | 743 } else { |
| 744 return DoArithmeticT(op, instr); | 744 return DoArithmeticT(op, instr); |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 | 747 |
| 748 | 748 |
| 749 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 749 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 750 HArithmeticBinaryOperation* instr) { | 750 HArithmeticBinaryOperation* instr) { |
| 751 ASSERT(instr->representation().IsDouble()); | 751 DCHECK(instr->representation().IsDouble()); |
| 752 ASSERT(instr->left()->representation().IsDouble()); | 752 DCHECK(instr->left()->representation().IsDouble()); |
| 753 ASSERT(instr->right()->representation().IsDouble()); | 753 DCHECK(instr->right()->representation().IsDouble()); |
| 754 if (op == Token::MOD) { | 754 if (op == Token::MOD) { |
| 755 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 755 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 756 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); | 756 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); |
| 757 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 757 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 758 return MarkAsCall(DefineSameAsFirst(result), instr); | 758 return MarkAsCall(DefineSameAsFirst(result), instr); |
| 759 } else { | 759 } else { |
| 760 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 760 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 761 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); | 761 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); |
| 762 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 762 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 763 return DefineSameAsFirst(result); | 763 return DefineSameAsFirst(result); |
| 764 } | 764 } |
| 765 } | 765 } |
| 766 | 766 |
| 767 | 767 |
| 768 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 768 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 769 HBinaryOperation* instr) { | 769 HBinaryOperation* instr) { |
| 770 HValue* left = instr->left(); | 770 HValue* left = instr->left(); |
| 771 HValue* right = instr->right(); | 771 HValue* right = instr->right(); |
| 772 ASSERT(left->representation().IsTagged()); | 772 DCHECK(left->representation().IsTagged()); |
| 773 ASSERT(right->representation().IsTagged()); | 773 DCHECK(right->representation().IsTagged()); |
| 774 LOperand* context = UseFixed(instr->context(), esi); | 774 LOperand* context = UseFixed(instr->context(), esi); |
| 775 LOperand* left_operand = UseFixed(left, edx); | 775 LOperand* left_operand = UseFixed(left, edx); |
| 776 LOperand* right_operand = UseFixed(right, eax); | 776 LOperand* right_operand = UseFixed(right, eax); |
| 777 LArithmeticT* result = | 777 LArithmeticT* result = |
| 778 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 778 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 779 return MarkAsCall(DefineFixed(result, eax), instr); | 779 return MarkAsCall(DefineFixed(result, eax), instr); |
| 780 } | 780 } |
| 781 | 781 |
| 782 | 782 |
| 783 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 783 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 784 ASSERT(is_building()); | 784 DCHECK(is_building()); |
| 785 current_block_ = block; | 785 current_block_ = block; |
| 786 next_block_ = next_block; | 786 next_block_ = next_block; |
| 787 if (block->IsStartBlock()) { | 787 if (block->IsStartBlock()) { |
| 788 block->UpdateEnvironment(graph_->start_environment()); | 788 block->UpdateEnvironment(graph_->start_environment()); |
| 789 argument_count_ = 0; | 789 argument_count_ = 0; |
| 790 } else if (block->predecessors()->length() == 1) { | 790 } else if (block->predecessors()->length() == 1) { |
| 791 // We have a single predecessor => copy environment and outgoing | 791 // We have a single predecessor => copy environment and outgoing |
| 792 // argument count from the predecessor. | 792 // argument count from the predecessor. |
| 793 ASSERT(block->phis()->length() == 0); | 793 DCHECK(block->phis()->length() == 0); |
| 794 HBasicBlock* pred = block->predecessors()->at(0); | 794 HBasicBlock* pred = block->predecessors()->at(0); |
| 795 HEnvironment* last_environment = pred->last_environment(); | 795 HEnvironment* last_environment = pred->last_environment(); |
| 796 ASSERT(last_environment != NULL); | 796 DCHECK(last_environment != NULL); |
| 797 // Only copy the environment, if it is later used again. | 797 // Only copy the environment, if it is later used again. |
| 798 if (pred->end()->SecondSuccessor() == NULL) { | 798 if (pred->end()->SecondSuccessor() == NULL) { |
| 799 ASSERT(pred->end()->FirstSuccessor() == block); | 799 DCHECK(pred->end()->FirstSuccessor() == block); |
| 800 } else { | 800 } else { |
| 801 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || | 801 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
| 802 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { | 802 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
| 803 last_environment = last_environment->Copy(); | 803 last_environment = last_environment->Copy(); |
| 804 } | 804 } |
| 805 } | 805 } |
| 806 block->UpdateEnvironment(last_environment); | 806 block->UpdateEnvironment(last_environment); |
| 807 ASSERT(pred->argument_count() >= 0); | 807 DCHECK(pred->argument_count() >= 0); |
| 808 argument_count_ = pred->argument_count(); | 808 argument_count_ = pred->argument_count(); |
| 809 } else { | 809 } else { |
| 810 // We are at a state join => process phis. | 810 // We are at a state join => process phis. |
| 811 HBasicBlock* pred = block->predecessors()->at(0); | 811 HBasicBlock* pred = block->predecessors()->at(0); |
| 812 // No need to copy the environment, it cannot be used later. | 812 // No need to copy the environment, it cannot be used later. |
| 813 HEnvironment* last_environment = pred->last_environment(); | 813 HEnvironment* last_environment = pred->last_environment(); |
| 814 for (int i = 0; i < block->phis()->length(); ++i) { | 814 for (int i = 0; i < block->phis()->length(); ++i) { |
| 815 HPhi* phi = block->phis()->at(i); | 815 HPhi* phi = block->phis()->at(i); |
| 816 if (phi->HasMergedIndex()) { | 816 if (phi->HasMergedIndex()) { |
| 817 last_environment->SetValueAt(phi->merged_index(), phi); | 817 last_environment->SetValueAt(phi->merged_index(), phi); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 | 849 |
| 850 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 850 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 851 HInstruction* old_current = current_instruction_; | 851 HInstruction* old_current = current_instruction_; |
| 852 current_instruction_ = current; | 852 current_instruction_ = current; |
| 853 | 853 |
| 854 LInstruction* instr = NULL; | 854 LInstruction* instr = NULL; |
| 855 if (current->CanReplaceWithDummyUses()) { | 855 if (current->CanReplaceWithDummyUses()) { |
| 856 if (current->OperandCount() == 0) { | 856 if (current->OperandCount() == 0) { |
| 857 instr = DefineAsRegister(new(zone()) LDummy()); | 857 instr = DefineAsRegister(new(zone()) LDummy()); |
| 858 } else { | 858 } else { |
| 859 ASSERT(!current->OperandAt(0)->IsControlInstruction()); | 859 DCHECK(!current->OperandAt(0)->IsControlInstruction()); |
| 860 instr = DefineAsRegister(new(zone()) | 860 instr = DefineAsRegister(new(zone()) |
| 861 LDummyUse(UseAny(current->OperandAt(0)))); | 861 LDummyUse(UseAny(current->OperandAt(0)))); |
| 862 } | 862 } |
| 863 for (int i = 1; i < current->OperandCount(); ++i) { | 863 for (int i = 1; i < current->OperandCount(); ++i) { |
| 864 if (current->OperandAt(i)->IsControlInstruction()) continue; | 864 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 865 LInstruction* dummy = | 865 LInstruction* dummy = |
| 866 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 866 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 867 dummy->set_hydrogen_value(current); | 867 dummy->set_hydrogen_value(current); |
| 868 chunk_->AddInstruction(dummy, current_block_); | 868 chunk_->AddInstruction(dummy, current_block_); |
| 869 } | 869 } |
| 870 } else { | 870 } else { |
| 871 HBasicBlock* successor; | 871 HBasicBlock* successor; |
| 872 if (current->IsControlInstruction() && | 872 if (current->IsControlInstruction() && |
| 873 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && | 873 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 874 successor != NULL) { | 874 successor != NULL) { |
| 875 instr = new(zone()) LGoto(successor); | 875 instr = new(zone()) LGoto(successor); |
| 876 } else { | 876 } else { |
| 877 instr = current->CompileToLithium(this); | 877 instr = current->CompileToLithium(this); |
| 878 } | 878 } |
| 879 } | 879 } |
| 880 | 880 |
| 881 argument_count_ += current->argument_delta(); | 881 argument_count_ += current->argument_delta(); |
| 882 ASSERT(argument_count_ >= 0); | 882 DCHECK(argument_count_ >= 0); |
| 883 | 883 |
| 884 if (instr != NULL) { | 884 if (instr != NULL) { |
| 885 AddInstruction(instr, current); | 885 AddInstruction(instr, current); |
| 886 } | 886 } |
| 887 | 887 |
| 888 current_instruction_ = old_current; | 888 current_instruction_ = old_current; |
| 889 } | 889 } |
| 890 | 890 |
| 891 | 891 |
| 892 void LChunkBuilder::AddInstruction(LInstruction* instr, | 892 void LChunkBuilder::AddInstruction(LInstruction* instr, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 914 LUnallocated* operand = LUnallocated::cast(it.Current()); | 914 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 915 if (operand->IsUsedAtStart()) ++used_at_start; | 915 if (operand->IsUsedAtStart()) ++used_at_start; |
| 916 } | 916 } |
| 917 if (instr->Output() != NULL) { | 917 if (instr->Output() != NULL) { |
| 918 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 918 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 919 } | 919 } |
| 920 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 920 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 921 LUnallocated* operand = LUnallocated::cast(it.Current()); | 921 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 922 if (operand->HasFixedPolicy()) ++fixed; | 922 if (operand->HasFixedPolicy()) ++fixed; |
| 923 } | 923 } |
| 924 ASSERT(fixed == 0 || used_at_start == 0); | 924 DCHECK(fixed == 0 || used_at_start == 0); |
| 925 } | 925 } |
| 926 #endif | 926 #endif |
| 927 | 927 |
| 928 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 928 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 929 instr = AssignPointerMap(instr); | 929 instr = AssignPointerMap(instr); |
| 930 } | 930 } |
| 931 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 931 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 932 instr = AssignEnvironment(instr); | 932 instr = AssignEnvironment(instr); |
| 933 } | 933 } |
| 934 if (instr->IsGoto() && LGoto::cast(instr)->jumps_to_join()) { | 934 if (instr->IsGoto() && LGoto::cast(instr)->jumps_to_join()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 return branch; | 988 return branch; |
| 989 } | 989 } |
| 990 | 990 |
| 991 | 991 |
| 992 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 992 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
| 993 return new(zone()) LDebugBreak(); | 993 return new(zone()) LDebugBreak(); |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 997 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 998 ASSERT(instr->value()->representation().IsTagged()); | 998 DCHECK(instr->value()->representation().IsTagged()); |
| 999 LOperand* value = UseRegisterAtStart(instr->value()); | 999 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1000 return new(zone()) LCmpMapAndBranch(value); | 1000 return new(zone()) LCmpMapAndBranch(value); |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 | 1003 |
| 1004 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1004 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 1005 info()->MarkAsRequiresFrame(); | 1005 info()->MarkAsRequiresFrame(); |
| 1006 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 1006 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
| 1007 } | 1007 } |
| 1008 | 1008 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 LInstruction* result = | 1188 LInstruction* result = |
| 1189 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); | 1189 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); |
| 1190 Representation r = instr->value()->representation(); | 1190 Representation r = instr->value()->representation(); |
| 1191 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); | 1191 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); |
| 1192 if (!r.IsDouble()) result = AssignEnvironment(result); | 1192 if (!r.IsDouble()) result = AssignEnvironment(result); |
| 1193 return result; | 1193 return result; |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 | 1196 |
| 1197 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1197 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
| 1198 ASSERT(instr->representation().IsDouble()); | 1198 DCHECK(instr->representation().IsDouble()); |
| 1199 ASSERT(instr->value()->representation().IsDouble()); | 1199 DCHECK(instr->value()->representation().IsDouble()); |
| 1200 LOperand* input = UseRegisterAtStart(instr->value()); | 1200 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1201 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); | 1201 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 | 1204 |
| 1205 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { | 1205 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
| 1206 LOperand* input = UseRegisterAtStart(instr->value()); | 1206 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1207 LMathClz32* result = new(zone()) LMathClz32(input); | 1207 LMathClz32* result = new(zone()) LMathClz32(input); |
| 1208 return DefineAsRegister(result); | 1208 return DefineAsRegister(result); |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 | 1211 |
| 1212 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1212 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
| 1213 ASSERT(instr->representation().IsDouble()); | 1213 DCHECK(instr->representation().IsDouble()); |
| 1214 ASSERT(instr->value()->representation().IsDouble()); | 1214 DCHECK(instr->value()->representation().IsDouble()); |
| 1215 LOperand* value = UseTempRegister(instr->value()); | 1215 LOperand* value = UseTempRegister(instr->value()); |
| 1216 LOperand* temp1 = TempRegister(); | 1216 LOperand* temp1 = TempRegister(); |
| 1217 LOperand* temp2 = TempRegister(); | 1217 LOperand* temp2 = TempRegister(); |
| 1218 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); | 1218 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); |
| 1219 return DefineAsRegister(result); | 1219 return DefineAsRegister(result); |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 | 1222 |
| 1223 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1223 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
| 1224 LOperand* input = UseRegisterAtStart(instr->value()); | 1224 LOperand* input = UseRegisterAtStart(instr->value()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 } | 1280 } |
| 1281 | 1281 |
| 1282 | 1282 |
| 1283 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1283 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
| 1284 return DoShift(Token::SHL, instr); | 1284 return DoShift(Token::SHL, instr); |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 | 1287 |
| 1288 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1288 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 1289 if (instr->representation().IsSmiOrInteger32()) { | 1289 if (instr->representation().IsSmiOrInteger32()) { |
| 1290 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1290 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1291 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1291 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1292 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); | 1292 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); |
| 1293 | 1293 |
| 1294 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1294 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1295 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1295 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1296 return DefineSameAsFirst(new(zone()) LBitI(left, right)); | 1296 return DefineSameAsFirst(new(zone()) LBitI(left, right)); |
| 1297 } else { | 1297 } else { |
| 1298 return DoArithmeticT(instr->op(), instr); | 1298 return DoArithmeticT(instr->op(), instr); |
| 1299 } | 1299 } |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 | 1302 |
| 1303 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1303 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
| 1304 ASSERT(instr->representation().IsSmiOrInteger32()); | 1304 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1305 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1305 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1306 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1306 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1307 LOperand* dividend = UseRegister(instr->left()); | 1307 LOperand* dividend = UseRegister(instr->left()); |
| 1308 int32_t divisor = instr->right()->GetInteger32Constant(); | 1308 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1309 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( | 1309 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
| 1310 dividend, divisor)); | 1310 dividend, divisor)); |
| 1311 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1311 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1312 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || | 1312 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
| 1313 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1313 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1314 divisor != 1 && divisor != -1)) { | 1314 divisor != 1 && divisor != -1)) { |
| 1315 result = AssignEnvironment(result); | 1315 result = AssignEnvironment(result); |
| 1316 } | 1316 } |
| 1317 return result; | 1317 return result; |
| 1318 } | 1318 } |
| 1319 | 1319 |
| 1320 | 1320 |
| 1321 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { | 1321 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1322 ASSERT(instr->representation().IsInteger32()); | 1322 DCHECK(instr->representation().IsInteger32()); |
| 1323 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1323 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1324 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1324 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1325 LOperand* dividend = UseRegister(instr->left()); | 1325 LOperand* dividend = UseRegister(instr->left()); |
| 1326 int32_t divisor = instr->right()->GetInteger32Constant(); | 1326 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1327 LOperand* temp1 = FixedTemp(eax); | 1327 LOperand* temp1 = FixedTemp(eax); |
| 1328 LOperand* temp2 = FixedTemp(edx); | 1328 LOperand* temp2 = FixedTemp(edx); |
| 1329 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( | 1329 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( |
| 1330 dividend, divisor, temp1, temp2), edx); | 1330 dividend, divisor, temp1, temp2), edx); |
| 1331 if (divisor == 0 || | 1331 if (divisor == 0 || |
| 1332 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1332 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1333 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1333 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1334 result = AssignEnvironment(result); | 1334 result = AssignEnvironment(result); |
| 1335 } | 1335 } |
| 1336 return result; | 1336 return result; |
| 1337 } | 1337 } |
| 1338 | 1338 |
| 1339 | 1339 |
| 1340 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { | 1340 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { |
| 1341 ASSERT(instr->representation().IsSmiOrInteger32()); | 1341 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1342 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1342 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1343 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1343 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1344 LOperand* dividend = UseFixed(instr->left(), eax); | 1344 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1345 LOperand* divisor = UseRegister(instr->right()); | 1345 LOperand* divisor = UseRegister(instr->right()); |
| 1346 LOperand* temp = FixedTemp(edx); | 1346 LOperand* temp = FixedTemp(edx); |
| 1347 LInstruction* result = DefineFixed(new(zone()) LDivI( | 1347 LInstruction* result = DefineFixed(new(zone()) LDivI( |
| 1348 dividend, divisor, temp), eax); | 1348 dividend, divisor, temp), eax); |
| 1349 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1349 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1350 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1350 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1351 instr->CheckFlag(HValue::kCanOverflow) || | 1351 instr->CheckFlag(HValue::kCanOverflow) || |
| 1352 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1352 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1353 result = AssignEnvironment(result); | 1353 result = AssignEnvironment(result); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1380 dividend, divisor)); | 1380 dividend, divisor)); |
| 1381 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1381 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1382 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { | 1382 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
| 1383 result = AssignEnvironment(result); | 1383 result = AssignEnvironment(result); |
| 1384 } | 1384 } |
| 1385 return result; | 1385 return result; |
| 1386 } | 1386 } |
| 1387 | 1387 |
| 1388 | 1388 |
| 1389 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { | 1389 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1390 ASSERT(instr->representation().IsInteger32()); | 1390 DCHECK(instr->representation().IsInteger32()); |
| 1391 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1391 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1392 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1392 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1393 LOperand* dividend = UseRegister(instr->left()); | 1393 LOperand* dividend = UseRegister(instr->left()); |
| 1394 int32_t divisor = instr->right()->GetInteger32Constant(); | 1394 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1395 LOperand* temp1 = FixedTemp(eax); | 1395 LOperand* temp1 = FixedTemp(eax); |
| 1396 LOperand* temp2 = FixedTemp(edx); | 1396 LOperand* temp2 = FixedTemp(edx); |
| 1397 LOperand* temp3 = | 1397 LOperand* temp3 = |
| 1398 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || | 1398 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || |
| 1399 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? | 1399 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? |
| 1400 NULL : TempRegister(); | 1400 NULL : TempRegister(); |
| 1401 LInstruction* result = | 1401 LInstruction* result = |
| 1402 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, | 1402 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, |
| 1403 divisor, | 1403 divisor, |
| 1404 temp1, | 1404 temp1, |
| 1405 temp2, | 1405 temp2, |
| 1406 temp3), | 1406 temp3), |
| 1407 edx); | 1407 edx); |
| 1408 if (divisor == 0 || | 1408 if (divisor == 0 || |
| 1409 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { | 1409 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { |
| 1410 result = AssignEnvironment(result); | 1410 result = AssignEnvironment(result); |
| 1411 } | 1411 } |
| 1412 return result; | 1412 return result; |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 | 1415 |
| 1416 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1416 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
| 1417 ASSERT(instr->representation().IsSmiOrInteger32()); | 1417 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1418 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1418 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1419 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1419 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1420 LOperand* dividend = UseFixed(instr->left(), eax); | 1420 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1421 LOperand* divisor = UseRegister(instr->right()); | 1421 LOperand* divisor = UseRegister(instr->right()); |
| 1422 LOperand* temp = FixedTemp(edx); | 1422 LOperand* temp = FixedTemp(edx); |
| 1423 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( | 1423 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( |
| 1424 dividend, divisor, temp), eax); | 1424 dividend, divisor, temp), eax); |
| 1425 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1425 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1426 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1426 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1427 instr->CheckFlag(HValue::kCanOverflow)) { | 1427 instr->CheckFlag(HValue::kCanOverflow)) { |
| 1428 result = AssignEnvironment(result); | 1428 result = AssignEnvironment(result); |
| 1429 } | 1429 } |
| 1430 return result; | 1430 return result; |
| 1431 } | 1431 } |
| 1432 | 1432 |
| 1433 | 1433 |
| 1434 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1434 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1435 if (instr->RightIsPowerOf2()) { | 1435 if (instr->RightIsPowerOf2()) { |
| 1436 return DoFlooringDivByPowerOf2I(instr); | 1436 return DoFlooringDivByPowerOf2I(instr); |
| 1437 } else if (instr->right()->IsConstant()) { | 1437 } else if (instr->right()->IsConstant()) { |
| 1438 return DoFlooringDivByConstI(instr); | 1438 return DoFlooringDivByConstI(instr); |
| 1439 } else { | 1439 } else { |
| 1440 return DoFlooringDivI(instr); | 1440 return DoFlooringDivI(instr); |
| 1441 } | 1441 } |
| 1442 } | 1442 } |
| 1443 | 1443 |
| 1444 | 1444 |
| 1445 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1445 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
| 1446 ASSERT(instr->representation().IsSmiOrInteger32()); | 1446 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1447 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1447 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1448 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1448 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1449 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1449 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1450 int32_t divisor = instr->right()->GetInteger32Constant(); | 1450 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1451 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( | 1451 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
| 1452 dividend, divisor)); | 1452 dividend, divisor)); |
| 1453 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && | 1453 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && |
| 1454 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1454 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1455 result = AssignEnvironment(result); | 1455 result = AssignEnvironment(result); |
| 1456 } | 1456 } |
| 1457 return result; | 1457 return result; |
| 1458 } | 1458 } |
| 1459 | 1459 |
| 1460 | 1460 |
| 1461 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { | 1461 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1462 ASSERT(instr->representation().IsSmiOrInteger32()); | 1462 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1463 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1463 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1464 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1464 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1465 LOperand* dividend = UseRegister(instr->left()); | 1465 LOperand* dividend = UseRegister(instr->left()); |
| 1466 int32_t divisor = instr->right()->GetInteger32Constant(); | 1466 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1467 LOperand* temp1 = FixedTemp(eax); | 1467 LOperand* temp1 = FixedTemp(eax); |
| 1468 LOperand* temp2 = FixedTemp(edx); | 1468 LOperand* temp2 = FixedTemp(edx); |
| 1469 LInstruction* result = DefineFixed(new(zone()) LModByConstI( | 1469 LInstruction* result = DefineFixed(new(zone()) LModByConstI( |
| 1470 dividend, divisor, temp1, temp2), eax); | 1470 dividend, divisor, temp1, temp2), eax); |
| 1471 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1471 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1472 result = AssignEnvironment(result); | 1472 result = AssignEnvironment(result); |
| 1473 } | 1473 } |
| 1474 return result; | 1474 return result; |
| 1475 } | 1475 } |
| 1476 | 1476 |
| 1477 | 1477 |
| 1478 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1478 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
| 1479 ASSERT(instr->representation().IsSmiOrInteger32()); | 1479 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1480 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1480 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1481 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1481 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1482 LOperand* dividend = UseFixed(instr->left(), eax); | 1482 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1483 LOperand* divisor = UseRegister(instr->right()); | 1483 LOperand* divisor = UseRegister(instr->right()); |
| 1484 LOperand* temp = FixedTemp(edx); | 1484 LOperand* temp = FixedTemp(edx); |
| 1485 LInstruction* result = DefineFixed(new(zone()) LModI( | 1485 LInstruction* result = DefineFixed(new(zone()) LModI( |
| 1486 dividend, divisor, temp), edx); | 1486 dividend, divisor, temp), edx); |
| 1487 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1487 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1488 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1488 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1489 result = AssignEnvironment(result); | 1489 result = AssignEnvironment(result); |
| 1490 } | 1490 } |
| 1491 return result; | 1491 return result; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1504 } else if (instr->representation().IsDouble()) { | 1504 } else if (instr->representation().IsDouble()) { |
| 1505 return DoArithmeticD(Token::MOD, instr); | 1505 return DoArithmeticD(Token::MOD, instr); |
| 1506 } else { | 1506 } else { |
| 1507 return DoArithmeticT(Token::MOD, instr); | 1507 return DoArithmeticT(Token::MOD, instr); |
| 1508 } | 1508 } |
| 1509 } | 1509 } |
| 1510 | 1510 |
| 1511 | 1511 |
| 1512 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1512 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1513 if (instr->representation().IsSmiOrInteger32()) { | 1513 if (instr->representation().IsSmiOrInteger32()) { |
| 1514 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1514 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1515 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1515 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1516 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1516 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1517 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1517 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
| 1518 LOperand* temp = NULL; | 1518 LOperand* temp = NULL; |
| 1519 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1519 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1520 temp = TempRegister(); | 1520 temp = TempRegister(); |
| 1521 } | 1521 } |
| 1522 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1522 LMulI* mul = new(zone()) LMulI(left, right, temp); |
| 1523 if (instr->CheckFlag(HValue::kCanOverflow) || | 1523 if (instr->CheckFlag(HValue::kCanOverflow) || |
| 1524 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1524 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1525 AssignEnvironment(mul); | 1525 AssignEnvironment(mul); |
| 1526 } | 1526 } |
| 1527 return DefineSameAsFirst(mul); | 1527 return DefineSameAsFirst(mul); |
| 1528 } else if (instr->representation().IsDouble()) { | 1528 } else if (instr->representation().IsDouble()) { |
| 1529 return DoArithmeticD(Token::MUL, instr); | 1529 return DoArithmeticD(Token::MUL, instr); |
| 1530 } else { | 1530 } else { |
| 1531 return DoArithmeticT(Token::MUL, instr); | 1531 return DoArithmeticT(Token::MUL, instr); |
| 1532 } | 1532 } |
| 1533 } | 1533 } |
| 1534 | 1534 |
| 1535 | 1535 |
| 1536 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1536 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1537 if (instr->representation().IsSmiOrInteger32()) { | 1537 if (instr->representation().IsSmiOrInteger32()) { |
| 1538 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1538 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1539 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1539 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1540 LOperand* left = UseRegisterAtStart(instr->left()); | 1540 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1541 LOperand* right = UseOrConstantAtStart(instr->right()); | 1541 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1542 LSubI* sub = new(zone()) LSubI(left, right); | 1542 LSubI* sub = new(zone()) LSubI(left, right); |
| 1543 LInstruction* result = DefineSameAsFirst(sub); | 1543 LInstruction* result = DefineSameAsFirst(sub); |
| 1544 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1544 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1545 result = AssignEnvironment(result); | 1545 result = AssignEnvironment(result); |
| 1546 } | 1546 } |
| 1547 return result; | 1547 return result; |
| 1548 } else if (instr->representation().IsDouble()) { | 1548 } else if (instr->representation().IsDouble()) { |
| 1549 return DoArithmeticD(Token::SUB, instr); | 1549 return DoArithmeticD(Token::SUB, instr); |
| 1550 } else { | 1550 } else { |
| 1551 return DoArithmeticT(Token::SUB, instr); | 1551 return DoArithmeticT(Token::SUB, instr); |
| 1552 } | 1552 } |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 | 1555 |
| 1556 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1556 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 1557 if (instr->representation().IsSmiOrInteger32()) { | 1557 if (instr->representation().IsSmiOrInteger32()) { |
| 1558 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1558 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1559 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1559 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1560 // Check to see if it would be advantageous to use an lea instruction rather | 1560 // Check to see if it would be advantageous to use an lea instruction rather |
| 1561 // than an add. This is the case when no overflow check is needed and there | 1561 // than an add. This is the case when no overflow check is needed and there |
| 1562 // are multiple uses of the add's inputs, so using a 3-register add will | 1562 // are multiple uses of the add's inputs, so using a 3-register add will |
| 1563 // preserve all input values for later uses. | 1563 // preserve all input values for later uses. |
| 1564 bool use_lea = LAddI::UseLea(instr); | 1564 bool use_lea = LAddI::UseLea(instr); |
| 1565 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1565 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1566 HValue* right_candidate = instr->BetterRightOperand(); | 1566 HValue* right_candidate = instr->BetterRightOperand(); |
| 1567 LOperand* right = use_lea | 1567 LOperand* right = use_lea |
| 1568 ? UseRegisterOrConstantAtStart(right_candidate) | 1568 ? UseRegisterOrConstantAtStart(right_candidate) |
| 1569 : UseOrConstantAtStart(right_candidate); | 1569 : UseOrConstantAtStart(right_candidate); |
| 1570 LAddI* add = new(zone()) LAddI(left, right); | 1570 LAddI* add = new(zone()) LAddI(left, right); |
| 1571 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1571 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1572 LInstruction* result = use_lea | 1572 LInstruction* result = use_lea |
| 1573 ? DefineAsRegister(add) | 1573 ? DefineAsRegister(add) |
| 1574 : DefineSameAsFirst(add); | 1574 : DefineSameAsFirst(add); |
| 1575 if (can_overflow) { | 1575 if (can_overflow) { |
| 1576 result = AssignEnvironment(result); | 1576 result = AssignEnvironment(result); |
| 1577 } | 1577 } |
| 1578 return result; | 1578 return result; |
| 1579 } else if (instr->representation().IsDouble()) { | 1579 } else if (instr->representation().IsDouble()) { |
| 1580 return DoArithmeticD(Token::ADD, instr); | 1580 return DoArithmeticD(Token::ADD, instr); |
| 1581 } else if (instr->representation().IsExternal()) { | 1581 } else if (instr->representation().IsExternal()) { |
| 1582 ASSERT(instr->left()->representation().IsExternal()); | 1582 DCHECK(instr->left()->representation().IsExternal()); |
| 1583 ASSERT(instr->right()->representation().IsInteger32()); | 1583 DCHECK(instr->right()->representation().IsInteger32()); |
| 1584 ASSERT(!instr->CheckFlag(HValue::kCanOverflow)); | 1584 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); |
| 1585 bool use_lea = LAddI::UseLea(instr); | 1585 bool use_lea = LAddI::UseLea(instr); |
| 1586 LOperand* left = UseRegisterAtStart(instr->left()); | 1586 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1587 HValue* right_candidate = instr->right(); | 1587 HValue* right_candidate = instr->right(); |
| 1588 LOperand* right = use_lea | 1588 LOperand* right = use_lea |
| 1589 ? UseRegisterOrConstantAtStart(right_candidate) | 1589 ? UseRegisterOrConstantAtStart(right_candidate) |
| 1590 : UseOrConstantAtStart(right_candidate); | 1590 : UseOrConstantAtStart(right_candidate); |
| 1591 LAddI* add = new(zone()) LAddI(left, right); | 1591 LAddI* add = new(zone()) LAddI(left, right); |
| 1592 LInstruction* result = use_lea | 1592 LInstruction* result = use_lea |
| 1593 ? DefineAsRegister(add) | 1593 ? DefineAsRegister(add) |
| 1594 : DefineSameAsFirst(add); | 1594 : DefineSameAsFirst(add); |
| 1595 return result; | 1595 return result; |
| 1596 } else { | 1596 } else { |
| 1597 return DoArithmeticT(Token::ADD, instr); | 1597 return DoArithmeticT(Token::ADD, instr); |
| 1598 } | 1598 } |
| 1599 } | 1599 } |
| 1600 | 1600 |
| 1601 | 1601 |
| 1602 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1602 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1603 LOperand* left = NULL; | 1603 LOperand* left = NULL; |
| 1604 LOperand* right = NULL; | 1604 LOperand* right = NULL; |
| 1605 if (instr->representation().IsSmiOrInteger32()) { | 1605 if (instr->representation().IsSmiOrInteger32()) { |
| 1606 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1606 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1607 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1607 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1608 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1608 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1609 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1609 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1610 } else { | 1610 } else { |
| 1611 ASSERT(instr->representation().IsDouble()); | 1611 DCHECK(instr->representation().IsDouble()); |
| 1612 ASSERT(instr->left()->representation().IsDouble()); | 1612 DCHECK(instr->left()->representation().IsDouble()); |
| 1613 ASSERT(instr->right()->representation().IsDouble()); | 1613 DCHECK(instr->right()->representation().IsDouble()); |
| 1614 left = UseRegisterAtStart(instr->left()); | 1614 left = UseRegisterAtStart(instr->left()); |
| 1615 right = UseRegisterAtStart(instr->right()); | 1615 right = UseRegisterAtStart(instr->right()); |
| 1616 } | 1616 } |
| 1617 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); | 1617 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); |
| 1618 return DefineSameAsFirst(minmax); | 1618 return DefineSameAsFirst(minmax); |
| 1619 } | 1619 } |
| 1620 | 1620 |
| 1621 | 1621 |
| 1622 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1622 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1623 // Crankshaft is turned off for nosse2. | 1623 // Crankshaft is turned off for nosse2. |
| 1624 UNREACHABLE(); | 1624 UNREACHABLE(); |
| 1625 return NULL; | 1625 return NULL; |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 | 1628 |
| 1629 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1629 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1630 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 1630 DCHECK(instr->left()->representation().IsSmiOrTagged()); |
| 1631 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 1631 DCHECK(instr->right()->representation().IsSmiOrTagged()); |
| 1632 LOperand* context = UseFixed(instr->context(), esi); | 1632 LOperand* context = UseFixed(instr->context(), esi); |
| 1633 LOperand* left = UseFixed(instr->left(), edx); | 1633 LOperand* left = UseFixed(instr->left(), edx); |
| 1634 LOperand* right = UseFixed(instr->right(), eax); | 1634 LOperand* right = UseFixed(instr->right(), eax); |
| 1635 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1635 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1636 return MarkAsCall(DefineFixed(result, eax), instr); | 1636 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1637 } | 1637 } |
| 1638 | 1638 |
| 1639 | 1639 |
| 1640 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1640 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1641 HCompareNumericAndBranch* instr) { | 1641 HCompareNumericAndBranch* instr) { |
| 1642 Representation r = instr->representation(); | 1642 Representation r = instr->representation(); |
| 1643 if (r.IsSmiOrInteger32()) { | 1643 if (r.IsSmiOrInteger32()) { |
| 1644 ASSERT(instr->left()->representation().Equals(r)); | 1644 DCHECK(instr->left()->representation().Equals(r)); |
| 1645 ASSERT(instr->right()->representation().Equals(r)); | 1645 DCHECK(instr->right()->representation().Equals(r)); |
| 1646 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1646 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1647 LOperand* right = UseOrConstantAtStart(instr->right()); | 1647 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1648 return new(zone()) LCompareNumericAndBranch(left, right); | 1648 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1649 } else { | 1649 } else { |
| 1650 ASSERT(r.IsDouble()); | 1650 DCHECK(r.IsDouble()); |
| 1651 ASSERT(instr->left()->representation().IsDouble()); | 1651 DCHECK(instr->left()->representation().IsDouble()); |
| 1652 ASSERT(instr->right()->representation().IsDouble()); | 1652 DCHECK(instr->right()->representation().IsDouble()); |
| 1653 LOperand* left; | 1653 LOperand* left; |
| 1654 LOperand* right; | 1654 LOperand* right; |
| 1655 if (CanBeImmediateConstant(instr->left()) && | 1655 if (CanBeImmediateConstant(instr->left()) && |
| 1656 CanBeImmediateConstant(instr->right())) { | 1656 CanBeImmediateConstant(instr->right())) { |
| 1657 // The code generator requires either both inputs to be constant | 1657 // The code generator requires either both inputs to be constant |
| 1658 // operands, or neither. | 1658 // operands, or neither. |
| 1659 left = UseConstant(instr->left()); | 1659 left = UseConstant(instr->left()); |
| 1660 right = UseConstant(instr->right()); | 1660 right = UseConstant(instr->right()); |
| 1661 } else { | 1661 } else { |
| 1662 left = UseRegisterAtStart(instr->left()); | 1662 left = UseRegisterAtStart(instr->left()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1684 | 1684 |
| 1685 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1685 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1686 HCompareMinusZeroAndBranch* instr) { | 1686 HCompareMinusZeroAndBranch* instr) { |
| 1687 LOperand* value = UseRegister(instr->value()); | 1687 LOperand* value = UseRegister(instr->value()); |
| 1688 LOperand* scratch = TempRegister(); | 1688 LOperand* scratch = TempRegister(); |
| 1689 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1689 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
| 1690 } | 1690 } |
| 1691 | 1691 |
| 1692 | 1692 |
| 1693 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1693 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1694 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 1694 DCHECK(instr->value()->representation().IsSmiOrTagged()); |
| 1695 LOperand* temp = TempRegister(); | 1695 LOperand* temp = TempRegister(); |
| 1696 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); | 1696 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); |
| 1697 } | 1697 } |
| 1698 | 1698 |
| 1699 | 1699 |
| 1700 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1700 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
| 1701 ASSERT(instr->value()->representation().IsTagged()); | 1701 DCHECK(instr->value()->representation().IsTagged()); |
| 1702 LOperand* temp = TempRegister(); | 1702 LOperand* temp = TempRegister(); |
| 1703 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp); | 1703 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp); |
| 1704 } | 1704 } |
| 1705 | 1705 |
| 1706 | 1706 |
| 1707 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { | 1707 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
| 1708 ASSERT(instr->value()->representation().IsTagged()); | 1708 DCHECK(instr->value()->representation().IsTagged()); |
| 1709 return new(zone()) LIsSmiAndBranch(Use(instr->value())); | 1709 return new(zone()) LIsSmiAndBranch(Use(instr->value())); |
| 1710 } | 1710 } |
| 1711 | 1711 |
| 1712 | 1712 |
| 1713 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( | 1713 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
| 1714 HIsUndetectableAndBranch* instr) { | 1714 HIsUndetectableAndBranch* instr) { |
| 1715 ASSERT(instr->value()->representation().IsTagged()); | 1715 DCHECK(instr->value()->representation().IsTagged()); |
| 1716 return new(zone()) LIsUndetectableAndBranch( | 1716 return new(zone()) LIsUndetectableAndBranch( |
| 1717 UseRegisterAtStart(instr->value()), TempRegister()); | 1717 UseRegisterAtStart(instr->value()), TempRegister()); |
| 1718 } | 1718 } |
| 1719 | 1719 |
| 1720 | 1720 |
| 1721 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1721 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 1722 HStringCompareAndBranch* instr) { | 1722 HStringCompareAndBranch* instr) { |
| 1723 ASSERT(instr->left()->representation().IsTagged()); | 1723 DCHECK(instr->left()->representation().IsTagged()); |
| 1724 ASSERT(instr->right()->representation().IsTagged()); | 1724 DCHECK(instr->right()->representation().IsTagged()); |
| 1725 LOperand* context = UseFixed(instr->context(), esi); | 1725 LOperand* context = UseFixed(instr->context(), esi); |
| 1726 LOperand* left = UseFixed(instr->left(), edx); | 1726 LOperand* left = UseFixed(instr->left(), edx); |
| 1727 LOperand* right = UseFixed(instr->right(), eax); | 1727 LOperand* right = UseFixed(instr->right(), eax); |
| 1728 | 1728 |
| 1729 LStringCompareAndBranch* result = new(zone()) | 1729 LStringCompareAndBranch* result = new(zone()) |
| 1730 LStringCompareAndBranch(context, left, right); | 1730 LStringCompareAndBranch(context, left, right); |
| 1731 | 1731 |
| 1732 return MarkAsCall(result, instr); | 1732 return MarkAsCall(result, instr); |
| 1733 } | 1733 } |
| 1734 | 1734 |
| 1735 | 1735 |
| 1736 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1736 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1737 HHasInstanceTypeAndBranch* instr) { | 1737 HHasInstanceTypeAndBranch* instr) { |
| 1738 ASSERT(instr->value()->representation().IsTagged()); | 1738 DCHECK(instr->value()->representation().IsTagged()); |
| 1739 return new(zone()) LHasInstanceTypeAndBranch( | 1739 return new(zone()) LHasInstanceTypeAndBranch( |
| 1740 UseRegisterAtStart(instr->value()), | 1740 UseRegisterAtStart(instr->value()), |
| 1741 TempRegister()); | 1741 TempRegister()); |
| 1742 } | 1742 } |
| 1743 | 1743 |
| 1744 | 1744 |
| 1745 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1745 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1746 HGetCachedArrayIndex* instr) { | 1746 HGetCachedArrayIndex* instr) { |
| 1747 ASSERT(instr->value()->representation().IsTagged()); | 1747 DCHECK(instr->value()->representation().IsTagged()); |
| 1748 LOperand* value = UseRegisterAtStart(instr->value()); | 1748 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1749 | 1749 |
| 1750 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); | 1750 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); |
| 1751 } | 1751 } |
| 1752 | 1752 |
| 1753 | 1753 |
| 1754 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( | 1754 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
| 1755 HHasCachedArrayIndexAndBranch* instr) { | 1755 HHasCachedArrayIndexAndBranch* instr) { |
| 1756 ASSERT(instr->value()->representation().IsTagged()); | 1756 DCHECK(instr->value()->representation().IsTagged()); |
| 1757 return new(zone()) LHasCachedArrayIndexAndBranch( | 1757 return new(zone()) LHasCachedArrayIndexAndBranch( |
| 1758 UseRegisterAtStart(instr->value())); | 1758 UseRegisterAtStart(instr->value())); |
| 1759 } | 1759 } |
| 1760 | 1760 |
| 1761 | 1761 |
| 1762 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1762 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1763 HClassOfTestAndBranch* instr) { | 1763 HClassOfTestAndBranch* instr) { |
| 1764 ASSERT(instr->value()->representation().IsTagged()); | 1764 DCHECK(instr->value()->representation().IsTagged()); |
| 1765 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), | 1765 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), |
| 1766 TempRegister(), | 1766 TempRegister(), |
| 1767 TempRegister()); | 1767 TempRegister()); |
| 1768 } | 1768 } |
| 1769 | 1769 |
| 1770 | 1770 |
| 1771 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1771 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1772 LOperand* map = UseRegisterAtStart(instr->value()); | 1772 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1773 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1773 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1774 } | 1774 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); | 1882 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); |
| 1883 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1883 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1884 return result; | 1884 return result; |
| 1885 } else if (to.IsSmi()) { | 1885 } else if (to.IsSmi()) { |
| 1886 LOperand* value = UseRegister(val); | 1886 LOperand* value = UseRegister(val); |
| 1887 if (val->type().IsSmi()) { | 1887 if (val->type().IsSmi()) { |
| 1888 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1888 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
| 1889 } | 1889 } |
| 1890 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1890 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1891 } else { | 1891 } else { |
| 1892 ASSERT(to.IsInteger32()); | 1892 DCHECK(to.IsInteger32()); |
| 1893 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1893 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1894 LOperand* value = UseRegister(val); | 1894 LOperand* value = UseRegister(val); |
| 1895 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1895 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
| 1896 } else { | 1896 } else { |
| 1897 LOperand* value = UseRegister(val); | 1897 LOperand* value = UseRegister(val); |
| 1898 LInstruction* result = DefineSameAsFirst(new(zone()) LTaggedToI(value)); | 1898 LInstruction* result = DefineSameAsFirst(new(zone()) LTaggedToI(value)); |
| 1899 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1899 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1900 return result; | 1900 return result; |
| 1901 } | 1901 } |
| 1902 } | 1902 } |
| 1903 } else if (from.IsDouble()) { | 1903 } else if (from.IsDouble()) { |
| 1904 if (to.IsTagged()) { | 1904 if (to.IsTagged()) { |
| 1905 info()->MarkAsDeferredCalling(); | 1905 info()->MarkAsDeferredCalling(); |
| 1906 LOperand* value = UseRegisterAtStart(val); | 1906 LOperand* value = UseRegisterAtStart(val); |
| 1907 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; | 1907 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; |
| 1908 LUnallocated* result_temp = TempRegister(); | 1908 LUnallocated* result_temp = TempRegister(); |
| 1909 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1909 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
| 1910 return AssignPointerMap(Define(result, result_temp)); | 1910 return AssignPointerMap(Define(result, result_temp)); |
| 1911 } else if (to.IsSmi()) { | 1911 } else if (to.IsSmi()) { |
| 1912 LOperand* value = UseRegister(val); | 1912 LOperand* value = UseRegister(val); |
| 1913 return AssignEnvironment( | 1913 return AssignEnvironment( |
| 1914 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1914 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
| 1915 } else { | 1915 } else { |
| 1916 ASSERT(to.IsInteger32()); | 1916 DCHECK(to.IsInteger32()); |
| 1917 bool truncating = instr->CanTruncateToInt32(); | 1917 bool truncating = instr->CanTruncateToInt32(); |
| 1918 LOperand* value = UseRegister(val); | 1918 LOperand* value = UseRegister(val); |
| 1919 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); | 1919 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); |
| 1920 if (!truncating) result = AssignEnvironment(result); | 1920 if (!truncating) result = AssignEnvironment(result); |
| 1921 return result; | 1921 return result; |
| 1922 } | 1922 } |
| 1923 } else if (from.IsInteger32()) { | 1923 } else if (from.IsInteger32()) { |
| 1924 info()->MarkAsDeferredCalling(); | 1924 info()->MarkAsDeferredCalling(); |
| 1925 if (to.IsTagged()) { | 1925 if (to.IsTagged()) { |
| 1926 if (!instr->CheckFlag(HValue::kCanOverflow)) { | 1926 if (!instr->CheckFlag(HValue::kCanOverflow)) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1938 return AssignPointerMap(DefineSameAsFirst(result)); | 1938 return AssignPointerMap(DefineSameAsFirst(result)); |
| 1939 } | 1939 } |
| 1940 } else if (to.IsSmi()) { | 1940 } else if (to.IsSmi()) { |
| 1941 LOperand* value = UseRegister(val); | 1941 LOperand* value = UseRegister(val); |
| 1942 LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value)); | 1942 LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value)); |
| 1943 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1943 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1944 result = AssignEnvironment(result); | 1944 result = AssignEnvironment(result); |
| 1945 } | 1945 } |
| 1946 return result; | 1946 return result; |
| 1947 } else { | 1947 } else { |
| 1948 ASSERT(to.IsDouble()); | 1948 DCHECK(to.IsDouble()); |
| 1949 if (val->CheckFlag(HInstruction::kUint32)) { | 1949 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1950 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); | 1950 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); |
| 1951 } else { | 1951 } else { |
| 1952 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); | 1952 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); |
| 1953 } | 1953 } |
| 1954 } | 1954 } |
| 1955 } | 1955 } |
| 1956 UNREACHABLE(); | 1956 UNREACHABLE(); |
| 1957 return NULL; | 1957 return NULL; |
| 1958 } | 1958 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2008 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 2008 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| 2009 HValue* value = instr->value(); | 2009 HValue* value = instr->value(); |
| 2010 Representation input_rep = value->representation(); | 2010 Representation input_rep = value->representation(); |
| 2011 if (input_rep.IsDouble()) { | 2011 if (input_rep.IsDouble()) { |
| 2012 UNREACHABLE(); | 2012 UNREACHABLE(); |
| 2013 return NULL; | 2013 return NULL; |
| 2014 } else if (input_rep.IsInteger32()) { | 2014 } else if (input_rep.IsInteger32()) { |
| 2015 LOperand* reg = UseFixed(value, eax); | 2015 LOperand* reg = UseFixed(value, eax); |
| 2016 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); | 2016 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); |
| 2017 } else { | 2017 } else { |
| 2018 ASSERT(input_rep.IsSmiOrTagged()); | 2018 DCHECK(input_rep.IsSmiOrTagged()); |
| 2019 LOperand* value = UseRegister(instr->value()); | 2019 LOperand* value = UseRegister(instr->value()); |
| 2020 LClampTToUint8NoSSE2* res = | 2020 LClampTToUint8NoSSE2* res = |
| 2021 new(zone()) LClampTToUint8NoSSE2(value, TempRegister(), | 2021 new(zone()) LClampTToUint8NoSSE2(value, TempRegister(), |
| 2022 TempRegister(), TempRegister()); | 2022 TempRegister(), TempRegister()); |
| 2023 return AssignEnvironment(DefineFixed(res, ecx)); | 2023 return AssignEnvironment(DefineFixed(res, ecx)); |
| 2024 } | 2024 } |
| 2025 } | 2025 } |
| 2026 | 2026 |
| 2027 | 2027 |
| 2028 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2028 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 2029 HValue* value = instr->value(); | 2029 HValue* value = instr->value(); |
| 2030 ASSERT(value->representation().IsDouble()); | 2030 DCHECK(value->representation().IsDouble()); |
| 2031 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2031 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 2032 } | 2032 } |
| 2033 | 2033 |
| 2034 | 2034 |
| 2035 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { | 2035 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
| 2036 LOperand* lo = UseRegister(instr->lo()); | 2036 LOperand* lo = UseRegister(instr->lo()); |
| 2037 LOperand* hi = UseRegister(instr->hi()); | 2037 LOperand* hi = UseRegister(instr->hi()); |
| 2038 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); | 2038 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); |
| 2039 } | 2039 } |
| 2040 | 2040 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2158 TempRegister()))); | 2158 TempRegister()))); |
| 2159 } | 2159 } |
| 2160 | 2160 |
| 2161 | 2161 |
| 2162 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 2162 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
| 2163 return DefineAsRegister(new(zone()) LLoadRoot); | 2163 return DefineAsRegister(new(zone()) LLoadRoot); |
| 2164 } | 2164 } |
| 2165 | 2165 |
| 2166 | 2166 |
| 2167 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2167 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2168 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 2168 DCHECK(instr->key()->representation().IsSmiOrInteger32()); |
| 2169 ElementsKind elements_kind = instr->elements_kind(); | 2169 ElementsKind elements_kind = instr->elements_kind(); |
| 2170 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2170 bool clobbers_key = ExternalArrayOpRequiresTemp( |
| 2171 instr->key()->representation(), elements_kind); | 2171 instr->key()->representation(), elements_kind); |
| 2172 LOperand* key = clobbers_key | 2172 LOperand* key = clobbers_key |
| 2173 ? UseTempRegister(instr->key()) | 2173 ? UseTempRegister(instr->key()) |
| 2174 : UseRegisterOrConstantAtStart(instr->key()); | 2174 : UseRegisterOrConstantAtStart(instr->key()); |
| 2175 LInstruction* result = NULL; | 2175 LInstruction* result = NULL; |
| 2176 | 2176 |
| 2177 if (!instr->is_typed_elements()) { | 2177 if (!instr->is_typed_elements()) { |
| 2178 LOperand* obj = UseRegisterAtStart(instr->elements()); | 2178 LOperand* obj = UseRegisterAtStart(instr->elements()); |
| 2179 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); | 2179 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); |
| 2180 } else { | 2180 } else { |
| 2181 ASSERT( | 2181 DCHECK( |
| 2182 (instr->representation().IsInteger32() && | 2182 (instr->representation().IsInteger32() && |
| 2183 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || | 2183 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || |
| 2184 (instr->representation().IsDouble() && | 2184 (instr->representation().IsDouble() && |
| 2185 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); | 2185 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); |
| 2186 LOperand* backing_store = UseRegister(instr->elements()); | 2186 LOperand* backing_store = UseRegister(instr->elements()); |
| 2187 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); | 2187 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); |
| 2188 } | 2188 } |
| 2189 | 2189 |
| 2190 if ((instr->is_external() || instr->is_fixed_typed_array()) ? | 2190 if ((instr->is_external() || instr->is_fixed_typed_array()) ? |
| 2191 // see LCodeGen::DoLoadKeyedExternalArray | 2191 // see LCodeGen::DoLoadKeyedExternalArray |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 if (IsDoubleOrFloatElementsKind(elements_kind)) { | 2233 if (IsDoubleOrFloatElementsKind(elements_kind)) { |
| 2234 return UseRegisterAtStart(instr->value()); | 2234 return UseRegisterAtStart(instr->value()); |
| 2235 } | 2235 } |
| 2236 | 2236 |
| 2237 return UseRegister(instr->value()); | 2237 return UseRegister(instr->value()); |
| 2238 } | 2238 } |
| 2239 | 2239 |
| 2240 | 2240 |
| 2241 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2241 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2242 if (!instr->is_typed_elements()) { | 2242 if (!instr->is_typed_elements()) { |
| 2243 ASSERT(instr->elements()->representation().IsTagged()); | 2243 DCHECK(instr->elements()->representation().IsTagged()); |
| 2244 ASSERT(instr->key()->representation().IsInteger32() || | 2244 DCHECK(instr->key()->representation().IsInteger32() || |
| 2245 instr->key()->representation().IsSmi()); | 2245 instr->key()->representation().IsSmi()); |
| 2246 | 2246 |
| 2247 if (instr->value()->representation().IsDouble()) { | 2247 if (instr->value()->representation().IsDouble()) { |
| 2248 LOperand* object = UseRegisterAtStart(instr->elements()); | 2248 LOperand* object = UseRegisterAtStart(instr->elements()); |
| 2249 LOperand* val = NULL; | 2249 LOperand* val = NULL; |
| 2250 val = UseRegisterAtStart(instr->value()); | 2250 val = UseRegisterAtStart(instr->value()); |
| 2251 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2251 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2252 return new(zone()) LStoreKeyed(object, key, val); | 2252 return new(zone()) LStoreKeyed(object, key, val); |
| 2253 } else { | 2253 } else { |
| 2254 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 2254 DCHECK(instr->value()->representation().IsSmiOrTagged()); |
| 2255 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2255 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2256 | 2256 |
| 2257 LOperand* obj = UseRegister(instr->elements()); | 2257 LOperand* obj = UseRegister(instr->elements()); |
| 2258 LOperand* val; | 2258 LOperand* val; |
| 2259 LOperand* key; | 2259 LOperand* key; |
| 2260 if (needs_write_barrier) { | 2260 if (needs_write_barrier) { |
| 2261 val = UseTempRegister(instr->value()); | 2261 val = UseTempRegister(instr->value()); |
| 2262 key = UseTempRegister(instr->key()); | 2262 key = UseTempRegister(instr->key()); |
| 2263 } else { | 2263 } else { |
| 2264 val = UseRegisterOrConstantAtStart(instr->value()); | 2264 val = UseRegisterOrConstantAtStart(instr->value()); |
| 2265 key = UseRegisterOrConstantAtStart(instr->key()); | 2265 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2266 } | 2266 } |
| 2267 return new(zone()) LStoreKeyed(obj, key, val); | 2267 return new(zone()) LStoreKeyed(obj, key, val); |
| 2268 } | 2268 } |
| 2269 } | 2269 } |
| 2270 | 2270 |
| 2271 ElementsKind elements_kind = instr->elements_kind(); | 2271 ElementsKind elements_kind = instr->elements_kind(); |
| 2272 ASSERT( | 2272 DCHECK( |
| 2273 (instr->value()->representation().IsInteger32() && | 2273 (instr->value()->representation().IsInteger32() && |
| 2274 !IsDoubleOrFloatElementsKind(elements_kind)) || | 2274 !IsDoubleOrFloatElementsKind(elements_kind)) || |
| 2275 (instr->value()->representation().IsDouble() && | 2275 (instr->value()->representation().IsDouble() && |
| 2276 IsDoubleOrFloatElementsKind(elements_kind))); | 2276 IsDoubleOrFloatElementsKind(elements_kind))); |
| 2277 ASSERT((instr->is_fixed_typed_array() && | 2277 DCHECK((instr->is_fixed_typed_array() && |
| 2278 instr->elements()->representation().IsTagged()) || | 2278 instr->elements()->representation().IsTagged()) || |
| 2279 (instr->is_external() && | 2279 (instr->is_external() && |
| 2280 instr->elements()->representation().IsExternal())); | 2280 instr->elements()->representation().IsExternal())); |
| 2281 | 2281 |
| 2282 LOperand* backing_store = UseRegister(instr->elements()); | 2282 LOperand* backing_store = UseRegister(instr->elements()); |
| 2283 LOperand* val = GetStoreKeyedValueOperand(instr); | 2283 LOperand* val = GetStoreKeyedValueOperand(instr); |
| 2284 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2284 bool clobbers_key = ExternalArrayOpRequiresTemp( |
| 2285 instr->key()->representation(), elements_kind); | 2285 instr->key()->representation(), elements_kind); |
| 2286 LOperand* key = clobbers_key | 2286 LOperand* key = clobbers_key |
| 2287 ? UseTempRegister(instr->key()) | 2287 ? UseTempRegister(instr->key()) |
| 2288 : UseRegisterOrConstantAtStart(instr->key()); | 2288 : UseRegisterOrConstantAtStart(instr->key()); |
| 2289 return new(zone()) LStoreKeyed(backing_store, key, val); | 2289 return new(zone()) LStoreKeyed(backing_store, key, val); |
| 2290 } | 2290 } |
| 2291 | 2291 |
| 2292 | 2292 |
| 2293 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2293 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2294 LOperand* context = UseFixed(instr->context(), esi); | 2294 LOperand* context = UseFixed(instr->context(), esi); |
| 2295 LOperand* object = UseFixed(instr->object(), | 2295 LOperand* object = UseFixed(instr->object(), |
| 2296 KeyedStoreIC::ReceiverRegister()); | 2296 KeyedStoreIC::ReceiverRegister()); |
| 2297 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); | 2297 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); |
| 2298 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); | 2298 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); |
| 2299 | 2299 |
| 2300 ASSERT(instr->object()->representation().IsTagged()); | 2300 DCHECK(instr->object()->representation().IsTagged()); |
| 2301 ASSERT(instr->key()->representation().IsTagged()); | 2301 DCHECK(instr->key()->representation().IsTagged()); |
| 2302 ASSERT(instr->value()->representation().IsTagged()); | 2302 DCHECK(instr->value()->representation().IsTagged()); |
| 2303 | 2303 |
| 2304 LStoreKeyedGeneric* result = | 2304 LStoreKeyedGeneric* result = |
| 2305 new(zone()) LStoreKeyedGeneric(context, object, key, value); | 2305 new(zone()) LStoreKeyedGeneric(context, object, key, value); |
| 2306 return MarkAsCall(result, instr); | 2306 return MarkAsCall(result, instr); |
| 2307 } | 2307 } |
| 2308 | 2308 |
| 2309 | 2309 |
| 2310 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2310 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2311 HTransitionElementsKind* instr) { | 2311 HTransitionElementsKind* instr) { |
| 2312 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2312 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2344 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2344 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2345 bool needs_write_barrier_for_map = instr->has_transition() && | 2345 bool needs_write_barrier_for_map = instr->has_transition() && |
| 2346 instr->NeedsWriteBarrierForMap(); | 2346 instr->NeedsWriteBarrierForMap(); |
| 2347 | 2347 |
| 2348 LOperand* obj; | 2348 LOperand* obj; |
| 2349 if (needs_write_barrier) { | 2349 if (needs_write_barrier) { |
| 2350 obj = is_in_object | 2350 obj = is_in_object |
| 2351 ? UseRegister(instr->object()) | 2351 ? UseRegister(instr->object()) |
| 2352 : UseTempRegister(instr->object()); | 2352 : UseTempRegister(instr->object()); |
| 2353 } else if (is_external_location) { | 2353 } else if (is_external_location) { |
| 2354 ASSERT(!is_in_object); | 2354 DCHECK(!is_in_object); |
| 2355 ASSERT(!needs_write_barrier); | 2355 DCHECK(!needs_write_barrier); |
| 2356 ASSERT(!needs_write_barrier_for_map); | 2356 DCHECK(!needs_write_barrier_for_map); |
| 2357 obj = UseRegisterOrConstant(instr->object()); | 2357 obj = UseRegisterOrConstant(instr->object()); |
| 2358 } else { | 2358 } else { |
| 2359 obj = needs_write_barrier_for_map | 2359 obj = needs_write_barrier_for_map |
| 2360 ? UseRegister(instr->object()) | 2360 ? UseRegister(instr->object()) |
| 2361 : UseRegisterAtStart(instr->object()); | 2361 : UseRegisterAtStart(instr->object()); |
| 2362 } | 2362 } |
| 2363 | 2363 |
| 2364 bool can_be_constant = instr->value()->IsConstant() && | 2364 bool can_be_constant = instr->value()->IsConstant() && |
| 2365 HConstant::cast(instr->value())->NotInNewSpace() && | 2365 HConstant::cast(instr->value())->NotInNewSpace() && |
| 2366 !instr->field_representation().IsDouble(); | 2366 !instr->field_representation().IsDouble(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2454 | 2454 |
| 2455 | 2455 |
| 2456 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2456 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2457 LOperand* context = UseFixed(instr->context(), esi); | 2457 LOperand* context = UseFixed(instr->context(), esi); |
| 2458 return MarkAsCall( | 2458 return MarkAsCall( |
| 2459 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr); | 2459 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr); |
| 2460 } | 2460 } |
| 2461 | 2461 |
| 2462 | 2462 |
| 2463 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2463 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2464 ASSERT(argument_count_ == 0); | 2464 DCHECK(argument_count_ == 0); |
| 2465 allocator_->MarkAsOsrEntry(); | 2465 allocator_->MarkAsOsrEntry(); |
| 2466 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2466 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2467 return AssignEnvironment(new(zone()) LOsrEntry); | 2467 return AssignEnvironment(new(zone()) LOsrEntry); |
| 2468 } | 2468 } |
| 2469 | 2469 |
| 2470 | 2470 |
| 2471 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2471 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 2472 LParameter* result = new(zone()) LParameter; | 2472 LParameter* result = new(zone()) LParameter; |
| 2473 if (instr->kind() == HParameter::STACK_PARAMETER) { | 2473 if (instr->kind() == HParameter::STACK_PARAMETER) { |
| 2474 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2474 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 2475 return DefineAsSpilled(result, spill_index); | 2475 return DefineAsSpilled(result, spill_index); |
| 2476 } else { | 2476 } else { |
| 2477 ASSERT(info()->IsStub()); | 2477 DCHECK(info()->IsStub()); |
| 2478 CodeStubInterfaceDescriptor* descriptor = | 2478 CodeStubInterfaceDescriptor* descriptor = |
| 2479 info()->code_stub()->GetInterfaceDescriptor(); | 2479 info()->code_stub()->GetInterfaceDescriptor(); |
| 2480 int index = static_cast<int>(instr->index()); | 2480 int index = static_cast<int>(instr->index()); |
| 2481 Register reg = descriptor->GetEnvironmentParameterRegister(index); | 2481 Register reg = descriptor->GetEnvironmentParameterRegister(index); |
| 2482 return DefineFixed(result, reg); | 2482 return DefineFixed(result, reg); |
| 2483 } | 2483 } |
| 2484 } | 2484 } |
| 2485 | 2485 |
| 2486 | 2486 |
| 2487 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2487 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2578 return NULL; | 2578 return NULL; |
| 2579 } | 2579 } |
| 2580 | 2580 |
| 2581 | 2581 |
| 2582 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2582 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2583 info()->MarkAsDeferredCalling(); | 2583 info()->MarkAsDeferredCalling(); |
| 2584 if (instr->is_function_entry()) { | 2584 if (instr->is_function_entry()) { |
| 2585 LOperand* context = UseFixed(instr->context(), esi); | 2585 LOperand* context = UseFixed(instr->context(), esi); |
| 2586 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2586 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2587 } else { | 2587 } else { |
| 2588 ASSERT(instr->is_backwards_branch()); | 2588 DCHECK(instr->is_backwards_branch()); |
| 2589 LOperand* context = UseAny(instr->context()); | 2589 LOperand* context = UseAny(instr->context()); |
| 2590 return AssignEnvironment( | 2590 return AssignEnvironment( |
| 2591 AssignPointerMap(new(zone()) LStackCheck(context))); | 2591 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2592 } | 2592 } |
| 2593 } | 2593 } |
| 2594 | 2594 |
| 2595 | 2595 |
| 2596 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2596 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2597 HEnvironment* outer = current_block_->last_environment(); | 2597 HEnvironment* outer = current_block_->last_environment(); |
| 2598 outer->set_ast_id(instr->ReturnId()); | 2598 outer->set_ast_id(instr->ReturnId()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2614 | 2614 |
| 2615 | 2615 |
| 2616 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2616 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2617 LInstruction* pop = NULL; | 2617 LInstruction* pop = NULL; |
| 2618 | 2618 |
| 2619 HEnvironment* env = current_block_->last_environment(); | 2619 HEnvironment* env = current_block_->last_environment(); |
| 2620 | 2620 |
| 2621 if (env->entry()->arguments_pushed()) { | 2621 if (env->entry()->arguments_pushed()) { |
| 2622 int argument_count = env->arguments_environment()->parameter_count(); | 2622 int argument_count = env->arguments_environment()->parameter_count(); |
| 2623 pop = new(zone()) LDrop(argument_count); | 2623 pop = new(zone()) LDrop(argument_count); |
| 2624 ASSERT(instr->argument_delta() == -argument_count); | 2624 DCHECK(instr->argument_delta() == -argument_count); |
| 2625 } | 2625 } |
| 2626 | 2626 |
| 2627 HEnvironment* outer = current_block_->last_environment()-> | 2627 HEnvironment* outer = current_block_->last_environment()-> |
| 2628 DiscardInlined(false); | 2628 DiscardInlined(false); |
| 2629 current_block_->UpdateEnvironment(outer); | 2629 current_block_->UpdateEnvironment(outer); |
| 2630 return pop; | 2630 return pop; |
| 2631 } | 2631 } |
| 2632 | 2632 |
| 2633 | 2633 |
| 2634 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { | 2634 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2674 LOperand* function = UseRegisterAtStart(instr->function()); | 2674 LOperand* function = UseRegisterAtStart(instr->function()); |
| 2675 LAllocateBlockContext* result = | 2675 LAllocateBlockContext* result = |
| 2676 new(zone()) LAllocateBlockContext(context, function); | 2676 new(zone()) LAllocateBlockContext(context, function); |
| 2677 return MarkAsCall(DefineFixed(result, esi), instr); | 2677 return MarkAsCall(DefineFixed(result, esi), instr); |
| 2678 } | 2678 } |
| 2679 | 2679 |
| 2680 | 2680 |
| 2681 } } // namespace v8::internal | 2681 } } // namespace v8::internal |
| 2682 | 2682 |
| 2683 #endif // V8_TARGET_ARCH_X87 | 2683 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |