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

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

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 #ifdef DEBUG 72 #ifdef DEBUG
73 void LInstruction::VerifyCall() { 73 void LInstruction::VerifyCall() {
74 // Call instructions can use only fixed registers as temporaries and 74 // Call instructions can use only fixed registers as temporaries and
75 // outputs because all registers are blocked by the calling convention. 75 // outputs because all registers are blocked by the calling convention.
76 // Inputs operands must use a fixed register or use-at-start policy or 76 // Inputs operands must use a fixed register or use-at-start policy or
77 // a non-register policy. 77 // a non-register policy.
78 ASSERT(Output() == NULL || 78 ASSERT(Output() == NULL ||
79 LUnallocated::cast(Output())->HasFixedPolicy() || 79 LUnallocated::cast(Output())->HasFixedPolicy() ||
80 !LUnallocated::cast(Output())->HasRegisterPolicy()); 80 !LUnallocated::cast(Output())->HasRegisterPolicy());
81 for (UseIterator it(this); it.HasNext(); it.Advance()) { 81 for (UseIterator it(this); !it.Done(); it.Advance()) {
82 LUnallocated* operand = LUnallocated::cast(it.Next()); 82 LUnallocated* operand = LUnallocated::cast(it.Current());
83 ASSERT(operand->HasFixedPolicy() || 83 ASSERT(operand->HasFixedPolicy() ||
84 operand->IsUsedAtStart()); 84 operand->IsUsedAtStart());
85 } 85 }
86 for (TempIterator it(this); it.HasNext(); it.Advance()) { 86 for (TempIterator it(this); !it.Done(); it.Advance()) {
87 LUnallocated* operand = LUnallocated::cast(it.Next()); 87 LUnallocated* operand = LUnallocated::cast(it.Current());
88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); 88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
89 } 89 }
90 } 90 }
91 #endif 91 #endif
92 92
93 93
94 void LInstruction::PrintTo(StringStream* stream) { 94 void LInstruction::PrintTo(StringStream* stream) {
95 stream->Add("%s ", this->Mnemonic()); 95 stream->Add("%s ", this->Mnemonic());
96 96
97 PrintOutputOperandTo(stream); 97 PrintOutputOperandTo(stream);
98 98
99 PrintDataTo(stream); 99 PrintDataTo(stream);
100 100
101 if (HasEnvironment()) { 101 if (HasEnvironment()) {
102 stream->Add(" "); 102 stream->Add(" ");
103 environment()->PrintTo(stream); 103 environment()->PrintTo(stream);
104 } 104 }
105 105
106 if (HasPointerMap()) { 106 if (HasPointerMap()) {
107 stream->Add(" "); 107 stream->Add(" ");
108 pointer_map()->PrintTo(stream); 108 pointer_map()->PrintTo(stream);
109 } 109 }
110 } 110 }
111 111
112 112
113 template<int R, int I, int T> 113 template<int R, int I, int T>
114 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { 114 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
115 stream->Add("= "); 115 stream->Add("= ");
116 inputs_.PrintOperandsTo(stream); 116 for (int i = 0; i < inputs_.length(); i++) {
117 if (i > 0) stream->Add(" ");
118 inputs_[i]->PrintTo(stream);
119 }
117 } 120 }
118 121
119 122
120 template<int R, int I, int T> 123 template<int R, int I, int T>
121 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { 124 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
122 results_.PrintOperandsTo(stream); 125 for (int i = 0; i < results_.length(); i++) {
123 }
124
125
126 template<typename T, int N>
127 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
128 for (int i = 0; i < N; i++) {
129 if (i > 0) stream->Add(" "); 126 if (i > 0) stream->Add(" ");
130 elems_[i]->PrintTo(stream); 127 results_[i]->PrintTo(stream);
131 } 128 }
132 } 129 }
133 130
134 131
135 void LLabel::PrintDataTo(StringStream* stream) { 132 void LLabel::PrintDataTo(StringStream* stream) {
136 LGap::PrintDataTo(stream); 133 LGap::PrintDataTo(stream);
137 LLabel* rep = replacement(); 134 LLabel* rep = replacement();
138 if (rep != NULL) { 135 if (rep != NULL) {
139 stream->Add(" Dead block replaced with B%d", rep->block_id()); 136 stream->Add(" Dead block replaced with B%d", rep->block_id());
140 } 137 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { 260 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
264 stream->Add("if class_of_test("); 261 stream->Add("if class_of_test(");
265 InputAt(0)->PrintTo(stream); 262 InputAt(0)->PrintTo(stream);
266 stream->Add(", \"%o\") then B%d else B%d", 263 stream->Add(", \"%o\") then B%d else B%d",
267 *hydrogen()->class_name(), 264 *hydrogen()->class_name(),
268 true_block_id(), 265 true_block_id(),
269 false_block_id()); 266 false_block_id());
270 } 267 }
271 268
272 269
273 void LTypeofIs::PrintDataTo(StringStream* stream) {
274 InputAt(0)->PrintTo(stream);
275 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
276 }
277
278
279 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { 270 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
280 stream->Add("if typeof "); 271 stream->Add("if typeof ");
281 InputAt(0)->PrintTo(stream); 272 InputAt(0)->PrintTo(stream);
282 stream->Add(" == \"%s\" then B%d else B%d", 273 stream->Add(" == \"%s\" then B%d else B%d",
283 *hydrogen()->type_literal()->ToCString(), 274 *hydrogen()->type_literal()->ToCString(),
284 true_block_id(), false_block_id()); 275 true_block_id(), false_block_id());
285 } 276 }
286 277
287 278
288 void LCallConstantFunction::PrintDataTo(StringStream* stream) { 279 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 331 }
341 332
342 333
343 void LCallNew::PrintDataTo(StringStream* stream) { 334 void LCallNew::PrintDataTo(StringStream* stream) {
344 stream->Add("= "); 335 stream->Add("= ");
345 InputAt(0)->PrintTo(stream); 336 InputAt(0)->PrintTo(stream);
346 stream->Add(" #%d / ", arity()); 337 stream->Add(" #%d / ", arity());
347 } 338 }
348 339
349 340
350 void LClassOfTest::PrintDataTo(StringStream* stream) {
351 stream->Add("= class_of_test(");
352 InputAt(0)->PrintTo(stream);
353 stream->Add(", \"%o\")", *hydrogen()->class_name());
354 }
355
356
357 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { 341 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
358 arguments()->PrintTo(stream); 342 arguments()->PrintTo(stream);
359 343
360 stream->Add(" length "); 344 stream->Add(" length ");
361 length()->PrintTo(stream); 345 length()->PrintTo(stream);
362 346
363 stream->Add(" index "); 347 stream->Add(" index ");
364 index()->PrintTo(stream); 348 index()->PrintTo(stream);
365 } 349 }
366 350
(...skipping 20 matching lines...) Expand all
387 for (int i = 0; i < graph()->blocks()->length(); ++i) { 371 for (int i = 0; i < graph()->blocks()->length(); ++i) {
388 HBasicBlock* block = graph()->blocks()->at(i); 372 HBasicBlock* block = graph()->blocks()->at(i);
389 int first = block->first_instruction_index(); 373 int first = block->first_instruction_index();
390 int last = block->last_instruction_index(); 374 int last = block->last_instruction_index();
391 LInstruction* first_instr = instructions()->at(first); 375 LInstruction* first_instr = instructions()->at(first);
392 LInstruction* last_instr = instructions()->at(last); 376 LInstruction* last_instr = instructions()->at(last);
393 377
394 LLabel* label = LLabel::cast(first_instr); 378 LLabel* label = LLabel::cast(first_instr);
395 if (last_instr->IsGoto()) { 379 if (last_instr->IsGoto()) {
396 LGoto* goto_instr = LGoto::cast(last_instr); 380 LGoto* goto_instr = LGoto::cast(last_instr);
397 if (!goto_instr->include_stack_check() && 381 if (label->IsRedundant() &&
398 label->IsRedundant() &&
399 !label->is_loop_header()) { 382 !label->is_loop_header()) {
400 bool can_eliminate = true; 383 bool can_eliminate = true;
401 for (int i = first + 1; i < last && can_eliminate; ++i) { 384 for (int i = first + 1; i < last && can_eliminate; ++i) {
402 LInstruction* cur = instructions()->at(i); 385 LInstruction* cur = instructions()->at(i);
403 if (cur->IsGap()) { 386 if (cur->IsGap()) {
404 LGap* gap = LGap::cast(cur); 387 LGap* gap = LGap::cast(cur);
405 if (!gap->IsRedundant()) { 388 if (!gap->IsRedundant()) {
406 can_eliminate = false; 389 can_eliminate = false;
407 } 390 }
408 } else { 391 } else {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 allocator_->RecordTemporary(operand); 780 allocator_->RecordTemporary(operand);
798 return operand; 781 return operand;
799 } 782 }
800 783
801 784
802 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { 785 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
803 return new LLabel(instr->block()); 786 return new LLabel(instr->block());
804 } 787 }
805 788
806 789
790 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
791 return AssignEnvironment(new LDeoptimize);
792 }
793
794
807 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 795 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
808 return AssignEnvironment(new LDeoptimize); 796 return AssignEnvironment(new LDeoptimize);
809 } 797 }
810 798
811 799
812 LInstruction* LChunkBuilder::DoBit(Token::Value op, 800 LInstruction* LChunkBuilder::DoBit(Token::Value op,
813 HBitwiseBinaryOperation* instr) { 801 HBitwiseBinaryOperation* instr) {
814 if (instr->representation().IsInteger32()) { 802 if (instr->representation().IsInteger32()) {
815 ASSERT(instr->left()->representation().IsInteger32()); 803 ASSERT(instr->left()->representation().IsInteger32());
816 ASSERT(instr->right()->representation().IsInteger32()); 804 ASSERT(instr->right()->representation().IsInteger32());
817 805
818 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 806 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
819 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 807 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
820 return DefineSameAsFirst(new LBitI(op, left, right)); 808 return DefineSameAsFirst(new LBitI(op, left, right));
821 } else { 809 } else {
822 ASSERT(instr->representation().IsTagged()); 810 ASSERT(instr->representation().IsTagged());
823 ASSERT(instr->left()->representation().IsTagged()); 811 ASSERT(instr->left()->representation().IsTagged());
824 ASSERT(instr->right()->representation().IsTagged()); 812 ASSERT(instr->right()->representation().IsTagged());
825 813
814 LOperand* context = UseFixed(instr->context(), esi);
826 LOperand* left = UseFixed(instr->left(), edx); 815 LOperand* left = UseFixed(instr->left(), edx);
827 LOperand* right = UseFixed(instr->right(), eax); 816 LOperand* right = UseFixed(instr->right(), eax);
828 LArithmeticT* result = new LArithmeticT(op, left, right); 817 LArithmeticT* result = new LArithmeticT(op, context, left, right);
829 return MarkAsCall(DefineFixed(result, eax), instr); 818 return MarkAsCall(DefineFixed(result, eax), instr);
830 } 819 }
831 } 820 }
832 821
833 822
834 LInstruction* LChunkBuilder::DoShift(Token::Value op, 823 LInstruction* LChunkBuilder::DoShift(Token::Value op,
835 HBitwiseBinaryOperation* instr) { 824 HBitwiseBinaryOperation* instr) {
836 if (instr->representation().IsTagged()) { 825 if (instr->representation().IsTagged()) {
837 ASSERT(instr->left()->representation().IsTagged()); 826 ASSERT(instr->left()->representation().IsTagged());
838 ASSERT(instr->right()->representation().IsTagged()); 827 ASSERT(instr->right()->representation().IsTagged());
839 828
829 LOperand* context = UseFixed(instr->context(), esi);
840 LOperand* left = UseFixed(instr->left(), edx); 830 LOperand* left = UseFixed(instr->left(), edx);
841 LOperand* right = UseFixed(instr->right(), eax); 831 LOperand* right = UseFixed(instr->right(), eax);
842 LArithmeticT* result = new LArithmeticT(op, left, right); 832 LArithmeticT* result = new LArithmeticT(op, context, left, right);
843 return MarkAsCall(DefineFixed(result, eax), instr); 833 return MarkAsCall(DefineFixed(result, eax), instr);
844 } 834 }
845 835
846 ASSERT(instr->representation().IsInteger32()); 836 ASSERT(instr->representation().IsInteger32());
847 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 837 ASSERT(instr->left()->representation().IsInteger32());
848 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 838 ASSERT(instr->right()->representation().IsInteger32());
849 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 839 LOperand* left = UseRegisterAtStart(instr->left());
850 840
851 HValue* right_value = instr->OperandAt(1); 841 HValue* right_value = instr->right();
852 LOperand* right = NULL; 842 LOperand* right = NULL;
853 int constant_value = 0; 843 int constant_value = 0;
854 if (right_value->IsConstant()) { 844 if (right_value->IsConstant()) {
855 HConstant* constant = HConstant::cast(right_value); 845 HConstant* constant = HConstant::cast(right_value);
856 right = chunk_->DefineConstantOperand(constant); 846 right = chunk_->DefineConstantOperand(constant);
857 constant_value = constant->Integer32Value() & 0x1f; 847 constant_value = constant->Integer32Value() & 0x1f;
858 } else { 848 } else {
859 right = UseFixed(right_value, ecx); 849 right = UseFixed(right_value, ecx);
860 } 850 }
861 851
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 HArithmeticBinaryOperation* instr) { 885 HArithmeticBinaryOperation* instr) {
896 ASSERT(op == Token::ADD || 886 ASSERT(op == Token::ADD ||
897 op == Token::DIV || 887 op == Token::DIV ||
898 op == Token::MOD || 888 op == Token::MOD ||
899 op == Token::MUL || 889 op == Token::MUL ||
900 op == Token::SUB); 890 op == Token::SUB);
901 HValue* left = instr->left(); 891 HValue* left = instr->left();
902 HValue* right = instr->right(); 892 HValue* right = instr->right();
903 ASSERT(left->representation().IsTagged()); 893 ASSERT(left->representation().IsTagged());
904 ASSERT(right->representation().IsTagged()); 894 ASSERT(right->representation().IsTagged());
895 LOperand* context = UseFixed(instr->context(), esi);
905 LOperand* left_operand = UseFixed(left, edx); 896 LOperand* left_operand = UseFixed(left, edx);
906 LOperand* right_operand = UseFixed(right, eax); 897 LOperand* right_operand = UseFixed(right, eax);
907 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); 898 LArithmeticT* result =
899 new LArithmeticT(op, context, left_operand, right_operand);
908 return MarkAsCall(DefineFixed(result, eax), instr); 900 return MarkAsCall(DefineFixed(result, eax), instr);
909 } 901 }
910 902
903
911 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 904 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
912 ASSERT(is_building()); 905 ASSERT(is_building());
913 current_block_ = block; 906 current_block_ = block;
914 next_block_ = next_block; 907 next_block_ = next_block;
915 if (block->IsStartBlock()) { 908 if (block->IsStartBlock()) {
916 block->UpdateEnvironment(graph_->start_environment()); 909 block->UpdateEnvironment(graph_->start_environment());
917 argument_count_ = 0; 910 argument_count_ = 0;
918 } else if (block->predecessors()->length() == 1) { 911 } else if (block->predecessors()->length() == 1) {
919 // We have a single predecessor => copy environment and outgoing 912 // We have a single predecessor => copy environment and outgoing
920 // argument count from the predecessor. 913 // argument count from the predecessor.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 if (current->has_position()) position_ = current->position(); 970 if (current->has_position()) position_ = current->position();
978 LInstruction* instr = current->CompileToLithium(this); 971 LInstruction* instr = current->CompileToLithium(this);
979 972
980 if (instr != NULL) { 973 if (instr != NULL) {
981 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 974 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
982 instr = AssignPointerMap(instr); 975 instr = AssignPointerMap(instr);
983 } 976 }
984 if (FLAG_stress_environments && !instr->HasEnvironment()) { 977 if (FLAG_stress_environments && !instr->HasEnvironment()) {
985 instr = AssignEnvironment(instr); 978 instr = AssignEnvironment(instr);
986 } 979 }
987 if (current->IsTest() && !instr->IsGoto()) { 980 instr->set_hydrogen_value(current);
988 ASSERT(instr->IsControl());
989 HTest* test = HTest::cast(current);
990 instr->set_hydrogen_value(test->value());
991 HBasicBlock* first = test->FirstSuccessor();
992 HBasicBlock* second = test->SecondSuccessor();
993 ASSERT(first != NULL && second != NULL);
994 instr->SetBranchTargets(first->block_id(), second->block_id());
995 } else {
996 instr->set_hydrogen_value(current);
997 }
998
999 chunk_->AddInstruction(instr, current_block_); 981 chunk_->AddInstruction(instr, current_block_);
1000 } 982 }
1001 current_instruction_ = old_current; 983 current_instruction_ = old_current;
1002 } 984 }
1003 985
1004 986
1005 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 987 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1006 if (hydrogen_env == NULL) return NULL; 988 if (hydrogen_env == NULL) return NULL;
1007 989
1008 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 990 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
(...skipping 20 matching lines...) Expand all
1029 op = UseAny(value); 1011 op = UseAny(value);
1030 } 1012 }
1031 result->AddValue(op, value->representation()); 1013 result->AddValue(op, value->representation());
1032 } 1014 }
1033 1015
1034 return result; 1016 return result;
1035 } 1017 }
1036 1018
1037 1019
1038 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1020 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1039 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), 1021 return new LGoto(instr->FirstSuccessor()->block_id());
1040 instr->include_stack_check());
1041 return (instr->include_stack_check())
1042 ? AssignPointerMap(result)
1043 : result;
1044 } 1022 }
1045 1023
1046 1024
1047 LInstruction* LChunkBuilder::DoTest(HTest* instr) { 1025 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1048 HValue* v = instr->value(); 1026 HValue* v = instr->value();
1049 if (!v->EmitAtUses()) { 1027 if (v->EmitAtUses()) {
1050 return new LBranch(UseRegisterAtStart(v)); 1028 ASSERT(v->IsConstant());
1051 } else if (v->IsClassOfTest()) { 1029 ASSERT(!v->representation().IsDouble());
1052 HClassOfTest* compare = HClassOfTest::cast(v);
1053 ASSERT(compare->value()->representation().IsTagged());
1054 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1055 TempRegister(),
1056 TempRegister());
1057 } else if (v->IsCompare()) {
1058 HCompare* compare = HCompare::cast(v);
1059 Token::Value op = compare->token();
1060 HValue* left = compare->left();
1061 HValue* right = compare->right();
1062 Representation r = compare->GetInputRepresentation();
1063 if (r.IsInteger32()) {
1064 ASSERT(left->representation().IsInteger32());
1065 ASSERT(right->representation().IsInteger32());
1066 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1067 UseOrConstantAtStart(right));
1068 } else if (r.IsDouble()) {
1069 ASSERT(left->representation().IsDouble());
1070 ASSERT(right->representation().IsDouble());
1071 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1072 UseRegisterAtStart(right));
1073 } else {
1074 ASSERT(left->representation().IsTagged());
1075 ASSERT(right->representation().IsTagged());
1076 bool reversed = op == Token::GT || op == Token::LTE;
1077 LOperand* left_operand = UseFixed(left, reversed ? eax : edx);
1078 LOperand* right_operand = UseFixed(right, reversed ? edx : eax);
1079 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, right_operand);
1080 return MarkAsCall(result, instr);
1081 }
1082 } else if (v->IsIsSmi()) {
1083 HIsSmi* compare = HIsSmi::cast(v);
1084 ASSERT(compare->value()->representation().IsTagged());
1085 return new LIsSmiAndBranch(Use(compare->value()));
1086 } else if (v->IsIsUndetectable()) {
1087 HIsUndetectable* compare = HIsUndetectable::cast(v);
1088 ASSERT(compare->value()->representation().IsTagged());
1089 return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
1090 TempRegister());
1091 } else if (v->IsHasInstanceType()) {
1092 HHasInstanceType* compare = HHasInstanceType::cast(v);
1093 ASSERT(compare->value()->representation().IsTagged());
1094 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()),
1095 TempRegister());
1096 } else if (v->IsHasCachedArrayIndex()) {
1097 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
1098 ASSERT(compare->value()->representation().IsTagged());
1099 return new LHasCachedArrayIndexAndBranch(
1100 UseRegisterAtStart(compare->value()));
1101 } else if (v->IsIsNull()) {
1102 HIsNull* compare = HIsNull::cast(v);
1103 ASSERT(compare->value()->representation().IsTagged());
1104 // We only need a temp register for non-strict compare.
1105 LOperand* temp = compare->is_strict() ? NULL : TempRegister();
1106 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), temp);
1107 } else if (v->IsIsObject()) {
1108 HIsObject* compare = HIsObject::cast(v);
1109 ASSERT(compare->value()->representation().IsTagged());
1110 LOperand* temp1 = TempRegister();
1111 LOperand* temp2 = TempRegister();
1112 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
1113 temp1,
1114 temp2);
1115 } else if (v->IsCompareJSObjectEq()) {
1116 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1117 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1118 UseRegisterAtStart(compare->right()));
1119 } else if (v->IsCompareSymbolEq()) {
1120 HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
1121 return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
1122 UseRegisterAtStart(compare->right()));
1123 } else if (v->IsInstanceOf()) {
1124 HInstanceOf* instance_of = HInstanceOf::cast(v);
1125 LOperand* left = UseFixed(instance_of->left(), InstanceofStub::left());
1126 LOperand* right = UseFixed(instance_of->right(), InstanceofStub::right());
1127 LOperand* context = UseFixed(instance_of->context(), esi);
1128 LInstanceOfAndBranch* result =
1129 new LInstanceOfAndBranch(context, left, right);
1130 return MarkAsCall(result, instr);
1131 } else if (v->IsTypeofIs()) {
1132 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1133 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1134 } else if (v->IsIsConstructCall()) {
1135 return new LIsConstructCallAndBranch(TempRegister());
1136 } else if (v->IsConstant()) {
1137 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() 1030 HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
1138 ? instr->FirstSuccessor() 1031 ? instr->FirstSuccessor()
1139 : instr->SecondSuccessor(); 1032 : instr->SecondSuccessor();
1140 return new LGoto(successor->block_id()); 1033 return new LGoto(successor->block_id());
1141 } else {
1142 Abort("Undefined compare before branch");
1143 return NULL;
1144 } 1034 }
1035 return new LBranch(UseRegisterAtStart(v));
1145 } 1036 }
1146 1037
1147 1038
1148 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 1039 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1149 ASSERT(instr->value()->representation().IsTagged()); 1040 ASSERT(instr->value()->representation().IsTagged());
1150 LOperand* value = UseRegisterAtStart(instr->value()); 1041 LOperand* value = UseRegisterAtStart(instr->value());
1151 return new LCmpMapAndBranch(value); 1042 return new LCmpMapAndBranch(value);
1152 } 1043 }
1153 1044
1154 1045
(...skipping 13 matching lines...) Expand all
1168 LOperand* context = UseFixed(instr->context(), esi); 1059 LOperand* context = UseFixed(instr->context(), esi);
1169 LInstanceOf* result = new LInstanceOf(context, left, right); 1060 LInstanceOf* result = new LInstanceOf(context, left, right);
1170 return MarkAsCall(DefineFixed(result, eax), instr); 1061 return MarkAsCall(DefineFixed(result, eax), instr);
1171 } 1062 }
1172 1063
1173 1064
1174 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1065 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1175 HInstanceOfKnownGlobal* instr) { 1066 HInstanceOfKnownGlobal* instr) {
1176 LInstanceOfKnownGlobal* result = 1067 LInstanceOfKnownGlobal* result =
1177 new LInstanceOfKnownGlobal( 1068 new LInstanceOfKnownGlobal(
1178 UseFixed(instr->value(), InstanceofStub::left()), 1069 UseFixed(instr->context(), esi),
1070 UseFixed(instr->left(), InstanceofStub::left()),
1179 FixedTemp(edi)); 1071 FixedTemp(edi));
1180 return MarkAsCall(DefineFixed(result, eax), instr); 1072 return MarkAsCall(DefineFixed(result, eax), instr);
1181 } 1073 }
1182 1074
1183 1075
1184 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1076 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1185 LOperand* function = UseFixed(instr->function(), edi); 1077 LOperand* function = UseFixed(instr->function(), edi);
1186 LOperand* receiver = UseFixed(instr->receiver(), eax); 1078 LOperand* receiver = UseFixed(instr->receiver(), eax);
1187 LOperand* length = UseFixed(instr->length(), ebx); 1079 LOperand* length = UseFixed(instr->length(), ebx);
1188 LOperand* elements = UseFixed(instr->elements(), ecx); 1080 LOperand* elements = UseFixed(instr->elements(), ecx);
1189 LOperand* temp = FixedTemp(edx); 1081 LOperand* temp = FixedTemp(edx);
1190 LApplyArguments* result = new LApplyArguments(function, 1082 LApplyArguments* result = new LApplyArguments(function,
1191 receiver, 1083 receiver,
1192 length, 1084 length,
1193 elements, 1085 elements,
1194 temp); 1086 temp);
1195 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); 1087 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1196 } 1088 }
1197 1089
1198 1090
1199 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1091 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1200 ++argument_count_; 1092 ++argument_count_;
1201 LOperand* argument = UseAny(instr->argument()); 1093 LOperand* argument = UseAny(instr->argument());
1202 return new LPushArgument(argument); 1094 return new LPushArgument(argument);
1203 } 1095 }
1204 1096
1205 1097
1098 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1099 return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
1100 }
1101
1102
1206 LInstruction* LChunkBuilder::DoContext(HContext* instr) { 1103 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1207 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); 1104 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
1208 } 1105 }
1209 1106
1210 1107
1211 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { 1108 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1212 LOperand* context = UseRegisterAtStart(instr->value()); 1109 LOperand* context = UseRegisterAtStart(instr->value());
1213 return DefineAsRegister(new LOuterContext(context)); 1110 return DefineAsRegister(new LOuterContext(context));
1214 } 1111 }
1215 1112
(...skipping 24 matching lines...) Expand all
1240 LInvokeFunction* result = new LInvokeFunction(context, function); 1137 LInvokeFunction* result = new LInvokeFunction(context, function);
1241 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); 1138 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1242 } 1139 }
1243 1140
1244 1141
1245 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1142 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1246 BuiltinFunctionId op = instr->op(); 1143 BuiltinFunctionId op = instr->op();
1247 if (op == kMathLog) { 1144 if (op == kMathLog) {
1248 ASSERT(instr->representation().IsDouble()); 1145 ASSERT(instr->representation().IsDouble());
1249 ASSERT(instr->value()->representation().IsDouble()); 1146 ASSERT(instr->value()->representation().IsDouble());
1147 LOperand* context = UseAny(instr->context()); // Not actually used.
1250 LOperand* input = UseRegisterAtStart(instr->value()); 1148 LOperand* input = UseRegisterAtStart(instr->value());
1251 LUnaryMathOperation* result = new LUnaryMathOperation(input); 1149 LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
1252 return DefineSameAsFirst(result); 1150 return DefineSameAsFirst(result);
1253 } else if (op == kMathSin || op == kMathCos) { 1151 } else if (op == kMathSin || op == kMathCos) {
1152 LOperand* context = UseFixed(instr->context(), esi);
1254 LOperand* input = UseFixedDouble(instr->value(), xmm1); 1153 LOperand* input = UseFixedDouble(instr->value(), xmm1);
1255 LUnaryMathOperation* result = new LUnaryMathOperation(input); 1154 LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
1256 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); 1155 return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1257 } else { 1156 } else {
1258 LOperand* input = UseRegisterAtStart(instr->value()); 1157 LOperand* input = UseRegisterAtStart(instr->value());
1259 LUnaryMathOperation* result = new LUnaryMathOperation(input); 1158 LOperand* context = UseAny(instr->context()); // Deferred use by MathAbs.
1159 LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
1260 switch (op) { 1160 switch (op) {
1261 case kMathAbs: 1161 case kMathAbs:
1262 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1162 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1263 case kMathFloor: 1163 case kMathFloor:
1264 return AssignEnvironment(DefineAsRegister(result)); 1164 return AssignEnvironment(DefineAsRegister(result));
1265 case kMathRound: 1165 case kMathRound:
1266 return AssignEnvironment(DefineAsRegister(result)); 1166 return AssignEnvironment(DefineAsRegister(result));
1267 case kMathSqrt: 1167 case kMathSqrt:
1268 return DefineSameAsFirst(result); 1168 return DefineSameAsFirst(result);
1269 case kMathPowHalf: 1169 case kMathPowHalf:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1220 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1321 LOperand* context = UseFixed(instr->context(), esi); 1221 LOperand* context = UseFixed(instr->context(), esi);
1322 argument_count_ -= instr->argument_count(); 1222 argument_count_ -= instr->argument_count();
1323 LCallFunction* result = new LCallFunction(context); 1223 LCallFunction* result = new LCallFunction(context);
1324 return MarkAsCall(DefineFixed(result, eax), instr); 1224 return MarkAsCall(DefineFixed(result, eax), instr);
1325 } 1225 }
1326 1226
1327 1227
1328 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1228 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1329 argument_count_ -= instr->argument_count(); 1229 argument_count_ -= instr->argument_count();
1330 return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr); 1230 LOperand* context = UseFixed(instr->context(), esi);
1231 return MarkAsCall(DefineFixed(new LCallRuntime(context), eax), instr);
1331 } 1232 }
1332 1233
1333 1234
1334 LInstruction* LChunkBuilder::DoShr(HShr* instr) { 1235 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1335 return DoShift(Token::SHR, instr); 1236 return DoShift(Token::SHR, instr);
1336 } 1237 }
1337 1238
1338 1239
1339 LInstruction* LChunkBuilder::DoSar(HSar* instr) { 1240 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1340 return DoShift(Token::SAR, instr); 1241 return DoShift(Token::SAR, instr);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 LOperand* left = UseFixedDouble(instr->left(), xmm1); 1401 LOperand* left = UseFixedDouble(instr->left(), xmm1);
1501 LOperand* right = exponent_type.IsDouble() ? 1402 LOperand* right = exponent_type.IsDouble() ?
1502 UseFixedDouble(instr->right(), xmm2) : 1403 UseFixedDouble(instr->right(), xmm2) :
1503 UseFixed(instr->right(), eax); 1404 UseFixed(instr->right(), eax);
1504 LPower* result = new LPower(left, right); 1405 LPower* result = new LPower(left, right);
1505 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, 1406 return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1506 CAN_DEOPTIMIZE_EAGERLY); 1407 CAN_DEOPTIMIZE_EAGERLY);
1507 } 1408 }
1508 1409
1509 1410
1510 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1411 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1511 Token::Value op = instr->token(); 1412 Token::Value op = instr->token();
1413 ASSERT(instr->left()->representation().IsTagged());
1414 ASSERT(instr->right()->representation().IsTagged());
1415 bool reversed = (op == Token::GT || op == Token::LTE);
1416 LOperand* context = UseFixed(instr->context(), esi);
1417 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx);
1418 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax);
1419 LCmpT* result = new LCmpT(context, left, right);
1420 return MarkAsCall(DefineFixed(result, eax), instr);
1421 }
1422
1423
1424 LInstruction* LChunkBuilder::DoCompareIDAndBranch(
1425 HCompareIDAndBranch* instr) {
1512 Representation r = instr->GetInputRepresentation(); 1426 Representation r = instr->GetInputRepresentation();
1513 if (r.IsInteger32()) { 1427 if (r.IsInteger32()) {
1514 ASSERT(instr->left()->representation().IsInteger32()); 1428 ASSERT(instr->left()->representation().IsInteger32());
1515 ASSERT(instr->right()->representation().IsInteger32()); 1429 ASSERT(instr->right()->representation().IsInteger32());
1516 LOperand* left = UseRegisterAtStart(instr->left()); 1430 LOperand* left = UseRegisterAtStart(instr->left());
1517 LOperand* right = UseOrConstantAtStart(instr->right()); 1431 LOperand* right = UseOrConstantAtStart(instr->right());
1518 return DefineAsRegister(new LCmpID(left, right)); 1432 return new LCmpIDAndBranch(left, right);
1519 } else if (r.IsDouble()) { 1433 } else {
1434 ASSERT(r.IsDouble());
1520 ASSERT(instr->left()->representation().IsDouble()); 1435 ASSERT(instr->left()->representation().IsDouble());
1521 ASSERT(instr->right()->representation().IsDouble()); 1436 ASSERT(instr->right()->representation().IsDouble());
1522 LOperand* left = UseRegisterAtStart(instr->left()); 1437 LOperand* left = UseRegisterAtStart(instr->left());
1523 LOperand* right = UseRegisterAtStart(instr->right()); 1438 LOperand* right = UseRegisterAtStart(instr->right());
1524 return DefineAsRegister(new LCmpID(left, right)); 1439 return new LCmpIDAndBranch(left, right);
1525 } else {
1526 ASSERT(instr->left()->representation().IsTagged());
1527 ASSERT(instr->right()->representation().IsTagged());
1528 bool reversed = (op == Token::GT || op == Token::LTE);
1529 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx);
1530 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax);
1531 LCmpT* result = new LCmpT(left, right);
1532 return MarkAsCall(DefineFixed(result, eax), instr);
1533 } 1440 }
1534 } 1441 }
1535 1442
1536 1443
1537 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1444 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1538 HCompareJSObjectEq* instr) { 1445 HCompareObjectEqAndBranch* instr) {
1539 LOperand* left = UseRegisterAtStart(instr->left()); 1446 LOperand* left = UseRegisterAtStart(instr->left());
1540 LOperand* right = UseRegisterAtStart(instr->right()); 1447 LOperand* right = UseAtStart(instr->right());
1541 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); 1448 return new LCmpObjectEqAndBranch(left, right);
1542 return DefineAsRegister(result);
1543 } 1449 }
1544 1450
1545 1451
1546 LInstruction* LChunkBuilder::DoCompareSymbolEq( 1452 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
1547 HCompareSymbolEq* instr) { 1453 HCompareConstantEqAndBranch* instr) {
1548 LOperand* left = UseRegisterAtStart(instr->left()); 1454 return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
1549 LOperand* right = UseRegisterAtStart(instr->right());
1550 LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
1551 return DefineAsRegister(result);
1552 } 1455 }
1553 1456
1554 1457
1555 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1458 LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
1556 ASSERT(instr->value()->representation().IsTagged()); 1459 // We only need a temp register for non-strict compare.
1557 LOperand* value = UseRegisterAtStart(instr->value()); 1460 LOperand* temp = instr->is_strict() ? NULL : TempRegister();
1558 1461 return new LIsNullAndBranch(UseRegisterAtStart(instr->value()), temp);
1559 return DefineAsRegister(new LIsNull(value));
1560 } 1462 }
1561 1463
1562 1464
1563 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { 1465 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1564 ASSERT(instr->value()->representation().IsTagged()); 1466 ASSERT(instr->value()->representation().IsTagged());
1565 LOperand* value = UseRegister(instr->value()); 1467 LOperand* temp = TempRegister();
1566 1468 return new LIsObjectAndBranch(UseRegister(instr->value()), temp);
1567 return DefineAsRegister(new LIsObject(value, TempRegister()));
1568 } 1469 }
1569 1470
1570 1471
1571 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { 1472 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1572 ASSERT(instr->value()->representation().IsTagged()); 1473 ASSERT(instr->value()->representation().IsTagged());
1573 LOperand* value = UseAtStart(instr->value()); 1474 return new LIsSmiAndBranch(Use(instr->value()));
1574
1575 return DefineAsRegister(new LIsSmi(value));
1576 } 1475 }
1577 1476
1578 1477
1579 LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) { 1478 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1580 ASSERT(instr->value()->representation().IsTagged()); 1479 HIsUndetectableAndBranch* instr) {
1581 LOperand* value = UseRegisterAtStart(instr->value()); 1480 ASSERT(instr ->value()->representation().IsTagged());
1582 1481 return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
1583 return DefineAsRegister(new LIsUndetectable(value)); 1482 TempRegister());
1584 } 1483 }
1585 1484
1586 1485
1587 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { 1486 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1487 HHasInstanceTypeAndBranch* instr) {
1588 ASSERT(instr->value()->representation().IsTagged()); 1488 ASSERT(instr->value()->representation().IsTagged());
1589 LOperand* value = UseRegisterAtStart(instr->value()); 1489 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()),
1590 1490 TempRegister());
1591 return DefineAsRegister(new LHasInstanceType(value));
1592 } 1491 }
1593 1492
1594 1493
1595 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( 1494 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1596 HGetCachedArrayIndex* instr) { 1495 HGetCachedArrayIndex* instr) {
1597 ASSERT(instr->value()->representation().IsTagged()); 1496 ASSERT(instr->value()->representation().IsTagged());
1598 LOperand* value = UseRegisterAtStart(instr->value()); 1497 LOperand* value = UseRegisterAtStart(instr->value());
1599 1498
1600 return DefineAsRegister(new LGetCachedArrayIndex(value)); 1499 return DefineAsRegister(new LGetCachedArrayIndex(value));
1601 } 1500 }
1602 1501
1603 1502
1604 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( 1503 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1605 HHasCachedArrayIndex* instr) { 1504 HHasCachedArrayIndexAndBranch* instr) {
1606 ASSERT(instr->value()->representation().IsTagged()); 1505 ASSERT(instr->value()->representation().IsTagged());
1607 LOperand* value = UseRegister(instr->value()); 1506 return new LHasCachedArrayIndexAndBranch(
1608 1507 UseRegisterAtStart(instr->value()));
1609 return DefineAsRegister(new LHasCachedArrayIndex(value));
1610 } 1508 }
1611 1509
1612 1510
1613 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1511 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1512 HClassOfTestAndBranch* instr) {
1614 ASSERT(instr->value()->representation().IsTagged()); 1513 ASSERT(instr->value()->representation().IsTagged());
1615 LOperand* value = UseTempRegister(instr->value()); 1514 return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
1616 1515 TempRegister(),
1617 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); 1516 TempRegister());
1618 } 1517 }
1619 1518
1620 1519
1621 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1520 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1622 LOperand* array = UseRegisterAtStart(instr->value()); 1521 LOperand* array = UseRegisterAtStart(instr->value());
1623 return DefineAsRegister(new LJSArrayLength(array)); 1522 return DefineAsRegister(new LJSArrayLength(array));
1624 } 1523 }
1625 1524
1626 1525
1627 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1526 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1628 LOperand* array = UseRegisterAtStart(instr->value()); 1527 LOperand* array = UseRegisterAtStart(instr->value());
1629 return DefineAsRegister(new LFixedArrayLength(array)); 1528 return DefineAsRegister(new LFixedArrayLength(array));
1630 } 1529 }
1631 1530
1632 1531
1633 LInstruction* LChunkBuilder::DoExternalArrayLength( 1532 LInstruction* LChunkBuilder::DoExternalArrayLength(
1634 HExternalArrayLength* instr) { 1533 HExternalArrayLength* instr) {
1635 LOperand* array = UseRegisterAtStart(instr->value()); 1534 LOperand* array = UseRegisterAtStart(instr->value());
1636 return DefineAsRegister(new LExternalArrayLength(array)); 1535 return DefineAsRegister(new LExternalArrayLength(array));
1637 } 1536 }
1638 1537
1639 1538
1539 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
1540 LOperand* object = UseRegisterAtStart(instr->value());
1541 return DefineAsRegister(new LElementsKind(object));
1542 }
1543
1544
1640 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1545 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1641 LOperand* object = UseRegister(instr->value()); 1546 LOperand* object = UseRegister(instr->value());
1642 LValueOf* result = new LValueOf(object, TempRegister()); 1547 LValueOf* result = new LValueOf(object, TempRegister());
1643 return AssignEnvironment(DefineSameAsFirst(result)); 1548 return AssignEnvironment(DefineSameAsFirst(result));
1644 } 1549 }
1645 1550
1646 1551
1647 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1552 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1648 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1553 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1649 Use(instr->length()))); 1554 UseAtStart(instr->length())));
1650 } 1555 }
1651 1556
1652 1557
1653 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1558 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1654 // The control instruction marking the end of a block that completed 1559 // The control instruction marking the end of a block that completed
1655 // abruptly (e.g., threw an exception). There is nothing specific to do. 1560 // abruptly (e.g., threw an exception). There is nothing specific to do.
1656 return NULL; 1561 return NULL;
1657 } 1562 }
1658 1563
1659 1564
1660 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1565 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1566 LOperand* context = UseFixed(instr->context(), esi);
1661 LOperand* value = UseFixed(instr->value(), eax); 1567 LOperand* value = UseFixed(instr->value(), eax);
1662 return MarkAsCall(new LThrow(value), instr); 1568 return MarkAsCall(new LThrow(context, value), instr);
1569 }
1570
1571
1572 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1573 return NULL;
1663 } 1574 }
1664 1575
1665 1576
1666 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { 1577 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1667 // All HForceRepresentation instructions should be eliminated in the 1578 // All HForceRepresentation instructions should be eliminated in the
1668 // representation change phase of Hydrogen. 1579 // representation change phase of Hydrogen.
1669 UNREACHABLE(); 1580 UNREACHABLE();
1670 return NULL; 1581 return NULL;
1671 } 1582 }
1672 1583
1673 1584
1674 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1585 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1675 Representation from = instr->from(); 1586 Representation from = instr->from();
1676 Representation to = instr->to(); 1587 Representation to = instr->to();
1677 if (from.IsTagged()) { 1588 if (from.IsTagged()) {
1678 if (to.IsDouble()) { 1589 if (to.IsDouble()) {
1679 LOperand* value = UseRegister(instr->value()); 1590 LOperand* value = UseRegister(instr->value());
1680 LNumberUntagD* res = new LNumberUntagD(value); 1591 LNumberUntagD* res = new LNumberUntagD(value);
1681 return AssignEnvironment(DefineAsRegister(res)); 1592 return AssignEnvironment(DefineAsRegister(res));
1682 } else { 1593 } else {
1683 ASSERT(to.IsInteger32()); 1594 ASSERT(to.IsInteger32());
1684 LOperand* value = UseRegister(instr->value()); 1595 LOperand* value = UseRegister(instr->value());
1685 bool needs_check = !instr->value()->type().IsSmi(); 1596 bool needs_check = !instr->value()->type().IsSmi();
1686 if (needs_check) { 1597 if (needs_check) {
1598 bool truncating = instr->CanTruncateToInt32();
1687 LOperand* xmm_temp = 1599 LOperand* xmm_temp =
1688 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) 1600 (truncating && CpuFeatures::IsSupported(SSE3))
1689 ? NULL 1601 ? NULL
1690 : FixedTemp(xmm1); 1602 : FixedTemp(xmm1);
1691 LTaggedToI* res = new LTaggedToI(value, xmm_temp); 1603 LTaggedToI* res = new LTaggedToI(value, xmm_temp);
1692 return AssignEnvironment(DefineSameAsFirst(res)); 1604 return AssignEnvironment(DefineSameAsFirst(res));
1693 } else { 1605 } else {
1694 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1606 return DefineSameAsFirst(new LSmiUntag(value, needs_check));
1695 } 1607 }
1696 } 1608 }
1697 } else if (from.IsDouble()) { 1609 } else if (from.IsDouble()) {
1698 if (to.IsTagged()) { 1610 if (to.IsTagged()) {
1699 LOperand* value = UseRegister(instr->value()); 1611 LOperand* value = UseRegister(instr->value());
1700 LOperand* temp = TempRegister(); 1612 LOperand* temp = TempRegister();
1701 1613
1702 // Make sure that temp and result_temp are different registers. 1614 // Make sure that temp and result_temp are different registers.
1703 LUnallocated* result_temp = TempRegister(); 1615 LUnallocated* result_temp = TempRegister();
1704 LNumberTagD* result = new LNumberTagD(value, temp); 1616 LNumberTagD* result = new LNumberTagD(value, temp);
1705 return AssignPointerMap(Define(result, result_temp)); 1617 return AssignPointerMap(Define(result, result_temp));
1706 } else { 1618 } else {
1707 ASSERT(to.IsInteger32()); 1619 ASSERT(to.IsInteger32());
1708 bool needs_temp = instr->CanTruncateToInt32() && 1620 bool truncating = instr->CanTruncateToInt32();
1709 !CpuFeatures::IsSupported(SSE3); 1621 bool needs_temp = truncating && !CpuFeatures::IsSupported(SSE3);
1710 LOperand* value = needs_temp ? 1622 LOperand* value = needs_temp ?
1711 UseTempRegister(instr->value()) : UseRegister(instr->value()); 1623 UseTempRegister(instr->value()) : UseRegister(instr->value());
1712 LOperand* temp = needs_temp ? TempRegister() : NULL; 1624 LOperand* temp = needs_temp ? TempRegister() : NULL;
1713 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); 1625 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
1714 } 1626 }
1715 } else if (from.IsInteger32()) { 1627 } else if (from.IsInteger32()) {
1716 if (to.IsTagged()) { 1628 if (to.IsTagged()) {
1717 HValue* val = instr->value(); 1629 HValue* val = instr->value();
1718 LOperand* value = UseRegister(val); 1630 LOperand* value = UseRegister(val);
1719 if (val->HasRange() && val->range()->IsInSmiRange()) { 1631 if (val->HasRange() && val->range()->IsInSmiRange()) {
1720 return DefineSameAsFirst(new LSmiTag(value)); 1632 return DefineSameAsFirst(new LSmiTag(value));
1721 } else { 1633 } else {
1722 LNumberTagI* result = new LNumberTagI(value); 1634 LNumberTagI* result = new LNumberTagI(value);
1723 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1635 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1724 } 1636 }
1725 } else { 1637 } else {
1726 ASSERT(to.IsDouble()); 1638 ASSERT(to.IsDouble());
1727 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); 1639 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
1728 } 1640 }
1729 } 1641 }
1730 UNREACHABLE(); 1642 UNREACHABLE();
1731 return NULL; 1643 return NULL;
1732 } 1644 }
1733 1645
1734 1646
1735 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { 1647 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1736 LOperand* value = UseRegisterAtStart(instr->value()); 1648 LOperand* value = UseAtStart(instr->value());
1737 return AssignEnvironment(new LCheckNonSmi(value)); 1649 return AssignEnvironment(new LCheckNonSmi(value));
1738 } 1650 }
1739 1651
1740 1652
1741 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1653 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1742 LOperand* value = UseRegisterAtStart(instr->value()); 1654 LOperand* value = UseRegisterAtStart(instr->value());
1743 LOperand* temp = TempRegister(); 1655 LOperand* temp = TempRegister();
1744 LCheckInstanceType* result = new LCheckInstanceType(value, temp); 1656 LCheckInstanceType* result = new LCheckInstanceType(value, temp);
1745 return AssignEnvironment(result); 1657 return AssignEnvironment(result);
1746 } 1658 }
1747 1659
1748 1660
1749 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { 1661 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1750 LOperand* temp = TempRegister(); 1662 LOperand* temp = TempRegister();
1751 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp); 1663 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp);
1752 return AssignEnvironment(result); 1664 return AssignEnvironment(result);
1753 } 1665 }
1754 1666
1755 1667
1756 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 1668 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1757 LOperand* value = UseRegisterAtStart(instr->value()); 1669 LOperand* value = UseAtStart(instr->value());
1758 return AssignEnvironment(new LCheckSmi(value)); 1670 return AssignEnvironment(new LCheckSmi(value));
1759 } 1671 }
1760 1672
1761 1673
1762 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { 1674 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1763 LOperand* value = UseRegisterAtStart(instr->value()); 1675 LOperand* value = UseAtStart(instr->value());
1764 return AssignEnvironment(new LCheckFunction(value)); 1676 return AssignEnvironment(new LCheckFunction(value));
1765 } 1677 }
1766 1678
1767 1679
1768 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { 1680 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
1769 LOperand* value = UseRegisterAtStart(instr->value()); 1681 LOperand* value = UseRegisterAtStart(instr->value());
1770 LCheckMap* result = new LCheckMap(value); 1682 LCheckMap* result = new LCheckMap(value);
1771 return AssignEnvironment(result); 1683 return AssignEnvironment(result);
1772 } 1684 }
1773 1685
(...skipping 12 matching lines...) Expand all
1786 LOperand* reg = UseFixed(value, eax); 1698 LOperand* reg = UseFixed(value, eax);
1787 // Register allocator doesn't (yet) support allocation of double 1699 // Register allocator doesn't (yet) support allocation of double
1788 // temps. Reserve xmm1 explicitly. 1700 // temps. Reserve xmm1 explicitly.
1789 LOperand* temp = FixedTemp(xmm1); 1701 LOperand* temp = FixedTemp(xmm1);
1790 LClampTToUint8* result = new LClampTToUint8(reg, temp); 1702 LClampTToUint8* result = new LClampTToUint8(reg, temp);
1791 return AssignEnvironment(DefineFixed(result, eax)); 1703 return AssignEnvironment(DefineFixed(result, eax));
1792 } 1704 }
1793 } 1705 }
1794 1706
1795 1707
1708 LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
1709 HValue* value = instr->value();
1710 Representation input_rep = value->representation();
1711
1712 LInstruction* result;
1713 if (input_rep.IsDouble()) {
1714 LOperand* reg = UseRegister(value);
1715 LOperand* temp_reg =
1716 CpuFeatures::IsSupported(SSE3) ? NULL : TempRegister();
1717 result = DefineAsRegister(new LDoubleToI(reg, temp_reg));
1718 } else if (input_rep.IsInteger32()) {
1719 // Canonicalization should already have removed the hydrogen instruction in
1720 // this case, since it is a noop.
1721 UNREACHABLE();
1722 return NULL;
1723 } else {
1724 ASSERT(input_rep.IsTagged());
1725 LOperand* reg = UseRegister(value);
1726 // Register allocator doesn't (yet) support allocation of double
1727 // temps. Reserve xmm1 explicitly.
1728 LOperand* xmm_temp =
1729 CpuFeatures::IsSupported(SSE3) ? NULL : FixedTemp(xmm1);
1730 result = DefineSameAsFirst(new LTaggedToI(reg, xmm_temp));
1731 }
1732 return AssignEnvironment(result);
1733 }
1734
1735
1796 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1736 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1797 return new LReturn(UseFixed(instr->value(), eax)); 1737 return new LReturn(UseFixed(instr->value(), eax));
1798 } 1738 }
1799 1739
1800 1740
1801 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1741 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1802 Representation r = instr->representation(); 1742 Representation r = instr->representation();
1803 if (r.IsInteger32()) { 1743 if (r.IsInteger32()) {
1804 return DefineAsRegister(new LConstantI); 1744 return DefineAsRegister(new LConstantI);
1805 } else if (r.IsDouble()) { 1745 } else if (r.IsDouble()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1876 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1816 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1877 ASSERT(instr->representation().IsTagged()); 1817 ASSERT(instr->representation().IsTagged());
1878 LOperand* obj = UseRegisterAtStart(instr->object()); 1818 LOperand* obj = UseRegisterAtStart(instr->object());
1879 return DefineAsRegister(new LLoadNamedField(obj)); 1819 return DefineAsRegister(new LLoadNamedField(obj));
1880 } 1820 }
1881 1821
1882 1822
1883 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( 1823 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
1884 HLoadNamedFieldPolymorphic* instr) { 1824 HLoadNamedFieldPolymorphic* instr) {
1885 ASSERT(instr->representation().IsTagged()); 1825 ASSERT(instr->representation().IsTagged());
1826 LOperand* context = UseFixed(instr->context(), esi);
1886 if (instr->need_generic()) { 1827 if (instr->need_generic()) {
1887 LOperand* obj = UseFixed(instr->object(), eax); 1828 LOperand* obj = UseFixed(instr->object(), eax);
1888 LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); 1829 LLoadNamedFieldPolymorphic* result =
1830 new LLoadNamedFieldPolymorphic(context, obj);
1889 return MarkAsCall(DefineFixed(result, eax), instr); 1831 return MarkAsCall(DefineFixed(result, eax), instr);
1890 } else { 1832 } else {
1891 LOperand* obj = UseRegisterAtStart(instr->object()); 1833 LOperand* obj = UseRegisterAtStart(instr->object());
1892 LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); 1834 LLoadNamedFieldPolymorphic* result =
1835 new LLoadNamedFieldPolymorphic(context, obj);
1893 return AssignEnvironment(DefineAsRegister(result)); 1836 return AssignEnvironment(DefineAsRegister(result));
1894 } 1837 }
1895 } 1838 }
1896 1839
1897 1840
1898 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 1841 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1899 LOperand* context = UseFixed(instr->context(), esi); 1842 LOperand* context = UseFixed(instr->context(), esi);
1900 LOperand* object = UseFixed(instr->object(), eax); 1843 LOperand* object = UseFixed(instr->object(), eax);
1901 LLoadNamedGeneric* result = new LLoadNamedGeneric(context, object); 1844 LLoadNamedGeneric* result = new LLoadNamedGeneric(context, object);
1902 return MarkAsCall(DefineFixed(result, eax), instr); 1845 return MarkAsCall(DefineFixed(result, eax), instr);
(...skipping 27 matching lines...) Expand all
1930 ASSERT(instr->key()->representation().IsInteger32()); 1873 ASSERT(instr->key()->representation().IsInteger32());
1931 LOperand* obj = UseRegisterAtStart(instr->object()); 1874 LOperand* obj = UseRegisterAtStart(instr->object());
1932 LOperand* key = UseRegisterAtStart(instr->key()); 1875 LOperand* key = UseRegisterAtStart(instr->key());
1933 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1876 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1934 return AssignEnvironment(DefineSameAsFirst(result)); 1877 return AssignEnvironment(DefineSameAsFirst(result));
1935 } 1878 }
1936 1879
1937 1880
1938 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( 1881 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1939 HLoadKeyedSpecializedArrayElement* instr) { 1882 HLoadKeyedSpecializedArrayElement* instr) {
1940 ExternalArrayType array_type = instr->array_type(); 1883 JSObject::ElementsKind elements_kind = instr->elements_kind();
1941 Representation representation(instr->representation()); 1884 Representation representation(instr->representation());
1942 ASSERT( 1885 ASSERT(
1943 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1886 (representation.IsInteger32() &&
1944 array_type != kExternalDoubleArray)) || 1887 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1945 (representation.IsDouble() && (array_type == kExternalFloatArray || 1888 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1946 array_type == kExternalDoubleArray))); 1889 (representation.IsDouble() &&
1890 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1891 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
1947 ASSERT(instr->key()->representation().IsInteger32()); 1892 ASSERT(instr->key()->representation().IsInteger32());
1948 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1893 LOperand* external_pointer = UseRegister(instr->external_pointer());
1949 LOperand* key = UseRegisterOrConstant(instr->key()); 1894 LOperand* key = UseRegisterOrConstant(instr->key());
1950 LLoadKeyedSpecializedArrayElement* result = 1895 LLoadKeyedSpecializedArrayElement* result =
1951 new LLoadKeyedSpecializedArrayElement(external_pointer, 1896 new LLoadKeyedSpecializedArrayElement(external_pointer,
1952 key); 1897 key);
1953 LInstruction* load_instr = DefineAsRegister(result); 1898 LInstruction* load_instr = DefineAsRegister(result);
1954 // An unsigned int array load might overflow and cause a deopt, make sure it 1899 // An unsigned int array load might overflow and cause a deopt, make sure it
1955 // has an environment. 1900 // has an environment.
1956 return (array_type == kExternalUnsignedIntArray) 1901 return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS)
1957 ? AssignEnvironment(load_instr) 1902 ? AssignEnvironment(load_instr)
1958 : load_instr; 1903 : load_instr;
1959 } 1904 }
1960 1905
1961 1906
1962 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1907 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1963 LOperand* context = UseFixed(instr->context(), esi); 1908 LOperand* context = UseFixed(instr->context(), esi);
1964 LOperand* object = UseFixed(instr->object(), edx); 1909 LOperand* object = UseFixed(instr->object(), edx);
1965 LOperand* key = UseFixed(instr->key(), eax); 1910 LOperand* key = UseFixed(instr->key(), eax);
1966 1911
(...skipping 17 matching lines...) Expand all
1984 ? UseTempRegister(instr->key()) 1929 ? UseTempRegister(instr->key())
1985 : UseRegisterOrConstantAtStart(instr->key()); 1930 : UseRegisterOrConstantAtStart(instr->key());
1986 1931
1987 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1932 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1988 } 1933 }
1989 1934
1990 1935
1991 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( 1936 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1992 HStoreKeyedSpecializedArrayElement* instr) { 1937 HStoreKeyedSpecializedArrayElement* instr) {
1993 Representation representation(instr->value()->representation()); 1938 Representation representation(instr->value()->representation());
1994 ExternalArrayType array_type = instr->array_type(); 1939 JSObject::ElementsKind elements_kind = instr->elements_kind();
1995 ASSERT( 1940 ASSERT(
1996 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1941 (representation.IsInteger32() &&
1997 array_type != kExternalDoubleArray)) || 1942 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1998 (representation.IsDouble() && (array_type == kExternalFloatArray || 1943 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1999 array_type == kExternalDoubleArray))); 1944 (representation.IsDouble() &&
1945 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1946 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
2000 ASSERT(instr->external_pointer()->representation().IsExternal()); 1947 ASSERT(instr->external_pointer()->representation().IsExternal());
2001 ASSERT(instr->key()->representation().IsInteger32()); 1948 ASSERT(instr->key()->representation().IsInteger32());
2002 1949
2003 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1950 LOperand* external_pointer = UseRegister(instr->external_pointer());
2004 LOperand* key = UseRegisterOrConstant(instr->key()); 1951 LOperand* key = UseRegisterOrConstant(instr->key());
2005 LOperand* val = NULL; 1952 LOperand* val = NULL;
2006 if (array_type == kExternalByteArray || 1953 if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS ||
2007 array_type == kExternalUnsignedByteArray || 1954 elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
2008 array_type == kExternalPixelArray) { 1955 elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
2009 // We need a byte register in this case for the value. 1956 // We need a byte register in this case for the value.
2010 val = UseFixed(instr->value(), eax); 1957 val = UseFixed(instr->value(), eax);
2011 } else { 1958 } else {
2012 val = UseRegister(instr->value()); 1959 val = UseRegister(instr->value());
2013 } 1960 }
2014 1961
2015 return new LStoreKeyedSpecializedArrayElement(external_pointer, 1962 return new LStoreKeyedSpecializedArrayElement(external_pointer,
2016 key, 1963 key,
2017 val); 1964 val);
2018 } 1965 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 LOperand* context = UseFixed(instr->context(), esi); 2011 LOperand* context = UseFixed(instr->context(), esi);
2065 LOperand* object = UseFixed(instr->object(), edx); 2012 LOperand* object = UseFixed(instr->object(), edx);
2066 LOperand* value = UseFixed(instr->value(), eax); 2013 LOperand* value = UseFixed(instr->value(), eax);
2067 2014
2068 LStoreNamedGeneric* result = new LStoreNamedGeneric(context, object, value); 2015 LStoreNamedGeneric* result = new LStoreNamedGeneric(context, object, value);
2069 return MarkAsCall(result, instr); 2016 return MarkAsCall(result, instr);
2070 } 2017 }
2071 2018
2072 2019
2073 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { 2020 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2021 LOperand* context = UseFixed(instr->context(), esi);
2074 LOperand* left = UseOrConstantAtStart(instr->left()); 2022 LOperand* left = UseOrConstantAtStart(instr->left());
2075 LOperand* right = UseOrConstantAtStart(instr->right()); 2023 LOperand* right = UseOrConstantAtStart(instr->right());
2076 return MarkAsCall(DefineFixed(new LStringAdd(left, right), eax), instr); 2024 LStringAdd* string_add = new LStringAdd(context, left, right);
2025 return MarkAsCall(DefineFixed(string_add, eax), instr);
2077 } 2026 }
2078 2027
2079 2028
2080 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2029 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2081 LOperand* string = UseRegister(instr->string()); 2030 LOperand* string = UseRegister(instr->string());
2082 LOperand* index = UseRegisterOrConstant(instr->index()); 2031 LOperand* index = UseRegisterOrConstant(instr->index());
2083 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); 2032 LOperand* context = UseAny(instr->context());
2033 LStringCharCodeAt* result = new LStringCharCodeAt(context, string, index);
2084 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 2034 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
2085 } 2035 }
2086 2036
2087 2037
2088 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2038 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2089 LOperand* char_code = UseRegister(instr->value()); 2039 LOperand* char_code = UseRegister(instr->value());
2090 LStringCharFromCode* result = new LStringCharFromCode(char_code); 2040 LOperand* context = UseAny(instr->context());
2041 LStringCharFromCode* result = new LStringCharFromCode(context, char_code);
2091 return AssignPointerMap(DefineAsRegister(result)); 2042 return AssignPointerMap(DefineAsRegister(result));
2092 } 2043 }
2093 2044
2094 2045
2095 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { 2046 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
2096 LOperand* string = UseRegisterAtStart(instr->value()); 2047 LOperand* string = UseRegisterAtStart(instr->value());
2097 return DefineAsRegister(new LStringLength(string)); 2048 return DefineAsRegister(new LStringLength(string));
2098 } 2049 }
2099 2050
2100 2051
2101 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 2052 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
2102 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); 2053 LOperand* context = UseFixed(instr->context(), esi);
2054 return MarkAsCall(DefineFixed(new LArrayLiteral(context), eax), instr);
2103 } 2055 }
2104 2056
2105 2057
2106 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 2058 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
2107 LOperand* context = UseFixed(instr->context(), esi); 2059 LOperand* context = UseFixed(instr->context(), esi);
2108 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); 2060 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr);
2109 } 2061 }
2110 2062
2111 2063
2112 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 2064 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2113 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); 2065 LOperand* context = UseFixed(instr->context(), esi);
2066 return MarkAsCall(DefineFixed(new LRegExpLiteral(context), eax), instr);
2114 } 2067 }
2115 2068
2116 2069
2117 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 2070 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2118 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); 2071 LOperand* context = UseFixed(instr->context(), esi);
2072 return MarkAsCall(DefineFixed(new LFunctionLiteral(context), eax), instr);
2119 } 2073 }
2120 2074
2121 2075
2122 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 2076 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
2123 LDeleteProperty* result = 2077 LOperand* context = UseFixed(instr->context(), esi);
2124 new LDeleteProperty(UseAtStart(instr->object()), 2078 LOperand* object = UseAtStart(instr->object());
2125 UseOrConstantAtStart(instr->key())); 2079 LOperand* key = UseOrConstantAtStart(instr->key());
2080 LDeleteProperty* result = new LDeleteProperty(context, object, key);
2126 return MarkAsCall(DefineFixed(result, eax), instr); 2081 return MarkAsCall(DefineFixed(result, eax), instr);
2127 } 2082 }
2128 2083
2129 2084
2130 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 2085 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2131 allocator_->MarkAsOsrEntry(); 2086 allocator_->MarkAsOsrEntry();
2132 current_block_->last_environment()->set_ast_id(instr->ast_id()); 2087 current_block_->last_environment()->set_ast_id(instr->ast_id());
2133 return AssignEnvironment(new LOsrEntry); 2088 return AssignEnvironment(new LOsrEntry);
2134 } 2089 }
2135 2090
2136 2091
2137 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 2092 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2138 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 2093 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2139 return DefineAsSpilled(new LParameter, spill_index); 2094 return DefineAsSpilled(new LParameter, spill_index);
2140 } 2095 }
2141 2096
2142 2097
2143 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 2098 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2144 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. 2099 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
2100 if (spill_index > LUnallocated::kMaxFixedIndex) {
2101 Abort("Too many spill slots needed for OSR");
2102 spill_index = 0;
2103 }
2145 return DefineAsSpilled(new LUnknownOSRValue, spill_index); 2104 return DefineAsSpilled(new LUnknownOSRValue, spill_index);
2146 } 2105 }
2147 2106
2148 2107
2149 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2108 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2150 LOperand* context = UseFixed(instr->context(), esi); 2109 LOperand* context = UseFixed(instr->context(), esi);
2151 argument_count_ -= instr->argument_count(); 2110 argument_count_ -= instr->argument_count();
2152 LCallStub* result = new LCallStub(context); 2111 LCallStub* result = new LCallStub(context);
2153 return MarkAsCall(DefineFixed(result, eax), instr); 2112 return MarkAsCall(DefineFixed(result, eax), instr);
2154 } 2113 }
(...skipping 18 matching lines...) Expand all
2173 2132
2174 2133
2175 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { 2134 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2176 LOperand* object = UseFixed(instr->value(), eax); 2135 LOperand* object = UseFixed(instr->value(), eax);
2177 LToFastProperties* result = new LToFastProperties(object); 2136 LToFastProperties* result = new LToFastProperties(object);
2178 return MarkAsCall(DefineFixed(result, eax), instr); 2137 return MarkAsCall(DefineFixed(result, eax), instr);
2179 } 2138 }
2180 2139
2181 2140
2182 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2141 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2183 LTypeof* result = new LTypeof(UseAtStart(instr->value())); 2142 LOperand* context = UseFixed(instr->context(), esi);
2143 LOperand* value = UseAtStart(instr->value());
2144 LTypeof* result = new LTypeof(context, value);
2184 return MarkAsCall(DefineFixed(result, eax), instr); 2145 return MarkAsCall(DefineFixed(result, eax), instr);
2185 } 2146 }
2186 2147
2187 2148
2188 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 2149 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2189 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 2150 return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
2190 } 2151 }
2191 2152
2192 2153
2193 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { 2154 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2194 return DefineAsRegister(new LIsConstructCall); 2155 HIsConstructCallAndBranch* instr) {
2156 return new LIsConstructCallAndBranch(TempRegister());
2195 } 2157 }
2196 2158
2197 2159
2198 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2160 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2199 HEnvironment* env = current_block_->last_environment(); 2161 HEnvironment* env = current_block_->last_environment();
2200 ASSERT(env != NULL); 2162 ASSERT(env != NULL);
2201 2163
2202 env->set_ast_id(instr->ast_id()); 2164 env->set_ast_id(instr->ast_id());
2203 2165
2204 env->Drop(instr->pop_count()); 2166 env->Drop(instr->pop_count());
(...skipping 16 matching lines...) Expand all
2221 set_deoptimization_environment(result->environment()); 2183 set_deoptimization_environment(result->environment());
2222 ClearInstructionPendingDeoptimizationEnvironment(); 2184 ClearInstructionPendingDeoptimizationEnvironment();
2223 return result; 2185 return result;
2224 } 2186 }
2225 2187
2226 return NULL; 2188 return NULL;
2227 } 2189 }
2228 2190
2229 2191
2230 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2192 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2231 return MarkAsCall(new LStackCheck, instr); 2193 if (instr->is_function_entry()) {
2194 LOperand* context = UseFixed(instr->context(), esi);
2195 return MarkAsCall(new LStackCheck(context), instr);
2196 } else {
2197 ASSERT(instr->is_backwards_branch());
2198 LOperand* context = UseAny(instr->context());
2199 return AssignEnvironment(AssignPointerMap(new LStackCheck(context)));
2200 }
2232 } 2201 }
2233 2202
2234 2203
2235 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2204 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2236 HEnvironment* outer = current_block_->last_environment(); 2205 HEnvironment* outer = current_block_->last_environment();
2237 HConstant* undefined = graph()->GetConstantUndefined(); 2206 HConstant* undefined = graph()->GetConstantUndefined();
2238 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2207 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2239 instr->function(), 2208 instr->function(),
2240 HEnvironment::LITHIUM,
2241 undefined, 2209 undefined,
2242 instr->call_kind()); 2210 instr->call_kind());
2243 current_block_->UpdateEnvironment(inner); 2211 current_block_->UpdateEnvironment(inner);
2244 chunk_->AddInlinedClosure(instr->closure()); 2212 chunk_->AddInlinedClosure(instr->closure());
2245 return NULL; 2213 return NULL;
2246 } 2214 }
2247 2215
2248 2216
2249 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2217 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2250 HEnvironment* outer = current_block_->last_environment()->outer(); 2218 HEnvironment* outer = current_block_->last_environment()->outer();
2251 current_block_->UpdateEnvironment(outer); 2219 current_block_->UpdateEnvironment(outer);
2252 return NULL; 2220 return NULL;
2253 } 2221 }
2254 2222
2255 2223
2256 LInstruction* LChunkBuilder::DoIn(HIn* instr) { 2224 LInstruction* LChunkBuilder::DoIn(HIn* instr) {
2225 LOperand* context = UseFixed(instr->context(), esi);
2257 LOperand* key = UseOrConstantAtStart(instr->key()); 2226 LOperand* key = UseOrConstantAtStart(instr->key());
2258 LOperand* object = UseOrConstantAtStart(instr->object()); 2227 LOperand* object = UseOrConstantAtStart(instr->object());
2259 LIn* result = new LIn(key, object); 2228 LIn* result = new LIn(context, key, object);
2260 return MarkAsCall(DefineFixed(result, eax), instr); 2229 return MarkAsCall(DefineFixed(result, eax), instr);
2261 } 2230 }
2262 2231
2263 2232
2264 } } // namespace v8::internal 2233 } } // namespace v8::internal
2265 2234
2266 #endif // V8_TARGET_ARCH_IA32 2235 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698