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