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

Side by Side Diff: src/x64/lithium-x64.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/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 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 } 329 }
339 330
340 331
341 void LCallNew::PrintDataTo(StringStream* stream) { 332 void LCallNew::PrintDataTo(StringStream* stream) {
342 stream->Add("= "); 333 stream->Add("= ");
343 InputAt(0)->PrintTo(stream); 334 InputAt(0)->PrintTo(stream);
344 stream->Add(" #%d / ", arity()); 335 stream->Add(" #%d / ", arity());
345 } 336 }
346 337
347 338
348 void LClassOfTest::PrintDataTo(StringStream* stream) {
349 stream->Add("= class_of_test(");
350 InputAt(0)->PrintTo(stream);
351 stream->Add(", \"%o\")", *hydrogen()->class_name());
352 }
353
354
355 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { 339 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
356 arguments()->PrintTo(stream); 340 arguments()->PrintTo(stream);
357 341
358 stream->Add(" length "); 342 stream->Add(" length ");
359 length()->PrintTo(stream); 343 length()->PrintTo(stream);
360 344
361 stream->Add(" index "); 345 stream->Add(" index ");
362 index()->PrintTo(stream); 346 index()->PrintTo(stream);
363 } 347 }
364 348
(...skipping 21 matching lines...) Expand all
386 for (int i = 0; i < graph()->blocks()->length(); ++i) { 370 for (int i = 0; i < graph()->blocks()->length(); ++i) {
387 HBasicBlock* block = graph()->blocks()->at(i); 371 HBasicBlock* block = graph()->blocks()->at(i);
388 int first = block->first_instruction_index(); 372 int first = block->first_instruction_index();
389 int last = block->last_instruction_index(); 373 int last = block->last_instruction_index();
390 LInstruction* first_instr = instructions()->at(first); 374 LInstruction* first_instr = instructions()->at(first);
391 LInstruction* last_instr = instructions()->at(last); 375 LInstruction* last_instr = instructions()->at(last);
392 376
393 LLabel* label = LLabel::cast(first_instr); 377 LLabel* label = LLabel::cast(first_instr);
394 if (last_instr->IsGoto()) { 378 if (last_instr->IsGoto()) {
395 LGoto* goto_instr = LGoto::cast(last_instr); 379 LGoto* goto_instr = LGoto::cast(last_instr);
396 if (!goto_instr->include_stack_check() && 380 if (label->IsRedundant() &&
397 label->IsRedundant() &&
398 !label->is_loop_header()) { 381 !label->is_loop_header()) {
399 bool can_eliminate = true; 382 bool can_eliminate = true;
400 for (int i = first + 1; i < last && can_eliminate; ++i) { 383 for (int i = first + 1; i < last && can_eliminate; ++i) {
401 LInstruction* cur = instructions()->at(i); 384 LInstruction* cur = instructions()->at(i);
402 if (cur->IsGap()) { 385 if (cur->IsGap()) {
403 LGap* gap = LGap::cast(cur); 386 LGap* gap = LGap::cast(cur);
404 if (!gap->IsRedundant()) { 387 if (!gap->IsRedundant()) {
405 can_eliminate = false; 388 can_eliminate = false;
406 } 389 }
407 } else { 390 } else {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 allocator_->RecordTemporary(operand); 779 allocator_->RecordTemporary(operand);
797 return operand; 780 return operand;
798 } 781 }
799 782
800 783
801 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { 784 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
802 return new LLabel(instr->block()); 785 return new LLabel(instr->block());
803 } 786 }
804 787
805 788
789 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
790 return AssignEnvironment(new LDeoptimize);
791 }
792
793
806 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 794 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
807 return AssignEnvironment(new LDeoptimize); 795 return AssignEnvironment(new LDeoptimize);
808 } 796 }
809 797
810 798
811 LInstruction* LChunkBuilder::DoBit(Token::Value op, 799 LInstruction* LChunkBuilder::DoBit(Token::Value op,
812 HBitwiseBinaryOperation* instr) { 800 HBitwiseBinaryOperation* instr) {
813 if (instr->representation().IsInteger32()) { 801 if (instr->representation().IsInteger32()) {
814 ASSERT(instr->left()->representation().IsInteger32()); 802 ASSERT(instr->left()->representation().IsInteger32());
815 ASSERT(instr->right()->representation().IsInteger32()); 803 ASSERT(instr->right()->representation().IsInteger32());
(...skipping 20 matching lines...) Expand all
836 ASSERT(instr->left()->representation().IsTagged()); 824 ASSERT(instr->left()->representation().IsTagged());
837 ASSERT(instr->right()->representation().IsTagged()); 825 ASSERT(instr->right()->representation().IsTagged());
838 826
839 LOperand* left = UseFixed(instr->left(), rdx); 827 LOperand* left = UseFixed(instr->left(), rdx);
840 LOperand* right = UseFixed(instr->right(), rax); 828 LOperand* right = UseFixed(instr->right(), rax);
841 LArithmeticT* result = new LArithmeticT(op, left, right); 829 LArithmeticT* result = new LArithmeticT(op, left, right);
842 return MarkAsCall(DefineFixed(result, rax), instr); 830 return MarkAsCall(DefineFixed(result, rax), instr);
843 } 831 }
844 832
845 ASSERT(instr->representation().IsInteger32()); 833 ASSERT(instr->representation().IsInteger32());
846 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 834 ASSERT(instr->left()->representation().IsInteger32());
847 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 835 ASSERT(instr->right()->representation().IsInteger32());
848 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 836 LOperand* left = UseRegisterAtStart(instr->left());
849 837
850 HValue* right_value = instr->OperandAt(1); 838 HValue* right_value = instr->right();
851 LOperand* right = NULL; 839 LOperand* right = NULL;
852 int constant_value = 0; 840 int constant_value = 0;
853 if (right_value->IsConstant()) { 841 if (right_value->IsConstant()) {
854 HConstant* constant = HConstant::cast(right_value); 842 HConstant* constant = HConstant::cast(right_value);
855 right = chunk_->DefineConstantOperand(constant); 843 right = chunk_->DefineConstantOperand(constant);
856 constant_value = constant->Integer32Value() & 0x1f; 844 constant_value = constant->Integer32Value() & 0x1f;
857 } else { 845 } else {
858 right = UseFixed(right_value, rcx); 846 right = UseFixed(right_value, rcx);
859 } 847 }
860 848
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 if (current->has_position()) position_ = current->position(); 965 if (current->has_position()) position_ = current->position();
978 LInstruction* instr = current->CompileToLithium(this); 966 LInstruction* instr = current->CompileToLithium(this);
979 967
980 if (instr != NULL) { 968 if (instr != NULL) {
981 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 969 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
982 instr = AssignPointerMap(instr); 970 instr = AssignPointerMap(instr);
983 } 971 }
984 if (FLAG_stress_environments && !instr->HasEnvironment()) { 972 if (FLAG_stress_environments && !instr->HasEnvironment()) {
985 instr = AssignEnvironment(instr); 973 instr = AssignEnvironment(instr);
986 } 974 }
987 if (current->IsTest() && !instr->IsGoto()) { 975 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_); 976 chunk_->AddInstruction(instr, current_block_);
1000 } 977 }
1001 current_instruction_ = old_current; 978 current_instruction_ = old_current;
1002 } 979 }
1003 980
1004 981
1005 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 982 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1006 if (hydrogen_env == NULL) return NULL; 983 if (hydrogen_env == NULL) return NULL;
1007 984
1008 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 985 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
(...skipping 20 matching lines...) Expand all
1029 op = UseAny(value); 1006 op = UseAny(value);
1030 } 1007 }
1031 result->AddValue(op, value->representation()); 1008 result->AddValue(op, value->representation());
1032 } 1009 }
1033 1010
1034 return result; 1011 return result;
1035 } 1012 }
1036 1013
1037 1014
1038 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1015 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1039 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), 1016 return new LGoto(instr->FirstSuccessor()->block_id());
1040 instr->include_stack_check());
1041 return (instr->include_stack_check())
1042 ? AssignPointerMap(result)
1043 : result;
1044 } 1017 }
1045 1018
1046 1019
1047 LInstruction* LChunkBuilder::DoTest(HTest* instr) { 1020 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1048 HValue* v = instr->value(); 1021 HValue* v = instr->value();
1049 if (!v->EmitAtUses()) { 1022 if (v->EmitAtUses()) {
1050 return new LBranch(UseRegisterAtStart(v)); 1023 ASSERT(v->IsConstant());
1051 } else if (v->IsClassOfTest()) { 1024 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 } else if (v->IsCompare()) {
1057 HCompare* compare = HCompare::cast(v);
1058 Token::Value op = compare->token();
1059 HValue* left = compare->left();
1060 HValue* right = compare->right();
1061 Representation r = compare->GetInputRepresentation();
1062 if (r.IsInteger32()) {
1063 ASSERT(left->representation().IsInteger32());
1064 ASSERT(right->representation().IsInteger32());
1065 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1066 UseOrConstantAtStart(right));
1067 } else if (r.IsDouble()) {
1068 ASSERT(left->representation().IsDouble());
1069 ASSERT(right->representation().IsDouble());
1070 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1071 UseRegisterAtStart(right));
1072 } else {
1073 ASSERT(left->representation().IsTagged());
1074 ASSERT(right->representation().IsTagged());
1075 bool reversed = op == Token::GT || op == Token::LTE;
1076 LOperand* left_operand = UseFixed(left, reversed ? rax : rdx);
1077 LOperand* right_operand = UseFixed(right, reversed ? rdx : rax);
1078 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, right_operand);
1079 return MarkAsCall(result, instr);
1080 }
1081 } else if (v->IsIsSmi()) {
1082 HIsSmi* compare = HIsSmi::cast(v);
1083 ASSERT(compare->value()->representation().IsTagged());
1084 return new LIsSmiAndBranch(Use(compare->value()));
1085 } else if (v->IsIsUndetectable()) {
1086 HIsUndetectable* compare = HIsUndetectable::cast(v);
1087 ASSERT(compare->value()->representation().IsTagged());
1088 return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
1089 TempRegister());
1090 } else if (v->IsHasInstanceType()) {
1091 HHasInstanceType* compare = HHasInstanceType::cast(v);
1092 ASSERT(compare->value()->representation().IsTagged());
1093 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()));
1094 } else if (v->IsHasCachedArrayIndex()) {
1095 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
1096 ASSERT(compare->value()->representation().IsTagged());
1097 return new LHasCachedArrayIndexAndBranch(
1098 UseRegisterAtStart(compare->value()));
1099 } else if (v->IsIsNull()) {
1100 HIsNull* compare = HIsNull::cast(v);
1101 ASSERT(compare->value()->representation().IsTagged());
1102 // We only need a temp register for non-strict compare.
1103 LOperand* temp = compare->is_strict() ? NULL : TempRegister();
1104 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), temp);
1105 } else if (v->IsIsObject()) {
1106 HIsObject* compare = HIsObject::cast(v);
1107 ASSERT(compare->value()->representation().IsTagged());
1108 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()));
1109 } else if (v->IsCompareJSObjectEq()) {
1110 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1111 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1112 UseRegisterAtStart(compare->right()));
1113 } else if (v->IsCompareSymbolEq()) {
1114 HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
1115 return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
1116 UseRegisterAtStart(compare->right()));
1117 } else if (v->IsInstanceOf()) {
1118 HInstanceOf* instance_of = HInstanceOf::cast(v);
1119 LInstanceOfAndBranch* result =
1120 new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax),
1121 UseFixed(instance_of->right(), rdx));
1122 return MarkAsCall(result, instr);
1123 } else if (v->IsTypeofIs()) {
1124 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1125 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1126 } else if (v->IsIsConstructCall()) {
1127 return new LIsConstructCallAndBranch(TempRegister());
1128 } else if (v->IsConstant()) {
1129 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() 1025 HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
1130 ? instr->FirstSuccessor() 1026 ? instr->FirstSuccessor()
1131 : instr->SecondSuccessor(); 1027 : instr->SecondSuccessor();
1132 return new LGoto(successor->block_id()); 1028 return new LGoto(successor->block_id());
1133 } else {
1134 Abort("Undefined compare before branch");
1135 return NULL;
1136 } 1029 }
1030 return new LBranch(UseRegisterAtStart(v));
1137 } 1031 }
1138 1032
1139 1033
1140 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 1034 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1141 ASSERT(instr->value()->representation().IsTagged()); 1035 ASSERT(instr->value()->representation().IsTagged());
1142 LOperand* value = UseRegisterAtStart(instr->value()); 1036 LOperand* value = UseRegisterAtStart(instr->value());
1143 return new LCmpMapAndBranch(value); 1037 return new LCmpMapAndBranch(value);
1144 } 1038 }
1145 1039
1146 1040
(...skipping 11 matching lines...) Expand all
1158 LOperand* left = UseFixed(instr->left(), rax); 1052 LOperand* left = UseFixed(instr->left(), rax);
1159 LOperand* right = UseFixed(instr->right(), rdx); 1053 LOperand* right = UseFixed(instr->right(), rdx);
1160 LInstanceOf* result = new LInstanceOf(left, right); 1054 LInstanceOf* result = new LInstanceOf(left, right);
1161 return MarkAsCall(DefineFixed(result, rax), instr); 1055 return MarkAsCall(DefineFixed(result, rax), instr);
1162 } 1056 }
1163 1057
1164 1058
1165 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1059 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1166 HInstanceOfKnownGlobal* instr) { 1060 HInstanceOfKnownGlobal* instr) {
1167 LInstanceOfKnownGlobal* result = 1061 LInstanceOfKnownGlobal* result =
1168 new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax), 1062 new LInstanceOfKnownGlobal(UseFixed(instr->left(), rax),
1169 FixedTemp(rdi)); 1063 FixedTemp(rdi));
1170 return MarkAsCall(DefineFixed(result, rax), instr); 1064 return MarkAsCall(DefineFixed(result, rax), instr);
1171 } 1065 }
1172 1066
1173 1067
1174 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1068 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1175 LOperand* function = UseFixed(instr->function(), rdi); 1069 LOperand* function = UseFixed(instr->function(), rdi);
1176 LOperand* receiver = UseFixed(instr->receiver(), rax); 1070 LOperand* receiver = UseFixed(instr->receiver(), rax);
1177 LOperand* length = UseFixed(instr->length(), rbx); 1071 LOperand* length = UseFixed(instr->length(), rbx);
1178 LOperand* elements = UseFixed(instr->elements(), rcx); 1072 LOperand* elements = UseFixed(instr->elements(), rcx);
1179 LApplyArguments* result = new LApplyArguments(function, 1073 LApplyArguments* result = new LApplyArguments(function,
1180 receiver, 1074 receiver,
1181 length, 1075 length,
1182 elements); 1076 elements);
1183 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); 1077 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
1184 } 1078 }
1185 1079
1186 1080
1187 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1081 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1188 ++argument_count_; 1082 ++argument_count_;
1189 LOperand* argument = UseOrConstant(instr->argument()); 1083 LOperand* argument = UseOrConstant(instr->argument());
1190 return new LPushArgument(argument); 1084 return new LPushArgument(argument);
1191 } 1085 }
1192 1086
1193 1087
1088 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1089 return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
1090 }
1091
1092
1194 LInstruction* LChunkBuilder::DoContext(HContext* instr) { 1093 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1195 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); 1094 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
1196 } 1095 }
1197 1096
1198 1097
1199 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { 1098 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1200 LOperand* context = UseRegisterAtStart(instr->value()); 1099 LOperand* context = UseRegisterAtStart(instr->value());
1201 return DefineAsRegister(new LOuterContext(context)); 1100 return DefineAsRegister(new LOuterContext(context));
1202 } 1101 }
1203 1102
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 UseFixed(instr->right(), rdx); 1373 UseFixed(instr->right(), rdx);
1475 #else 1374 #else
1476 UseFixed(instr->right(), rdi); 1375 UseFixed(instr->right(), rdi);
1477 #endif 1376 #endif
1478 LPower* result = new LPower(left, right); 1377 LPower* result = new LPower(left, right);
1479 return MarkAsCall(DefineFixedDouble(result, xmm1), instr, 1378 return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
1480 CAN_DEOPTIMIZE_EAGERLY); 1379 CAN_DEOPTIMIZE_EAGERLY);
1481 } 1380 }
1482 1381
1483 1382
1484 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1383 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1485 Token::Value op = instr->token(); 1384 Token::Value op = instr->token();
1385 ASSERT(instr->left()->representation().IsTagged());
1386 ASSERT(instr->right()->representation().IsTagged());
1387 bool reversed = (op == Token::GT || op == Token::LTE);
1388 LOperand* left = UseFixed(instr->left(), reversed ? rax : rdx);
1389 LOperand* right = UseFixed(instr->right(), reversed ? rdx : rax);
1390 LCmpT* result = new LCmpT(left, right);
1391 return MarkAsCall(DefineFixed(result, rax), instr);
1392 }
1393
1394
1395 LInstruction* LChunkBuilder::DoCompareIDAndBranch(
1396 HCompareIDAndBranch* instr) {
1486 Representation r = instr->GetInputRepresentation(); 1397 Representation r = instr->GetInputRepresentation();
1487 if (r.IsInteger32()) { 1398 if (r.IsInteger32()) {
1488 ASSERT(instr->left()->representation().IsInteger32()); 1399 ASSERT(instr->left()->representation().IsInteger32());
1489 ASSERT(instr->right()->representation().IsInteger32()); 1400 ASSERT(instr->right()->representation().IsInteger32());
1490 LOperand* left = UseRegisterAtStart(instr->left()); 1401 LOperand* left = UseRegisterAtStart(instr->left());
1491 LOperand* right = UseOrConstantAtStart(instr->right()); 1402 LOperand* right = UseOrConstantAtStart(instr->right());
1492 return DefineAsRegister(new LCmpID(left, right)); 1403 return new LCmpIDAndBranch(left, right);
1493 } else if (r.IsDouble()) { 1404 } else {
1405 ASSERT(r.IsDouble());
1494 ASSERT(instr->left()->representation().IsDouble()); 1406 ASSERT(instr->left()->representation().IsDouble());
1495 ASSERT(instr->right()->representation().IsDouble()); 1407 ASSERT(instr->right()->representation().IsDouble());
1496 LOperand* left = UseRegisterAtStart(instr->left()); 1408 LOperand* left = UseRegisterAtStart(instr->left());
1497 LOperand* right = UseRegisterAtStart(instr->right()); 1409 LOperand* right = UseRegisterAtStart(instr->right());
1498 return DefineAsRegister(new LCmpID(left, right)); 1410 return new LCmpIDAndBranch(left, right);
1499 } else {
1500 ASSERT(instr->left()->representation().IsTagged());
1501 ASSERT(instr->right()->representation().IsTagged());
1502 bool reversed = (op == Token::GT || op == Token::LTE);
1503 LOperand* left = UseFixed(instr->left(), reversed ? rax : rdx);
1504 LOperand* right = UseFixed(instr->right(), reversed ? rdx : rax);
1505 LCmpT* result = new LCmpT(left, right);
1506 return MarkAsCall(DefineFixed(result, rax), instr);
1507 } 1411 }
1508 } 1412 }
1509 1413
1510 1414
1511 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1415 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1512 HCompareJSObjectEq* instr) { 1416 HCompareObjectEqAndBranch* instr) {
1513 LOperand* left = UseRegisterAtStart(instr->left()); 1417 LOperand* left = UseRegisterAtStart(instr->left());
1514 LOperand* right = UseRegisterAtStart(instr->right()); 1418 LOperand* right = UseRegisterAtStart(instr->right());
1515 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); 1419 return new LCmpObjectEqAndBranch(left, right);
1516 return DefineAsRegister(result);
1517 } 1420 }
1518 1421
1519 1422
1520 LInstruction* LChunkBuilder::DoCompareSymbolEq( 1423 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
1521 HCompareSymbolEq* instr) { 1424 HCompareConstantEqAndBranch* instr) {
1522 LOperand* left = UseRegisterAtStart(instr->left()); 1425 return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
1523 LOperand* right = UseRegisterAtStart(instr->right());
1524 LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
1525 return DefineAsRegister(result);
1526 } 1426 }
1527 1427
1528 1428
1529 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1429 LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
1530 ASSERT(instr->value()->representation().IsTagged()); 1430 ASSERT(instr->value()->representation().IsTagged());
1531 LOperand* value = UseRegisterAtStart(instr->value()); 1431 LOperand* temp = instr->is_strict() ? NULL : TempRegister();
1532 1432 return new LIsNullAndBranch(UseRegisterAtStart(instr->value()), temp);
1533 return DefineAsRegister(new LIsNull(value));
1534 } 1433 }
1535 1434
1536 1435
1537 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { 1436 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1538 ASSERT(instr->value()->representation().IsTagged()); 1437 ASSERT(instr->value()->representation().IsTagged());
1539 LOperand* value = UseRegister(instr->value()); 1438 return new LIsObjectAndBranch(UseRegisterAtStart(instr->value()));
1540
1541 return DefineAsRegister(new LIsObject(value));
1542 } 1439 }
1543 1440
1544 1441
1545 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { 1442 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1546 ASSERT(instr->value()->representation().IsTagged()); 1443 ASSERT(instr->value()->representation().IsTagged());
1547 LOperand* value = UseAtStart(instr->value()); 1444 return new LIsSmiAndBranch(Use(instr->value()));
1548
1549 return DefineAsRegister(new LIsSmi(value));
1550 } 1445 }
1551 1446
1552 1447
1553 LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) { 1448 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1449 HIsUndetectableAndBranch* instr) {
1554 ASSERT(instr->value()->representation().IsTagged()); 1450 ASSERT(instr->value()->representation().IsTagged());
1555 LOperand* value = UseRegisterAtStart(instr->value()); 1451 return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
1556 1452 TempRegister());
1557 return DefineAsRegister(new LIsUndetectable(value));
1558 } 1453 }
1559 1454
1560 1455
1561 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { 1456 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1457 HHasInstanceTypeAndBranch* instr) {
1562 ASSERT(instr->value()->representation().IsTagged()); 1458 ASSERT(instr->value()->representation().IsTagged());
1563 LOperand* value = UseRegisterAtStart(instr->value()); 1459 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()));
1564
1565 return DefineAsRegister(new LHasInstanceType(value));
1566 } 1460 }
1567 1461
1568 1462
1569 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( 1463 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1570 HGetCachedArrayIndex* instr) { 1464 HGetCachedArrayIndex* instr) {
1571 ASSERT(instr->value()->representation().IsTagged()); 1465 ASSERT(instr->value()->representation().IsTagged());
1572 LOperand* value = UseRegisterAtStart(instr->value()); 1466 LOperand* value = UseRegisterAtStart(instr->value());
1573 1467
1574 return DefineAsRegister(new LGetCachedArrayIndex(value)); 1468 return DefineAsRegister(new LGetCachedArrayIndex(value));
1575 } 1469 }
1576 1470
1577 1471
1578 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( 1472 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1579 HHasCachedArrayIndex* instr) { 1473 HHasCachedArrayIndexAndBranch* instr) {
1580 ASSERT(instr->value()->representation().IsTagged()); 1474 ASSERT(instr->value()->representation().IsTagged());
1581 LOperand* value = UseRegister(instr->value()); 1475 return new LHasCachedArrayIndexAndBranch(UseRegisterAtStart(instr->value()));
1582 return DefineAsRegister(new LHasCachedArrayIndex(value));
1583 } 1476 }
1584 1477
1585 1478
1586 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1479 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1587 Abort("Unimplemented: %s", "DoClassOfTest"); 1480 HClassOfTestAndBranch* instr) {
1588 return NULL; 1481 return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
1482 TempRegister());
1589 } 1483 }
1590 1484
1591 1485
1592 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1486 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1593 LOperand* array = UseRegisterAtStart(instr->value()); 1487 LOperand* array = UseRegisterAtStart(instr->value());
1594 return DefineAsRegister(new LJSArrayLength(array)); 1488 return DefineAsRegister(new LJSArrayLength(array));
1595 } 1489 }
1596 1490
1597 1491
1598 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1492 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1599 LOperand* array = UseRegisterAtStart(instr->value()); 1493 LOperand* array = UseRegisterAtStart(instr->value());
1600 return DefineAsRegister(new LFixedArrayLength(array)); 1494 return DefineAsRegister(new LFixedArrayLength(array));
1601 } 1495 }
1602 1496
1603 1497
1604 LInstruction* LChunkBuilder::DoExternalArrayLength( 1498 LInstruction* LChunkBuilder::DoExternalArrayLength(
1605 HExternalArrayLength* instr) { 1499 HExternalArrayLength* instr) {
1606 LOperand* array = UseRegisterAtStart(instr->value()); 1500 LOperand* array = UseRegisterAtStart(instr->value());
1607 return DefineAsRegister(new LExternalArrayLength(array)); 1501 return DefineAsRegister(new LExternalArrayLength(array));
1608 } 1502 }
1609 1503
1610 1504
1505 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
1506 LOperand* object = UseRegisterAtStart(instr->value());
1507 return DefineAsRegister(new LElementsKind(object));
1508 }
1509
1510
1611 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1511 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1612 LOperand* object = UseRegister(instr->value()); 1512 LOperand* object = UseRegister(instr->value());
1613 LValueOf* result = new LValueOf(object); 1513 LValueOf* result = new LValueOf(object);
1614 return AssignEnvironment(DefineSameAsFirst(result)); 1514 return AssignEnvironment(DefineSameAsFirst(result));
1615 } 1515 }
1616 1516
1617 1517
1618 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1518 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1619 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1519 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1620 Use(instr->length()))); 1520 Use(instr->length())));
1621 } 1521 }
1622 1522
1623 1523
1624 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1524 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1625 // The control instruction marking the end of a block that completed 1525 // The control instruction marking the end of a block that completed
1626 // abruptly (e.g., threw an exception). There is nothing specific to do. 1526 // abruptly (e.g., threw an exception). There is nothing specific to do.
1627 return NULL; 1527 return NULL;
1628 } 1528 }
1629 1529
1630 1530
1631 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1531 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1632 LOperand* value = UseFixed(instr->value(), rax); 1532 LOperand* value = UseFixed(instr->value(), rax);
1633 return MarkAsCall(new LThrow(value), instr); 1533 return MarkAsCall(new LThrow(value), instr);
1634 } 1534 }
1635 1535
1636 1536
1537 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1538 return NULL;
1539 }
1540
1541
1637 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { 1542 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1638 // All HForceRepresentation instructions should be eliminated in the 1543 // All HForceRepresentation instructions should be eliminated in the
1639 // representation change phase of Hydrogen. 1544 // representation change phase of Hydrogen.
1640 UNREACHABLE(); 1545 UNREACHABLE();
1641 return NULL; 1546 return NULL;
1642 } 1547 }
1643 1548
1644 1549
1645 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1550 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1646 Representation from = instr->from(); 1551 Representation from = instr->from();
1647 Representation to = instr->to(); 1552 Representation to = instr->to();
1648 if (from.IsTagged()) { 1553 if (from.IsTagged()) {
1649 if (to.IsDouble()) { 1554 if (to.IsDouble()) {
1650 LOperand* value = UseRegister(instr->value()); 1555 LOperand* value = UseRegister(instr->value());
1651 LNumberUntagD* res = new LNumberUntagD(value); 1556 LNumberUntagD* res = new LNumberUntagD(value);
1652 return AssignEnvironment(DefineAsRegister(res)); 1557 return AssignEnvironment(DefineAsRegister(res));
1653 } else { 1558 } else {
1654 ASSERT(to.IsInteger32()); 1559 ASSERT(to.IsInteger32());
1655 LOperand* value = UseRegister(instr->value()); 1560 LOperand* value = UseRegister(instr->value());
1656 bool needs_check = !instr->value()->type().IsSmi(); 1561 bool needs_check = !instr->value()->type().IsSmi();
1657 if (needs_check) { 1562 if (needs_check) {
1658 LOperand* xmm_temp = instr->CanTruncateToInt32() ? NULL 1563 bool truncating = instr->CanTruncateToInt32();
1659 : FixedTemp(xmm1); 1564 LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
1660 LTaggedToI* res = new LTaggedToI(value, xmm_temp); 1565 LTaggedToI* res = new LTaggedToI(value, xmm_temp);
1661 return AssignEnvironment(DefineSameAsFirst(res)); 1566 return AssignEnvironment(DefineSameAsFirst(res));
1662 } else { 1567 } else {
1663 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1568 return DefineSameAsFirst(new LSmiUntag(value, needs_check));
1664 } 1569 }
1665 } 1570 }
1666 } else if (from.IsDouble()) { 1571 } else if (from.IsDouble()) {
1667 if (to.IsTagged()) { 1572 if (to.IsTagged()) {
1668 LOperand* value = UseRegister(instr->value()); 1573 LOperand* value = UseRegister(instr->value());
1669 LOperand* temp = TempRegister(); 1574 LOperand* temp = TempRegister();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 // Register allocator doesn't (yet) support allocation of double 1655 // Register allocator doesn't (yet) support allocation of double
1751 // temps. Reserve xmm1 explicitly. 1656 // temps. Reserve xmm1 explicitly.
1752 LClampTToUint8* result = new LClampTToUint8(reg, 1657 LClampTToUint8* result = new LClampTToUint8(reg,
1753 TempRegister(), 1658 TempRegister(),
1754 FixedTemp(xmm1)); 1659 FixedTemp(xmm1));
1755 return AssignEnvironment(DefineSameAsFirst(result)); 1660 return AssignEnvironment(DefineSameAsFirst(result));
1756 } 1661 }
1757 } 1662 }
1758 1663
1759 1664
1665 LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
1666 HValue* value = instr->value();
1667 Representation input_rep = value->representation();
1668 LOperand* reg = UseRegister(value);
1669 if (input_rep.IsDouble()) {
1670 return AssignEnvironment(DefineAsRegister(new LDoubleToI(reg)));
1671 } else if (input_rep.IsInteger32()) {
1672 // Canonicalization should already have removed the hydrogen instruction in
1673 // this case, since it is a noop.
1674 UNREACHABLE();
1675 return NULL;
1676 } else {
1677 ASSERT(input_rep.IsTagged());
1678 LOperand* reg = UseRegister(value);
1679 // Register allocator doesn't (yet) support allocation of double
1680 // temps. Reserve xmm1 explicitly.
1681 LOperand* xmm_temp =
1682 CpuFeatures::IsSupported(SSE3)
1683 ? NULL
1684 : FixedTemp(xmm1);
1685 return AssignEnvironment(
1686 DefineSameAsFirst(new LTaggedToI(reg, xmm_temp)));
1687 }
1688 }
1689
1690
1760 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1691 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1761 return new LReturn(UseFixed(instr->value(), rax)); 1692 return new LReturn(UseFixed(instr->value(), rax));
1762 } 1693 }
1763 1694
1764 1695
1765 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1696 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1766 Representation r = instr->representation(); 1697 Representation r = instr->representation();
1767 if (r.IsInteger32()) { 1698 if (r.IsInteger32()) {
1768 return DefineAsRegister(new LConstantI); 1699 return DefineAsRegister(new LConstantI);
1769 } else if (r.IsDouble()) { 1700 } else if (r.IsDouble()) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 ASSERT(instr->key()->representation().IsInteger32()); 1819 ASSERT(instr->key()->representation().IsInteger32());
1889 LOperand* obj = UseRegisterAtStart(instr->object()); 1820 LOperand* obj = UseRegisterAtStart(instr->object());
1890 LOperand* key = UseRegisterAtStart(instr->key()); 1821 LOperand* key = UseRegisterAtStart(instr->key());
1891 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1822 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1892 return AssignEnvironment(DefineSameAsFirst(result)); 1823 return AssignEnvironment(DefineSameAsFirst(result));
1893 } 1824 }
1894 1825
1895 1826
1896 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( 1827 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1897 HLoadKeyedSpecializedArrayElement* instr) { 1828 HLoadKeyedSpecializedArrayElement* instr) {
1898 ExternalArrayType array_type = instr->array_type(); 1829 JSObject::ElementsKind elements_kind = instr->elements_kind();
1899 Representation representation(instr->representation()); 1830 Representation representation(instr->representation());
1900 ASSERT( 1831 ASSERT(
1901 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1832 (representation.IsInteger32() &&
1902 array_type != kExternalDoubleArray)) || 1833 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1903 (representation.IsDouble() && (array_type == kExternalFloatArray || 1834 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1904 array_type == kExternalDoubleArray))); 1835 (representation.IsDouble() &&
1836 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1837 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
1905 ASSERT(instr->key()->representation().IsInteger32()); 1838 ASSERT(instr->key()->representation().IsInteger32());
1906 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1839 LOperand* external_pointer = UseRegister(instr->external_pointer());
1907 LOperand* key = UseRegisterOrConstant(instr->key()); 1840 LOperand* key = UseRegisterOrConstant(instr->key());
1908 LLoadKeyedSpecializedArrayElement* result = 1841 LLoadKeyedSpecializedArrayElement* result =
1909 new LLoadKeyedSpecializedArrayElement(external_pointer, key); 1842 new LLoadKeyedSpecializedArrayElement(external_pointer, key);
1910 LInstruction* load_instr = DefineAsRegister(result); 1843 LInstruction* load_instr = DefineAsRegister(result);
1911 // An unsigned int array load might overflow and cause a deopt, make sure it 1844 // An unsigned int array load might overflow and cause a deopt, make sure it
1912 // has an environment. 1845 // has an environment.
1913 return (array_type == kExternalUnsignedIntArray) ? 1846 return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ?
1914 AssignEnvironment(load_instr) : load_instr; 1847 AssignEnvironment(load_instr) : load_instr;
1915 } 1848 }
1916 1849
1917 1850
1918 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1851 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1919 LOperand* object = UseFixed(instr->object(), rdx); 1852 LOperand* object = UseFixed(instr->object(), rdx);
1920 LOperand* key = UseFixed(instr->key(), rax); 1853 LOperand* key = UseFixed(instr->key(), rax);
1921 1854
1922 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); 1855 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key);
1923 return MarkAsCall(DefineFixed(result, rax), instr); 1856 return MarkAsCall(DefineFixed(result, rax), instr);
(...skipping 15 matching lines...) Expand all
1939 ? UseTempRegister(instr->key()) 1872 ? UseTempRegister(instr->key())
1940 : UseRegisterOrConstantAtStart(instr->key()); 1873 : UseRegisterOrConstantAtStart(instr->key());
1941 1874
1942 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1875 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1943 } 1876 }
1944 1877
1945 1878
1946 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( 1879 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1947 HStoreKeyedSpecializedArrayElement* instr) { 1880 HStoreKeyedSpecializedArrayElement* instr) {
1948 Representation representation(instr->value()->representation()); 1881 Representation representation(instr->value()->representation());
1949 ExternalArrayType array_type = instr->array_type(); 1882 JSObject::ElementsKind elements_kind = instr->elements_kind();
1950 ASSERT( 1883 ASSERT(
1951 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1884 (representation.IsInteger32() &&
1952 array_type != kExternalDoubleArray)) || 1885 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1953 (representation.IsDouble() && (array_type == kExternalFloatArray || 1886 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1954 array_type == kExternalDoubleArray))); 1887 (representation.IsDouble() &&
1888 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1889 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
1955 ASSERT(instr->external_pointer()->representation().IsExternal()); 1890 ASSERT(instr->external_pointer()->representation().IsExternal());
1956 ASSERT(instr->key()->representation().IsInteger32()); 1891 ASSERT(instr->key()->representation().IsInteger32());
1957 1892
1958 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1893 LOperand* external_pointer = UseRegister(instr->external_pointer());
1959 bool val_is_temp_register = array_type == kExternalPixelArray || 1894 bool val_is_temp_register =
1960 array_type == kExternalFloatArray; 1895 elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS ||
1896 elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS;
1961 LOperand* val = val_is_temp_register 1897 LOperand* val = val_is_temp_register
1962 ? UseTempRegister(instr->value()) 1898 ? UseTempRegister(instr->value())
1963 : UseRegister(instr->value()); 1899 : UseRegister(instr->value());
1964 LOperand* key = UseRegisterOrConstant(instr->key()); 1900 LOperand* key = UseRegisterOrConstant(instr->key());
1965 1901
1966 return new LStoreKeyedSpecializedArrayElement(external_pointer, 1902 return new LStoreKeyedSpecializedArrayElement(external_pointer,
1967 key, 1903 key,
1968 val); 1904 val);
1969 } 1905 }
1970 1906
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 2012
2077 2013
2078 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 2014 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2079 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 2015 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2080 return DefineAsSpilled(new LParameter, spill_index); 2016 return DefineAsSpilled(new LParameter, spill_index);
2081 } 2017 }
2082 2018
2083 2019
2084 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 2020 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2085 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. 2021 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
2022 if (spill_index > LUnallocated::kMaxFixedIndex) {
2023 Abort("Too many spill slots needed for OSR");
2024 spill_index = 0;
2025 }
2086 return DefineAsSpilled(new LUnknownOSRValue, spill_index); 2026 return DefineAsSpilled(new LUnknownOSRValue, spill_index);
2087 } 2027 }
2088 2028
2089 2029
2090 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2030 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2091 argument_count_ -= instr->argument_count(); 2031 argument_count_ -= instr->argument_count();
2092 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); 2032 return MarkAsCall(DefineFixed(new LCallStub, rax), instr);
2093 } 2033 }
2094 2034
2095 2035
(...skipping 21 matching lines...) Expand all
2117 return MarkAsCall(DefineFixed(result, rax), instr); 2057 return MarkAsCall(DefineFixed(result, rax), instr);
2118 } 2058 }
2119 2059
2120 2060
2121 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2061 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2122 LTypeof* result = new LTypeof(UseAtStart(instr->value())); 2062 LTypeof* result = new LTypeof(UseAtStart(instr->value()));
2123 return MarkAsCall(DefineFixed(result, rax), instr); 2063 return MarkAsCall(DefineFixed(result, rax), instr);
2124 } 2064 }
2125 2065
2126 2066
2127 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 2067 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2128 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 2068 return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
2129 } 2069 }
2130 2070
2131 2071
2132 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { 2072 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2133 return DefineAsRegister(new LIsConstructCall); 2073 HIsConstructCallAndBranch* instr) {
2074 return new LIsConstructCallAndBranch(TempRegister());
2134 } 2075 }
2135 2076
2136 2077
2137 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2078 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2138 HEnvironment* env = current_block_->last_environment(); 2079 HEnvironment* env = current_block_->last_environment();
2139 ASSERT(env != NULL); 2080 ASSERT(env != NULL);
2140 2081
2141 env->set_ast_id(instr->ast_id()); 2082 env->set_ast_id(instr->ast_id());
2142 2083
2143 env->Drop(instr->pop_count()); 2084 env->Drop(instr->pop_count());
(...skipping 15 matching lines...) Expand all
2159 set_deoptimization_environment(result->environment()); 2100 set_deoptimization_environment(result->environment());
2160 ClearInstructionPendingDeoptimizationEnvironment(); 2101 ClearInstructionPendingDeoptimizationEnvironment();
2161 return result; 2102 return result;
2162 } 2103 }
2163 2104
2164 return NULL; 2105 return NULL;
2165 } 2106 }
2166 2107
2167 2108
2168 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2109 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2169 return MarkAsCall(new LStackCheck, instr); 2110 if (instr->is_function_entry()) {
2111 return MarkAsCall(new LStackCheck, instr);
2112 } else {
2113 ASSERT(instr->is_backwards_branch());
2114 return AssignEnvironment(AssignPointerMap(new LStackCheck));
2115 }
2170 } 2116 }
2171 2117
2172 2118
2173 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2119 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2174 HEnvironment* outer = current_block_->last_environment(); 2120 HEnvironment* outer = current_block_->last_environment();
2175 HConstant* undefined = graph()->GetConstantUndefined(); 2121 HConstant* undefined = graph()->GetConstantUndefined();
2176 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2122 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2177 instr->function(), 2123 instr->function(),
2178 HEnvironment::LITHIUM,
2179 undefined, 2124 undefined,
2180 instr->call_kind()); 2125 instr->call_kind());
2181 current_block_->UpdateEnvironment(inner); 2126 current_block_->UpdateEnvironment(inner);
2182 chunk_->AddInlinedClosure(instr->closure()); 2127 chunk_->AddInlinedClosure(instr->closure());
2183 return NULL; 2128 return NULL;
2184 } 2129 }
2185 2130
2186 2131
2187 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2132 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2188 HEnvironment* outer = current_block_->last_environment()->outer(); 2133 HEnvironment* outer = current_block_->last_environment()->outer();
2189 current_block_->UpdateEnvironment(outer); 2134 current_block_->UpdateEnvironment(outer);
2190 return NULL; 2135 return NULL;
2191 } 2136 }
2192 2137
2193 2138
2194 LInstruction* LChunkBuilder::DoIn(HIn* instr) { 2139 LInstruction* LChunkBuilder::DoIn(HIn* instr) {
2195 LOperand* key = UseOrConstantAtStart(instr->key()); 2140 LOperand* key = UseOrConstantAtStart(instr->key());
2196 LOperand* object = UseOrConstantAtStart(instr->object()); 2141 LOperand* object = UseOrConstantAtStart(instr->object());
2197 LIn* result = new LIn(key, object); 2142 LIn* result = new LIn(key, object);
2198 return MarkAsCall(DefineFixed(result, rax), instr); 2143 return MarkAsCall(DefineFixed(result, rax), instr);
2199 } 2144 }
2200 2145
2201 2146
2202 } } // namespace v8::internal 2147 } } // namespace v8::internal
2203 2148
2204 #endif // V8_TARGET_ARCH_X64 2149 #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