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