| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/hydrogen-osr.h" | 9 #include "src/hydrogen-osr.h" |
| 10 #include "src/ia32/lithium-codegen-ia32.h" | 10 #include "src/ia32/lithium-codegen-ia32.h" |
| 11 #include "src/lithium-inl.h" | 11 #include "src/lithium-inl.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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 } | 350 } |
| 351 return spill_slot_count_++; | 351 return spill_slot_count_++; |
| 352 } | 352 } |
| 353 | 353 |
| 354 | 354 |
| 355 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { | 355 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 356 int index = GetNextSpillIndex(kind); | 356 int index = GetNextSpillIndex(kind); |
| 357 if (kind == DOUBLE_REGISTERS) { | 357 if (kind == DOUBLE_REGISTERS) { |
| 358 return LDoubleStackSlot::Create(index, zone()); | 358 return LDoubleStackSlot::Create(index, zone()); |
| 359 } else { | 359 } else { |
| 360 ASSERT(kind == GENERAL_REGISTERS); | 360 DCHECK(kind == GENERAL_REGISTERS); |
| 361 return LStackSlot::Create(index, zone()); | 361 return LStackSlot::Create(index, zone()); |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 void LStoreNamedField::PrintDataTo(StringStream* stream) { | 366 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
| 367 object()->PrintTo(stream); | 367 object()->PrintTo(stream); |
| 368 OStringStream os; | 368 OStringStream os; |
| 369 os << hydrogen()->access() << " <- "; | 369 os << hydrogen()->access() << " <- "; |
| 370 stream->Add(os.c_str()); | 370 stream->Add(os.c_str()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 397 elements()->PrintTo(stream); | 397 elements()->PrintTo(stream); |
| 398 stream->Add("["); | 398 stream->Add("["); |
| 399 key()->PrintTo(stream); | 399 key()->PrintTo(stream); |
| 400 if (hydrogen()->IsDehoisted()) { | 400 if (hydrogen()->IsDehoisted()) { |
| 401 stream->Add(" + %d] <-", base_offset()); | 401 stream->Add(" + %d] <-", base_offset()); |
| 402 } else { | 402 } else { |
| 403 stream->Add("] <- "); | 403 stream->Add("] <- "); |
| 404 } | 404 } |
| 405 | 405 |
| 406 if (value() == NULL) { | 406 if (value() == NULL) { |
| 407 ASSERT(hydrogen()->IsConstantHoleStore() && | 407 DCHECK(hydrogen()->IsConstantHoleStore() && |
| 408 hydrogen()->value()->representation().IsDouble()); | 408 hydrogen()->value()->representation().IsDouble()); |
| 409 stream->Add("<the hole(nan)>"); | 409 stream->Add("<the hole(nan)>"); |
| 410 } else { | 410 } else { |
| 411 value()->PrintTo(stream); | 411 value()->PrintTo(stream); |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { | 416 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 417 object()->PrintTo(stream); | 417 object()->PrintTo(stream); |
| 418 stream->Add("["); | 418 stream->Add("["); |
| 419 key()->PrintTo(stream); | 419 key()->PrintTo(stream); |
| 420 stream->Add("] <- "); | 420 stream->Add("] <- "); |
| 421 value()->PrintTo(stream); | 421 value()->PrintTo(stream); |
| 422 } | 422 } |
| 423 | 423 |
| 424 | 424 |
| 425 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { | 425 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { |
| 426 object()->PrintTo(stream); | 426 object()->PrintTo(stream); |
| 427 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); | 427 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); |
| 428 } | 428 } |
| 429 | 429 |
| 430 | 430 |
| 431 LPlatformChunk* LChunkBuilder::Build() { | 431 LPlatformChunk* LChunkBuilder::Build() { |
| 432 ASSERT(is_unused()); | 432 DCHECK(is_unused()); |
| 433 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 433 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
| 434 LPhase phase("L_Building chunk", chunk_); | 434 LPhase phase("L_Building chunk", chunk_); |
| 435 status_ = BUILDING; | 435 status_ = BUILDING; |
| 436 | 436 |
| 437 // Reserve the first spill slot for the state of dynamic alignment. | 437 // Reserve the first spill slot for the state of dynamic alignment. |
| 438 if (info()->IsOptimizing()) { | 438 if (info()->IsOptimizing()) { |
| 439 int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 439 int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 440 ASSERT_EQ(alignment_state_index, 0); | 440 DCHECK_EQ(alignment_state_index, 0); |
| 441 USE(alignment_state_index); | 441 USE(alignment_state_index); |
| 442 } | 442 } |
| 443 | 443 |
| 444 // If compiling for OSR, reserve space for the unoptimized frame, | 444 // If compiling for OSR, reserve space for the unoptimized frame, |
| 445 // which will be subsumed into this frame. | 445 // which will be subsumed into this frame. |
| 446 if (graph()->has_osr()) { | 446 if (graph()->has_osr()) { |
| 447 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 447 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 448 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 448 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 449 } | 449 } |
| 450 } | 450 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 instr = AssignEnvironment(instr); | 656 instr = AssignEnvironment(instr); |
| 657 // We can't really figure out if the environment is needed or not. | 657 // We can't really figure out if the environment is needed or not. |
| 658 instr->environment()->set_has_been_used(); | 658 instr->environment()->set_has_been_used(); |
| 659 } | 659 } |
| 660 | 660 |
| 661 return instr; | 661 return instr; |
| 662 } | 662 } |
| 663 | 663 |
| 664 | 664 |
| 665 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 665 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 666 ASSERT(!instr->HasPointerMap()); | 666 DCHECK(!instr->HasPointerMap()); |
| 667 instr->set_pointer_map(new(zone()) LPointerMap(zone())); | 667 instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
| 668 return instr; | 668 return instr; |
| 669 } | 669 } |
| 670 | 670 |
| 671 | 671 |
| 672 LUnallocated* LChunkBuilder::TempRegister() { | 672 LUnallocated* LChunkBuilder::TempRegister() { |
| 673 LUnallocated* operand = | 673 LUnallocated* operand = |
| 674 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 674 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
| 675 int vreg = allocator_->GetVirtualRegister(); | 675 int vreg = allocator_->GetVirtualRegister(); |
| 676 if (!allocator_->AllocationOk()) { | 676 if (!allocator_->AllocationOk()) { |
| 677 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 677 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
| 678 vreg = 0; | 678 vreg = 0; |
| 679 } | 679 } |
| 680 operand->set_virtual_register(vreg); | 680 operand->set_virtual_register(vreg); |
| 681 return operand; | 681 return operand; |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 685 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
| 686 LUnallocated* operand = ToUnallocated(reg); | 686 LUnallocated* operand = ToUnallocated(reg); |
| 687 ASSERT(operand->HasFixedPolicy()); | 687 DCHECK(operand->HasFixedPolicy()); |
| 688 return operand; | 688 return operand; |
| 689 } | 689 } |
| 690 | 690 |
| 691 | 691 |
| 692 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) { | 692 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) { |
| 693 LUnallocated* operand = ToUnallocated(reg); | 693 LUnallocated* operand = ToUnallocated(reg); |
| 694 ASSERT(operand->HasFixedPolicy()); | 694 DCHECK(operand->HasFixedPolicy()); |
| 695 return operand; | 695 return operand; |
| 696 } | 696 } |
| 697 | 697 |
| 698 | 698 |
| 699 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { | 699 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { |
| 700 return new(zone()) LLabel(instr->block()); | 700 return new(zone()) LLabel(instr->block()); |
| 701 } | 701 } |
| 702 | 702 |
| 703 | 703 |
| 704 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 704 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
| 705 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 705 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
| 706 } | 706 } |
| 707 | 707 |
| 708 | 708 |
| 709 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { | 709 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { |
| 710 UNREACHABLE(); | 710 UNREACHABLE(); |
| 711 return NULL; | 711 return NULL; |
| 712 } | 712 } |
| 713 | 713 |
| 714 | 714 |
| 715 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 715 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 716 return AssignEnvironment(new(zone()) LDeoptimize); | 716 return AssignEnvironment(new(zone()) LDeoptimize); |
| 717 } | 717 } |
| 718 | 718 |
| 719 | 719 |
| 720 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 720 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 721 HBitwiseBinaryOperation* instr) { | 721 HBitwiseBinaryOperation* instr) { |
| 722 if (instr->representation().IsSmiOrInteger32()) { | 722 if (instr->representation().IsSmiOrInteger32()) { |
| 723 ASSERT(instr->left()->representation().Equals(instr->representation())); | 723 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 724 ASSERT(instr->right()->representation().Equals(instr->representation())); | 724 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 725 LOperand* left = UseRegisterAtStart(instr->left()); | 725 LOperand* left = UseRegisterAtStart(instr->left()); |
| 726 | 726 |
| 727 HValue* right_value = instr->right(); | 727 HValue* right_value = instr->right(); |
| 728 LOperand* right = NULL; | 728 LOperand* right = NULL; |
| 729 int constant_value = 0; | 729 int constant_value = 0; |
| 730 bool does_deopt = false; | 730 bool does_deopt = false; |
| 731 if (right_value->IsConstant()) { | 731 if (right_value->IsConstant()) { |
| 732 HConstant* constant = HConstant::cast(right_value); | 732 HConstant* constant = HConstant::cast(right_value); |
| 733 right = chunk_->DefineConstantOperand(constant); | 733 right = chunk_->DefineConstantOperand(constant); |
| 734 constant_value = constant->Integer32Value() & 0x1f; | 734 constant_value = constant->Integer32Value() & 0x1f; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 755 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); | 755 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); |
| 756 return does_deopt ? AssignEnvironment(result) : result; | 756 return does_deopt ? AssignEnvironment(result) : result; |
| 757 } else { | 757 } else { |
| 758 return DoArithmeticT(op, instr); | 758 return DoArithmeticT(op, instr); |
| 759 } | 759 } |
| 760 } | 760 } |
| 761 | 761 |
| 762 | 762 |
| 763 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 763 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 764 HArithmeticBinaryOperation* instr) { | 764 HArithmeticBinaryOperation* instr) { |
| 765 ASSERT(instr->representation().IsDouble()); | 765 DCHECK(instr->representation().IsDouble()); |
| 766 ASSERT(instr->left()->representation().IsDouble()); | 766 DCHECK(instr->left()->representation().IsDouble()); |
| 767 ASSERT(instr->right()->representation().IsDouble()); | 767 DCHECK(instr->right()->representation().IsDouble()); |
| 768 if (op == Token::MOD) { | 768 if (op == Token::MOD) { |
| 769 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 769 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 770 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); | 770 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); |
| 771 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 771 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 772 return MarkAsCall(DefineSameAsFirst(result), instr); | 772 return MarkAsCall(DefineSameAsFirst(result), instr); |
| 773 } else { | 773 } else { |
| 774 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 774 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 775 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); | 775 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); |
| 776 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 776 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 777 return DefineSameAsFirst(result); | 777 return DefineSameAsFirst(result); |
| 778 } | 778 } |
| 779 } | 779 } |
| 780 | 780 |
| 781 | 781 |
| 782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 783 HBinaryOperation* instr) { | 783 HBinaryOperation* instr) { |
| 784 HValue* left = instr->left(); | 784 HValue* left = instr->left(); |
| 785 HValue* right = instr->right(); | 785 HValue* right = instr->right(); |
| 786 ASSERT(left->representation().IsTagged()); | 786 DCHECK(left->representation().IsTagged()); |
| 787 ASSERT(right->representation().IsTagged()); | 787 DCHECK(right->representation().IsTagged()); |
| 788 LOperand* context = UseFixed(instr->context(), esi); | 788 LOperand* context = UseFixed(instr->context(), esi); |
| 789 LOperand* left_operand = UseFixed(left, edx); | 789 LOperand* left_operand = UseFixed(left, edx); |
| 790 LOperand* right_operand = UseFixed(right, eax); | 790 LOperand* right_operand = UseFixed(right, eax); |
| 791 LArithmeticT* result = | 791 LArithmeticT* result = |
| 792 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 792 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 793 return MarkAsCall(DefineFixed(result, eax), instr); | 793 return MarkAsCall(DefineFixed(result, eax), instr); |
| 794 } | 794 } |
| 795 | 795 |
| 796 | 796 |
| 797 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 797 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 798 ASSERT(is_building()); | 798 DCHECK(is_building()); |
| 799 current_block_ = block; | 799 current_block_ = block; |
| 800 next_block_ = next_block; | 800 next_block_ = next_block; |
| 801 if (block->IsStartBlock()) { | 801 if (block->IsStartBlock()) { |
| 802 block->UpdateEnvironment(graph_->start_environment()); | 802 block->UpdateEnvironment(graph_->start_environment()); |
| 803 argument_count_ = 0; | 803 argument_count_ = 0; |
| 804 } else if (block->predecessors()->length() == 1) { | 804 } else if (block->predecessors()->length() == 1) { |
| 805 // We have a single predecessor => copy environment and outgoing | 805 // We have a single predecessor => copy environment and outgoing |
| 806 // argument count from the predecessor. | 806 // argument count from the predecessor. |
| 807 ASSERT(block->phis()->length() == 0); | 807 DCHECK(block->phis()->length() == 0); |
| 808 HBasicBlock* pred = block->predecessors()->at(0); | 808 HBasicBlock* pred = block->predecessors()->at(0); |
| 809 HEnvironment* last_environment = pred->last_environment(); | 809 HEnvironment* last_environment = pred->last_environment(); |
| 810 ASSERT(last_environment != NULL); | 810 DCHECK(last_environment != NULL); |
| 811 // Only copy the environment, if it is later used again. | 811 // Only copy the environment, if it is later used again. |
| 812 if (pred->end()->SecondSuccessor() == NULL) { | 812 if (pred->end()->SecondSuccessor() == NULL) { |
| 813 ASSERT(pred->end()->FirstSuccessor() == block); | 813 DCHECK(pred->end()->FirstSuccessor() == block); |
| 814 } else { | 814 } else { |
| 815 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || | 815 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
| 816 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { | 816 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
| 817 last_environment = last_environment->Copy(); | 817 last_environment = last_environment->Copy(); |
| 818 } | 818 } |
| 819 } | 819 } |
| 820 block->UpdateEnvironment(last_environment); | 820 block->UpdateEnvironment(last_environment); |
| 821 ASSERT(pred->argument_count() >= 0); | 821 DCHECK(pred->argument_count() >= 0); |
| 822 argument_count_ = pred->argument_count(); | 822 argument_count_ = pred->argument_count(); |
| 823 } else { | 823 } else { |
| 824 // We are at a state join => process phis. | 824 // We are at a state join => process phis. |
| 825 HBasicBlock* pred = block->predecessors()->at(0); | 825 HBasicBlock* pred = block->predecessors()->at(0); |
| 826 // No need to copy the environment, it cannot be used later. | 826 // No need to copy the environment, it cannot be used later. |
| 827 HEnvironment* last_environment = pred->last_environment(); | 827 HEnvironment* last_environment = pred->last_environment(); |
| 828 for (int i = 0; i < block->phis()->length(); ++i) { | 828 for (int i = 0; i < block->phis()->length(); ++i) { |
| 829 HPhi* phi = block->phis()->at(i); | 829 HPhi* phi = block->phis()->at(i); |
| 830 if (phi->HasMergedIndex()) { | 830 if (phi->HasMergedIndex()) { |
| 831 last_environment->SetValueAt(phi->merged_index(), phi); | 831 last_environment->SetValueAt(phi->merged_index(), phi); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 | 863 |
| 864 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 864 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 865 HInstruction* old_current = current_instruction_; | 865 HInstruction* old_current = current_instruction_; |
| 866 current_instruction_ = current; | 866 current_instruction_ = current; |
| 867 | 867 |
| 868 LInstruction* instr = NULL; | 868 LInstruction* instr = NULL; |
| 869 if (current->CanReplaceWithDummyUses()) { | 869 if (current->CanReplaceWithDummyUses()) { |
| 870 if (current->OperandCount() == 0) { | 870 if (current->OperandCount() == 0) { |
| 871 instr = DefineAsRegister(new(zone()) LDummy()); | 871 instr = DefineAsRegister(new(zone()) LDummy()); |
| 872 } else { | 872 } else { |
| 873 ASSERT(!current->OperandAt(0)->IsControlInstruction()); | 873 DCHECK(!current->OperandAt(0)->IsControlInstruction()); |
| 874 instr = DefineAsRegister(new(zone()) | 874 instr = DefineAsRegister(new(zone()) |
| 875 LDummyUse(UseAny(current->OperandAt(0)))); | 875 LDummyUse(UseAny(current->OperandAt(0)))); |
| 876 } | 876 } |
| 877 for (int i = 1; i < current->OperandCount(); ++i) { | 877 for (int i = 1; i < current->OperandCount(); ++i) { |
| 878 if (current->OperandAt(i)->IsControlInstruction()) continue; | 878 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 879 LInstruction* dummy = | 879 LInstruction* dummy = |
| 880 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 880 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 881 dummy->set_hydrogen_value(current); | 881 dummy->set_hydrogen_value(current); |
| 882 chunk_->AddInstruction(dummy, current_block_); | 882 chunk_->AddInstruction(dummy, current_block_); |
| 883 } | 883 } |
| 884 } else { | 884 } else { |
| 885 HBasicBlock* successor; | 885 HBasicBlock* successor; |
| 886 if (current->IsControlInstruction() && | 886 if (current->IsControlInstruction() && |
| 887 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && | 887 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 888 successor != NULL) { | 888 successor != NULL) { |
| 889 instr = new(zone()) LGoto(successor); | 889 instr = new(zone()) LGoto(successor); |
| 890 } else { | 890 } else { |
| 891 instr = current->CompileToLithium(this); | 891 instr = current->CompileToLithium(this); |
| 892 } | 892 } |
| 893 } | 893 } |
| 894 | 894 |
| 895 argument_count_ += current->argument_delta(); | 895 argument_count_ += current->argument_delta(); |
| 896 ASSERT(argument_count_ >= 0); | 896 DCHECK(argument_count_ >= 0); |
| 897 | 897 |
| 898 if (instr != NULL) { | 898 if (instr != NULL) { |
| 899 AddInstruction(instr, current); | 899 AddInstruction(instr, current); |
| 900 } | 900 } |
| 901 | 901 |
| 902 current_instruction_ = old_current; | 902 current_instruction_ = old_current; |
| 903 } | 903 } |
| 904 | 904 |
| 905 | 905 |
| 906 void LChunkBuilder::AddInstruction(LInstruction* instr, | 906 void LChunkBuilder::AddInstruction(LInstruction* instr, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 928 LUnallocated* operand = LUnallocated::cast(it.Current()); | 928 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 929 if (operand->IsUsedAtStart()) ++used_at_start; | 929 if (operand->IsUsedAtStart()) ++used_at_start; |
| 930 } | 930 } |
| 931 if (instr->Output() != NULL) { | 931 if (instr->Output() != NULL) { |
| 932 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 932 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 933 } | 933 } |
| 934 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 934 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 935 LUnallocated* operand = LUnallocated::cast(it.Current()); | 935 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 936 if (operand->HasFixedPolicy()) ++fixed; | 936 if (operand->HasFixedPolicy()) ++fixed; |
| 937 } | 937 } |
| 938 ASSERT(fixed == 0 || used_at_start == 0); | 938 DCHECK(fixed == 0 || used_at_start == 0); |
| 939 } | 939 } |
| 940 #endif | 940 #endif |
| 941 | 941 |
| 942 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 942 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 943 instr = AssignPointerMap(instr); | 943 instr = AssignPointerMap(instr); |
| 944 } | 944 } |
| 945 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 945 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 946 instr = AssignEnvironment(instr); | 946 instr = AssignEnvironment(instr); |
| 947 } | 947 } |
| 948 chunk_->AddInstruction(instr, current_block_); | 948 chunk_->AddInstruction(instr, current_block_); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 return branch; | 993 return branch; |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 997 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
| 998 return new(zone()) LDebugBreak(); | 998 return new(zone()) LDebugBreak(); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 | 1001 |
| 1002 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1002 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1003 ASSERT(instr->value()->representation().IsTagged()); | 1003 DCHECK(instr->value()->representation().IsTagged()); |
| 1004 LOperand* value = UseRegisterAtStart(instr->value()); | 1004 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1005 return new(zone()) LCmpMapAndBranch(value); | 1005 return new(zone()) LCmpMapAndBranch(value); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 | 1008 |
| 1009 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1009 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 1010 info()->MarkAsRequiresFrame(); | 1010 info()->MarkAsRequiresFrame(); |
| 1011 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 1011 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 LInstruction* result = | 1203 LInstruction* result = |
| 1204 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); | 1204 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); |
| 1205 Representation r = instr->value()->representation(); | 1205 Representation r = instr->value()->representation(); |
| 1206 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); | 1206 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); |
| 1207 if (!r.IsDouble()) result = AssignEnvironment(result); | 1207 if (!r.IsDouble()) result = AssignEnvironment(result); |
| 1208 return result; | 1208 return result; |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 | 1211 |
| 1212 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1212 LInstruction* LChunkBuilder::DoMathLog(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* input = UseRegisterAtStart(instr->value()); | 1215 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1216 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); | 1216 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); |
| 1217 } | 1217 } |
| 1218 | 1218 |
| 1219 | 1219 |
| 1220 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { | 1220 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
| 1221 LOperand* input = UseRegisterAtStart(instr->value()); | 1221 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1222 LMathClz32* result = new(zone()) LMathClz32(input); | 1222 LMathClz32* result = new(zone()) LMathClz32(input); |
| 1223 return DefineAsRegister(result); | 1223 return DefineAsRegister(result); |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 | 1226 |
| 1227 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1227 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
| 1228 ASSERT(instr->representation().IsDouble()); | 1228 DCHECK(instr->representation().IsDouble()); |
| 1229 ASSERT(instr->value()->representation().IsDouble()); | 1229 DCHECK(instr->value()->representation().IsDouble()); |
| 1230 LOperand* value = UseTempRegister(instr->value()); | 1230 LOperand* value = UseTempRegister(instr->value()); |
| 1231 LOperand* temp1 = TempRegister(); | 1231 LOperand* temp1 = TempRegister(); |
| 1232 LOperand* temp2 = TempRegister(); | 1232 LOperand* temp2 = TempRegister(); |
| 1233 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); | 1233 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); |
| 1234 return DefineAsRegister(result); | 1234 return DefineAsRegister(result); |
| 1235 } | 1235 } |
| 1236 | 1236 |
| 1237 | 1237 |
| 1238 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1238 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
| 1239 LOperand* input = UseAtStart(instr->value()); | 1239 LOperand* input = UseAtStart(instr->value()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 | 1296 |
| 1297 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1297 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
| 1298 return DoShift(Token::SHL, instr); | 1298 return DoShift(Token::SHL, instr); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 | 1301 |
| 1302 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1302 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 1303 if (instr->representation().IsSmiOrInteger32()) { | 1303 if (instr->representation().IsSmiOrInteger32()) { |
| 1304 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1304 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1305 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1305 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1306 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); | 1306 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); |
| 1307 | 1307 |
| 1308 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1308 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1309 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1309 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1310 return DefineSameAsFirst(new(zone()) LBitI(left, right)); | 1310 return DefineSameAsFirst(new(zone()) LBitI(left, right)); |
| 1311 } else { | 1311 } else { |
| 1312 return DoArithmeticT(instr->op(), instr); | 1312 return DoArithmeticT(instr->op(), instr); |
| 1313 } | 1313 } |
| 1314 } | 1314 } |
| 1315 | 1315 |
| 1316 | 1316 |
| 1317 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1317 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
| 1318 ASSERT(instr->representation().IsSmiOrInteger32()); | 1318 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1319 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1319 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1320 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1320 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1321 LOperand* dividend = UseRegister(instr->left()); | 1321 LOperand* dividend = UseRegister(instr->left()); |
| 1322 int32_t divisor = instr->right()->GetInteger32Constant(); | 1322 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1323 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( | 1323 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
| 1324 dividend, divisor)); | 1324 dividend, divisor)); |
| 1325 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1325 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1326 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || | 1326 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
| 1327 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1327 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1328 divisor != 1 && divisor != -1)) { | 1328 divisor != 1 && divisor != -1)) { |
| 1329 result = AssignEnvironment(result); | 1329 result = AssignEnvironment(result); |
| 1330 } | 1330 } |
| 1331 return result; | 1331 return result; |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { | 1335 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1336 ASSERT(instr->representation().IsInteger32()); | 1336 DCHECK(instr->representation().IsInteger32()); |
| 1337 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1337 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1338 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1338 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1339 LOperand* dividend = UseRegister(instr->left()); | 1339 LOperand* dividend = UseRegister(instr->left()); |
| 1340 int32_t divisor = instr->right()->GetInteger32Constant(); | 1340 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1341 LOperand* temp1 = FixedTemp(eax); | 1341 LOperand* temp1 = FixedTemp(eax); |
| 1342 LOperand* temp2 = FixedTemp(edx); | 1342 LOperand* temp2 = FixedTemp(edx); |
| 1343 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( | 1343 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( |
| 1344 dividend, divisor, temp1, temp2), edx); | 1344 dividend, divisor, temp1, temp2), edx); |
| 1345 if (divisor == 0 || | 1345 if (divisor == 0 || |
| 1346 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1346 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1347 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1347 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1348 result = AssignEnvironment(result); | 1348 result = AssignEnvironment(result); |
| 1349 } | 1349 } |
| 1350 return result; | 1350 return result; |
| 1351 } | 1351 } |
| 1352 | 1352 |
| 1353 | 1353 |
| 1354 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { | 1354 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { |
| 1355 ASSERT(instr->representation().IsSmiOrInteger32()); | 1355 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1356 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1356 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1357 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1357 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1358 LOperand* dividend = UseFixed(instr->left(), eax); | 1358 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1359 LOperand* divisor = UseRegister(instr->right()); | 1359 LOperand* divisor = UseRegister(instr->right()); |
| 1360 LOperand* temp = FixedTemp(edx); | 1360 LOperand* temp = FixedTemp(edx); |
| 1361 LInstruction* result = DefineFixed(new(zone()) LDivI( | 1361 LInstruction* result = DefineFixed(new(zone()) LDivI( |
| 1362 dividend, divisor, temp), eax); | 1362 dividend, divisor, temp), eax); |
| 1363 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1363 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1364 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1364 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1365 instr->CheckFlag(HValue::kCanOverflow) || | 1365 instr->CheckFlag(HValue::kCanOverflow) || |
| 1366 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1366 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1367 result = AssignEnvironment(result); | 1367 result = AssignEnvironment(result); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1394 dividend, divisor)); | 1394 dividend, divisor)); |
| 1395 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1395 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1396 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { | 1396 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
| 1397 result = AssignEnvironment(result); | 1397 result = AssignEnvironment(result); |
| 1398 } | 1398 } |
| 1399 return result; | 1399 return result; |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 | 1402 |
| 1403 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { | 1403 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1404 ASSERT(instr->representation().IsInteger32()); | 1404 DCHECK(instr->representation().IsInteger32()); |
| 1405 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1405 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1406 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1406 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1407 LOperand* dividend = UseRegister(instr->left()); | 1407 LOperand* dividend = UseRegister(instr->left()); |
| 1408 int32_t divisor = instr->right()->GetInteger32Constant(); | 1408 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1409 LOperand* temp1 = FixedTemp(eax); | 1409 LOperand* temp1 = FixedTemp(eax); |
| 1410 LOperand* temp2 = FixedTemp(edx); | 1410 LOperand* temp2 = FixedTemp(edx); |
| 1411 LOperand* temp3 = | 1411 LOperand* temp3 = |
| 1412 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || | 1412 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || |
| 1413 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? | 1413 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? |
| 1414 NULL : TempRegister(); | 1414 NULL : TempRegister(); |
| 1415 LInstruction* result = | 1415 LInstruction* result = |
| 1416 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, | 1416 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, |
| 1417 divisor, | 1417 divisor, |
| 1418 temp1, | 1418 temp1, |
| 1419 temp2, | 1419 temp2, |
| 1420 temp3), | 1420 temp3), |
| 1421 edx); | 1421 edx); |
| 1422 if (divisor == 0 || | 1422 if (divisor == 0 || |
| 1423 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { | 1423 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { |
| 1424 result = AssignEnvironment(result); | 1424 result = AssignEnvironment(result); |
| 1425 } | 1425 } |
| 1426 return result; | 1426 return result; |
| 1427 } | 1427 } |
| 1428 | 1428 |
| 1429 | 1429 |
| 1430 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1430 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
| 1431 ASSERT(instr->representation().IsSmiOrInteger32()); | 1431 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1432 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1432 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1433 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1433 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1434 LOperand* dividend = UseFixed(instr->left(), eax); | 1434 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1435 LOperand* divisor = UseRegister(instr->right()); | 1435 LOperand* divisor = UseRegister(instr->right()); |
| 1436 LOperand* temp = FixedTemp(edx); | 1436 LOperand* temp = FixedTemp(edx); |
| 1437 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( | 1437 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( |
| 1438 dividend, divisor, temp), eax); | 1438 dividend, divisor, temp), eax); |
| 1439 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1439 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1440 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1440 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1441 instr->CheckFlag(HValue::kCanOverflow)) { | 1441 instr->CheckFlag(HValue::kCanOverflow)) { |
| 1442 result = AssignEnvironment(result); | 1442 result = AssignEnvironment(result); |
| 1443 } | 1443 } |
| 1444 return result; | 1444 return result; |
| 1445 } | 1445 } |
| 1446 | 1446 |
| 1447 | 1447 |
| 1448 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1448 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1449 if (instr->RightIsPowerOf2()) { | 1449 if (instr->RightIsPowerOf2()) { |
| 1450 return DoFlooringDivByPowerOf2I(instr); | 1450 return DoFlooringDivByPowerOf2I(instr); |
| 1451 } else if (instr->right()->IsConstant()) { | 1451 } else if (instr->right()->IsConstant()) { |
| 1452 return DoFlooringDivByConstI(instr); | 1452 return DoFlooringDivByConstI(instr); |
| 1453 } else { | 1453 } else { |
| 1454 return DoFlooringDivI(instr); | 1454 return DoFlooringDivI(instr); |
| 1455 } | 1455 } |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 | 1458 |
| 1459 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1459 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
| 1460 ASSERT(instr->representation().IsSmiOrInteger32()); | 1460 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1461 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1461 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1462 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1462 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1463 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1463 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1464 int32_t divisor = instr->right()->GetInteger32Constant(); | 1464 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1465 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( | 1465 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
| 1466 dividend, divisor)); | 1466 dividend, divisor)); |
| 1467 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && | 1467 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && |
| 1468 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1468 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1469 result = AssignEnvironment(result); | 1469 result = AssignEnvironment(result); |
| 1470 } | 1470 } |
| 1471 return result; | 1471 return result; |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 | 1474 |
| 1475 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { | 1475 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1476 ASSERT(instr->representation().IsSmiOrInteger32()); | 1476 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1477 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1477 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1478 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1478 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1479 LOperand* dividend = UseRegister(instr->left()); | 1479 LOperand* dividend = UseRegister(instr->left()); |
| 1480 int32_t divisor = instr->right()->GetInteger32Constant(); | 1480 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1481 LOperand* temp1 = FixedTemp(eax); | 1481 LOperand* temp1 = FixedTemp(eax); |
| 1482 LOperand* temp2 = FixedTemp(edx); | 1482 LOperand* temp2 = FixedTemp(edx); |
| 1483 LInstruction* result = DefineFixed(new(zone()) LModByConstI( | 1483 LInstruction* result = DefineFixed(new(zone()) LModByConstI( |
| 1484 dividend, divisor, temp1, temp2), eax); | 1484 dividend, divisor, temp1, temp2), eax); |
| 1485 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1485 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1486 result = AssignEnvironment(result); | 1486 result = AssignEnvironment(result); |
| 1487 } | 1487 } |
| 1488 return result; | 1488 return result; |
| 1489 } | 1489 } |
| 1490 | 1490 |
| 1491 | 1491 |
| 1492 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1492 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
| 1493 ASSERT(instr->representation().IsSmiOrInteger32()); | 1493 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1494 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1494 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1495 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1495 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1496 LOperand* dividend = UseFixed(instr->left(), eax); | 1496 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1497 LOperand* divisor = UseRegister(instr->right()); | 1497 LOperand* divisor = UseRegister(instr->right()); |
| 1498 LOperand* temp = FixedTemp(edx); | 1498 LOperand* temp = FixedTemp(edx); |
| 1499 LInstruction* result = DefineFixed(new(zone()) LModI( | 1499 LInstruction* result = DefineFixed(new(zone()) LModI( |
| 1500 dividend, divisor, temp), edx); | 1500 dividend, divisor, temp), edx); |
| 1501 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1501 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1502 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1502 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1503 result = AssignEnvironment(result); | 1503 result = AssignEnvironment(result); |
| 1504 } | 1504 } |
| 1505 return result; | 1505 return result; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1518 } else if (instr->representation().IsDouble()) { | 1518 } else if (instr->representation().IsDouble()) { |
| 1519 return DoArithmeticD(Token::MOD, instr); | 1519 return DoArithmeticD(Token::MOD, instr); |
| 1520 } else { | 1520 } else { |
| 1521 return DoArithmeticT(Token::MOD, instr); | 1521 return DoArithmeticT(Token::MOD, instr); |
| 1522 } | 1522 } |
| 1523 } | 1523 } |
| 1524 | 1524 |
| 1525 | 1525 |
| 1526 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1526 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1527 if (instr->representation().IsSmiOrInteger32()) { | 1527 if (instr->representation().IsSmiOrInteger32()) { |
| 1528 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1528 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1529 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1529 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1530 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1530 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1531 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1531 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
| 1532 LOperand* temp = NULL; | 1532 LOperand* temp = NULL; |
| 1533 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1533 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1534 temp = TempRegister(); | 1534 temp = TempRegister(); |
| 1535 } | 1535 } |
| 1536 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1536 LMulI* mul = new(zone()) LMulI(left, right, temp); |
| 1537 if (instr->CheckFlag(HValue::kCanOverflow) || | 1537 if (instr->CheckFlag(HValue::kCanOverflow) || |
| 1538 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1538 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1539 AssignEnvironment(mul); | 1539 AssignEnvironment(mul); |
| 1540 } | 1540 } |
| 1541 return DefineSameAsFirst(mul); | 1541 return DefineSameAsFirst(mul); |
| 1542 } else if (instr->representation().IsDouble()) { | 1542 } else if (instr->representation().IsDouble()) { |
| 1543 return DoArithmeticD(Token::MUL, instr); | 1543 return DoArithmeticD(Token::MUL, instr); |
| 1544 } else { | 1544 } else { |
| 1545 return DoArithmeticT(Token::MUL, instr); | 1545 return DoArithmeticT(Token::MUL, instr); |
| 1546 } | 1546 } |
| 1547 } | 1547 } |
| 1548 | 1548 |
| 1549 | 1549 |
| 1550 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1550 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1551 if (instr->representation().IsSmiOrInteger32()) { | 1551 if (instr->representation().IsSmiOrInteger32()) { |
| 1552 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1552 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1553 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1553 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1554 LOperand* left = UseRegisterAtStart(instr->left()); | 1554 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1555 LOperand* right = UseOrConstantAtStart(instr->right()); | 1555 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1556 LSubI* sub = new(zone()) LSubI(left, right); | 1556 LSubI* sub = new(zone()) LSubI(left, right); |
| 1557 LInstruction* result = DefineSameAsFirst(sub); | 1557 LInstruction* result = DefineSameAsFirst(sub); |
| 1558 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1558 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1559 result = AssignEnvironment(result); | 1559 result = AssignEnvironment(result); |
| 1560 } | 1560 } |
| 1561 return result; | 1561 return result; |
| 1562 } else if (instr->representation().IsDouble()) { | 1562 } else if (instr->representation().IsDouble()) { |
| 1563 return DoArithmeticD(Token::SUB, instr); | 1563 return DoArithmeticD(Token::SUB, instr); |
| 1564 } else { | 1564 } else { |
| 1565 return DoArithmeticT(Token::SUB, instr); | 1565 return DoArithmeticT(Token::SUB, instr); |
| 1566 } | 1566 } |
| 1567 } | 1567 } |
| 1568 | 1568 |
| 1569 | 1569 |
| 1570 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1570 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 1571 if (instr->representation().IsSmiOrInteger32()) { | 1571 if (instr->representation().IsSmiOrInteger32()) { |
| 1572 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1572 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1573 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1573 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1574 // Check to see if it would be advantageous to use an lea instruction rather | 1574 // Check to see if it would be advantageous to use an lea instruction rather |
| 1575 // than an add. This is the case when no overflow check is needed and there | 1575 // than an add. This is the case when no overflow check is needed and there |
| 1576 // are multiple uses of the add's inputs, so using a 3-register add will | 1576 // are multiple uses of the add's inputs, so using a 3-register add will |
| 1577 // preserve all input values for later uses. | 1577 // preserve all input values for later uses. |
| 1578 bool use_lea = LAddI::UseLea(instr); | 1578 bool use_lea = LAddI::UseLea(instr); |
| 1579 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1579 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1580 HValue* right_candidate = instr->BetterRightOperand(); | 1580 HValue* right_candidate = instr->BetterRightOperand(); |
| 1581 LOperand* right = use_lea | 1581 LOperand* right = use_lea |
| 1582 ? UseRegisterOrConstantAtStart(right_candidate) | 1582 ? UseRegisterOrConstantAtStart(right_candidate) |
| 1583 : UseOrConstantAtStart(right_candidate); | 1583 : UseOrConstantAtStart(right_candidate); |
| 1584 LAddI* add = new(zone()) LAddI(left, right); | 1584 LAddI* add = new(zone()) LAddI(left, right); |
| 1585 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1585 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1586 LInstruction* result = use_lea | 1586 LInstruction* result = use_lea |
| 1587 ? DefineAsRegister(add) | 1587 ? DefineAsRegister(add) |
| 1588 : DefineSameAsFirst(add); | 1588 : DefineSameAsFirst(add); |
| 1589 if (can_overflow) { | 1589 if (can_overflow) { |
| 1590 result = AssignEnvironment(result); | 1590 result = AssignEnvironment(result); |
| 1591 } | 1591 } |
| 1592 return result; | 1592 return result; |
| 1593 } else if (instr->representation().IsDouble()) { | 1593 } else if (instr->representation().IsDouble()) { |
| 1594 return DoArithmeticD(Token::ADD, instr); | 1594 return DoArithmeticD(Token::ADD, instr); |
| 1595 } else if (instr->representation().IsExternal()) { | 1595 } else if (instr->representation().IsExternal()) { |
| 1596 ASSERT(instr->left()->representation().IsExternal()); | 1596 DCHECK(instr->left()->representation().IsExternal()); |
| 1597 ASSERT(instr->right()->representation().IsInteger32()); | 1597 DCHECK(instr->right()->representation().IsInteger32()); |
| 1598 ASSERT(!instr->CheckFlag(HValue::kCanOverflow)); | 1598 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); |
| 1599 bool use_lea = LAddI::UseLea(instr); | 1599 bool use_lea = LAddI::UseLea(instr); |
| 1600 LOperand* left = UseRegisterAtStart(instr->left()); | 1600 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1601 HValue* right_candidate = instr->right(); | 1601 HValue* right_candidate = instr->right(); |
| 1602 LOperand* right = use_lea | 1602 LOperand* right = use_lea |
| 1603 ? UseRegisterOrConstantAtStart(right_candidate) | 1603 ? UseRegisterOrConstantAtStart(right_candidate) |
| 1604 : UseOrConstantAtStart(right_candidate); | 1604 : UseOrConstantAtStart(right_candidate); |
| 1605 LAddI* add = new(zone()) LAddI(left, right); | 1605 LAddI* add = new(zone()) LAddI(left, right); |
| 1606 LInstruction* result = use_lea | 1606 LInstruction* result = use_lea |
| 1607 ? DefineAsRegister(add) | 1607 ? DefineAsRegister(add) |
| 1608 : DefineSameAsFirst(add); | 1608 : DefineSameAsFirst(add); |
| 1609 return result; | 1609 return result; |
| 1610 } else { | 1610 } else { |
| 1611 return DoArithmeticT(Token::ADD, instr); | 1611 return DoArithmeticT(Token::ADD, instr); |
| 1612 } | 1612 } |
| 1613 } | 1613 } |
| 1614 | 1614 |
| 1615 | 1615 |
| 1616 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1616 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1617 LOperand* left = NULL; | 1617 LOperand* left = NULL; |
| 1618 LOperand* right = NULL; | 1618 LOperand* right = NULL; |
| 1619 if (instr->representation().IsSmiOrInteger32()) { | 1619 if (instr->representation().IsSmiOrInteger32()) { |
| 1620 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1620 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1621 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1621 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1622 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1622 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1623 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1623 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1624 } else { | 1624 } else { |
| 1625 ASSERT(instr->representation().IsDouble()); | 1625 DCHECK(instr->representation().IsDouble()); |
| 1626 ASSERT(instr->left()->representation().IsDouble()); | 1626 DCHECK(instr->left()->representation().IsDouble()); |
| 1627 ASSERT(instr->right()->representation().IsDouble()); | 1627 DCHECK(instr->right()->representation().IsDouble()); |
| 1628 left = UseRegisterAtStart(instr->left()); | 1628 left = UseRegisterAtStart(instr->left()); |
| 1629 right = UseRegisterAtStart(instr->right()); | 1629 right = UseRegisterAtStart(instr->right()); |
| 1630 } | 1630 } |
| 1631 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); | 1631 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); |
| 1632 return DefineSameAsFirst(minmax); | 1632 return DefineSameAsFirst(minmax); |
| 1633 } | 1633 } |
| 1634 | 1634 |
| 1635 | 1635 |
| 1636 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1636 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1637 ASSERT(instr->representation().IsDouble()); | 1637 DCHECK(instr->representation().IsDouble()); |
| 1638 // We call a C function for double power. It can't trigger a GC. | 1638 // We call a C function for double power. It can't trigger a GC. |
| 1639 // We need to use fixed result register for the call. | 1639 // We need to use fixed result register for the call. |
| 1640 Representation exponent_type = instr->right()->representation(); | 1640 Representation exponent_type = instr->right()->representation(); |
| 1641 ASSERT(instr->left()->representation().IsDouble()); | 1641 DCHECK(instr->left()->representation().IsDouble()); |
| 1642 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1642 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1643 LOperand* right = exponent_type.IsDouble() ? | 1643 LOperand* right = exponent_type.IsDouble() ? |
| 1644 UseFixedDouble(instr->right(), xmm1) : | 1644 UseFixedDouble(instr->right(), xmm1) : |
| 1645 UseFixed(instr->right(), eax); | 1645 UseFixed(instr->right(), eax); |
| 1646 LPower* result = new(zone()) LPower(left, right); | 1646 LPower* result = new(zone()) LPower(left, right); |
| 1647 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, | 1647 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, |
| 1648 CAN_DEOPTIMIZE_EAGERLY); | 1648 CAN_DEOPTIMIZE_EAGERLY); |
| 1649 } | 1649 } |
| 1650 | 1650 |
| 1651 | 1651 |
| 1652 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1652 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1653 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 1653 DCHECK(instr->left()->representation().IsSmiOrTagged()); |
| 1654 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 1654 DCHECK(instr->right()->representation().IsSmiOrTagged()); |
| 1655 LOperand* context = UseFixed(instr->context(), esi); | 1655 LOperand* context = UseFixed(instr->context(), esi); |
| 1656 LOperand* left = UseFixed(instr->left(), edx); | 1656 LOperand* left = UseFixed(instr->left(), edx); |
| 1657 LOperand* right = UseFixed(instr->right(), eax); | 1657 LOperand* right = UseFixed(instr->right(), eax); |
| 1658 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1658 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1659 return MarkAsCall(DefineFixed(result, eax), instr); | 1659 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1660 } | 1660 } |
| 1661 | 1661 |
| 1662 | 1662 |
| 1663 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1663 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1664 HCompareNumericAndBranch* instr) { | 1664 HCompareNumericAndBranch* instr) { |
| 1665 Representation r = instr->representation(); | 1665 Representation r = instr->representation(); |
| 1666 if (r.IsSmiOrInteger32()) { | 1666 if (r.IsSmiOrInteger32()) { |
| 1667 ASSERT(instr->left()->representation().Equals(r)); | 1667 DCHECK(instr->left()->representation().Equals(r)); |
| 1668 ASSERT(instr->right()->representation().Equals(r)); | 1668 DCHECK(instr->right()->representation().Equals(r)); |
| 1669 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1669 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1670 LOperand* right = UseOrConstantAtStart(instr->right()); | 1670 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1671 return new(zone()) LCompareNumericAndBranch(left, right); | 1671 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1672 } else { | 1672 } else { |
| 1673 ASSERT(r.IsDouble()); | 1673 DCHECK(r.IsDouble()); |
| 1674 ASSERT(instr->left()->representation().IsDouble()); | 1674 DCHECK(instr->left()->representation().IsDouble()); |
| 1675 ASSERT(instr->right()->representation().IsDouble()); | 1675 DCHECK(instr->right()->representation().IsDouble()); |
| 1676 LOperand* left; | 1676 LOperand* left; |
| 1677 LOperand* right; | 1677 LOperand* right; |
| 1678 if (CanBeImmediateConstant(instr->left()) && | 1678 if (CanBeImmediateConstant(instr->left()) && |
| 1679 CanBeImmediateConstant(instr->right())) { | 1679 CanBeImmediateConstant(instr->right())) { |
| 1680 // The code generator requires either both inputs to be constant | 1680 // The code generator requires either both inputs to be constant |
| 1681 // operands, or neither. | 1681 // operands, or neither. |
| 1682 left = UseConstant(instr->left()); | 1682 left = UseConstant(instr->left()); |
| 1683 right = UseConstant(instr->right()); | 1683 right = UseConstant(instr->right()); |
| 1684 } else { | 1684 } else { |
| 1685 left = UseRegisterAtStart(instr->left()); | 1685 left = UseRegisterAtStart(instr->left()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1707 | 1707 |
| 1708 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1708 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1709 HCompareMinusZeroAndBranch* instr) { | 1709 HCompareMinusZeroAndBranch* instr) { |
| 1710 LOperand* value = UseRegister(instr->value()); | 1710 LOperand* value = UseRegister(instr->value()); |
| 1711 LOperand* scratch = TempRegister(); | 1711 LOperand* scratch = TempRegister(); |
| 1712 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1712 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
| 1713 } | 1713 } |
| 1714 | 1714 |
| 1715 | 1715 |
| 1716 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1716 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1717 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 1717 DCHECK(instr->value()->representation().IsSmiOrTagged()); |
| 1718 LOperand* temp = TempRegister(); | 1718 LOperand* temp = TempRegister(); |
| 1719 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); | 1719 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); |
| 1720 } | 1720 } |
| 1721 | 1721 |
| 1722 | 1722 |
| 1723 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1723 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
| 1724 ASSERT(instr->value()->representation().IsTagged()); | 1724 DCHECK(instr->value()->representation().IsTagged()); |
| 1725 LOperand* temp = TempRegister(); | 1725 LOperand* temp = TempRegister(); |
| 1726 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp); | 1726 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp); |
| 1727 } | 1727 } |
| 1728 | 1728 |
| 1729 | 1729 |
| 1730 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { | 1730 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
| 1731 ASSERT(instr->value()->representation().IsTagged()); | 1731 DCHECK(instr->value()->representation().IsTagged()); |
| 1732 return new(zone()) LIsSmiAndBranch(Use(instr->value())); | 1732 return new(zone()) LIsSmiAndBranch(Use(instr->value())); |
| 1733 } | 1733 } |
| 1734 | 1734 |
| 1735 | 1735 |
| 1736 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( | 1736 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
| 1737 HIsUndetectableAndBranch* instr) { | 1737 HIsUndetectableAndBranch* instr) { |
| 1738 ASSERT(instr->value()->representation().IsTagged()); | 1738 DCHECK(instr->value()->representation().IsTagged()); |
| 1739 return new(zone()) LIsUndetectableAndBranch( | 1739 return new(zone()) LIsUndetectableAndBranch( |
| 1740 UseRegisterAtStart(instr->value()), TempRegister()); | 1740 UseRegisterAtStart(instr->value()), TempRegister()); |
| 1741 } | 1741 } |
| 1742 | 1742 |
| 1743 | 1743 |
| 1744 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1744 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 1745 HStringCompareAndBranch* instr) { | 1745 HStringCompareAndBranch* instr) { |
| 1746 ASSERT(instr->left()->representation().IsTagged()); | 1746 DCHECK(instr->left()->representation().IsTagged()); |
| 1747 ASSERT(instr->right()->representation().IsTagged()); | 1747 DCHECK(instr->right()->representation().IsTagged()); |
| 1748 LOperand* context = UseFixed(instr->context(), esi); | 1748 LOperand* context = UseFixed(instr->context(), esi); |
| 1749 LOperand* left = UseFixed(instr->left(), edx); | 1749 LOperand* left = UseFixed(instr->left(), edx); |
| 1750 LOperand* right = UseFixed(instr->right(), eax); | 1750 LOperand* right = UseFixed(instr->right(), eax); |
| 1751 | 1751 |
| 1752 LStringCompareAndBranch* result = new(zone()) | 1752 LStringCompareAndBranch* result = new(zone()) |
| 1753 LStringCompareAndBranch(context, left, right); | 1753 LStringCompareAndBranch(context, left, right); |
| 1754 | 1754 |
| 1755 return MarkAsCall(result, instr); | 1755 return MarkAsCall(result, instr); |
| 1756 } | 1756 } |
| 1757 | 1757 |
| 1758 | 1758 |
| 1759 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1759 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1760 HHasInstanceTypeAndBranch* instr) { | 1760 HHasInstanceTypeAndBranch* instr) { |
| 1761 ASSERT(instr->value()->representation().IsTagged()); | 1761 DCHECK(instr->value()->representation().IsTagged()); |
| 1762 return new(zone()) LHasInstanceTypeAndBranch( | 1762 return new(zone()) LHasInstanceTypeAndBranch( |
| 1763 UseRegisterAtStart(instr->value()), | 1763 UseRegisterAtStart(instr->value()), |
| 1764 TempRegister()); | 1764 TempRegister()); |
| 1765 } | 1765 } |
| 1766 | 1766 |
| 1767 | 1767 |
| 1768 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1768 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1769 HGetCachedArrayIndex* instr) { | 1769 HGetCachedArrayIndex* instr) { |
| 1770 ASSERT(instr->value()->representation().IsTagged()); | 1770 DCHECK(instr->value()->representation().IsTagged()); |
| 1771 LOperand* value = UseRegisterAtStart(instr->value()); | 1771 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1772 | 1772 |
| 1773 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); | 1773 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); |
| 1774 } | 1774 } |
| 1775 | 1775 |
| 1776 | 1776 |
| 1777 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( | 1777 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
| 1778 HHasCachedArrayIndexAndBranch* instr) { | 1778 HHasCachedArrayIndexAndBranch* instr) { |
| 1779 ASSERT(instr->value()->representation().IsTagged()); | 1779 DCHECK(instr->value()->representation().IsTagged()); |
| 1780 return new(zone()) LHasCachedArrayIndexAndBranch( | 1780 return new(zone()) LHasCachedArrayIndexAndBranch( |
| 1781 UseRegisterAtStart(instr->value())); | 1781 UseRegisterAtStart(instr->value())); |
| 1782 } | 1782 } |
| 1783 | 1783 |
| 1784 | 1784 |
| 1785 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1785 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1786 HClassOfTestAndBranch* instr) { | 1786 HClassOfTestAndBranch* instr) { |
| 1787 ASSERT(instr->value()->representation().IsTagged()); | 1787 DCHECK(instr->value()->representation().IsTagged()); |
| 1788 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), | 1788 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), |
| 1789 TempRegister(), | 1789 TempRegister(), |
| 1790 TempRegister()); | 1790 TempRegister()); |
| 1791 } | 1791 } |
| 1792 | 1792 |
| 1793 | 1793 |
| 1794 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1794 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1795 LOperand* map = UseRegisterAtStart(instr->value()); | 1795 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1796 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1796 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1797 } | 1797 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); | 1905 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); |
| 1906 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1906 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1907 return result; | 1907 return result; |
| 1908 } else if (to.IsSmi()) { | 1908 } else if (to.IsSmi()) { |
| 1909 LOperand* value = UseRegister(val); | 1909 LOperand* value = UseRegister(val); |
| 1910 if (val->type().IsSmi()) { | 1910 if (val->type().IsSmi()) { |
| 1911 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1911 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
| 1912 } | 1912 } |
| 1913 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1913 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1914 } else { | 1914 } else { |
| 1915 ASSERT(to.IsInteger32()); | 1915 DCHECK(to.IsInteger32()); |
| 1916 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1916 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1917 LOperand* value = UseRegister(val); | 1917 LOperand* value = UseRegister(val); |
| 1918 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1918 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
| 1919 } else { | 1919 } else { |
| 1920 LOperand* value = UseRegister(val); | 1920 LOperand* value = UseRegister(val); |
| 1921 bool truncating = instr->CanTruncateToInt32(); | 1921 bool truncating = instr->CanTruncateToInt32(); |
| 1922 LOperand* xmm_temp = !truncating ? FixedTemp(xmm1) : NULL; | 1922 LOperand* xmm_temp = !truncating ? FixedTemp(xmm1) : NULL; |
| 1923 LInstruction* result = | 1923 LInstruction* result = |
| 1924 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); | 1924 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); |
| 1925 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1925 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1926 return result; | 1926 return result; |
| 1927 } | 1927 } |
| 1928 } | 1928 } |
| 1929 } else if (from.IsDouble()) { | 1929 } else if (from.IsDouble()) { |
| 1930 if (to.IsTagged()) { | 1930 if (to.IsTagged()) { |
| 1931 info()->MarkAsDeferredCalling(); | 1931 info()->MarkAsDeferredCalling(); |
| 1932 LOperand* value = UseRegisterAtStart(val); | 1932 LOperand* value = UseRegisterAtStart(val); |
| 1933 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; | 1933 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; |
| 1934 LUnallocated* result_temp = TempRegister(); | 1934 LUnallocated* result_temp = TempRegister(); |
| 1935 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1935 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
| 1936 return AssignPointerMap(Define(result, result_temp)); | 1936 return AssignPointerMap(Define(result, result_temp)); |
| 1937 } else if (to.IsSmi()) { | 1937 } else if (to.IsSmi()) { |
| 1938 LOperand* value = UseRegister(val); | 1938 LOperand* value = UseRegister(val); |
| 1939 return AssignEnvironment( | 1939 return AssignEnvironment( |
| 1940 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1940 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
| 1941 } else { | 1941 } else { |
| 1942 ASSERT(to.IsInteger32()); | 1942 DCHECK(to.IsInteger32()); |
| 1943 bool truncating = instr->CanTruncateToInt32(); | 1943 bool truncating = instr->CanTruncateToInt32(); |
| 1944 bool needs_temp = !truncating; | 1944 bool needs_temp = !truncating; |
| 1945 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); | 1945 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); |
| 1946 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1946 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1947 LInstruction* result = | 1947 LInstruction* result = |
| 1948 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); | 1948 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); |
| 1949 if (!truncating) result = AssignEnvironment(result); | 1949 if (!truncating) result = AssignEnvironment(result); |
| 1950 return result; | 1950 return result; |
| 1951 } | 1951 } |
| 1952 } else if (from.IsInteger32()) { | 1952 } else if (from.IsInteger32()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1965 return AssignPointerMap(DefineSameAsFirst(result)); | 1965 return AssignPointerMap(DefineSameAsFirst(result)); |
| 1966 } | 1966 } |
| 1967 } else if (to.IsSmi()) { | 1967 } else if (to.IsSmi()) { |
| 1968 LOperand* value = UseRegister(val); | 1968 LOperand* value = UseRegister(val); |
| 1969 LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value)); | 1969 LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value)); |
| 1970 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1970 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1971 result = AssignEnvironment(result); | 1971 result = AssignEnvironment(result); |
| 1972 } | 1972 } |
| 1973 return result; | 1973 return result; |
| 1974 } else { | 1974 } else { |
| 1975 ASSERT(to.IsDouble()); | 1975 DCHECK(to.IsDouble()); |
| 1976 if (val->CheckFlag(HInstruction::kUint32)) { | 1976 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1977 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); | 1977 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); |
| 1978 } else { | 1978 } else { |
| 1979 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); | 1979 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); |
| 1980 } | 1980 } |
| 1981 } | 1981 } |
| 1982 } | 1982 } |
| 1983 UNREACHABLE(); | 1983 UNREACHABLE(); |
| 1984 return NULL; | 1984 return NULL; |
| 1985 } | 1985 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 2035 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| 2036 HValue* value = instr->value(); | 2036 HValue* value = instr->value(); |
| 2037 Representation input_rep = value->representation(); | 2037 Representation input_rep = value->representation(); |
| 2038 if (input_rep.IsDouble()) { | 2038 if (input_rep.IsDouble()) { |
| 2039 LOperand* reg = UseRegister(value); | 2039 LOperand* reg = UseRegister(value); |
| 2040 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); | 2040 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); |
| 2041 } else if (input_rep.IsInteger32()) { | 2041 } else if (input_rep.IsInteger32()) { |
| 2042 LOperand* reg = UseFixed(value, eax); | 2042 LOperand* reg = UseFixed(value, eax); |
| 2043 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); | 2043 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); |
| 2044 } else { | 2044 } else { |
| 2045 ASSERT(input_rep.IsSmiOrTagged()); | 2045 DCHECK(input_rep.IsSmiOrTagged()); |
| 2046 LOperand* reg = UseFixed(value, eax); | 2046 LOperand* reg = UseFixed(value, eax); |
| 2047 // Register allocator doesn't (yet) support allocation of double | 2047 // Register allocator doesn't (yet) support allocation of double |
| 2048 // temps. Reserve xmm1 explicitly. | 2048 // temps. Reserve xmm1 explicitly. |
| 2049 LOperand* temp = FixedTemp(xmm1); | 2049 LOperand* temp = FixedTemp(xmm1); |
| 2050 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); | 2050 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); |
| 2051 return AssignEnvironment(DefineFixed(result, eax)); | 2051 return AssignEnvironment(DefineFixed(result, eax)); |
| 2052 } | 2052 } |
| 2053 } | 2053 } |
| 2054 | 2054 |
| 2055 | 2055 |
| 2056 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2056 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 2057 HValue* value = instr->value(); | 2057 HValue* value = instr->value(); |
| 2058 ASSERT(value->representation().IsDouble()); | 2058 DCHECK(value->representation().IsDouble()); |
| 2059 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2059 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 2060 } | 2060 } |
| 2061 | 2061 |
| 2062 | 2062 |
| 2063 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { | 2063 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
| 2064 LOperand* lo = UseRegister(instr->lo()); | 2064 LOperand* lo = UseRegister(instr->lo()); |
| 2065 LOperand* hi = UseRegister(instr->hi()); | 2065 LOperand* hi = UseRegister(instr->hi()); |
| 2066 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); | 2066 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); |
| 2067 } | 2067 } |
| 2068 | 2068 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2186 TempRegister()))); | 2186 TempRegister()))); |
| 2187 } | 2187 } |
| 2188 | 2188 |
| 2189 | 2189 |
| 2190 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 2190 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
| 2191 return DefineAsRegister(new(zone()) LLoadRoot); | 2191 return DefineAsRegister(new(zone()) LLoadRoot); |
| 2192 } | 2192 } |
| 2193 | 2193 |
| 2194 | 2194 |
| 2195 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2195 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2196 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 2196 DCHECK(instr->key()->representation().IsSmiOrInteger32()); |
| 2197 ElementsKind elements_kind = instr->elements_kind(); | 2197 ElementsKind elements_kind = instr->elements_kind(); |
| 2198 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2198 bool clobbers_key = ExternalArrayOpRequiresTemp( |
| 2199 instr->key()->representation(), elements_kind); | 2199 instr->key()->representation(), elements_kind); |
| 2200 LOperand* key = clobbers_key | 2200 LOperand* key = clobbers_key |
| 2201 ? UseTempRegister(instr->key()) | 2201 ? UseTempRegister(instr->key()) |
| 2202 : UseRegisterOrConstantAtStart(instr->key()); | 2202 : UseRegisterOrConstantAtStart(instr->key()); |
| 2203 LInstruction* result = NULL; | 2203 LInstruction* result = NULL; |
| 2204 | 2204 |
| 2205 if (!instr->is_typed_elements()) { | 2205 if (!instr->is_typed_elements()) { |
| 2206 LOperand* obj = UseRegisterAtStart(instr->elements()); | 2206 LOperand* obj = UseRegisterAtStart(instr->elements()); |
| 2207 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); | 2207 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); |
| 2208 } else { | 2208 } else { |
| 2209 ASSERT( | 2209 DCHECK( |
| 2210 (instr->representation().IsInteger32() && | 2210 (instr->representation().IsInteger32() && |
| 2211 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || | 2211 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || |
| 2212 (instr->representation().IsDouble() && | 2212 (instr->representation().IsDouble() && |
| 2213 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); | 2213 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); |
| 2214 LOperand* backing_store = UseRegister(instr->elements()); | 2214 LOperand* backing_store = UseRegister(instr->elements()); |
| 2215 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); | 2215 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); |
| 2216 } | 2216 } |
| 2217 | 2217 |
| 2218 if ((instr->is_external() || instr->is_fixed_typed_array()) ? | 2218 if ((instr->is_external() || instr->is_fixed_typed_array()) ? |
| 2219 // see LCodeGen::DoLoadKeyedExternalArray | 2219 // see LCodeGen::DoLoadKeyedExternalArray |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2257 if (val_is_fixed_register) { | 2257 if (val_is_fixed_register) { |
| 2258 return UseFixed(instr->value(), eax); | 2258 return UseFixed(instr->value(), eax); |
| 2259 } | 2259 } |
| 2260 | 2260 |
| 2261 return UseRegister(instr->value()); | 2261 return UseRegister(instr->value()); |
| 2262 } | 2262 } |
| 2263 | 2263 |
| 2264 | 2264 |
| 2265 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2265 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2266 if (!instr->is_typed_elements()) { | 2266 if (!instr->is_typed_elements()) { |
| 2267 ASSERT(instr->elements()->representation().IsTagged()); | 2267 DCHECK(instr->elements()->representation().IsTagged()); |
| 2268 ASSERT(instr->key()->representation().IsInteger32() || | 2268 DCHECK(instr->key()->representation().IsInteger32() || |
| 2269 instr->key()->representation().IsSmi()); | 2269 instr->key()->representation().IsSmi()); |
| 2270 | 2270 |
| 2271 if (instr->value()->representation().IsDouble()) { | 2271 if (instr->value()->representation().IsDouble()) { |
| 2272 LOperand* object = UseRegisterAtStart(instr->elements()); | 2272 LOperand* object = UseRegisterAtStart(instr->elements()); |
| 2273 LOperand* val = NULL; | 2273 LOperand* val = NULL; |
| 2274 val = UseRegisterAtStart(instr->value()); | 2274 val = UseRegisterAtStart(instr->value()); |
| 2275 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2275 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2276 return new(zone()) LStoreKeyed(object, key, val); | 2276 return new(zone()) LStoreKeyed(object, key, val); |
| 2277 } else { | 2277 } else { |
| 2278 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 2278 DCHECK(instr->value()->representation().IsSmiOrTagged()); |
| 2279 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2279 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2280 | 2280 |
| 2281 LOperand* obj = UseRegister(instr->elements()); | 2281 LOperand* obj = UseRegister(instr->elements()); |
| 2282 LOperand* val; | 2282 LOperand* val; |
| 2283 LOperand* key; | 2283 LOperand* key; |
| 2284 if (needs_write_barrier) { | 2284 if (needs_write_barrier) { |
| 2285 val = UseTempRegister(instr->value()); | 2285 val = UseTempRegister(instr->value()); |
| 2286 key = UseTempRegister(instr->key()); | 2286 key = UseTempRegister(instr->key()); |
| 2287 } else { | 2287 } else { |
| 2288 val = UseRegisterOrConstantAtStart(instr->value()); | 2288 val = UseRegisterOrConstantAtStart(instr->value()); |
| 2289 key = UseRegisterOrConstantAtStart(instr->key()); | 2289 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2290 } | 2290 } |
| 2291 return new(zone()) LStoreKeyed(obj, key, val); | 2291 return new(zone()) LStoreKeyed(obj, key, val); |
| 2292 } | 2292 } |
| 2293 } | 2293 } |
| 2294 | 2294 |
| 2295 ElementsKind elements_kind = instr->elements_kind(); | 2295 ElementsKind elements_kind = instr->elements_kind(); |
| 2296 ASSERT( | 2296 DCHECK( |
| 2297 (instr->value()->representation().IsInteger32() && | 2297 (instr->value()->representation().IsInteger32() && |
| 2298 !IsDoubleOrFloatElementsKind(elements_kind)) || | 2298 !IsDoubleOrFloatElementsKind(elements_kind)) || |
| 2299 (instr->value()->representation().IsDouble() && | 2299 (instr->value()->representation().IsDouble() && |
| 2300 IsDoubleOrFloatElementsKind(elements_kind))); | 2300 IsDoubleOrFloatElementsKind(elements_kind))); |
| 2301 ASSERT((instr->is_fixed_typed_array() && | 2301 DCHECK((instr->is_fixed_typed_array() && |
| 2302 instr->elements()->representation().IsTagged()) || | 2302 instr->elements()->representation().IsTagged()) || |
| 2303 (instr->is_external() && | 2303 (instr->is_external() && |
| 2304 instr->elements()->representation().IsExternal())); | 2304 instr->elements()->representation().IsExternal())); |
| 2305 | 2305 |
| 2306 LOperand* backing_store = UseRegister(instr->elements()); | 2306 LOperand* backing_store = UseRegister(instr->elements()); |
| 2307 LOperand* val = GetStoreKeyedValueOperand(instr); | 2307 LOperand* val = GetStoreKeyedValueOperand(instr); |
| 2308 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2308 bool clobbers_key = ExternalArrayOpRequiresTemp( |
| 2309 instr->key()->representation(), elements_kind); | 2309 instr->key()->representation(), elements_kind); |
| 2310 LOperand* key = clobbers_key | 2310 LOperand* key = clobbers_key |
| 2311 ? UseTempRegister(instr->key()) | 2311 ? UseTempRegister(instr->key()) |
| 2312 : UseRegisterOrConstantAtStart(instr->key()); | 2312 : UseRegisterOrConstantAtStart(instr->key()); |
| 2313 return new(zone()) LStoreKeyed(backing_store, key, val); | 2313 return new(zone()) LStoreKeyed(backing_store, key, val); |
| 2314 } | 2314 } |
| 2315 | 2315 |
| 2316 | 2316 |
| 2317 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2317 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2318 LOperand* context = UseFixed(instr->context(), esi); | 2318 LOperand* context = UseFixed(instr->context(), esi); |
| 2319 LOperand* object = UseFixed(instr->object(), | 2319 LOperand* object = UseFixed(instr->object(), |
| 2320 KeyedStoreIC::ReceiverRegister()); | 2320 KeyedStoreIC::ReceiverRegister()); |
| 2321 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); | 2321 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); |
| 2322 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); | 2322 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); |
| 2323 | 2323 |
| 2324 ASSERT(instr->object()->representation().IsTagged()); | 2324 DCHECK(instr->object()->representation().IsTagged()); |
| 2325 ASSERT(instr->key()->representation().IsTagged()); | 2325 DCHECK(instr->key()->representation().IsTagged()); |
| 2326 ASSERT(instr->value()->representation().IsTagged()); | 2326 DCHECK(instr->value()->representation().IsTagged()); |
| 2327 | 2327 |
| 2328 LStoreKeyedGeneric* result = | 2328 LStoreKeyedGeneric* result = |
| 2329 new(zone()) LStoreKeyedGeneric(context, object, key, value); | 2329 new(zone()) LStoreKeyedGeneric(context, object, key, value); |
| 2330 return MarkAsCall(result, instr); | 2330 return MarkAsCall(result, instr); |
| 2331 } | 2331 } |
| 2332 | 2332 |
| 2333 | 2333 |
| 2334 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2334 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2335 HTransitionElementsKind* instr) { | 2335 HTransitionElementsKind* instr) { |
| 2336 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2336 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2368 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2369 bool needs_write_barrier_for_map = instr->has_transition() && | 2369 bool needs_write_barrier_for_map = instr->has_transition() && |
| 2370 instr->NeedsWriteBarrierForMap(); | 2370 instr->NeedsWriteBarrierForMap(); |
| 2371 | 2371 |
| 2372 LOperand* obj; | 2372 LOperand* obj; |
| 2373 if (needs_write_barrier) { | 2373 if (needs_write_barrier) { |
| 2374 obj = is_in_object | 2374 obj = is_in_object |
| 2375 ? UseRegister(instr->object()) | 2375 ? UseRegister(instr->object()) |
| 2376 : UseTempRegister(instr->object()); | 2376 : UseTempRegister(instr->object()); |
| 2377 } else if (is_external_location) { | 2377 } else if (is_external_location) { |
| 2378 ASSERT(!is_in_object); | 2378 DCHECK(!is_in_object); |
| 2379 ASSERT(!needs_write_barrier); | 2379 DCHECK(!needs_write_barrier); |
| 2380 ASSERT(!needs_write_barrier_for_map); | 2380 DCHECK(!needs_write_barrier_for_map); |
| 2381 obj = UseRegisterOrConstant(instr->object()); | 2381 obj = UseRegisterOrConstant(instr->object()); |
| 2382 } else { | 2382 } else { |
| 2383 obj = needs_write_barrier_for_map | 2383 obj = needs_write_barrier_for_map |
| 2384 ? UseRegister(instr->object()) | 2384 ? UseRegister(instr->object()) |
| 2385 : UseRegisterAtStart(instr->object()); | 2385 : UseRegisterAtStart(instr->object()); |
| 2386 } | 2386 } |
| 2387 | 2387 |
| 2388 bool can_be_constant = instr->value()->IsConstant() && | 2388 bool can_be_constant = instr->value()->IsConstant() && |
| 2389 HConstant::cast(instr->value())->NotInNewSpace() && | 2389 HConstant::cast(instr->value())->NotInNewSpace() && |
| 2390 !instr->field_representation().IsDouble(); | 2390 !instr->field_representation().IsDouble(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 | 2478 |
| 2479 | 2479 |
| 2480 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2480 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2481 LOperand* context = UseFixed(instr->context(), esi); | 2481 LOperand* context = UseFixed(instr->context(), esi); |
| 2482 return MarkAsCall( | 2482 return MarkAsCall( |
| 2483 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr); | 2483 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr); |
| 2484 } | 2484 } |
| 2485 | 2485 |
| 2486 | 2486 |
| 2487 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2487 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2488 ASSERT(argument_count_ == 0); | 2488 DCHECK(argument_count_ == 0); |
| 2489 allocator_->MarkAsOsrEntry(); | 2489 allocator_->MarkAsOsrEntry(); |
| 2490 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2490 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2491 return AssignEnvironment(new(zone()) LOsrEntry); | 2491 return AssignEnvironment(new(zone()) LOsrEntry); |
| 2492 } | 2492 } |
| 2493 | 2493 |
| 2494 | 2494 |
| 2495 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2495 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 2496 LParameter* result = new(zone()) LParameter; | 2496 LParameter* result = new(zone()) LParameter; |
| 2497 if (instr->kind() == HParameter::STACK_PARAMETER) { | 2497 if (instr->kind() == HParameter::STACK_PARAMETER) { |
| 2498 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2498 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 2499 return DefineAsSpilled(result, spill_index); | 2499 return DefineAsSpilled(result, spill_index); |
| 2500 } else { | 2500 } else { |
| 2501 ASSERT(info()->IsStub()); | 2501 DCHECK(info()->IsStub()); |
| 2502 CodeStubInterfaceDescriptor* descriptor = | 2502 CodeStubInterfaceDescriptor* descriptor = |
| 2503 info()->code_stub()->GetInterfaceDescriptor(); | 2503 info()->code_stub()->GetInterfaceDescriptor(); |
| 2504 int index = static_cast<int>(instr->index()); | 2504 int index = static_cast<int>(instr->index()); |
| 2505 Register reg = descriptor->GetEnvironmentParameterRegister(index); | 2505 Register reg = descriptor->GetEnvironmentParameterRegister(index); |
| 2506 return DefineFixed(result, reg); | 2506 return DefineFixed(result, reg); |
| 2507 } | 2507 } |
| 2508 } | 2508 } |
| 2509 | 2509 |
| 2510 | 2510 |
| 2511 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2511 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 return NULL; | 2602 return NULL; |
| 2603 } | 2603 } |
| 2604 | 2604 |
| 2605 | 2605 |
| 2606 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2606 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2607 info()->MarkAsDeferredCalling(); | 2607 info()->MarkAsDeferredCalling(); |
| 2608 if (instr->is_function_entry()) { | 2608 if (instr->is_function_entry()) { |
| 2609 LOperand* context = UseFixed(instr->context(), esi); | 2609 LOperand* context = UseFixed(instr->context(), esi); |
| 2610 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2610 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2611 } else { | 2611 } else { |
| 2612 ASSERT(instr->is_backwards_branch()); | 2612 DCHECK(instr->is_backwards_branch()); |
| 2613 LOperand* context = UseAny(instr->context()); | 2613 LOperand* context = UseAny(instr->context()); |
| 2614 return AssignEnvironment( | 2614 return AssignEnvironment( |
| 2615 AssignPointerMap(new(zone()) LStackCheck(context))); | 2615 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2616 } | 2616 } |
| 2617 } | 2617 } |
| 2618 | 2618 |
| 2619 | 2619 |
| 2620 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2620 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2621 HEnvironment* outer = current_block_->last_environment(); | 2621 HEnvironment* outer = current_block_->last_environment(); |
| 2622 outer->set_ast_id(instr->ReturnId()); | 2622 outer->set_ast_id(instr->ReturnId()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2638 | 2638 |
| 2639 | 2639 |
| 2640 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2640 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2641 LInstruction* pop = NULL; | 2641 LInstruction* pop = NULL; |
| 2642 | 2642 |
| 2643 HEnvironment* env = current_block_->last_environment(); | 2643 HEnvironment* env = current_block_->last_environment(); |
| 2644 | 2644 |
| 2645 if (env->entry()->arguments_pushed()) { | 2645 if (env->entry()->arguments_pushed()) { |
| 2646 int argument_count = env->arguments_environment()->parameter_count(); | 2646 int argument_count = env->arguments_environment()->parameter_count(); |
| 2647 pop = new(zone()) LDrop(argument_count); | 2647 pop = new(zone()) LDrop(argument_count); |
| 2648 ASSERT(instr->argument_delta() == -argument_count); | 2648 DCHECK(instr->argument_delta() == -argument_count); |
| 2649 } | 2649 } |
| 2650 | 2650 |
| 2651 HEnvironment* outer = current_block_->last_environment()-> | 2651 HEnvironment* outer = current_block_->last_environment()-> |
| 2652 DiscardInlined(false); | 2652 DiscardInlined(false); |
| 2653 current_block_->UpdateEnvironment(outer); | 2653 current_block_->UpdateEnvironment(outer); |
| 2654 return pop; | 2654 return pop; |
| 2655 } | 2655 } |
| 2656 | 2656 |
| 2657 | 2657 |
| 2658 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { | 2658 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2698 LOperand* function = UseRegisterAtStart(instr->function()); | 2698 LOperand* function = UseRegisterAtStart(instr->function()); |
| 2699 LAllocateBlockContext* result = | 2699 LAllocateBlockContext* result = |
| 2700 new(zone()) LAllocateBlockContext(context, function); | 2700 new(zone()) LAllocateBlockContext(context, function); |
| 2701 return MarkAsCall(DefineFixed(result, esi), instr); | 2701 return MarkAsCall(DefineFixed(result, esi), instr); |
| 2702 } | 2702 } |
| 2703 | 2703 |
| 2704 | 2704 |
| 2705 } } // namespace v8::internal | 2705 } } // namespace v8::internal |
| 2706 | 2706 |
| 2707 #endif // V8_TARGET_ARCH_IA32 | 2707 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |