Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/x64/lithium-x64.cc

Issue 6606006: [Isolates] Merge 6500:6700 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #if defined(V8_TARGET_ARCH_X64) 30 #if defined(V8_TARGET_ARCH_X64)
31 31
32 #include "lithium-allocator-inl.h"
32 #include "x64/lithium-x64.h" 33 #include "x64/lithium-x64.h"
33 #include "x64/lithium-codegen-x64.h" 34 #include "x64/lithium-codegen-x64.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 #define DEFINE_COMPILE(type) \ 39 #define DEFINE_COMPILE(type) \
39 void L##type::CompileToNative(LCodeGen* generator) { \ 40 void L##type::CompileToNative(LCodeGen* generator) { \
40 generator->Do##type(this); \ 41 generator->Do##type(this); \
41 } 42 }
(...skipping 19 matching lines...) Expand all
61 62
62 63
63 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 64 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
64 LOperand* spill_operand) { 65 LOperand* spill_operand) {
65 ASSERT(spill_operand->IsDoubleStackSlot()); 66 ASSERT(spill_operand->IsDoubleStackSlot());
66 ASSERT(double_register_spills_[allocation_index] == NULL); 67 ASSERT(double_register_spills_[allocation_index] == NULL);
67 double_register_spills_[allocation_index] = spill_operand; 68 double_register_spills_[allocation_index] = spill_operand;
68 } 69 }
69 70
70 71
72 #ifdef DEBUG
73 void LInstruction::VerifyCall() {
74 // Call instructions can use only fixed registers as
75 // temporaries and outputs because all registers
76 // are blocked by the calling convention.
77 // Inputs can use either fixed register or have a short lifetime (be
78 // used at start of the instruction).
79 ASSERT(Output() == NULL ||
80 LUnallocated::cast(Output())->HasFixedPolicy() ||
81 !LUnallocated::cast(Output())->HasRegisterPolicy());
82 for (UseIterator it(this); it.HasNext(); it.Advance()) {
83 LOperand* operand = it.Next();
84 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
85 LUnallocated::cast(operand)->IsUsedAtStart() ||
86 !LUnallocated::cast(operand)->HasRegisterPolicy());
87 }
88 for (TempIterator it(this); it.HasNext(); it.Advance()) {
89 LOperand* operand = it.Next();
90 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
91 !LUnallocated::cast(operand)->HasRegisterPolicy());
92 }
93 }
94 #endif
95
96
71 void LInstruction::PrintTo(StringStream* stream) { 97 void LInstruction::PrintTo(StringStream* stream) {
72 stream->Add("%s ", this->Mnemonic()); 98 stream->Add("%s ", this->Mnemonic());
73 if (HasResult()) { 99
74 PrintOutputOperandTo(stream); 100 PrintOutputOperandTo(stream);
75 }
76 101
77 PrintDataTo(stream); 102 PrintDataTo(stream);
78 103
79 if (HasEnvironment()) { 104 if (HasEnvironment()) {
80 stream->Add(" "); 105 stream->Add(" ");
81 environment()->PrintTo(stream); 106 environment()->PrintTo(stream);
82 } 107 }
83 108
84 if (HasPointerMap()) { 109 if (HasPointerMap()) {
85 stream->Add(" "); 110 stream->Add(" ");
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 } 180 }
156 181
157 182
158 const char* LArithmeticT::Mnemonic() const { 183 const char* LArithmeticT::Mnemonic() const {
159 switch (op()) { 184 switch (op()) {
160 case Token::ADD: return "add-t"; 185 case Token::ADD: return "add-t";
161 case Token::SUB: return "sub-t"; 186 case Token::SUB: return "sub-t";
162 case Token::MUL: return "mul-t"; 187 case Token::MUL: return "mul-t";
163 case Token::MOD: return "mod-t"; 188 case Token::MOD: return "mod-t";
164 case Token::DIV: return "div-t"; 189 case Token::DIV: return "div-t";
190 case Token::BIT_AND: return "bit-and-t";
191 case Token::BIT_OR: return "bit-or-t";
192 case Token::BIT_XOR: return "bit-xor-t";
193 case Token::SHL: return "sal-t";
194 case Token::SAR: return "sar-t";
195 case Token::SHR: return "shr-t";
165 default: 196 default:
166 UNREACHABLE(); 197 UNREACHABLE();
167 return NULL; 198 return NULL;
168 } 199 }
169 } 200 }
170 201
171 202
172 void LGoto::PrintDataTo(StringStream* stream) { 203 void LGoto::PrintDataTo(StringStream* stream) {
173 stream->Add("B%d", block_id()); 204 stream->Add("B%d", block_id());
174 } 205 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 } 286 }
256 287
257 288
258 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { 289 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
259 stream->Add("/%s ", hydrogen()->OpName()); 290 stream->Add("/%s ", hydrogen()->OpName());
260 InputAt(0)->PrintTo(stream); 291 InputAt(0)->PrintTo(stream);
261 } 292 }
262 293
263 294
264 void LLoadContextSlot::PrintDataTo(StringStream* stream) { 295 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
265 stream->Add("(%d, %d)", context_chain_length(), slot_index()); 296 InputAt(0)->PrintTo(stream);
297 stream->Add("[%d]", slot_index());
266 } 298 }
267 299
268 300
269 void LCallKeyed::PrintDataTo(StringStream* stream) { 301 void LCallKeyed::PrintDataTo(StringStream* stream) {
270 stream->Add("[ecx] #%d / ", arity()); 302 stream->Add("[ecx] #%d / ", arity());
271 } 303 }
272 304
273 305
274 void LCallNamed::PrintDataTo(StringStream* stream) { 306 void LCallNamed::PrintDataTo(StringStream* stream) {
275 SmartPointer<char> name_string = name()->ToCString(); 307 SmartPointer<char> name_string = name()->ToCString();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 stream->Add(" index "); 343 stream->Add(" index ");
312 index()->PrintTo(stream); 344 index()->PrintTo(stream);
313 } 345 }
314 346
315 347
316 int LChunk::GetNextSpillIndex(bool is_double) { 348 int LChunk::GetNextSpillIndex(bool is_double) {
317 return spill_slot_count_++; 349 return spill_slot_count_++;
318 } 350 }
319 351
320 352
321 LOperand* LChunk::GetNextSpillSlot(bool is_double) { 353 LOperand* LChunk::GetNextSpillSlot(bool is_double) {
322 // All stack slots are Double stack slots on x64. 354 // All stack slots are Double stack slots on x64.
323 // Alternatively, at some point, start using half-size 355 // Alternatively, at some point, start using half-size
324 // stack slots for int32 values. 356 // stack slots for int32 values.
325 int index = GetNextSpillIndex(is_double); 357 int index = GetNextSpillIndex(is_double);
326 if (is_double) { 358 if (is_double) {
327 return LDoubleStackSlot::Create(index); 359 return LDoubleStackSlot::Create(index);
328 } else { 360 } else {
329 return LStackSlot::Create(index); 361 return LStackSlot::Create(index);
330 } 362 }
331 } 363 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 411
380 void LStoreKeyed::PrintDataTo(StringStream* stream) { 412 void LStoreKeyed::PrintDataTo(StringStream* stream) {
381 object()->PrintTo(stream); 413 object()->PrintTo(stream);
382 stream->Add("["); 414 stream->Add("[");
383 key()->PrintTo(stream); 415 key()->PrintTo(stream);
384 stream->Add("] <- "); 416 stream->Add("] <- ");
385 value()->PrintTo(stream); 417 value()->PrintTo(stream);
386 } 418 }
387 419
388 420
389 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 421 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
390 LGap* gap = new LGap(block); 422 LGap* gap = new LGap(block);
391 int index = -1; 423 int index = -1;
392 if (instr->IsControl()) { 424 if (instr->IsControl()) {
393 instructions_.Add(gap); 425 instructions_.Add(gap);
394 index = instructions_.length(); 426 index = instructions_.length();
395 instructions_.Add(instr); 427 instructions_.Add(instr);
396 } else { 428 } else {
397 index = instructions_.length(); 429 index = instructions_.length();
398 instructions_.Add(instr); 430 instructions_.Add(instr);
399 instructions_.Add(gap); 431 instructions_.Add(gap);
400 } 432 }
401 if (instr->HasPointerMap()) { 433 if (instr->HasPointerMap()) {
402 pointer_maps_.Add(instr->pointer_map()); 434 pointer_maps_.Add(instr->pointer_map());
403 instr->pointer_map()->set_lithium_position(index); 435 instr->pointer_map()->set_lithium_position(index);
404 } 436 }
405 return index;
406 } 437 }
407 438
408 439
409 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 440 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
410 return LConstantOperand::Create(constant->id()); 441 return LConstantOperand::Create(constant->id());
411 } 442 }
412 443
413 444
414 int LChunk::GetParameterStackSlot(int index) const { 445 int LChunk::GetParameterStackSlot(int index) const {
415 // The receiver is at index 0, the first parameter at index 1, so we 446 // The receiver is at index 0, the first parameter at index 1, so we
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 677
647 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 678 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
648 HEnvironment* hydrogen_env = current_block_->last_environment(); 679 HEnvironment* hydrogen_env = current_block_->last_environment();
649 instr->set_environment(CreateEnvironment(hydrogen_env)); 680 instr->set_environment(CreateEnvironment(hydrogen_env));
650 return instr; 681 return instr;
651 } 682 }
652 683
653 684
654 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( 685 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
655 LInstruction* instr, int ast_id) { 686 LInstruction* instr, int ast_id) {
656 ASSERT(instructions_pending_deoptimization_environment_ == NULL); 687 ASSERT(instruction_pending_deoptimization_environment_ == NULL);
657 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); 688 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
658 instructions_pending_deoptimization_environment_ = instr; 689 instruction_pending_deoptimization_environment_ = instr;
659 pending_deoptimization_ast_id_ = ast_id; 690 pending_deoptimization_ast_id_ = ast_id;
660 return instr; 691 return instr;
661 } 692 }
662 693
663 694
664 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { 695 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
665 instructions_pending_deoptimization_environment_ = NULL; 696 instruction_pending_deoptimization_environment_ = NULL;
666 pending_deoptimization_ast_id_ = AstNode::kNoNumber; 697 pending_deoptimization_ast_id_ = AstNode::kNoNumber;
667 } 698 }
668 699
669 700
670 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 701 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
671 HInstruction* hinstr, 702 HInstruction* hinstr,
672 CanDeoptimize can_deoptimize) { 703 CanDeoptimize can_deoptimize) {
673 allocator_->MarkAsCall(); 704 #ifdef DEBUG
705 instr->VerifyCall();
706 #endif
707 instr->MarkAsCall();
674 instr = AssignPointerMap(instr); 708 instr = AssignPointerMap(instr);
675 709
676 if (hinstr->HasSideEffects()) { 710 if (hinstr->HasSideEffects()) {
677 ASSERT(hinstr->next()->IsSimulate()); 711 ASSERT(hinstr->next()->IsSimulate());
678 HSimulate* sim = HSimulate::cast(hinstr->next()); 712 HSimulate* sim = HSimulate::cast(hinstr->next());
679 instr = SetInstructionPendingDeoptimizationEnvironment( 713 instr = SetInstructionPendingDeoptimizationEnvironment(
680 instr, sim->ast_id()); 714 instr, sim->ast_id());
681 } 715 }
682 716
683 // If instruction does not have side-effects lazy deoptimization 717 // If instruction does not have side-effects lazy deoptimization
684 // after the call will try to deoptimize to the point before the call. 718 // after the call will try to deoptimize to the point before the call.
685 // Thus we still need to attach environment to this call even if 719 // Thus we still need to attach environment to this call even if
686 // call sequence can not deoptimize eagerly. 720 // call sequence can not deoptimize eagerly.
687 bool needs_environment = 721 bool needs_environment =
688 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 722 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
689 if (needs_environment && !instr->HasEnvironment()) { 723 if (needs_environment && !instr->HasEnvironment()) {
690 instr = AssignEnvironment(instr); 724 instr = AssignEnvironment(instr);
691 } 725 }
692 726
693 return instr; 727 return instr;
694 } 728 }
695 729
696 730
697 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { 731 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
698 allocator_->MarkAsSaveDoubles(); 732 instr->MarkAsSaveDoubles();
699 return instr; 733 return instr;
700 } 734 }
701 735
702 736
703 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 737 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
704 ASSERT(!instr->HasPointerMap()); 738 ASSERT(!instr->HasPointerMap());
705 instr->set_pointer_map(new LPointerMap(position_)); 739 instr->set_pointer_map(new LPointerMap(position_));
706 return instr; 740 return instr;
707 } 741 }
708 742
(...skipping 24 matching lines...) Expand all
733 } 767 }
734 768
735 769
736 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 770 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
737 return AssignEnvironment(new LDeoptimize); 771 return AssignEnvironment(new LDeoptimize);
738 } 772 }
739 773
740 774
741 LInstruction* LChunkBuilder::DoBit(Token::Value op, 775 LInstruction* LChunkBuilder::DoBit(Token::Value op,
742 HBitwiseBinaryOperation* instr) { 776 HBitwiseBinaryOperation* instr) {
743 Abort("Unimplemented: %s", "DoBit"); 777 if (instr->representation().IsInteger32()) {
744 return NULL; 778 ASSERT(instr->left()->representation().IsInteger32());
779 ASSERT(instr->right()->representation().IsInteger32());
780
781 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
782 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
783 return DefineSameAsFirst(new LBitI(op, left, right));
784 } else {
785 ASSERT(instr->representation().IsTagged());
786 ASSERT(instr->left()->representation().IsTagged());
787 ASSERT(instr->right()->representation().IsTagged());
788
789 LOperand* left = UseFixed(instr->left(), rdx);
790 LOperand* right = UseFixed(instr->right(), rax);
791 LArithmeticT* result = new LArithmeticT(op, left, right);
792 return MarkAsCall(DefineFixed(result, rax), instr);
793 }
794 }
795
796
797 LInstruction* LChunkBuilder::DoShift(Token::Value op,
798 HBitwiseBinaryOperation* instr) {
799 if (instr->representation().IsTagged()) {
800 ASSERT(instr->left()->representation().IsTagged());
801 ASSERT(instr->right()->representation().IsTagged());
802
803 LOperand* left = UseFixed(instr->left(), rdx);
804 LOperand* right = UseFixed(instr->right(), rax);
805 LArithmeticT* result = new LArithmeticT(op, left, right);
806 return MarkAsCall(DefineFixed(result, rax), instr);
807 }
808
809 ASSERT(instr->representation().IsInteger32());
810 ASSERT(instr->OperandAt(0)->representation().IsInteger32());
811 ASSERT(instr->OperandAt(1)->representation().IsInteger32());
812 LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
813
814 HValue* right_value = instr->OperandAt(1);
815 LOperand* right = NULL;
816 int constant_value = 0;
817 if (right_value->IsConstant()) {
818 HConstant* constant = HConstant::cast(right_value);
819 right = chunk_->DefineConstantOperand(constant);
820 constant_value = constant->Integer32Value() & 0x1f;
821 } else {
822 right = UseFixed(right_value, rcx);
823 }
824
825 // Shift operations can only deoptimize if we do a logical shift
826 // by 0 and the result cannot be truncated to int32.
827 bool can_deopt = (op == Token::SHR && constant_value == 0);
828 if (can_deopt) {
829 bool can_truncate = true;
830 for (int i = 0; i < instr->uses()->length(); i++) {
831 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) {
832 can_truncate = false;
833 break;
834 }
835 }
836 can_deopt = !can_truncate;
837 }
838
839 LShiftI* result = new LShiftI(op, left, right, can_deopt);
840 return can_deopt
841 ? AssignEnvironment(DefineSameAsFirst(result))
842 : DefineSameAsFirst(result);
745 } 843 }
746 844
747 845
748 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 846 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
749 HArithmeticBinaryOperation* instr) { 847 HArithmeticBinaryOperation* instr) {
750 Abort("Unimplemented: %s", "DoArithmeticD"); 848 Abort("Unimplemented: %s", "DoArithmeticD");
751 return NULL; 849 return NULL;
752 } 850 }
753 851
754 852
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 } 927 }
830 block->set_argument_count(argument_count_); 928 block->set_argument_count(argument_count_);
831 next_block_ = NULL; 929 next_block_ = NULL;
832 current_block_ = NULL; 930 current_block_ = NULL;
833 } 931 }
834 932
835 933
836 void LChunkBuilder::VisitInstruction(HInstruction* current) { 934 void LChunkBuilder::VisitInstruction(HInstruction* current) {
837 HInstruction* old_current = current_instruction_; 935 HInstruction* old_current = current_instruction_;
838 current_instruction_ = current; 936 current_instruction_ = current;
839 allocator_->BeginInstruction();
840 if (current->has_position()) position_ = current->position(); 937 if (current->has_position()) position_ = current->position();
841 LInstruction* instr = current->CompileToLithium(this); 938 LInstruction* instr = current->CompileToLithium(this);
842 939
843 if (instr != NULL) { 940 if (instr != NULL) {
844 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 941 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
845 instr = AssignPointerMap(instr); 942 instr = AssignPointerMap(instr);
846 } 943 }
847 if (FLAG_stress_environments && !instr->HasEnvironment()) { 944 if (FLAG_stress_environments && !instr->HasEnvironment()) {
848 instr = AssignEnvironment(instr); 945 instr = AssignEnvironment(instr);
849 } 946 }
850 if (current->IsTest() && !instr->IsGoto()) { 947 if (current->IsTest() && !instr->IsGoto()) {
851 ASSERT(instr->IsControl()); 948 ASSERT(instr->IsControl());
852 HTest* test = HTest::cast(current); 949 HTest* test = HTest::cast(current);
853 instr->set_hydrogen_value(test->value()); 950 instr->set_hydrogen_value(test->value());
854 HBasicBlock* first = test->FirstSuccessor(); 951 HBasicBlock* first = test->FirstSuccessor();
855 HBasicBlock* second = test->SecondSuccessor(); 952 HBasicBlock* second = test->SecondSuccessor();
856 ASSERT(first != NULL && second != NULL); 953 ASSERT(first != NULL && second != NULL);
857 instr->SetBranchTargets(first->block_id(), second->block_id()); 954 instr->SetBranchTargets(first->block_id(), second->block_id());
858 } else { 955 } else {
859 instr->set_hydrogen_value(current); 956 instr->set_hydrogen_value(current);
860 } 957 }
861 958
862 int index = chunk_->AddInstruction(instr, current_block_); 959 chunk_->AddInstruction(instr, current_block_);
863 allocator_->SummarizeInstruction(index);
864 } else {
865 // This instruction should be omitted.
866 allocator_->OmitInstruction();
867 } 960 }
868 current_instruction_ = old_current; 961 current_instruction_ = old_current;
869 } 962 }
870 963
871 964
872 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 965 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
873 if (hydrogen_env == NULL) return NULL; 966 if (hydrogen_env == NULL) return NULL;
874 967
875 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 968 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
876 int ast_id = hydrogen_env->ast_id(); 969 int ast_id = hydrogen_env->ast_id();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 } else if (v->IsInstanceOf()) { 1075 } else if (v->IsInstanceOf()) {
983 HInstanceOf* instance_of = HInstanceOf::cast(v); 1076 HInstanceOf* instance_of = HInstanceOf::cast(v);
984 LInstanceOfAndBranch* result = 1077 LInstanceOfAndBranch* result =
985 new LInstanceOfAndBranch( 1078 new LInstanceOfAndBranch(
986 UseFixed(instance_of->left(), InstanceofStub::left()), 1079 UseFixed(instance_of->left(), InstanceofStub::left()),
987 UseFixed(instance_of->right(), InstanceofStub::right())); 1080 UseFixed(instance_of->right(), InstanceofStub::right()));
988 return MarkAsCall(result, instr); 1081 return MarkAsCall(result, instr);
989 } else if (v->IsTypeofIs()) { 1082 } else if (v->IsTypeofIs()) {
990 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1083 HTypeofIs* typeof_is = HTypeofIs::cast(v);
991 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); 1084 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1085 } else if (v->IsIsConstructCall()) {
1086 return new LIsConstructCallAndBranch(TempRegister());
992 } else { 1087 } else {
993 if (v->IsConstant()) { 1088 if (v->IsConstant()) {
994 if (HConstant::cast(v)->handle()->IsTrue()) { 1089 if (HConstant::cast(v)->handle()->IsTrue()) {
995 return new LGoto(instr->FirstSuccessor()->block_id()); 1090 return new LGoto(instr->FirstSuccessor()->block_id());
996 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1091 } else if (HConstant::cast(v)->handle()->IsFalse()) {
997 return new LGoto(instr->SecondSuccessor()->block_id()); 1092 return new LGoto(instr->SecondSuccessor()->block_id());
998 } 1093 }
999 } 1094 }
1000 Abort("Undefined compare before branch"); 1095 Abort("Undefined compare before branch");
1001 return NULL; 1096 return NULL;
1002 } 1097 }
1003 } 1098 }
1004 return new LBranch(UseRegisterAtStart(v)); 1099 return new LBranch(UseRegisterAtStart(v));
1005 } 1100 }
1006 1101
1007 1102
1008 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 1103 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1009 Abort("Unimplemented: %s", "DoCompareMap"); 1104 ASSERT(instr->value()->representation().IsTagged());
1010 return NULL; 1105 LOperand* value = UseRegisterAtStart(instr->value());
1106 return new LCmpMapAndBranch(value);
1011 } 1107 }
1012 1108
1013 1109
1014 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1110 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1015 Abort("Unimplemented: %s", "DoArgumentsLength"); 1111 Abort("Unimplemented: %s", "DoArgumentsLength");
1016 return NULL; 1112 return NULL;
1017 } 1113 }
1018 1114
1019 1115
1020 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1116 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
(...skipping 15 matching lines...) Expand all
1036 } 1132 }
1037 1133
1038 1134
1039 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1135 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1040 Abort("Unimplemented: %s", "DoApplyArguments"); 1136 Abort("Unimplemented: %s", "DoApplyArguments");
1041 return NULL; 1137 return NULL;
1042 } 1138 }
1043 1139
1044 1140
1045 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1141 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1046 Abort("Unimplemented: %s", "DoPushArgument"); 1142 ++argument_count_;
1143 LOperand* argument = UseOrConstant(instr->argument());
1144 return new LPushArgument(argument);
1145 }
1146
1147
1148 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1149 Abort("Unimplemented: DoContext");
1150 return NULL;
1151 }
1152
1153
1154 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1155 Abort("Unimplemented: DoOuterContext");
1047 return NULL; 1156 return NULL;
1048 } 1157 }
1049 1158
1050 1159
1051 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { 1160 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1052 return DefineAsRegister(new LGlobalObject); 1161 return DefineAsRegister(new LGlobalObject);
1053 } 1162 }
1054 1163
1055 1164
1056 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1165 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1057 Abort("Unimplemented: %s", "DoGlobalReceiver"); 1166 return DefineAsRegister(new LGlobalReceiver);
1058 return NULL;
1059 } 1167 }
1060 1168
1061 1169
1062 LInstruction* LChunkBuilder::DoCallConstantFunction( 1170 LInstruction* LChunkBuilder::DoCallConstantFunction(
1063 HCallConstantFunction* instr) { 1171 HCallConstantFunction* instr) {
1064 Abort("Unimplemented: %s", "DoCallConstantFunction"); 1172 argument_count_ -= instr->argument_count();
1065 return NULL; 1173 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr);
1066 } 1174 }
1067 1175
1068 1176
1069 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1177 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1070 Abort("Unimplemented: %s", "DoUnaryMathOperation"); 1178 Abort("Unimplemented: %s", "DoUnaryMathOperation");
1071 return NULL; 1179 return NULL;
1072 } 1180 }
1073 1181
1074 1182
1075 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1183 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1076 Abort("Unimplemented: %s", "DoCallKeyed"); 1184 Abort("Unimplemented: %s", "DoCallKeyed");
1077 return NULL; 1185 return NULL;
1078 } 1186 }
1079 1187
1080 1188
1081 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { 1189 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1082 Abort("Unimplemented: %s", "DoCallNamed"); 1190 argument_count_ -= instr->argument_count();
1083 return NULL; 1191 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr);
1084 } 1192 }
1085 1193
1086 1194
1087 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { 1195 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1088 Abort("Unimplemented: %s", "DoCallGlobal"); 1196 Abort("Unimplemented: %s", "DoCallGlobal");
1089 return NULL; 1197 return NULL;
1090 } 1198 }
1091 1199
1092 1200
1093 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { 1201 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1094 Abort("Unimplemented: %s", "DoCallKnownGlobal"); 1202 argument_count_ -= instr->argument_count();
1095 return NULL; 1203 return MarkAsCall(DefineFixed(new LCallKnownGlobal, rax), instr);
1096 } 1204 }
1097 1205
1098 1206
1099 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1207 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1100 Abort("Unimplemented: %s", "DoCallNew"); 1208 LOperand* constructor = UseFixed(instr->constructor(), rdi);
1101 return NULL; 1209 argument_count_ -= instr->argument_count();
1210 LCallNew* result = new LCallNew(constructor);
1211 return MarkAsCall(DefineFixed(result, rax), instr);
1102 } 1212 }
1103 1213
1104 1214
1105 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1215 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1106 Abort("Unimplemented: %s", "DoCallFunction"); 1216 Abort("Unimplemented: %s", "DoCallFunction");
1107 return NULL; 1217 return NULL;
1108 } 1218 }
1109 1219
1110 1220
1111 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1221 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1112 Abort("Unimplemented: %s", "DoCallRuntime"); 1222 argument_count_ -= instr->argument_count();
1113 return NULL; 1223 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr);
1114 } 1224 }
1115 1225
1116 1226
1117 LInstruction* LChunkBuilder::DoShr(HShr* instr) { 1227 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1118 Abort("Unimplemented: %s", "DoShr"); 1228 return DoShift(Token::SHR, instr);
1119 return NULL;
1120 } 1229 }
1121 1230
1122 1231
1123 LInstruction* LChunkBuilder::DoSar(HSar* instr) { 1232 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1124 Abort("Unimplemented: %s", "DoSar"); 1233 return DoShift(Token::SAR, instr);
1125 return NULL;
1126 } 1234 }
1127 1235
1128 1236
1129 LInstruction* LChunkBuilder::DoShl(HShl* instr) { 1237 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1130 Abort("Unimplemented: %s", "DoShl"); 1238 return DoShift(Token::SHL, instr);
1131 return NULL;
1132 } 1239 }
1133 1240
1134 1241
1135 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { 1242 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
1136 Abort("Unimplemented: %s", "DoBitAnd"); 1243 return DoBit(Token::BIT_AND, instr);
1137 return NULL;
1138 } 1244 }
1139 1245
1140 1246
1141 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { 1247 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1142 Abort("Unimplemented: %s", "DoBitNot"); 1248 ASSERT(instr->value()->representation().IsInteger32());
1143 return NULL; 1249 ASSERT(instr->representation().IsInteger32());
1250 LOperand* input = UseRegisterAtStart(instr->value());
1251 LBitNotI* result = new LBitNotI(input);
1252 return DefineSameAsFirst(result);
1144 } 1253 }
1145 1254
1146 1255
1147 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { 1256 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
1148 Abort("Unimplemented: %s", "DoBitOr"); 1257 return DoBit(Token::BIT_OR, instr);
1149 return NULL;
1150 } 1258 }
1151 1259
1152 1260
1153 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { 1261 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1154 Abort("Unimplemented: %s", "DoBitXor"); 1262 return DoBit(Token::BIT_XOR, instr);
1155 return NULL;
1156 } 1263 }
1157 1264
1158 1265
1159 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1266 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1160 Abort("Unimplemented: %s", "DoDiv"); 1267 if (instr->representation().IsDouble()) {
1161 return NULL; 1268 return DoArithmeticD(Token::DIV, instr);
1269 } else if (instr->representation().IsInteger32()) {
1270 // The temporary operand is necessary to ensure that right is not allocated
1271 // into rdx.
1272 LOperand* temp = FixedTemp(rdx);
1273 LOperand* dividend = UseFixed(instr->left(), rax);
1274 LOperand* divisor = UseRegister(instr->right());
1275 LDivI* result = new LDivI(dividend, divisor, temp);
1276 return AssignEnvironment(DefineFixed(result, rax));
1277 } else {
1278 ASSERT(instr->representation().IsTagged());
1279 return DoArithmeticT(Token::DIV, instr);
1280 }
1162 } 1281 }
1163 1282
1164 1283
1165 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1284 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1166 Abort("Unimplemented: %s", "DoMod"); 1285 Abort("Unimplemented: %s", "DoMod");
1167 return NULL; 1286 return NULL;
1168 } 1287 }
1169 1288
1170 1289
1171 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1290 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1172 Abort("Unimplemented: %s", "DoMul"); 1291 if (instr->representation().IsInteger32()) {
1173 return NULL; 1292 ASSERT(instr->left()->representation().IsInteger32());
1293 ASSERT(instr->right()->representation().IsInteger32());
1294 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1295 LOperand* right = UseOrConstant(instr->MostConstantOperand());
1296 LMulI* mul = new LMulI(left, right);
1297 return AssignEnvironment(DefineSameAsFirst(mul));
1298 } else if (instr->representation().IsDouble()) {
1299 return DoArithmeticD(Token::MUL, instr);
1300 } else {
1301 ASSERT(instr->representation().IsTagged());
1302 return DoArithmeticT(Token::MUL, instr);
1303 }
1174 } 1304 }
1175 1305
1176 1306
1177 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1307 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1178 if (instr->representation().IsInteger32()) { 1308 if (instr->representation().IsInteger32()) {
1179 ASSERT(instr->left()->representation().IsInteger32()); 1309 ASSERT(instr->left()->representation().IsInteger32());
1180 ASSERT(instr->right()->representation().IsInteger32()); 1310 ASSERT(instr->right()->representation().IsInteger32());
1181 LOperand* left = UseRegisterAtStart(instr->left()); 1311 LOperand* left = UseRegisterAtStart(instr->left());
1182 LOperand* right = UseOrConstantAtStart(instr->right()); 1312 LOperand* right = UseOrConstantAtStart(instr->right());
1183 LSubI* sub = new LSubI(left, right); 1313 LSubI* sub = new LSubI(left, right);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 } 1426 }
1297 1427
1298 1428
1299 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1429 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1300 Abort("Unimplemented: %s", "DoClassOfTest"); 1430 Abort("Unimplemented: %s", "DoClassOfTest");
1301 return NULL; 1431 return NULL;
1302 } 1432 }
1303 1433
1304 1434
1305 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1435 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1306 Abort("Unimplemented: %s", "DoJSArrayLength"); 1436 LOperand* array = UseRegisterAtStart(instr->value());
1307 return NULL; 1437 return DefineAsRegister(new LJSArrayLength(array));
1308 } 1438 }
1309 1439
1310 1440
1311 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1441 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1312 Abort("Unimplemented: %s", "DoFixedArrayLength"); 1442 LOperand* array = UseRegisterAtStart(instr->value());
1313 return NULL; 1443 return DefineAsRegister(new LFixedArrayLength(array));
1314 } 1444 }
1315 1445
1316 1446
1317 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1447 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1318 Abort("Unimplemented: %s", "DoValueOf"); 1448 Abort("Unimplemented: %s", "DoValueOf");
1319 return NULL; 1449 return NULL;
1320 } 1450 }
1321 1451
1322 1452
1323 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1453 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1324 Abort("Unimplemented: %s", "DoBoundsCheck"); 1454 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1455 Use(instr->length())));
1456 }
1457
1458
1459 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1460 // The control instruction marking the end of a block that completed
1461 // abruptly (e.g., threw an exception). There is nothing specific to do.
1325 return NULL; 1462 return NULL;
1326 } 1463 }
1327 1464
1328 1465
1329 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1466 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1330 Abort("Unimplemented: %s", "DoThrow"); 1467 LOperand* value = UseFixed(instr->value(), rax);
1331 return NULL; 1468 return MarkAsCall(new LThrow(value), instr);
1332 } 1469 }
1333 1470
1334 1471
1335 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1472 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1336 Representation from = instr->from(); 1473 Representation from = instr->from();
1337 Representation to = instr->to(); 1474 Representation to = instr->to();
1338 if (from.IsTagged()) { 1475 if (from.IsTagged()) {
1339 if (to.IsDouble()) { 1476 if (to.IsDouble()) {
1340 LOperand* value = UseRegister(instr->value()); 1477 LOperand* value = UseRegister(instr->value());
1341 LNumberUntagD* res = new LNumberUntagD(value); 1478 LNumberUntagD* res = new LNumberUntagD(value);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 ASSERT(to.IsDouble()); 1525 ASSERT(to.IsDouble());
1389 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); 1526 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
1390 } 1527 }
1391 } 1528 }
1392 UNREACHABLE(); 1529 UNREACHABLE();
1393 return NULL; 1530 return NULL;
1394 } 1531 }
1395 1532
1396 1533
1397 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { 1534 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1398 Abort("Unimplemented: %s", "DoCheckNonSmi"); 1535 LOperand* value = UseRegisterAtStart(instr->value());
1399 return NULL; 1536 return AssignEnvironment(new LCheckSmi(value, zero));
1400 } 1537 }
1401 1538
1402 1539
1403 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1540 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1404 Abort("Unimplemented: %s", "DoCheckInstanceType"); 1541 LOperand* value = UseRegisterAtStart(instr->value());
1405 return NULL; 1542 LCheckInstanceType* result = new LCheckInstanceType(value);
1543 return AssignEnvironment(result);
1406 } 1544 }
1407 1545
1408 1546
1409 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { 1547 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1410 Abort("Unimplemented: %s", "DoCheckPrototypeMaps"); 1548 LOperand* temp = TempRegister();
1411 return NULL; 1549 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp);
1550 return AssignEnvironment(result);
1412 } 1551 }
1413 1552
1414 1553
1415 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 1554 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1416 Abort("Unimplemented: %s", "DoCheckSmi"); 1555 LOperand* value = UseRegisterAtStart(instr->value());
1417 return NULL; 1556 return AssignEnvironment(new LCheckSmi(value, not_zero));
1418 } 1557 }
1419 1558
1420 1559
1421 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { 1560 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1422 Abort("Unimplemented: %s", "DoCheckFunction"); 1561 LOperand* value = UseRegisterAtStart(instr->value());
1423 return NULL; 1562 return AssignEnvironment(new LCheckFunction(value));
1424 } 1563 }
1425 1564
1426 1565
1427 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { 1566 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
1428 Abort("Unimplemented: %s", "DoCheckMap"); 1567 LOperand* value = UseRegisterAtStart(instr->value());
1429 return NULL; 1568 LCheckMap* result = new LCheckMap(value);
1569 return AssignEnvironment(result);
1430 } 1570 }
1431 1571
1432 1572
1433 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1573 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1434 return new LReturn(UseFixed(instr->value(), rax)); 1574 return new LReturn(UseFixed(instr->value(), rax));
1435 } 1575 }
1436 1576
1437 1577
1438 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1578 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1439 Representation r = instr->representation(); 1579 Representation r = instr->representation();
1440 if (r.IsInteger32()) { 1580 if (r.IsInteger32()) {
1441 int32_t value = instr->Integer32Value(); 1581 return DefineAsRegister(new LConstantI);
1442 return DefineAsRegister(new LConstantI(value));
1443 } else if (r.IsDouble()) { 1582 } else if (r.IsDouble()) {
1444 double value = instr->DoubleValue();
1445 LOperand* temp = TempRegister(); 1583 LOperand* temp = TempRegister();
1446 return DefineAsRegister(new LConstantD(value, temp)); 1584 return DefineAsRegister(new LConstantD(temp));
1447 } else if (r.IsTagged()) { 1585 } else if (r.IsTagged()) {
1448 return DefineAsRegister(new LConstantT(instr->handle())); 1586 return DefineAsRegister(new LConstantT);
1449 } else { 1587 } else {
1450 UNREACHABLE(); 1588 UNREACHABLE();
1451 return NULL; 1589 return NULL;
1452 } 1590 }
1453 } 1591 }
1454 1592
1455 1593
1456 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1594 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1457 Abort("Unimplemented: %s", "DoLoadGlobal"); 1595 LLoadGlobal* result = new LLoadGlobal;
1458 return NULL; 1596 return instr->check_hole_value()
1597 ? AssignEnvironment(DefineAsRegister(result))
1598 : DefineAsRegister(result);
1459 } 1599 }
1460 1600
1461 1601
1462 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1602 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1463 Abort("Unimplemented: %s", "DoStoreGlobal"); 1603 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()),
1464 return NULL; 1604 TempRegister());
1605 return instr->check_hole_value() ? AssignEnvironment(result) : result;
1465 } 1606 }
1466 1607
1467 1608
1468 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1609 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1469 Abort("Unimplemented: %s", "DoLoadContextSlot"); 1610 Abort("Unimplemented: %s", "DoLoadContextSlot");
1470 return NULL; 1611 return NULL;
1471 } 1612 }
1472 1613
1473 1614
1615 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1616 Abort("Unimplemented: DoStoreContextSlot");
1617 return NULL;
1618 }
1619
1620
1474 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1621 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1475 Abort("Unimplemented: %s", "DoLoadNamedField"); 1622 ASSERT(instr->representation().IsTagged());
1476 return NULL; 1623 LOperand* obj = UseRegisterAtStart(instr->object());
1624 return DefineAsRegister(new LLoadNamedField(obj));
1477 } 1625 }
1478 1626
1479 1627
1480 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 1628 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1481 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); 1629 LOperand* object = UseFixed(instr->object(), rax);
1482 return NULL; 1630 LLoadNamedGeneric* result = new LLoadNamedGeneric(object);
1631 return MarkAsCall(DefineFixed(result, rax), instr);
1483 } 1632 }
1484 1633
1485 1634
1486 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( 1635 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1487 HLoadFunctionPrototype* instr) { 1636 HLoadFunctionPrototype* instr) {
1488 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); 1637 Abort("Unimplemented: %s", "DoLoadFunctionPrototype");
1489 return NULL; 1638 return NULL;
1490 } 1639 }
1491 1640
1492 1641
1493 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { 1642 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1494 Abort("Unimplemented: %s", "DoLoadElements"); 1643 LOperand* input = UseRegisterAtStart(instr->value());
1495 return NULL; 1644 return DefineSameAsFirst(new LLoadElements(input));
1496 } 1645 }
1497 1646
1498 1647
1499 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1648 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1500 HLoadKeyedFastElement* instr) { 1649 HLoadKeyedFastElement* instr) {
1501 Abort("Unimplemented: %s", "DoLoadKeyedFastElement"); 1650 ASSERT(instr->representation().IsTagged());
1502 return NULL; 1651 ASSERT(instr->key()->representation().IsInteger32());
1652 LOperand* obj = UseRegisterAtStart(instr->object());
1653 LOperand* key = UseRegisterAtStart(instr->key());
1654 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1655 return AssignEnvironment(DefineSameAsFirst(result));
1503 } 1656 }
1504 1657
1505 1658
1506 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1659 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1507 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); 1660 Abort("Unimplemented: %s", "DoLoadKeyedGeneric");
1508 return NULL; 1661 return NULL;
1509 } 1662 }
1510 1663
1511 1664
1512 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( 1665 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1513 HStoreKeyedFastElement* instr) { 1666 HStoreKeyedFastElement* instr) {
1514 Abort("Unimplemented: %s", "DoStoreKeyedFastElement"); 1667 bool needs_write_barrier = instr->NeedsWriteBarrier();
1515 return NULL; 1668 ASSERT(instr->value()->representation().IsTagged());
1669 ASSERT(instr->object()->representation().IsTagged());
1670 ASSERT(instr->key()->representation().IsInteger32());
1671
1672 LOperand* obj = UseTempRegister(instr->object());
1673 LOperand* val = needs_write_barrier
1674 ? UseTempRegister(instr->value())
1675 : UseRegisterAtStart(instr->value());
1676 LOperand* key = needs_write_barrier
1677 ? UseTempRegister(instr->key())
1678 : UseRegisterOrConstantAtStart(instr->key());
1679
1680 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1516 } 1681 }
1517 1682
1518 1683
1519 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 1684 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1520 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); 1685 Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
1521 return NULL; 1686 return NULL;
1522 } 1687 }
1523 1688
1524 1689
1525 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 1690 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1526 Abort("Unimplemented: %s", "DoStoreNamedField"); 1691 bool needs_write_barrier = instr->NeedsWriteBarrier();
1527 return NULL; 1692
1693 LOperand* obj = needs_write_barrier
1694 ? UseTempRegister(instr->object())
1695 : UseRegisterAtStart(instr->object());
1696
1697 LOperand* val = needs_write_barrier
1698 ? UseTempRegister(instr->value())
1699 : UseRegister(instr->value());
1700
1701 // We only need a scratch register if we have a write barrier or we
1702 // have a store into the properties array (not in-object-property).
1703 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1704 ? TempRegister() : NULL;
1705
1706 return new LStoreNamedField(obj, val, temp);
1528 } 1707 }
1529 1708
1530 1709
1531 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1710 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1532 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); 1711 Abort("Unimplemented: %s", "DoStoreNamedGeneric");
1533 return NULL; 1712 return NULL;
1534 } 1713 }
1535 1714
1536 1715
1537 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 1716 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
1538 Abort("Unimplemented: %s", "DoStringCharCodeAt"); 1717 Abort("Unimplemented: %s", "DoStringCharCodeAt");
1539 return NULL; 1718 return NULL;
1540 } 1719 }
1541 1720
1542 1721
1543 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { 1722 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
1544 Abort("Unimplemented: %s", "DoStringLength"); 1723 Abort("Unimplemented: %s", "DoStringLength");
1545 return NULL; 1724 return NULL;
1546 } 1725 }
1547 1726
1548 1727
1549 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1728 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1550 Abort("Unimplemented: %s", "DoArrayLiteral"); 1729 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr);
1551 return NULL;
1552 } 1730 }
1553 1731
1554 1732
1555 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 1733 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1556 Abort("Unimplemented: %s", "DoObjectLiteral"); 1734 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr);
1557 return NULL;
1558 } 1735 }
1559 1736
1560 1737
1561 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 1738 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1562 Abort("Unimplemented: %s", "DoRegExpLiteral"); 1739 Abort("Unimplemented: %s", "DoRegExpLiteral");
1563 return NULL; 1740 return NULL;
1564 } 1741 }
1565 1742
1566 1743
1567 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 1744 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1568 Abort("Unimplemented: %s", "DoFunctionLiteral"); 1745 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr);
1569 return NULL;
1570 } 1746 }
1571 1747
1572 1748
1573 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 1749 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1574 Abort("Unimplemented: %s", "DoDeleteProperty"); 1750 Abort("Unimplemented: %s", "DoDeleteProperty");
1575 return NULL; 1751 return NULL;
1576 } 1752 }
1577 1753
1578 1754
1579 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1755 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1580 Abort("Unimplemented: %s", "DoOsrEntry"); 1756 Abort("Unimplemented: %s", "DoOsrEntry");
1581 return NULL; 1757 return NULL;
1582 } 1758 }
1583 1759
1584 1760
1585 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 1761 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
1586 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 1762 int spill_index = chunk()->GetParameterStackSlot(instr->index());
1587 return DefineAsSpilled(new LParameter, spill_index); 1763 return DefineAsSpilled(new LParameter, spill_index);
1588 } 1764 }
1589 1765
1590 1766
1591 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 1767 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
1592 Abort("Unimplemented: %s", "DoUnknownOSRValue"); 1768 Abort("Unimplemented: %s", "DoUnknownOSRValue");
1593 return NULL; 1769 return NULL;
1594 } 1770 }
1595 1771
1596 1772
1597 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 1773 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
1598 Abort("Unimplemented: %s", "DoCallStub"); 1774 argument_count_ -= instr->argument_count();
1599 return NULL; 1775 return MarkAsCall(DefineFixed(new LCallStub, rax), instr);
1600 } 1776 }
1601 1777
1602 1778
1603 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 1779 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
1604 Abort("Unimplemented: %s", "DoArgumentsObject"); 1780 Abort("Unimplemented: %s", "DoArgumentsObject");
1605 return NULL; 1781 return NULL;
1606 } 1782 }
1607 1783
1608 1784
1609 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1785 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
1610 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); 1786 Abort("Unimplemented: %s", "DoAccessArgumentsAt");
1611 return NULL; 1787 return NULL;
1612 } 1788 }
1613 1789
1614 1790
1615 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1791 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1616 Abort("Unimplemented: %s", "DoTypeof"); 1792 Abort("Unimplemented: %s", "DoTypeof");
1617 return NULL; 1793 return NULL;
1618 } 1794 }
1619 1795
1620 1796
1621 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1797 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1622 Abort("Unimplemented: %s", "DoTypeofIs"); 1798 Abort("Unimplemented: %s", "DoTypeofIs");
1623 return NULL; 1799 return NULL;
1624 } 1800 }
1625 1801
1802
1803 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
1804 return DefineAsRegister(new LIsConstructCall);
1805 }
1806
1807
1626 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1808 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1627 HEnvironment* env = current_block_->last_environment(); 1809 HEnvironment* env = current_block_->last_environment();
1628 ASSERT(env != NULL); 1810 ASSERT(env != NULL);
1629 1811
1630 env->set_ast_id(instr->ast_id()); 1812 env->set_ast_id(instr->ast_id());
1631 1813
1632 env->Drop(instr->pop_count()); 1814 env->Drop(instr->pop_count());
1633 for (int i = 0; i < instr->values()->length(); ++i) { 1815 for (int i = 0; i < instr->values()->length(); ++i) {
1634 HValue* value = instr->values()->at(i); 1816 HValue* value = instr->values()->at(i);
1635 if (instr->HasAssignedIndexAt(i)) { 1817 if (instr->HasAssignedIndexAt(i)) {
1636 env->Bind(instr->GetAssignedIndexAt(i), value); 1818 env->Bind(instr->GetAssignedIndexAt(i), value);
1637 } else { 1819 } else {
1638 env->Push(value); 1820 env->Push(value);
1639 } 1821 }
1640 } 1822 }
1641 ASSERT(env->length() == instr->environment_length()); 1823 ASSERT(env->length() == instr->environment_length());
1642 1824
1643 // If there is an instruction pending deoptimization environment create a 1825 // If there is an instruction pending deoptimization environment create a
1644 // lazy bailout instruction to capture the environment. 1826 // lazy bailout instruction to capture the environment.
1645 if (pending_deoptimization_ast_id_ == instr->ast_id()) { 1827 if (pending_deoptimization_ast_id_ == instr->ast_id()) {
1646 LLazyBailout* lazy_bailout = new LLazyBailout; 1828 LLazyBailout* lazy_bailout = new LLazyBailout;
1647 LInstruction* result = AssignEnvironment(lazy_bailout); 1829 LInstruction* result = AssignEnvironment(lazy_bailout);
1648 instructions_pending_deoptimization_environment_-> 1830 instruction_pending_deoptimization_environment_->
1649 set_deoptimization_environment(result->environment()); 1831 set_deoptimization_environment(result->environment());
1650 ClearInstructionPendingDeoptimizationEnvironment(); 1832 ClearInstructionPendingDeoptimizationEnvironment();
1651 return result; 1833 return result;
1652 } 1834 }
1653 1835
1654 return NULL; 1836 return NULL;
1655 } 1837 }
1656 1838
1657 1839
1658 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 1840 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
1659 return MarkAsCall(new LStackCheck, instr); 1841 return MarkAsCall(new LStackCheck, instr);
1660 } 1842 }
1661 1843
1662 1844
1663 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 1845 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
1664 Abort("Unimplemented: %s", "DoEnterInlined"); 1846 HEnvironment* outer = current_block_->last_environment();
1847 HConstant* undefined = graph()->GetConstantUndefined();
1848 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
1849 instr->function(),
1850 false,
1851 undefined);
1852 current_block_->UpdateEnvironment(inner);
1853 chunk_->AddInlinedClosure(instr->closure());
1665 return NULL; 1854 return NULL;
1666 } 1855 }
1667 1856
1668 1857
1669 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1858 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1670 Abort("Unimplemented: %s", "DoLeaveInlined"); 1859 HEnvironment* outer = current_block_->last_environment()->outer();
1860 current_block_->UpdateEnvironment(outer);
1671 return NULL; 1861 return NULL;
1672 } 1862 }
1673 1863
1674 } } // namespace v8::internal 1864 } } // namespace v8::internal
1675 1865
1676 #endif // V8_TARGET_ARCH_X64 1866 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698