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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/hydrogen-osr.h" | 9 #include "src/hydrogen-osr.h" |
10 #include "src/lithium-inl.h" | 10 #include "src/lithium-inl.h" |
11 #include "src/x64/lithium-codegen-x64.h" | 11 #include "src/x64/lithium-codegen-x64.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 void LInstruction::PrintTo(StringStream* stream) { | 46 void LInstruction::PrintTo(StringStream* stream) { |
47 stream->Add("%s ", this->Mnemonic()); | 47 stream->Add("%s ", this->Mnemonic()); |
48 | 48 |
49 PrintOutputOperandTo(stream); | 49 PrintOutputOperandTo(stream); |
50 | 50 |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 345 |
346 | 346 |
347 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { | 347 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
348 // All stack slots are Double stack slots on x64. | 348 // All stack slots are Double stack slots on x64. |
349 // Alternatively, at some point, start using half-size | 349 // Alternatively, at some point, start using half-size |
350 // stack slots for int32 values. | 350 // stack slots for int32 values. |
351 int index = GetNextSpillIndex(kind); | 351 int index = GetNextSpillIndex(kind); |
352 if (kind == DOUBLE_REGISTERS) { | 352 if (kind == DOUBLE_REGISTERS) { |
353 return LDoubleStackSlot::Create(index, zone()); | 353 return LDoubleStackSlot::Create(index, zone()); |
354 } else { | 354 } else { |
355 ASSERT(kind == GENERAL_REGISTERS); | 355 DCHECK(kind == GENERAL_REGISTERS); |
356 return LStackSlot::Create(index, zone()); | 356 return LStackSlot::Create(index, zone()); |
357 } | 357 } |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 void LStoreNamedField::PrintDataTo(StringStream* stream) { | 361 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
362 object()->PrintTo(stream); | 362 object()->PrintTo(stream); |
363 OStringStream os; | 363 OStringStream os; |
364 os << hydrogen()->access() << " <- "; | 364 os << hydrogen()->access() << " <- "; |
365 stream->Add(os.c_str()); | 365 stream->Add(os.c_str()); |
(...skipping 26 matching lines...) Expand all Loading... |
392 elements()->PrintTo(stream); | 392 elements()->PrintTo(stream); |
393 stream->Add("["); | 393 stream->Add("["); |
394 key()->PrintTo(stream); | 394 key()->PrintTo(stream); |
395 if (hydrogen()->IsDehoisted()) { | 395 if (hydrogen()->IsDehoisted()) { |
396 stream->Add(" + %d] <-", base_offset()); | 396 stream->Add(" + %d] <-", base_offset()); |
397 } else { | 397 } else { |
398 stream->Add("] <- "); | 398 stream->Add("] <- "); |
399 } | 399 } |
400 | 400 |
401 if (value() == NULL) { | 401 if (value() == NULL) { |
402 ASSERT(hydrogen()->IsConstantHoleStore() && | 402 DCHECK(hydrogen()->IsConstantHoleStore() && |
403 hydrogen()->value()->representation().IsDouble()); | 403 hydrogen()->value()->representation().IsDouble()); |
404 stream->Add("<the hole(nan)>"); | 404 stream->Add("<the hole(nan)>"); |
405 } else { | 405 } else { |
406 value()->PrintTo(stream); | 406 value()->PrintTo(stream); |
407 } | 407 } |
408 } | 408 } |
409 | 409 |
410 | 410 |
411 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { | 411 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
412 object()->PrintTo(stream); | 412 object()->PrintTo(stream); |
413 stream->Add("["); | 413 stream->Add("["); |
414 key()->PrintTo(stream); | 414 key()->PrintTo(stream); |
415 stream->Add("] <- "); | 415 stream->Add("] <- "); |
416 value()->PrintTo(stream); | 416 value()->PrintTo(stream); |
417 } | 417 } |
418 | 418 |
419 | 419 |
420 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { | 420 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { |
421 object()->PrintTo(stream); | 421 object()->PrintTo(stream); |
422 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); | 422 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); |
423 } | 423 } |
424 | 424 |
425 | 425 |
426 LPlatformChunk* LChunkBuilder::Build() { | 426 LPlatformChunk* LChunkBuilder::Build() { |
427 ASSERT(is_unused()); | 427 DCHECK(is_unused()); |
428 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 428 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
429 LPhase phase("L_Building chunk", chunk_); | 429 LPhase phase("L_Building chunk", chunk_); |
430 status_ = BUILDING; | 430 status_ = BUILDING; |
431 | 431 |
432 // If compiling for OSR, reserve space for the unoptimized frame, | 432 // If compiling for OSR, reserve space for the unoptimized frame, |
433 // which will be subsumed into this frame. | 433 // which will be subsumed into this frame. |
434 if (graph()->has_osr()) { | 434 if (graph()->has_osr()) { |
435 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 435 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
436 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); | 436 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
437 } | 437 } |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 instr = AssignEnvironment(instr); | 638 instr = AssignEnvironment(instr); |
639 // We can't really figure out if the environment is needed or not. | 639 // We can't really figure out if the environment is needed or not. |
640 instr->environment()->set_has_been_used(); | 640 instr->environment()->set_has_been_used(); |
641 } | 641 } |
642 | 642 |
643 return instr; | 643 return instr; |
644 } | 644 } |
645 | 645 |
646 | 646 |
647 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 647 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
648 ASSERT(!instr->HasPointerMap()); | 648 DCHECK(!instr->HasPointerMap()); |
649 instr->set_pointer_map(new(zone()) LPointerMap(zone())); | 649 instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
650 return instr; | 650 return instr; |
651 } | 651 } |
652 | 652 |
653 | 653 |
654 LUnallocated* LChunkBuilder::TempRegister() { | 654 LUnallocated* LChunkBuilder::TempRegister() { |
655 LUnallocated* operand = | 655 LUnallocated* operand = |
656 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 656 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
657 int vreg = allocator_->GetVirtualRegister(); | 657 int vreg = allocator_->GetVirtualRegister(); |
658 if (!allocator_->AllocationOk()) { | 658 if (!allocator_->AllocationOk()) { |
659 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 659 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
660 vreg = 0; | 660 vreg = 0; |
661 } | 661 } |
662 operand->set_virtual_register(vreg); | 662 operand->set_virtual_register(vreg); |
663 return operand; | 663 return operand; |
664 } | 664 } |
665 | 665 |
666 | 666 |
667 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 667 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
668 LUnallocated* operand = ToUnallocated(reg); | 668 LUnallocated* operand = ToUnallocated(reg); |
669 ASSERT(operand->HasFixedPolicy()); | 669 DCHECK(operand->HasFixedPolicy()); |
670 return operand; | 670 return operand; |
671 } | 671 } |
672 | 672 |
673 | 673 |
674 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) { | 674 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) { |
675 LUnallocated* operand = ToUnallocated(reg); | 675 LUnallocated* operand = ToUnallocated(reg); |
676 ASSERT(operand->HasFixedPolicy()); | 676 DCHECK(operand->HasFixedPolicy()); |
677 return operand; | 677 return operand; |
678 } | 678 } |
679 | 679 |
680 | 680 |
681 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { | 681 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { |
682 return new(zone()) LLabel(instr->block()); | 682 return new(zone()) LLabel(instr->block()); |
683 } | 683 } |
684 | 684 |
685 | 685 |
686 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 686 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
687 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 687 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
688 } | 688 } |
689 | 689 |
690 | 690 |
691 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { | 691 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { |
692 UNREACHABLE(); | 692 UNREACHABLE(); |
693 return NULL; | 693 return NULL; |
694 } | 694 } |
695 | 695 |
696 | 696 |
697 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 697 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
698 return AssignEnvironment(new(zone()) LDeoptimize); | 698 return AssignEnvironment(new(zone()) LDeoptimize); |
699 } | 699 } |
700 | 700 |
701 | 701 |
702 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 702 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
703 HBitwiseBinaryOperation* instr) { | 703 HBitwiseBinaryOperation* instr) { |
704 if (instr->representation().IsSmiOrInteger32()) { | 704 if (instr->representation().IsSmiOrInteger32()) { |
705 ASSERT(instr->left()->representation().Equals(instr->representation())); | 705 DCHECK(instr->left()->representation().Equals(instr->representation())); |
706 ASSERT(instr->right()->representation().Equals(instr->representation())); | 706 DCHECK(instr->right()->representation().Equals(instr->representation())); |
707 LOperand* left = UseRegisterAtStart(instr->left()); | 707 LOperand* left = UseRegisterAtStart(instr->left()); |
708 | 708 |
709 HValue* right_value = instr->right(); | 709 HValue* right_value = instr->right(); |
710 LOperand* right = NULL; | 710 LOperand* right = NULL; |
711 int constant_value = 0; | 711 int constant_value = 0; |
712 bool does_deopt = false; | 712 bool does_deopt = false; |
713 if (right_value->IsConstant()) { | 713 if (right_value->IsConstant()) { |
714 HConstant* constant = HConstant::cast(right_value); | 714 HConstant* constant = HConstant::cast(right_value); |
715 right = chunk_->DefineConstantOperand(constant); | 715 right = chunk_->DefineConstantOperand(constant); |
716 constant_value = constant->Integer32Value() & 0x1f; | 716 constant_value = constant->Integer32Value() & 0x1f; |
(...skipping 21 matching lines...) Expand all Loading... |
738 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); | 738 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); |
739 return does_deopt ? AssignEnvironment(result) : result; | 739 return does_deopt ? AssignEnvironment(result) : result; |
740 } else { | 740 } else { |
741 return DoArithmeticT(op, instr); | 741 return DoArithmeticT(op, instr); |
742 } | 742 } |
743 } | 743 } |
744 | 744 |
745 | 745 |
746 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 746 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
747 HArithmeticBinaryOperation* instr) { | 747 HArithmeticBinaryOperation* instr) { |
748 ASSERT(instr->representation().IsDouble()); | 748 DCHECK(instr->representation().IsDouble()); |
749 ASSERT(instr->left()->representation().IsDouble()); | 749 DCHECK(instr->left()->representation().IsDouble()); |
750 ASSERT(instr->right()->representation().IsDouble()); | 750 DCHECK(instr->right()->representation().IsDouble()); |
751 if (op == Token::MOD) { | 751 if (op == Token::MOD) { |
752 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 752 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
753 LOperand* right = UseFixedDouble(instr->BetterRightOperand(), xmm1); | 753 LOperand* right = UseFixedDouble(instr->BetterRightOperand(), xmm1); |
754 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 754 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
755 return MarkAsCall(DefineSameAsFirst(result), instr); | 755 return MarkAsCall(DefineSameAsFirst(result), instr); |
756 } else { | 756 } else { |
757 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 757 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
758 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); | 758 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand()); |
759 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 759 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
760 return DefineSameAsFirst(result); | 760 return DefineSameAsFirst(result); |
761 } | 761 } |
762 } | 762 } |
763 | 763 |
764 | 764 |
765 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 765 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
766 HBinaryOperation* instr) { | 766 HBinaryOperation* instr) { |
767 HValue* left = instr->left(); | 767 HValue* left = instr->left(); |
768 HValue* right = instr->right(); | 768 HValue* right = instr->right(); |
769 ASSERT(left->representation().IsTagged()); | 769 DCHECK(left->representation().IsTagged()); |
770 ASSERT(right->representation().IsTagged()); | 770 DCHECK(right->representation().IsTagged()); |
771 LOperand* context = UseFixed(instr->context(), rsi); | 771 LOperand* context = UseFixed(instr->context(), rsi); |
772 LOperand* left_operand = UseFixed(left, rdx); | 772 LOperand* left_operand = UseFixed(left, rdx); |
773 LOperand* right_operand = UseFixed(right, rax); | 773 LOperand* right_operand = UseFixed(right, rax); |
774 LArithmeticT* result = | 774 LArithmeticT* result = |
775 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 775 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
776 return MarkAsCall(DefineFixed(result, rax), instr); | 776 return MarkAsCall(DefineFixed(result, rax), instr); |
777 } | 777 } |
778 | 778 |
779 | 779 |
780 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 780 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
781 ASSERT(is_building()); | 781 DCHECK(is_building()); |
782 current_block_ = block; | 782 current_block_ = block; |
783 next_block_ = next_block; | 783 next_block_ = next_block; |
784 if (block->IsStartBlock()) { | 784 if (block->IsStartBlock()) { |
785 block->UpdateEnvironment(graph_->start_environment()); | 785 block->UpdateEnvironment(graph_->start_environment()); |
786 argument_count_ = 0; | 786 argument_count_ = 0; |
787 } else if (block->predecessors()->length() == 1) { | 787 } else if (block->predecessors()->length() == 1) { |
788 // We have a single predecessor => copy environment and outgoing | 788 // We have a single predecessor => copy environment and outgoing |
789 // argument count from the predecessor. | 789 // argument count from the predecessor. |
790 ASSERT(block->phis()->length() == 0); | 790 DCHECK(block->phis()->length() == 0); |
791 HBasicBlock* pred = block->predecessors()->at(0); | 791 HBasicBlock* pred = block->predecessors()->at(0); |
792 HEnvironment* last_environment = pred->last_environment(); | 792 HEnvironment* last_environment = pred->last_environment(); |
793 ASSERT(last_environment != NULL); | 793 DCHECK(last_environment != NULL); |
794 // Only copy the environment, if it is later used again. | 794 // Only copy the environment, if it is later used again. |
795 if (pred->end()->SecondSuccessor() == NULL) { | 795 if (pred->end()->SecondSuccessor() == NULL) { |
796 ASSERT(pred->end()->FirstSuccessor() == block); | 796 DCHECK(pred->end()->FirstSuccessor() == block); |
797 } else { | 797 } else { |
798 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || | 798 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
799 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { | 799 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
800 last_environment = last_environment->Copy(); | 800 last_environment = last_environment->Copy(); |
801 } | 801 } |
802 } | 802 } |
803 block->UpdateEnvironment(last_environment); | 803 block->UpdateEnvironment(last_environment); |
804 ASSERT(pred->argument_count() >= 0); | 804 DCHECK(pred->argument_count() >= 0); |
805 argument_count_ = pred->argument_count(); | 805 argument_count_ = pred->argument_count(); |
806 } else { | 806 } else { |
807 // We are at a state join => process phis. | 807 // We are at a state join => process phis. |
808 HBasicBlock* pred = block->predecessors()->at(0); | 808 HBasicBlock* pred = block->predecessors()->at(0); |
809 // No need to copy the environment, it cannot be used later. | 809 // No need to copy the environment, it cannot be used later. |
810 HEnvironment* last_environment = pred->last_environment(); | 810 HEnvironment* last_environment = pred->last_environment(); |
811 for (int i = 0; i < block->phis()->length(); ++i) { | 811 for (int i = 0; i < block->phis()->length(); ++i) { |
812 HPhi* phi = block->phis()->at(i); | 812 HPhi* phi = block->phis()->at(i); |
813 if (phi->HasMergedIndex()) { | 813 if (phi->HasMergedIndex()) { |
814 last_environment->SetValueAt(phi->merged_index(), phi); | 814 last_environment->SetValueAt(phi->merged_index(), phi); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 | 846 |
847 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 847 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
848 HInstruction* old_current = current_instruction_; | 848 HInstruction* old_current = current_instruction_; |
849 current_instruction_ = current; | 849 current_instruction_ = current; |
850 | 850 |
851 LInstruction* instr = NULL; | 851 LInstruction* instr = NULL; |
852 if (current->CanReplaceWithDummyUses()) { | 852 if (current->CanReplaceWithDummyUses()) { |
853 if (current->OperandCount() == 0) { | 853 if (current->OperandCount() == 0) { |
854 instr = DefineAsRegister(new(zone()) LDummy()); | 854 instr = DefineAsRegister(new(zone()) LDummy()); |
855 } else { | 855 } else { |
856 ASSERT(!current->OperandAt(0)->IsControlInstruction()); | 856 DCHECK(!current->OperandAt(0)->IsControlInstruction()); |
857 instr = DefineAsRegister(new(zone()) | 857 instr = DefineAsRegister(new(zone()) |
858 LDummyUse(UseAny(current->OperandAt(0)))); | 858 LDummyUse(UseAny(current->OperandAt(0)))); |
859 } | 859 } |
860 for (int i = 1; i < current->OperandCount(); ++i) { | 860 for (int i = 1; i < current->OperandCount(); ++i) { |
861 if (current->OperandAt(i)->IsControlInstruction()) continue; | 861 if (current->OperandAt(i)->IsControlInstruction()) continue; |
862 LInstruction* dummy = | 862 LInstruction* dummy = |
863 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 863 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
864 dummy->set_hydrogen_value(current); | 864 dummy->set_hydrogen_value(current); |
865 chunk_->AddInstruction(dummy, current_block_); | 865 chunk_->AddInstruction(dummy, current_block_); |
866 } | 866 } |
867 } else { | 867 } else { |
868 HBasicBlock* successor; | 868 HBasicBlock* successor; |
869 if (current->IsControlInstruction() && | 869 if (current->IsControlInstruction() && |
870 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && | 870 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
871 successor != NULL) { | 871 successor != NULL) { |
872 instr = new(zone()) LGoto(successor); | 872 instr = new(zone()) LGoto(successor); |
873 } else { | 873 } else { |
874 instr = current->CompileToLithium(this); | 874 instr = current->CompileToLithium(this); |
875 } | 875 } |
876 } | 876 } |
877 | 877 |
878 argument_count_ += current->argument_delta(); | 878 argument_count_ += current->argument_delta(); |
879 ASSERT(argument_count_ >= 0); | 879 DCHECK(argument_count_ >= 0); |
880 | 880 |
881 if (instr != NULL) { | 881 if (instr != NULL) { |
882 AddInstruction(instr, current); | 882 AddInstruction(instr, current); |
883 } | 883 } |
884 | 884 |
885 current_instruction_ = old_current; | 885 current_instruction_ = old_current; |
886 } | 886 } |
887 | 887 |
888 | 888 |
889 void LChunkBuilder::AddInstruction(LInstruction* instr, | 889 void LChunkBuilder::AddInstruction(LInstruction* instr, |
(...skipping 21 matching lines...) Expand all Loading... |
911 LUnallocated* operand = LUnallocated::cast(it.Current()); | 911 LUnallocated* operand = LUnallocated::cast(it.Current()); |
912 if (operand->IsUsedAtStart()) ++used_at_start; | 912 if (operand->IsUsedAtStart()) ++used_at_start; |
913 } | 913 } |
914 if (instr->Output() != NULL) { | 914 if (instr->Output() != NULL) { |
915 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 915 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
916 } | 916 } |
917 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 917 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
918 LUnallocated* operand = LUnallocated::cast(it.Current()); | 918 LUnallocated* operand = LUnallocated::cast(it.Current()); |
919 if (operand->HasFixedPolicy()) ++fixed; | 919 if (operand->HasFixedPolicy()) ++fixed; |
920 } | 920 } |
921 ASSERT(fixed == 0 || used_at_start == 0); | 921 DCHECK(fixed == 0 || used_at_start == 0); |
922 } | 922 } |
923 #endif | 923 #endif |
924 | 924 |
925 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 925 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
926 instr = AssignPointerMap(instr); | 926 instr = AssignPointerMap(instr); |
927 } | 927 } |
928 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 928 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
929 instr = AssignEnvironment(instr); | 929 instr = AssignEnvironment(instr); |
930 } | 930 } |
931 chunk_->AddInstruction(instr, current_block_); | 931 chunk_->AddInstruction(instr, current_block_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 if (!easy_case && | 975 if (!easy_case && |
976 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || | 976 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || |
977 !expected.IsGeneric())) { | 977 !expected.IsGeneric())) { |
978 branch = AssignEnvironment(branch); | 978 branch = AssignEnvironment(branch); |
979 } | 979 } |
980 return branch; | 980 return branch; |
981 } | 981 } |
982 | 982 |
983 | 983 |
984 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 984 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
985 ASSERT(instr->value()->representation().IsTagged()); | 985 DCHECK(instr->value()->representation().IsTagged()); |
986 LOperand* value = UseRegisterAtStart(instr->value()); | 986 LOperand* value = UseRegisterAtStart(instr->value()); |
987 return new(zone()) LCmpMapAndBranch(value); | 987 return new(zone()) LCmpMapAndBranch(value); |
988 } | 988 } |
989 | 989 |
990 | 990 |
991 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 991 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
992 info()->MarkAsRequiresFrame(); | 992 info()->MarkAsRequiresFrame(); |
993 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 993 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
994 } | 994 } |
995 | 995 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 LInstruction* result = | 1183 LInstruction* result = |
1184 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); | 1184 DefineSameAsFirst(new(zone()) LMathAbs(context, input)); |
1185 Representation r = instr->value()->representation(); | 1185 Representation r = instr->value()->representation(); |
1186 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); | 1186 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); |
1187 if (!r.IsDouble()) result = AssignEnvironment(result); | 1187 if (!r.IsDouble()) result = AssignEnvironment(result); |
1188 return result; | 1188 return result; |
1189 } | 1189 } |
1190 | 1190 |
1191 | 1191 |
1192 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1192 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
1193 ASSERT(instr->representation().IsDouble()); | 1193 DCHECK(instr->representation().IsDouble()); |
1194 ASSERT(instr->value()->representation().IsDouble()); | 1194 DCHECK(instr->value()->representation().IsDouble()); |
1195 LOperand* input = UseRegisterAtStart(instr->value()); | 1195 LOperand* input = UseRegisterAtStart(instr->value()); |
1196 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); | 1196 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); |
1197 } | 1197 } |
1198 | 1198 |
1199 | 1199 |
1200 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { | 1200 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
1201 LOperand* input = UseRegisterAtStart(instr->value()); | 1201 LOperand* input = UseRegisterAtStart(instr->value()); |
1202 LMathClz32* result = new(zone()) LMathClz32(input); | 1202 LMathClz32* result = new(zone()) LMathClz32(input); |
1203 return DefineAsRegister(result); | 1203 return DefineAsRegister(result); |
1204 } | 1204 } |
1205 | 1205 |
1206 | 1206 |
1207 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1207 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
1208 ASSERT(instr->representation().IsDouble()); | 1208 DCHECK(instr->representation().IsDouble()); |
1209 ASSERT(instr->value()->representation().IsDouble()); | 1209 DCHECK(instr->value()->representation().IsDouble()); |
1210 LOperand* value = UseTempRegister(instr->value()); | 1210 LOperand* value = UseTempRegister(instr->value()); |
1211 LOperand* temp1 = TempRegister(); | 1211 LOperand* temp1 = TempRegister(); |
1212 LOperand* temp2 = TempRegister(); | 1212 LOperand* temp2 = TempRegister(); |
1213 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); | 1213 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); |
1214 return DefineAsRegister(result); | 1214 return DefineAsRegister(result); |
1215 } | 1215 } |
1216 | 1216 |
1217 | 1217 |
1218 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1218 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
1219 LOperand* input = UseAtStart(instr->value()); | 1219 LOperand* input = UseAtStart(instr->value()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 } | 1274 } |
1275 | 1275 |
1276 | 1276 |
1277 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1277 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
1278 return DoShift(Token::SHL, instr); | 1278 return DoShift(Token::SHL, instr); |
1279 } | 1279 } |
1280 | 1280 |
1281 | 1281 |
1282 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1282 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
1283 if (instr->representation().IsSmiOrInteger32()) { | 1283 if (instr->representation().IsSmiOrInteger32()) { |
1284 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1284 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1285 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1285 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1286 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); | 1286 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); |
1287 | 1287 |
1288 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1288 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1289 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1289 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1290 return DefineSameAsFirst(new(zone()) LBitI(left, right)); | 1290 return DefineSameAsFirst(new(zone()) LBitI(left, right)); |
1291 } else { | 1291 } else { |
1292 return DoArithmeticT(instr->op(), instr); | 1292 return DoArithmeticT(instr->op(), instr); |
1293 } | 1293 } |
1294 } | 1294 } |
1295 | 1295 |
1296 | 1296 |
1297 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1297 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
1298 ASSERT(instr->representation().IsSmiOrInteger32()); | 1298 DCHECK(instr->representation().IsSmiOrInteger32()); |
1299 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1299 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1300 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1300 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1301 LOperand* dividend = UseRegister(instr->left()); | 1301 LOperand* dividend = UseRegister(instr->left()); |
1302 int32_t divisor = instr->right()->GetInteger32Constant(); | 1302 int32_t divisor = instr->right()->GetInteger32Constant(); |
1303 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( | 1303 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
1304 dividend, divisor)); | 1304 dividend, divisor)); |
1305 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1305 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
1306 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || | 1306 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
1307 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1307 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
1308 divisor != 1 && divisor != -1)) { | 1308 divisor != 1 && divisor != -1)) { |
1309 result = AssignEnvironment(result); | 1309 result = AssignEnvironment(result); |
1310 } | 1310 } |
1311 return result; | 1311 return result; |
1312 } | 1312 } |
1313 | 1313 |
1314 | 1314 |
1315 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { | 1315 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
1316 ASSERT(instr->representation().IsInteger32()); | 1316 DCHECK(instr->representation().IsInteger32()); |
1317 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1317 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1318 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1318 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1319 LOperand* dividend = UseRegister(instr->left()); | 1319 LOperand* dividend = UseRegister(instr->left()); |
1320 int32_t divisor = instr->right()->GetInteger32Constant(); | 1320 int32_t divisor = instr->right()->GetInteger32Constant(); |
1321 LOperand* temp1 = FixedTemp(rax); | 1321 LOperand* temp1 = FixedTemp(rax); |
1322 LOperand* temp2 = FixedTemp(rdx); | 1322 LOperand* temp2 = FixedTemp(rdx); |
1323 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( | 1323 LInstruction* result = DefineFixed(new(zone()) LDivByConstI( |
1324 dividend, divisor, temp1, temp2), rdx); | 1324 dividend, divisor, temp1, temp2), rdx); |
1325 if (divisor == 0 || | 1325 if (divisor == 0 || |
1326 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1326 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
1327 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1327 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
1328 result = AssignEnvironment(result); | 1328 result = AssignEnvironment(result); |
1329 } | 1329 } |
1330 return result; | 1330 return result; |
1331 } | 1331 } |
1332 | 1332 |
1333 | 1333 |
1334 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { | 1334 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { |
1335 ASSERT(instr->representation().IsSmiOrInteger32()); | 1335 DCHECK(instr->representation().IsSmiOrInteger32()); |
1336 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1336 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1337 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1337 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1338 LOperand* dividend = UseFixed(instr->left(), rax); | 1338 LOperand* dividend = UseFixed(instr->left(), rax); |
1339 LOperand* divisor = UseRegister(instr->right()); | 1339 LOperand* divisor = UseRegister(instr->right()); |
1340 LOperand* temp = FixedTemp(rdx); | 1340 LOperand* temp = FixedTemp(rdx); |
1341 LInstruction* result = DefineFixed(new(zone()) LDivI( | 1341 LInstruction* result = DefineFixed(new(zone()) LDivI( |
1342 dividend, divisor, temp), rax); | 1342 dividend, divisor, temp), rax); |
1343 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1343 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
1344 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1344 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1345 instr->CheckFlag(HValue::kCanOverflow) || | 1345 instr->CheckFlag(HValue::kCanOverflow) || |
1346 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1346 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
1347 result = AssignEnvironment(result); | 1347 result = AssignEnvironment(result); |
(...skipping 26 matching lines...) Expand all Loading... |
1374 dividend, divisor)); | 1374 dividend, divisor)); |
1375 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1375 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
1376 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { | 1376 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
1377 result = AssignEnvironment(result); | 1377 result = AssignEnvironment(result); |
1378 } | 1378 } |
1379 return result; | 1379 return result; |
1380 } | 1380 } |
1381 | 1381 |
1382 | 1382 |
1383 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { | 1383 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
1384 ASSERT(instr->representation().IsInteger32()); | 1384 DCHECK(instr->representation().IsInteger32()); |
1385 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1385 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1386 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1386 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1387 LOperand* dividend = UseRegister(instr->left()); | 1387 LOperand* dividend = UseRegister(instr->left()); |
1388 int32_t divisor = instr->right()->GetInteger32Constant(); | 1388 int32_t divisor = instr->right()->GetInteger32Constant(); |
1389 LOperand* temp1 = FixedTemp(rax); | 1389 LOperand* temp1 = FixedTemp(rax); |
1390 LOperand* temp2 = FixedTemp(rdx); | 1390 LOperand* temp2 = FixedTemp(rdx); |
1391 LOperand* temp3 = | 1391 LOperand* temp3 = |
1392 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || | 1392 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || |
1393 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? | 1393 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? |
1394 NULL : TempRegister(); | 1394 NULL : TempRegister(); |
1395 LInstruction* result = | 1395 LInstruction* result = |
1396 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, | 1396 DefineFixed(new(zone()) LFlooringDivByConstI(dividend, |
1397 divisor, | 1397 divisor, |
1398 temp1, | 1398 temp1, |
1399 temp2, | 1399 temp2, |
1400 temp3), | 1400 temp3), |
1401 rdx); | 1401 rdx); |
1402 if (divisor == 0 || | 1402 if (divisor == 0 || |
1403 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { | 1403 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { |
1404 result = AssignEnvironment(result); | 1404 result = AssignEnvironment(result); |
1405 } | 1405 } |
1406 return result; | 1406 return result; |
1407 } | 1407 } |
1408 | 1408 |
1409 | 1409 |
1410 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1410 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
1411 ASSERT(instr->representation().IsSmiOrInteger32()); | 1411 DCHECK(instr->representation().IsSmiOrInteger32()); |
1412 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1412 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1413 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1413 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1414 LOperand* dividend = UseFixed(instr->left(), rax); | 1414 LOperand* dividend = UseFixed(instr->left(), rax); |
1415 LOperand* divisor = UseRegister(instr->right()); | 1415 LOperand* divisor = UseRegister(instr->right()); |
1416 LOperand* temp = FixedTemp(rdx); | 1416 LOperand* temp = FixedTemp(rdx); |
1417 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( | 1417 LInstruction* result = DefineFixed(new(zone()) LFlooringDivI( |
1418 dividend, divisor, temp), rax); | 1418 dividend, divisor, temp), rax); |
1419 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1419 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
1420 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1420 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1421 instr->CheckFlag(HValue::kCanOverflow)) { | 1421 instr->CheckFlag(HValue::kCanOverflow)) { |
1422 result = AssignEnvironment(result); | 1422 result = AssignEnvironment(result); |
1423 } | 1423 } |
1424 return result; | 1424 return result; |
1425 } | 1425 } |
1426 | 1426 |
1427 | 1427 |
1428 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1428 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
1429 if (instr->RightIsPowerOf2()) { | 1429 if (instr->RightIsPowerOf2()) { |
1430 return DoFlooringDivByPowerOf2I(instr); | 1430 return DoFlooringDivByPowerOf2I(instr); |
1431 } else if (instr->right()->IsConstant()) { | 1431 } else if (instr->right()->IsConstant()) { |
1432 return DoFlooringDivByConstI(instr); | 1432 return DoFlooringDivByConstI(instr); |
1433 } else { | 1433 } else { |
1434 return DoFlooringDivI(instr); | 1434 return DoFlooringDivI(instr); |
1435 } | 1435 } |
1436 } | 1436 } |
1437 | 1437 |
1438 | 1438 |
1439 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1439 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
1440 ASSERT(instr->representation().IsSmiOrInteger32()); | 1440 DCHECK(instr->representation().IsSmiOrInteger32()); |
1441 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1441 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1442 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1442 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1443 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1443 LOperand* dividend = UseRegisterAtStart(instr->left()); |
1444 int32_t divisor = instr->right()->GetInteger32Constant(); | 1444 int32_t divisor = instr->right()->GetInteger32Constant(); |
1445 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( | 1445 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
1446 dividend, divisor)); | 1446 dividend, divisor)); |
1447 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && | 1447 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && |
1448 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1448 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1449 result = AssignEnvironment(result); | 1449 result = AssignEnvironment(result); |
1450 } | 1450 } |
1451 return result; | 1451 return result; |
1452 } | 1452 } |
1453 | 1453 |
1454 | 1454 |
1455 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { | 1455 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
1456 ASSERT(instr->representation().IsSmiOrInteger32()); | 1456 DCHECK(instr->representation().IsSmiOrInteger32()); |
1457 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1457 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1458 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1458 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1459 LOperand* dividend = UseRegister(instr->left()); | 1459 LOperand* dividend = UseRegister(instr->left()); |
1460 int32_t divisor = instr->right()->GetInteger32Constant(); | 1460 int32_t divisor = instr->right()->GetInteger32Constant(); |
1461 LOperand* temp1 = FixedTemp(rax); | 1461 LOperand* temp1 = FixedTemp(rax); |
1462 LOperand* temp2 = FixedTemp(rdx); | 1462 LOperand* temp2 = FixedTemp(rdx); |
1463 LInstruction* result = DefineFixed(new(zone()) LModByConstI( | 1463 LInstruction* result = DefineFixed(new(zone()) LModByConstI( |
1464 dividend, divisor, temp1, temp2), rax); | 1464 dividend, divisor, temp1, temp2), rax); |
1465 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1465 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1466 result = AssignEnvironment(result); | 1466 result = AssignEnvironment(result); |
1467 } | 1467 } |
1468 return result; | 1468 return result; |
1469 } | 1469 } |
1470 | 1470 |
1471 | 1471 |
1472 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1472 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
1473 ASSERT(instr->representation().IsSmiOrInteger32()); | 1473 DCHECK(instr->representation().IsSmiOrInteger32()); |
1474 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1474 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1475 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1475 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1476 LOperand* dividend = UseFixed(instr->left(), rax); | 1476 LOperand* dividend = UseFixed(instr->left(), rax); |
1477 LOperand* divisor = UseRegister(instr->right()); | 1477 LOperand* divisor = UseRegister(instr->right()); |
1478 LOperand* temp = FixedTemp(rdx); | 1478 LOperand* temp = FixedTemp(rdx); |
1479 LInstruction* result = DefineFixed(new(zone()) LModI( | 1479 LInstruction* result = DefineFixed(new(zone()) LModI( |
1480 dividend, divisor, temp), rdx); | 1480 dividend, divisor, temp), rdx); |
1481 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1481 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
1482 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1482 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1483 result = AssignEnvironment(result); | 1483 result = AssignEnvironment(result); |
1484 } | 1484 } |
1485 return result; | 1485 return result; |
(...skipping 12 matching lines...) Expand all Loading... |
1498 } else if (instr->representation().IsDouble()) { | 1498 } else if (instr->representation().IsDouble()) { |
1499 return DoArithmeticD(Token::MOD, instr); | 1499 return DoArithmeticD(Token::MOD, instr); |
1500 } else { | 1500 } else { |
1501 return DoArithmeticT(Token::MOD, instr); | 1501 return DoArithmeticT(Token::MOD, instr); |
1502 } | 1502 } |
1503 } | 1503 } |
1504 | 1504 |
1505 | 1505 |
1506 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1506 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1507 if (instr->representation().IsSmiOrInteger32()) { | 1507 if (instr->representation().IsSmiOrInteger32()) { |
1508 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1508 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1509 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1509 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1510 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1510 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1511 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1511 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
1512 LMulI* mul = new(zone()) LMulI(left, right); | 1512 LMulI* mul = new(zone()) LMulI(left, right); |
1513 if (instr->CheckFlag(HValue::kCanOverflow) || | 1513 if (instr->CheckFlag(HValue::kCanOverflow) || |
1514 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1514 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1515 AssignEnvironment(mul); | 1515 AssignEnvironment(mul); |
1516 } | 1516 } |
1517 return DefineSameAsFirst(mul); | 1517 return DefineSameAsFirst(mul); |
1518 } else if (instr->representation().IsDouble()) { | 1518 } else if (instr->representation().IsDouble()) { |
1519 return DoArithmeticD(Token::MUL, instr); | 1519 return DoArithmeticD(Token::MUL, instr); |
1520 } else { | 1520 } else { |
1521 return DoArithmeticT(Token::MUL, instr); | 1521 return DoArithmeticT(Token::MUL, instr); |
1522 } | 1522 } |
1523 } | 1523 } |
1524 | 1524 |
1525 | 1525 |
1526 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1526 LInstruction* LChunkBuilder::DoSub(HSub* 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->left()); | 1530 LOperand* left = UseRegisterAtStart(instr->left()); |
1531 LOperand* right = UseOrConstantAtStart(instr->right()); | 1531 LOperand* right = UseOrConstantAtStart(instr->right()); |
1532 LSubI* sub = new(zone()) LSubI(left, right); | 1532 LSubI* sub = new(zone()) LSubI(left, right); |
1533 LInstruction* result = DefineSameAsFirst(sub); | 1533 LInstruction* result = DefineSameAsFirst(sub); |
1534 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1534 if (instr->CheckFlag(HValue::kCanOverflow)) { |
1535 result = AssignEnvironment(result); | 1535 result = AssignEnvironment(result); |
1536 } | 1536 } |
1537 return result; | 1537 return result; |
1538 } else if (instr->representation().IsDouble()) { | 1538 } else if (instr->representation().IsDouble()) { |
1539 return DoArithmeticD(Token::SUB, instr); | 1539 return DoArithmeticD(Token::SUB, instr); |
1540 } else { | 1540 } else { |
1541 return DoArithmeticT(Token::SUB, instr); | 1541 return DoArithmeticT(Token::SUB, instr); |
1542 } | 1542 } |
1543 } | 1543 } |
1544 | 1544 |
1545 | 1545 |
1546 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1546 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
1547 if (instr->representation().IsSmiOrInteger32()) { | 1547 if (instr->representation().IsSmiOrInteger32()) { |
1548 // Check to see if it would be advantageous to use an lea instruction rather | 1548 // Check to see if it would be advantageous to use an lea instruction rather |
1549 // than an add. This is the case when no overflow check is needed and there | 1549 // than an add. This is the case when no overflow check is needed and there |
1550 // are multiple uses of the add's inputs, so using a 3-register add will | 1550 // are multiple uses of the add's inputs, so using a 3-register add will |
1551 // preserve all input values for later uses. | 1551 // preserve all input values for later uses. |
1552 bool use_lea = LAddI::UseLea(instr); | 1552 bool use_lea = LAddI::UseLea(instr); |
1553 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1553 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1554 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1554 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1555 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1555 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1556 HValue* right_candidate = instr->BetterRightOperand(); | 1556 HValue* right_candidate = instr->BetterRightOperand(); |
1557 LOperand* right; | 1557 LOperand* right; |
1558 if (SmiValuesAre32Bits() && instr->representation().IsSmi()) { | 1558 if (SmiValuesAre32Bits() && instr->representation().IsSmi()) { |
1559 // We cannot add a tagged immediate to a tagged value, | 1559 // We cannot add a tagged immediate to a tagged value, |
1560 // so we request it in a register. | 1560 // so we request it in a register. |
1561 right = UseRegisterAtStart(right_candidate); | 1561 right = UseRegisterAtStart(right_candidate); |
1562 } else { | 1562 } else { |
1563 right = use_lea ? UseRegisterOrConstantAtStart(right_candidate) | 1563 right = use_lea ? UseRegisterOrConstantAtStart(right_candidate) |
1564 : UseOrConstantAtStart(right_candidate); | 1564 : UseOrConstantAtStart(right_candidate); |
1565 } | 1565 } |
1566 LAddI* add = new(zone()) LAddI(left, right); | 1566 LAddI* add = new(zone()) LAddI(left, right); |
1567 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1567 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
1568 LInstruction* result = use_lea ? DefineAsRegister(add) | 1568 LInstruction* result = use_lea ? DefineAsRegister(add) |
1569 : DefineSameAsFirst(add); | 1569 : DefineSameAsFirst(add); |
1570 if (can_overflow) { | 1570 if (can_overflow) { |
1571 result = AssignEnvironment(result); | 1571 result = AssignEnvironment(result); |
1572 } | 1572 } |
1573 return result; | 1573 return result; |
1574 } else if (instr->representation().IsExternal()) { | 1574 } else if (instr->representation().IsExternal()) { |
1575 ASSERT(instr->left()->representation().IsExternal()); | 1575 DCHECK(instr->left()->representation().IsExternal()); |
1576 ASSERT(instr->right()->representation().IsInteger32()); | 1576 DCHECK(instr->right()->representation().IsInteger32()); |
1577 ASSERT(!instr->CheckFlag(HValue::kCanOverflow)); | 1577 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); |
1578 bool use_lea = LAddI::UseLea(instr); | 1578 bool use_lea = LAddI::UseLea(instr); |
1579 LOperand* left = UseRegisterAtStart(instr->left()); | 1579 LOperand* left = UseRegisterAtStart(instr->left()); |
1580 HValue* right_candidate = instr->right(); | 1580 HValue* right_candidate = instr->right(); |
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 LInstruction* result = use_lea | 1585 LInstruction* result = use_lea |
1586 ? DefineAsRegister(add) | 1586 ? DefineAsRegister(add) |
1587 : DefineSameAsFirst(add); | 1587 : DefineSameAsFirst(add); |
1588 return result; | 1588 return result; |
1589 } else if (instr->representation().IsDouble()) { | 1589 } else if (instr->representation().IsDouble()) { |
1590 return DoArithmeticD(Token::ADD, instr); | 1590 return DoArithmeticD(Token::ADD, instr); |
1591 } else { | 1591 } else { |
1592 return DoArithmeticT(Token::ADD, instr); | 1592 return DoArithmeticT(Token::ADD, instr); |
1593 } | 1593 } |
1594 return NULL; | 1594 return NULL; |
1595 } | 1595 } |
1596 | 1596 |
1597 | 1597 |
1598 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1598 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1599 LOperand* left = NULL; | 1599 LOperand* left = NULL; |
1600 LOperand* right = NULL; | 1600 LOperand* right = NULL; |
1601 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1601 DCHECK(instr->left()->representation().Equals(instr->representation())); |
1602 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1602 DCHECK(instr->right()->representation().Equals(instr->representation())); |
1603 if (instr->representation().IsSmi()) { | 1603 if (instr->representation().IsSmi()) { |
1604 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1604 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1605 right = UseAtStart(instr->BetterRightOperand()); | 1605 right = UseAtStart(instr->BetterRightOperand()); |
1606 } else if (instr->representation().IsInteger32()) { | 1606 } else if (instr->representation().IsInteger32()) { |
1607 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1607 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1608 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1608 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1609 } else { | 1609 } else { |
1610 ASSERT(instr->representation().IsDouble()); | 1610 DCHECK(instr->representation().IsDouble()); |
1611 left = UseRegisterAtStart(instr->left()); | 1611 left = UseRegisterAtStart(instr->left()); |
1612 right = UseRegisterAtStart(instr->right()); | 1612 right = UseRegisterAtStart(instr->right()); |
1613 } | 1613 } |
1614 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); | 1614 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); |
1615 return DefineSameAsFirst(minmax); | 1615 return DefineSameAsFirst(minmax); |
1616 } | 1616 } |
1617 | 1617 |
1618 | 1618 |
1619 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1619 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
1620 ASSERT(instr->representation().IsDouble()); | 1620 DCHECK(instr->representation().IsDouble()); |
1621 // We call a C function for double power. It can't trigger a GC. | 1621 // We call a C function for double power. It can't trigger a GC. |
1622 // We need to use fixed result register for the call. | 1622 // We need to use fixed result register for the call. |
1623 Representation exponent_type = instr->right()->representation(); | 1623 Representation exponent_type = instr->right()->representation(); |
1624 ASSERT(instr->left()->representation().IsDouble()); | 1624 DCHECK(instr->left()->representation().IsDouble()); |
1625 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1625 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
1626 LOperand* right = exponent_type.IsDouble() ? | 1626 LOperand* right = exponent_type.IsDouble() ? |
1627 UseFixedDouble(instr->right(), xmm1) : UseFixed(instr->right(), rdx); | 1627 UseFixedDouble(instr->right(), xmm1) : UseFixed(instr->right(), rdx); |
1628 LPower* result = new(zone()) LPower(left, right); | 1628 LPower* result = new(zone()) LPower(left, right); |
1629 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, | 1629 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, |
1630 CAN_DEOPTIMIZE_EAGERLY); | 1630 CAN_DEOPTIMIZE_EAGERLY); |
1631 } | 1631 } |
1632 | 1632 |
1633 | 1633 |
1634 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1634 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
1635 ASSERT(instr->left()->representation().IsTagged()); | 1635 DCHECK(instr->left()->representation().IsTagged()); |
1636 ASSERT(instr->right()->representation().IsTagged()); | 1636 DCHECK(instr->right()->representation().IsTagged()); |
1637 LOperand* context = UseFixed(instr->context(), rsi); | 1637 LOperand* context = UseFixed(instr->context(), rsi); |
1638 LOperand* left = UseFixed(instr->left(), rdx); | 1638 LOperand* left = UseFixed(instr->left(), rdx); |
1639 LOperand* right = UseFixed(instr->right(), rax); | 1639 LOperand* right = UseFixed(instr->right(), rax); |
1640 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1640 LCmpT* result = new(zone()) LCmpT(context, left, right); |
1641 return MarkAsCall(DefineFixed(result, rax), instr); | 1641 return MarkAsCall(DefineFixed(result, rax), instr); |
1642 } | 1642 } |
1643 | 1643 |
1644 | 1644 |
1645 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1645 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
1646 HCompareNumericAndBranch* instr) { | 1646 HCompareNumericAndBranch* instr) { |
1647 Representation r = instr->representation(); | 1647 Representation r = instr->representation(); |
1648 if (r.IsSmiOrInteger32()) { | 1648 if (r.IsSmiOrInteger32()) { |
1649 ASSERT(instr->left()->representation().Equals(r)); | 1649 DCHECK(instr->left()->representation().Equals(r)); |
1650 ASSERT(instr->right()->representation().Equals(r)); | 1650 DCHECK(instr->right()->representation().Equals(r)); |
1651 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1651 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
1652 LOperand* right = UseOrConstantAtStart(instr->right()); | 1652 LOperand* right = UseOrConstantAtStart(instr->right()); |
1653 return new(zone()) LCompareNumericAndBranch(left, right); | 1653 return new(zone()) LCompareNumericAndBranch(left, right); |
1654 } else { | 1654 } else { |
1655 ASSERT(r.IsDouble()); | 1655 DCHECK(r.IsDouble()); |
1656 ASSERT(instr->left()->representation().IsDouble()); | 1656 DCHECK(instr->left()->representation().IsDouble()); |
1657 ASSERT(instr->right()->representation().IsDouble()); | 1657 DCHECK(instr->right()->representation().IsDouble()); |
1658 LOperand* left; | 1658 LOperand* left; |
1659 LOperand* right; | 1659 LOperand* right; |
1660 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { | 1660 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { |
1661 left = UseRegisterOrConstantAtStart(instr->left()); | 1661 left = UseRegisterOrConstantAtStart(instr->left()); |
1662 right = UseRegisterOrConstantAtStart(instr->right()); | 1662 right = UseRegisterOrConstantAtStart(instr->right()); |
1663 } else { | 1663 } else { |
1664 left = UseRegisterAtStart(instr->left()); | 1664 left = UseRegisterAtStart(instr->left()); |
1665 right = UseRegisterAtStart(instr->right()); | 1665 right = UseRegisterAtStart(instr->right()); |
1666 } | 1666 } |
1667 return new(zone()) LCompareNumericAndBranch(left, right); | 1667 return new(zone()) LCompareNumericAndBranch(left, right); |
(...skipping 17 matching lines...) Expand all Loading... |
1685 | 1685 |
1686 | 1686 |
1687 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1687 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
1688 HCompareMinusZeroAndBranch* instr) { | 1688 HCompareMinusZeroAndBranch* instr) { |
1689 LOperand* value = UseRegister(instr->value()); | 1689 LOperand* value = UseRegister(instr->value()); |
1690 return new(zone()) LCompareMinusZeroAndBranch(value); | 1690 return new(zone()) LCompareMinusZeroAndBranch(value); |
1691 } | 1691 } |
1692 | 1692 |
1693 | 1693 |
1694 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1694 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
1695 ASSERT(instr->value()->representation().IsTagged()); | 1695 DCHECK(instr->value()->representation().IsTagged()); |
1696 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); | 1696 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); |
1697 } | 1697 } |
1698 | 1698 |
1699 | 1699 |
1700 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1700 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
1701 ASSERT(instr->value()->representation().IsTagged()); | 1701 DCHECK(instr->value()->representation().IsTagged()); |
1702 LOperand* value = UseRegisterAtStart(instr->value()); | 1702 LOperand* value = UseRegisterAtStart(instr->value()); |
1703 LOperand* temp = TempRegister(); | 1703 LOperand* temp = TempRegister(); |
1704 return new(zone()) LIsStringAndBranch(value, temp); | 1704 return new(zone()) LIsStringAndBranch(value, temp); |
1705 } | 1705 } |
1706 | 1706 |
1707 | 1707 |
1708 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { | 1708 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
1709 ASSERT(instr->value()->representation().IsTagged()); | 1709 DCHECK(instr->value()->representation().IsTagged()); |
1710 return new(zone()) LIsSmiAndBranch(Use(instr->value())); | 1710 return new(zone()) LIsSmiAndBranch(Use(instr->value())); |
1711 } | 1711 } |
1712 | 1712 |
1713 | 1713 |
1714 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( | 1714 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
1715 HIsUndetectableAndBranch* instr) { | 1715 HIsUndetectableAndBranch* instr) { |
1716 ASSERT(instr->value()->representation().IsTagged()); | 1716 DCHECK(instr->value()->representation().IsTagged()); |
1717 LOperand* value = UseRegisterAtStart(instr->value()); | 1717 LOperand* value = UseRegisterAtStart(instr->value()); |
1718 LOperand* temp = TempRegister(); | 1718 LOperand* temp = TempRegister(); |
1719 return new(zone()) LIsUndetectableAndBranch(value, temp); | 1719 return new(zone()) LIsUndetectableAndBranch(value, temp); |
1720 } | 1720 } |
1721 | 1721 |
1722 | 1722 |
1723 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1723 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
1724 HStringCompareAndBranch* instr) { | 1724 HStringCompareAndBranch* instr) { |
1725 | 1725 |
1726 ASSERT(instr->left()->representation().IsTagged()); | 1726 DCHECK(instr->left()->representation().IsTagged()); |
1727 ASSERT(instr->right()->representation().IsTagged()); | 1727 DCHECK(instr->right()->representation().IsTagged()); |
1728 LOperand* context = UseFixed(instr->context(), rsi); | 1728 LOperand* context = UseFixed(instr->context(), rsi); |
1729 LOperand* left = UseFixed(instr->left(), rdx); | 1729 LOperand* left = UseFixed(instr->left(), rdx); |
1730 LOperand* right = UseFixed(instr->right(), rax); | 1730 LOperand* right = UseFixed(instr->right(), rax); |
1731 LStringCompareAndBranch* result = | 1731 LStringCompareAndBranch* result = |
1732 new(zone()) LStringCompareAndBranch(context, left, right); | 1732 new(zone()) LStringCompareAndBranch(context, left, right); |
1733 | 1733 |
1734 return MarkAsCall(result, instr); | 1734 return MarkAsCall(result, instr); |
1735 } | 1735 } |
1736 | 1736 |
1737 | 1737 |
1738 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1738 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
1739 HHasInstanceTypeAndBranch* instr) { | 1739 HHasInstanceTypeAndBranch* instr) { |
1740 ASSERT(instr->value()->representation().IsTagged()); | 1740 DCHECK(instr->value()->representation().IsTagged()); |
1741 LOperand* value = UseRegisterAtStart(instr->value()); | 1741 LOperand* value = UseRegisterAtStart(instr->value()); |
1742 return new(zone()) LHasInstanceTypeAndBranch(value); | 1742 return new(zone()) LHasInstanceTypeAndBranch(value); |
1743 } | 1743 } |
1744 | 1744 |
1745 | 1745 |
1746 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1746 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
1747 HGetCachedArrayIndex* instr) { | 1747 HGetCachedArrayIndex* instr) { |
1748 ASSERT(instr->value()->representation().IsTagged()); | 1748 DCHECK(instr->value()->representation().IsTagged()); |
1749 LOperand* value = UseRegisterAtStart(instr->value()); | 1749 LOperand* value = UseRegisterAtStart(instr->value()); |
1750 | 1750 |
1751 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); | 1751 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); |
1752 } | 1752 } |
1753 | 1753 |
1754 | 1754 |
1755 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( | 1755 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
1756 HHasCachedArrayIndexAndBranch* instr) { | 1756 HHasCachedArrayIndexAndBranch* instr) { |
1757 ASSERT(instr->value()->representation().IsTagged()); | 1757 DCHECK(instr->value()->representation().IsTagged()); |
1758 LOperand* value = UseRegisterAtStart(instr->value()); | 1758 LOperand* value = UseRegisterAtStart(instr->value()); |
1759 return new(zone()) LHasCachedArrayIndexAndBranch(value); | 1759 return new(zone()) LHasCachedArrayIndexAndBranch(value); |
1760 } | 1760 } |
1761 | 1761 |
1762 | 1762 |
1763 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1763 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
1764 HClassOfTestAndBranch* instr) { | 1764 HClassOfTestAndBranch* instr) { |
1765 LOperand* value = UseRegister(instr->value()); | 1765 LOperand* value = UseRegister(instr->value()); |
1766 return new(zone()) LClassOfTestAndBranch(value, | 1766 return new(zone()) LClassOfTestAndBranch(value, |
1767 TempRegister(), | 1767 TempRegister(), |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); | 1865 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); |
1866 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1866 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
1867 return result; | 1867 return result; |
1868 } else if (to.IsSmi()) { | 1868 } else if (to.IsSmi()) { |
1869 LOperand* value = UseRegister(val); | 1869 LOperand* value = UseRegister(val); |
1870 if (val->type().IsSmi()) { | 1870 if (val->type().IsSmi()) { |
1871 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1871 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
1872 } | 1872 } |
1873 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1873 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
1874 } else { | 1874 } else { |
1875 ASSERT(to.IsInteger32()); | 1875 DCHECK(to.IsInteger32()); |
1876 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1876 if (val->type().IsSmi() || val->representation().IsSmi()) { |
1877 LOperand* value = UseRegister(val); | 1877 LOperand* value = UseRegister(val); |
1878 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1878 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
1879 } else { | 1879 } else { |
1880 LOperand* value = UseRegister(val); | 1880 LOperand* value = UseRegister(val); |
1881 bool truncating = instr->CanTruncateToInt32(); | 1881 bool truncating = instr->CanTruncateToInt32(); |
1882 LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1); | 1882 LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1); |
1883 LInstruction* result = | 1883 LInstruction* result = |
1884 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); | 1884 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); |
1885 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1885 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
1886 return result; | 1886 return result; |
1887 } | 1887 } |
1888 } | 1888 } |
1889 } else if (from.IsDouble()) { | 1889 } else if (from.IsDouble()) { |
1890 if (to.IsTagged()) { | 1890 if (to.IsTagged()) { |
1891 info()->MarkAsDeferredCalling(); | 1891 info()->MarkAsDeferredCalling(); |
1892 LOperand* value = UseRegister(val); | 1892 LOperand* value = UseRegister(val); |
1893 LOperand* temp = TempRegister(); | 1893 LOperand* temp = TempRegister(); |
1894 LUnallocated* result_temp = TempRegister(); | 1894 LUnallocated* result_temp = TempRegister(); |
1895 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1895 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
1896 return AssignPointerMap(Define(result, result_temp)); | 1896 return AssignPointerMap(Define(result, result_temp)); |
1897 } else if (to.IsSmi()) { | 1897 } else if (to.IsSmi()) { |
1898 LOperand* value = UseRegister(val); | 1898 LOperand* value = UseRegister(val); |
1899 return AssignEnvironment( | 1899 return AssignEnvironment( |
1900 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1900 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
1901 } else { | 1901 } else { |
1902 ASSERT(to.IsInteger32()); | 1902 DCHECK(to.IsInteger32()); |
1903 LOperand* value = UseRegister(val); | 1903 LOperand* value = UseRegister(val); |
1904 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); | 1904 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); |
1905 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); | 1905 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); |
1906 return result; | 1906 return result; |
1907 } | 1907 } |
1908 } else if (from.IsInteger32()) { | 1908 } else if (from.IsInteger32()) { |
1909 info()->MarkAsDeferredCalling(); | 1909 info()->MarkAsDeferredCalling(); |
1910 if (to.IsTagged()) { | 1910 if (to.IsTagged()) { |
1911 if (!instr->CheckFlag(HValue::kCanOverflow)) { | 1911 if (!instr->CheckFlag(HValue::kCanOverflow)) { |
1912 LOperand* value = UseRegister(val); | 1912 LOperand* value = UseRegister(val); |
(...skipping 12 matching lines...) Expand all Loading... |
1925 return AssignPointerMap(DefineSameAsFirst(result)); | 1925 return AssignPointerMap(DefineSameAsFirst(result)); |
1926 } | 1926 } |
1927 } else if (to.IsSmi()) { | 1927 } else if (to.IsSmi()) { |
1928 LOperand* value = UseRegister(val); | 1928 LOperand* value = UseRegister(val); |
1929 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); | 1929 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); |
1930 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1930 if (instr->CheckFlag(HValue::kCanOverflow)) { |
1931 result = AssignEnvironment(result); | 1931 result = AssignEnvironment(result); |
1932 } | 1932 } |
1933 return result; | 1933 return result; |
1934 } else { | 1934 } else { |
1935 ASSERT(to.IsDouble()); | 1935 DCHECK(to.IsDouble()); |
1936 if (val->CheckFlag(HInstruction::kUint32)) { | 1936 if (val->CheckFlag(HInstruction::kUint32)) { |
1937 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); | 1937 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); |
1938 } else { | 1938 } else { |
1939 LOperand* value = Use(val); | 1939 LOperand* value = Use(val); |
1940 return DefineAsRegister(new(zone()) LInteger32ToDouble(value)); | 1940 return DefineAsRegister(new(zone()) LInteger32ToDouble(value)); |
1941 } | 1941 } |
1942 } | 1942 } |
1943 } | 1943 } |
1944 UNREACHABLE(); | 1944 UNREACHABLE(); |
1945 return NULL; | 1945 return NULL; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 | 1989 |
1990 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 1990 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
1991 HValue* value = instr->value(); | 1991 HValue* value = instr->value(); |
1992 Representation input_rep = value->representation(); | 1992 Representation input_rep = value->representation(); |
1993 LOperand* reg = UseRegister(value); | 1993 LOperand* reg = UseRegister(value); |
1994 if (input_rep.IsDouble()) { | 1994 if (input_rep.IsDouble()) { |
1995 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); | 1995 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); |
1996 } else if (input_rep.IsInteger32()) { | 1996 } else if (input_rep.IsInteger32()) { |
1997 return DefineSameAsFirst(new(zone()) LClampIToUint8(reg)); | 1997 return DefineSameAsFirst(new(zone()) LClampIToUint8(reg)); |
1998 } else { | 1998 } else { |
1999 ASSERT(input_rep.IsSmiOrTagged()); | 1999 DCHECK(input_rep.IsSmiOrTagged()); |
2000 // Register allocator doesn't (yet) support allocation of double | 2000 // Register allocator doesn't (yet) support allocation of double |
2001 // temps. Reserve xmm1 explicitly. | 2001 // temps. Reserve xmm1 explicitly. |
2002 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, | 2002 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, |
2003 FixedTemp(xmm1)); | 2003 FixedTemp(xmm1)); |
2004 return AssignEnvironment(DefineSameAsFirst(result)); | 2004 return AssignEnvironment(DefineSameAsFirst(result)); |
2005 } | 2005 } |
2006 } | 2006 } |
2007 | 2007 |
2008 | 2008 |
2009 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2009 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
2010 HValue* value = instr->value(); | 2010 HValue* value = instr->value(); |
2011 ASSERT(value->representation().IsDouble()); | 2011 DCHECK(value->representation().IsDouble()); |
2012 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2012 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
2013 } | 2013 } |
2014 | 2014 |
2015 | 2015 |
2016 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { | 2016 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
2017 LOperand* lo = UseRegister(instr->lo()); | 2017 LOperand* lo = UseRegister(instr->lo()); |
2018 LOperand* hi = UseRegister(instr->hi()); | 2018 LOperand* hi = UseRegister(instr->hi()); |
2019 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); | 2019 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); |
2020 } | 2020 } |
2021 | 2021 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2152 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 2152 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
2153 return DefineAsRegister(new(zone()) LLoadRoot); | 2153 return DefineAsRegister(new(zone()) LLoadRoot); |
2154 } | 2154 } |
2155 | 2155 |
2156 | 2156 |
2157 void LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) { | 2157 void LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) { |
2158 // We sign extend the dehoisted key at the definition point when the pointer | 2158 // We sign extend the dehoisted key at the definition point when the pointer |
2159 // size is 64-bit. For x32 port, we sign extend the dehoisted key at the use | 2159 // size is 64-bit. For x32 port, we sign extend the dehoisted key at the use |
2160 // points and should not invoke this function. We can't use STATIC_ASSERT | 2160 // points and should not invoke this function. We can't use STATIC_ASSERT |
2161 // here as the pointer size is 32-bit for x32. | 2161 // here as the pointer size is 32-bit for x32. |
2162 ASSERT(kPointerSize == kInt64Size); | 2162 DCHECK(kPointerSize == kInt64Size); |
2163 BitVector* dehoisted_key_ids = chunk_->GetDehoistedKeyIds(); | 2163 BitVector* dehoisted_key_ids = chunk_->GetDehoistedKeyIds(); |
2164 if (dehoisted_key_ids->Contains(candidate->id())) return; | 2164 if (dehoisted_key_ids->Contains(candidate->id())) return; |
2165 dehoisted_key_ids->Add(candidate->id()); | 2165 dehoisted_key_ids->Add(candidate->id()); |
2166 if (!candidate->IsPhi()) return; | 2166 if (!candidate->IsPhi()) return; |
2167 for (int i = 0; i < candidate->OperandCount(); ++i) { | 2167 for (int i = 0; i < candidate->OperandCount(); ++i) { |
2168 FindDehoistedKeyDefinitions(candidate->OperandAt(i)); | 2168 FindDehoistedKeyDefinitions(candidate->OperandAt(i)); |
2169 } | 2169 } |
2170 } | 2170 } |
2171 | 2171 |
2172 | 2172 |
2173 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2173 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
2174 ASSERT((kPointerSize == kInt64Size && | 2174 DCHECK((kPointerSize == kInt64Size && |
2175 instr->key()->representation().IsInteger32()) || | 2175 instr->key()->representation().IsInteger32()) || |
2176 (kPointerSize == kInt32Size && | 2176 (kPointerSize == kInt32Size && |
2177 instr->key()->representation().IsSmiOrInteger32())); | 2177 instr->key()->representation().IsSmiOrInteger32())); |
2178 ElementsKind elements_kind = instr->elements_kind(); | 2178 ElementsKind elements_kind = instr->elements_kind(); |
2179 LOperand* key = NULL; | 2179 LOperand* key = NULL; |
2180 LInstruction* result = NULL; | 2180 LInstruction* result = NULL; |
2181 | 2181 |
2182 if (kPointerSize == kInt64Size) { | 2182 if (kPointerSize == kInt64Size) { |
2183 key = UseRegisterOrConstantAtStart(instr->key()); | 2183 key = UseRegisterOrConstantAtStart(instr->key()); |
2184 } else { | 2184 } else { |
2185 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2185 bool clobbers_key = ExternalArrayOpRequiresTemp( |
2186 instr->key()->representation(), elements_kind); | 2186 instr->key()->representation(), elements_kind); |
2187 key = clobbers_key | 2187 key = clobbers_key |
2188 ? UseTempRegister(instr->key()) | 2188 ? UseTempRegister(instr->key()) |
2189 : UseRegisterOrConstantAtStart(instr->key()); | 2189 : UseRegisterOrConstantAtStart(instr->key()); |
2190 } | 2190 } |
2191 | 2191 |
2192 if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) { | 2192 if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) { |
2193 FindDehoistedKeyDefinitions(instr->key()); | 2193 FindDehoistedKeyDefinitions(instr->key()); |
2194 } | 2194 } |
2195 | 2195 |
2196 if (!instr->is_typed_elements()) { | 2196 if (!instr->is_typed_elements()) { |
2197 LOperand* obj = UseRegisterAtStart(instr->elements()); | 2197 LOperand* obj = UseRegisterAtStart(instr->elements()); |
2198 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); | 2198 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); |
2199 } else { | 2199 } else { |
2200 ASSERT( | 2200 DCHECK( |
2201 (instr->representation().IsInteger32() && | 2201 (instr->representation().IsInteger32() && |
2202 !(IsDoubleOrFloatElementsKind(elements_kind))) || | 2202 !(IsDoubleOrFloatElementsKind(elements_kind))) || |
2203 (instr->representation().IsDouble() && | 2203 (instr->representation().IsDouble() && |
2204 (IsDoubleOrFloatElementsKind(elements_kind)))); | 2204 (IsDoubleOrFloatElementsKind(elements_kind)))); |
2205 LOperand* backing_store = UseRegister(instr->elements()); | 2205 LOperand* backing_store = UseRegister(instr->elements()); |
2206 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); | 2206 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); |
2207 } | 2207 } |
2208 | 2208 |
2209 if ((instr->is_external() || instr->is_fixed_typed_array()) ? | 2209 if ((instr->is_external() || instr->is_fixed_typed_array()) ? |
2210 // see LCodeGen::DoLoadKeyedExternalArray | 2210 // see LCodeGen::DoLoadKeyedExternalArray |
(...skipping 25 matching lines...) Expand all Loading... |
2236 | 2236 |
2237 | 2237 |
2238 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2238 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
2239 ElementsKind elements_kind = instr->elements_kind(); | 2239 ElementsKind elements_kind = instr->elements_kind(); |
2240 | 2240 |
2241 if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) { | 2241 if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) { |
2242 FindDehoistedKeyDefinitions(instr->key()); | 2242 FindDehoistedKeyDefinitions(instr->key()); |
2243 } | 2243 } |
2244 | 2244 |
2245 if (!instr->is_typed_elements()) { | 2245 if (!instr->is_typed_elements()) { |
2246 ASSERT(instr->elements()->representation().IsTagged()); | 2246 DCHECK(instr->elements()->representation().IsTagged()); |
2247 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2247 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
2248 LOperand* object = NULL; | 2248 LOperand* object = NULL; |
2249 LOperand* key = NULL; | 2249 LOperand* key = NULL; |
2250 LOperand* val = NULL; | 2250 LOperand* val = NULL; |
2251 | 2251 |
2252 Representation value_representation = instr->value()->representation(); | 2252 Representation value_representation = instr->value()->representation(); |
2253 if (value_representation.IsDouble()) { | 2253 if (value_representation.IsDouble()) { |
2254 object = UseRegisterAtStart(instr->elements()); | 2254 object = UseRegisterAtStart(instr->elements()); |
2255 val = UseRegisterAtStart(instr->value()); | 2255 val = UseRegisterAtStart(instr->value()); |
2256 key = UseRegisterOrConstantAtStart(instr->key()); | 2256 key = UseRegisterOrConstantAtStart(instr->key()); |
2257 } else { | 2257 } else { |
2258 ASSERT(value_representation.IsSmiOrTagged() || | 2258 DCHECK(value_representation.IsSmiOrTagged() || |
2259 value_representation.IsInteger32()); | 2259 value_representation.IsInteger32()); |
2260 if (needs_write_barrier) { | 2260 if (needs_write_barrier) { |
2261 object = UseTempRegister(instr->elements()); | 2261 object = UseTempRegister(instr->elements()); |
2262 val = UseTempRegister(instr->value()); | 2262 val = UseTempRegister(instr->value()); |
2263 key = UseTempRegister(instr->key()); | 2263 key = UseTempRegister(instr->key()); |
2264 } else { | 2264 } else { |
2265 object = UseRegisterAtStart(instr->elements()); | 2265 object = UseRegisterAtStart(instr->elements()); |
2266 val = UseRegisterOrConstantAtStart(instr->value()); | 2266 val = UseRegisterOrConstantAtStart(instr->value()); |
2267 key = UseRegisterOrConstantAtStart(instr->key()); | 2267 key = UseRegisterOrConstantAtStart(instr->key()); |
2268 } | 2268 } |
2269 } | 2269 } |
2270 | 2270 |
2271 return new(zone()) LStoreKeyed(object, key, val); | 2271 return new(zone()) LStoreKeyed(object, key, val); |
2272 } | 2272 } |
2273 | 2273 |
2274 ASSERT( | 2274 DCHECK( |
2275 (instr->value()->representation().IsInteger32() && | 2275 (instr->value()->representation().IsInteger32() && |
2276 !IsDoubleOrFloatElementsKind(elements_kind)) || | 2276 !IsDoubleOrFloatElementsKind(elements_kind)) || |
2277 (instr->value()->representation().IsDouble() && | 2277 (instr->value()->representation().IsDouble() && |
2278 IsDoubleOrFloatElementsKind(elements_kind))); | 2278 IsDoubleOrFloatElementsKind(elements_kind))); |
2279 ASSERT((instr->is_fixed_typed_array() && | 2279 DCHECK((instr->is_fixed_typed_array() && |
2280 instr->elements()->representation().IsTagged()) || | 2280 instr->elements()->representation().IsTagged()) || |
2281 (instr->is_external() && | 2281 (instr->is_external() && |
2282 instr->elements()->representation().IsExternal())); | 2282 instr->elements()->representation().IsExternal())); |
2283 bool val_is_temp_register = | 2283 bool val_is_temp_register = |
2284 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || | 2284 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || |
2285 elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 2285 elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
2286 elements_kind == FLOAT32_ELEMENTS; | 2286 elements_kind == FLOAT32_ELEMENTS; |
2287 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) | 2287 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) |
2288 : UseRegister(instr->value()); | 2288 : UseRegister(instr->value()); |
2289 LOperand* key = NULL; | 2289 LOperand* key = NULL; |
(...skipping 11 matching lines...) Expand all Loading... |
2301 } | 2301 } |
2302 | 2302 |
2303 | 2303 |
2304 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2304 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
2305 LOperand* context = UseFixed(instr->context(), rsi); | 2305 LOperand* context = UseFixed(instr->context(), rsi); |
2306 LOperand* object = UseFixed(instr->object(), | 2306 LOperand* object = UseFixed(instr->object(), |
2307 KeyedStoreIC::ReceiverRegister()); | 2307 KeyedStoreIC::ReceiverRegister()); |
2308 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); | 2308 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); |
2309 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); | 2309 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); |
2310 | 2310 |
2311 ASSERT(instr->object()->representation().IsTagged()); | 2311 DCHECK(instr->object()->representation().IsTagged()); |
2312 ASSERT(instr->key()->representation().IsTagged()); | 2312 DCHECK(instr->key()->representation().IsTagged()); |
2313 ASSERT(instr->value()->representation().IsTagged()); | 2313 DCHECK(instr->value()->representation().IsTagged()); |
2314 | 2314 |
2315 LStoreKeyedGeneric* result = | 2315 LStoreKeyedGeneric* result = |
2316 new(zone()) LStoreKeyedGeneric(context, object, key, value); | 2316 new(zone()) LStoreKeyedGeneric(context, object, key, value); |
2317 return MarkAsCall(result, instr); | 2317 return MarkAsCall(result, instr); |
2318 } | 2318 } |
2319 | 2319 |
2320 | 2320 |
2321 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2321 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
2322 HTransitionElementsKind* instr) { | 2322 HTransitionElementsKind* instr) { |
2323 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2323 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
(...skipping 30 matching lines...) Expand all Loading... |
2354 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2354 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
2355 bool needs_write_barrier_for_map = instr->has_transition() && | 2355 bool needs_write_barrier_for_map = instr->has_transition() && |
2356 instr->NeedsWriteBarrierForMap(); | 2356 instr->NeedsWriteBarrierForMap(); |
2357 | 2357 |
2358 LOperand* obj; | 2358 LOperand* obj; |
2359 if (needs_write_barrier) { | 2359 if (needs_write_barrier) { |
2360 obj = is_in_object | 2360 obj = is_in_object |
2361 ? UseRegister(instr->object()) | 2361 ? UseRegister(instr->object()) |
2362 : UseTempRegister(instr->object()); | 2362 : UseTempRegister(instr->object()); |
2363 } else if (is_external_location) { | 2363 } else if (is_external_location) { |
2364 ASSERT(!is_in_object); | 2364 DCHECK(!is_in_object); |
2365 ASSERT(!needs_write_barrier); | 2365 DCHECK(!needs_write_barrier); |
2366 ASSERT(!needs_write_barrier_for_map); | 2366 DCHECK(!needs_write_barrier_for_map); |
2367 obj = UseRegisterOrConstant(instr->object()); | 2367 obj = UseRegisterOrConstant(instr->object()); |
2368 } else { | 2368 } else { |
2369 obj = needs_write_barrier_for_map | 2369 obj = needs_write_barrier_for_map |
2370 ? UseRegister(instr->object()) | 2370 ? UseRegister(instr->object()) |
2371 : UseRegisterAtStart(instr->object()); | 2371 : UseRegisterAtStart(instr->object()); |
2372 } | 2372 } |
2373 | 2373 |
2374 bool can_be_constant = instr->value()->IsConstant() && | 2374 bool can_be_constant = instr->value()->IsConstant() && |
2375 HConstant::cast(instr->value())->NotInNewSpace() && | 2375 HConstant::cast(instr->value())->NotInNewSpace() && |
2376 !instr->field_representation().IsDouble(); | 2376 !instr->field_representation().IsDouble(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2458 | 2458 |
2459 | 2459 |
2460 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2460 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
2461 LOperand* context = UseFixed(instr->context(), rsi); | 2461 LOperand* context = UseFixed(instr->context(), rsi); |
2462 LFunctionLiteral* result = new(zone()) LFunctionLiteral(context); | 2462 LFunctionLiteral* result = new(zone()) LFunctionLiteral(context); |
2463 return MarkAsCall(DefineFixed(result, rax), instr); | 2463 return MarkAsCall(DefineFixed(result, rax), instr); |
2464 } | 2464 } |
2465 | 2465 |
2466 | 2466 |
2467 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2467 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
2468 ASSERT(argument_count_ == 0); | 2468 DCHECK(argument_count_ == 0); |
2469 allocator_->MarkAsOsrEntry(); | 2469 allocator_->MarkAsOsrEntry(); |
2470 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2470 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
2471 return AssignEnvironment(new(zone()) LOsrEntry); | 2471 return AssignEnvironment(new(zone()) LOsrEntry); |
2472 } | 2472 } |
2473 | 2473 |
2474 | 2474 |
2475 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2475 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
2476 LParameter* result = new(zone()) LParameter; | 2476 LParameter* result = new(zone()) LParameter; |
2477 if (instr->kind() == HParameter::STACK_PARAMETER) { | 2477 if (instr->kind() == HParameter::STACK_PARAMETER) { |
2478 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2478 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
2479 return DefineAsSpilled(result, spill_index); | 2479 return DefineAsSpilled(result, spill_index); |
2480 } else { | 2480 } else { |
2481 ASSERT(info()->IsStub()); | 2481 DCHECK(info()->IsStub()); |
2482 CodeStubInterfaceDescriptor* descriptor = | 2482 CodeStubInterfaceDescriptor* descriptor = |
2483 info()->code_stub()->GetInterfaceDescriptor(); | 2483 info()->code_stub()->GetInterfaceDescriptor(); |
2484 int index = static_cast<int>(instr->index()); | 2484 int index = static_cast<int>(instr->index()); |
2485 Register reg = descriptor->GetEnvironmentParameterRegister(index); | 2485 Register reg = descriptor->GetEnvironmentParameterRegister(index); |
2486 return DefineFixed(result, reg); | 2486 return DefineFixed(result, reg); |
2487 } | 2487 } |
2488 } | 2488 } |
2489 | 2489 |
2490 | 2490 |
2491 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2491 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2577 return NULL; | 2577 return NULL; |
2578 } | 2578 } |
2579 | 2579 |
2580 | 2580 |
2581 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2581 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
2582 info()->MarkAsDeferredCalling(); | 2582 info()->MarkAsDeferredCalling(); |
2583 if (instr->is_function_entry()) { | 2583 if (instr->is_function_entry()) { |
2584 LOperand* context = UseFixed(instr->context(), rsi); | 2584 LOperand* context = UseFixed(instr->context(), rsi); |
2585 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2585 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
2586 } else { | 2586 } else { |
2587 ASSERT(instr->is_backwards_branch()); | 2587 DCHECK(instr->is_backwards_branch()); |
2588 LOperand* context = UseAny(instr->context()); | 2588 LOperand* context = UseAny(instr->context()); |
2589 return AssignEnvironment( | 2589 return AssignEnvironment( |
2590 AssignPointerMap(new(zone()) LStackCheck(context))); | 2590 AssignPointerMap(new(zone()) LStackCheck(context))); |
2591 } | 2591 } |
2592 } | 2592 } |
2593 | 2593 |
2594 | 2594 |
2595 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2595 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
2596 HEnvironment* outer = current_block_->last_environment(); | 2596 HEnvironment* outer = current_block_->last_environment(); |
2597 outer->set_ast_id(instr->ReturnId()); | 2597 outer->set_ast_id(instr->ReturnId()); |
(...skipping 15 matching lines...) Expand all Loading... |
2613 | 2613 |
2614 | 2614 |
2615 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2615 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
2616 LInstruction* pop = NULL; | 2616 LInstruction* pop = NULL; |
2617 | 2617 |
2618 HEnvironment* env = current_block_->last_environment(); | 2618 HEnvironment* env = current_block_->last_environment(); |
2619 | 2619 |
2620 if (env->entry()->arguments_pushed()) { | 2620 if (env->entry()->arguments_pushed()) { |
2621 int argument_count = env->arguments_environment()->parameter_count(); | 2621 int argument_count = env->arguments_environment()->parameter_count(); |
2622 pop = new(zone()) LDrop(argument_count); | 2622 pop = new(zone()) LDrop(argument_count); |
2623 ASSERT(instr->argument_delta() == -argument_count); | 2623 DCHECK(instr->argument_delta() == -argument_count); |
2624 } | 2624 } |
2625 | 2625 |
2626 HEnvironment* outer = current_block_->last_environment()-> | 2626 HEnvironment* outer = current_block_->last_environment()-> |
2627 DiscardInlined(false); | 2627 DiscardInlined(false); |
2628 current_block_->UpdateEnvironment(outer); | 2628 current_block_->UpdateEnvironment(outer); |
2629 | 2629 |
2630 return pop; | 2630 return pop; |
2631 } | 2631 } |
2632 | 2632 |
2633 | 2633 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2674 LOperand* function = UseRegisterAtStart(instr->function()); | 2674 LOperand* function = UseRegisterAtStart(instr->function()); |
2675 LAllocateBlockContext* result = | 2675 LAllocateBlockContext* result = |
2676 new(zone()) LAllocateBlockContext(context, function); | 2676 new(zone()) LAllocateBlockContext(context, function); |
2677 return MarkAsCall(DefineFixed(result, rsi), instr); | 2677 return MarkAsCall(DefineFixed(result, rsi), instr); |
2678 } | 2678 } |
2679 | 2679 |
2680 | 2680 |
2681 } } // namespace v8::internal | 2681 } } // namespace v8::internal |
2682 | 2682 |
2683 #endif // V8_TARGET_ARCH_X64 | 2683 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |