OLD | NEW |
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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 stream->Add("%s #%d / ", *name_string, arity()); | 286 stream->Add("%s #%d / ", *name_string, arity()); |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { | 290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { |
291 stream->Add("#%d / ", arity()); | 291 stream->Add("#%d / ", arity()); |
292 } | 292 } |
293 | 293 |
294 | 294 |
295 void LCallNew::PrintDataTo(StringStream* stream) const { | 295 void LCallNew::PrintDataTo(StringStream* stream) const { |
296 LUnaryOperation::PrintDataTo(stream); | 296 LUnaryOperation<1>::PrintDataTo(stream); |
297 stream->Add(" #%d / ", arity()); | 297 stream->Add(" #%d / ", arity()); |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 void LClassOfTest::PrintDataTo(StringStream* stream) const { | 301 void LClassOfTest::PrintDataTo(StringStream* stream) const { |
302 stream->Add("= class_of_test("); | 302 stream->Add("= class_of_test("); |
303 input()->PrintTo(stream); | 303 input()->PrintTo(stream); |
304 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 304 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 void LUnaryOperation::PrintDataTo(StringStream* stream) const { | 308 template <int R> |
| 309 void LUnaryOperation<R>::PrintDataTo(StringStream* stream) const { |
309 stream->Add("= "); | 310 stream->Add("= "); |
310 input()->PrintTo(stream); | 311 input()->PrintTo(stream); |
311 } | 312 } |
312 | 313 |
313 | 314 |
314 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const { | 315 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const { |
315 arguments()->PrintTo(stream); | 316 arguments()->PrintTo(stream); |
316 | 317 |
317 stream->Add(" length "); | 318 stream->Add(" length "); |
318 length()->PrintTo(stream); | 319 length()->PrintTo(stream); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 592 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { |
592 if (value->EmitAtUses()) { | 593 if (value->EmitAtUses()) { |
593 HInstruction* instr = HInstruction::cast(value); | 594 HInstruction* instr = HInstruction::cast(value); |
594 VisitInstruction(instr); | 595 VisitInstruction(instr); |
595 } | 596 } |
596 allocator_->RecordUse(value, operand); | 597 allocator_->RecordUse(value, operand); |
597 return operand; | 598 return operand; |
598 } | 599 } |
599 | 600 |
600 | 601 |
601 LInstruction* LChunkBuilder::Define(LInstruction* instr) { | 602 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr) { |
602 return Define(instr, new LUnallocated(LUnallocated::NONE)); | 603 return Define(instr, new LUnallocated(LUnallocated::NONE)); |
603 } | 604 } |
604 | 605 |
605 | 606 |
606 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { | 607 LInstruction* LChunkBuilder::DefineAsRegister(LTemplateInstruction<1>* instr) { |
607 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); | 608 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); |
608 } | 609 } |
609 | 610 |
610 | 611 |
611 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { | 612 LInstruction* LChunkBuilder::DefineAsSpilled(LTemplateInstruction<1>* instr, |
| 613 int index) { |
612 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); | 614 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); |
613 } | 615 } |
614 | 616 |
615 | 617 |
616 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { | 618 LInstruction* LChunkBuilder::DefineSameAsFirst(LTemplateInstruction<1>* instr) { |
617 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); | 619 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); |
618 } | 620 } |
619 | 621 |
620 | 622 |
621 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { | 623 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1>* instr, |
| 624 Register reg) { |
622 return Define(instr, ToUnallocated(reg)); | 625 return Define(instr, ToUnallocated(reg)); |
623 } | 626 } |
624 | 627 |
625 | 628 |
626 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, | 629 LInstruction* LChunkBuilder::DefineFixedDouble(LTemplateInstruction<1>* instr, |
627 XMMRegister reg) { | 630 XMMRegister reg) { |
628 return Define(instr, ToUnallocated(reg)); | 631 return Define(instr, ToUnallocated(reg)); |
629 } | 632 } |
630 | 633 |
631 | 634 |
632 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 635 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
633 HEnvironment* hydrogen_env = current_block_->last_environment(); | 636 HEnvironment* hydrogen_env = current_block_->last_environment(); |
634 instr->set_environment(CreateEnvironment(hydrogen_env)); | 637 instr->set_environment(CreateEnvironment(hydrogen_env)); |
635 return instr; | 638 return instr; |
636 } | 639 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 688 } |
686 | 689 |
687 | 690 |
688 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 691 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
689 ASSERT(!instr->HasPointerMap()); | 692 ASSERT(!instr->HasPointerMap()); |
690 instr->set_pointer_map(new LPointerMap(position_)); | 693 instr->set_pointer_map(new LPointerMap(position_)); |
691 return instr; | 694 return instr; |
692 } | 695 } |
693 | 696 |
694 | 697 |
695 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) { | 698 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr, |
| 699 LUnallocated* result) { |
696 allocator_->RecordDefinition(current_instruction_, result); | 700 allocator_->RecordDefinition(current_instruction_, result); |
697 instr->set_result(result); | 701 instr->set_result(result); |
698 return instr; | 702 return instr; |
699 } | 703 } |
700 | 704 |
701 | 705 |
702 LOperand* LChunkBuilder::Temp() { | 706 LOperand* LChunkBuilder::Temp() { |
703 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); | 707 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); |
704 allocator_->RecordTemporary(operand); | 708 allocator_->RecordTemporary(operand); |
705 return operand; | 709 return operand; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 bool can_truncate = true; | 778 bool can_truncate = true; |
775 for (int i = 0; i < instr->uses()->length(); i++) { | 779 for (int i = 0; i < instr->uses()->length(); i++) { |
776 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { | 780 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { |
777 can_truncate = false; | 781 can_truncate = false; |
778 break; | 782 break; |
779 } | 783 } |
780 } | 784 } |
781 can_deopt = !can_truncate; | 785 can_deopt = !can_truncate; |
782 } | 786 } |
783 | 787 |
784 LInstruction* result = | 788 LShiftI* result = new LShiftI(op, left, right, can_deopt); |
785 DefineSameAsFirst(new LShiftI(op, left, right, can_deopt)); | 789 return can_deopt |
786 if (can_deopt) AssignEnvironment(result); | 790 ? AssignEnvironment(DefineSameAsFirst(result)) |
787 return result; | 791 : DefineSameAsFirst(result); |
788 } | 792 } |
789 | 793 |
790 | 794 |
791 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 795 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
792 HArithmeticBinaryOperation* instr) { | 796 HArithmeticBinaryOperation* instr) { |
793 ASSERT(instr->representation().IsDouble()); | 797 ASSERT(instr->representation().IsDouble()); |
794 ASSERT(instr->left()->representation().IsDouble()); | 798 ASSERT(instr->left()->representation().IsDouble()); |
795 ASSERT(instr->right()->representation().IsDouble()); | 799 ASSERT(instr->right()->representation().IsDouble()); |
796 LOperand* left = UseRegisterAtStart(instr->left()); | 800 LOperand* left = UseRegisterAtStart(instr->left()); |
797 LOperand* right = UseRegisterAtStart(instr->right()); | 801 LOperand* right = UseRegisterAtStart(instr->right()); |
798 LArithmeticD* result = new LArithmeticD(op, left, right); | 802 LArithmeticD* result = new LArithmeticD(op, left, right); |
799 return DefineSameAsFirst(result); | 803 return DefineSameAsFirst(result); |
800 } | 804 } |
801 | 805 |
802 | 806 |
803 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 807 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
804 HArithmeticBinaryOperation* instr) { | 808 HArithmeticBinaryOperation* instr) { |
805 ASSERT(op == Token::ADD || | 809 ASSERT(op == Token::ADD || |
806 op == Token::DIV || | 810 op == Token::DIV || |
807 op == Token::MOD || | 811 op == Token::MOD || |
808 op == Token::MUL || | 812 op == Token::MUL || |
809 op == Token::SUB); | 813 op == Token::SUB); |
810 HValue* left = instr->left(); | 814 HValue* left = instr->left(); |
811 HValue* right = instr->right(); | 815 HValue* right = instr->right(); |
812 ASSERT(left->representation().IsTagged()); | 816 ASSERT(left->representation().IsTagged()); |
813 ASSERT(right->representation().IsTagged()); | 817 ASSERT(right->representation().IsTagged()); |
814 LOperand* left_operand = UseFixed(left, edx); | 818 LOperand* left_operand = UseFixed(left, edx); |
815 LOperand* right_operand = UseFixed(right, eax); | 819 LOperand* right_operand = UseFixed(right, eax); |
816 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); | 820 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); |
817 return MarkAsCall(DefineFixed(result, eax), instr); | 821 return MarkAsCall(DefineFixed(result, eax), instr); |
818 } | 822 } |
819 | 823 |
820 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 824 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
821 ASSERT(is_building()); | 825 ASSERT(is_building()); |
822 current_block_ = block; | 826 current_block_ = block; |
823 next_block_ = next_block; | 827 next_block_ = next_block; |
824 if (block->IsStartBlock()) { | 828 if (block->IsStartBlock()) { |
825 block->UpdateEnvironment(graph_->start_environment()); | 829 block->UpdateEnvironment(graph_->start_environment()); |
826 argument_count_ = 0; | 830 argument_count_ = 0; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 } | 996 } |
993 } | 997 } |
994 result->AddValue(op, value->representation()); | 998 result->AddValue(op, value->representation()); |
995 } | 999 } |
996 | 1000 |
997 return result; | 1001 return result; |
998 } | 1002 } |
999 | 1003 |
1000 | 1004 |
1001 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1005 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
1002 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), | 1006 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
1003 instr->include_stack_check()); | 1007 instr->include_stack_check()); |
1004 if (instr->include_stack_check()) result = AssignPointerMap(result); | 1008 return (instr->include_stack_check()) |
1005 return result; | 1009 ? AssignPointerMap(result) |
| 1010 : result; |
1006 } | 1011 } |
1007 | 1012 |
1008 | 1013 |
1009 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1014 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
1010 HValue* v = instr->value(); | 1015 HValue* v = instr->value(); |
1011 HBasicBlock* first = instr->FirstSuccessor(); | 1016 HBasicBlock* first = instr->FirstSuccessor(); |
1012 HBasicBlock* second = instr->SecondSuccessor(); | 1017 HBasicBlock* second = instr->SecondSuccessor(); |
1013 ASSERT(first != NULL && second != NULL); | 1018 ASSERT(first != NULL && second != NULL); |
1014 int first_id = first->block_id(); | 1019 int first_id = first->block_id(); |
1015 int second_id = second->block_id(); | 1020 int second_id = second->block_id(); |
(...skipping 28 matching lines...) Expand all Loading... |
1044 UseRegisterAtStart(right), | 1049 UseRegisterAtStart(right), |
1045 first_id, | 1050 first_id, |
1046 second_id, | 1051 second_id, |
1047 true); | 1052 true); |
1048 } else { | 1053 } else { |
1049 ASSERT(left->representation().IsTagged()); | 1054 ASSERT(left->representation().IsTagged()); |
1050 ASSERT(right->representation().IsTagged()); | 1055 ASSERT(right->representation().IsTagged()); |
1051 bool reversed = op == Token::GT || op == Token::LTE; | 1056 bool reversed = op == Token::GT || op == Token::LTE; |
1052 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | 1057 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); |
1053 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | 1058 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); |
1054 LInstruction* result = new LCmpTAndBranch(left_operand, | 1059 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
1055 right_operand, | 1060 right_operand, |
1056 first_id, | 1061 first_id, |
1057 second_id); | 1062 second_id); |
1058 return MarkAsCall(result, instr); | 1063 return MarkAsCall(result, instr); |
1059 } | 1064 } |
1060 } else if (v->IsIsSmi()) { | 1065 } else if (v->IsIsSmi()) { |
1061 HIsSmi* compare = HIsSmi::cast(v); | 1066 HIsSmi* compare = HIsSmi::cast(v); |
1062 ASSERT(compare->value()->representation().IsTagged()); | 1067 ASSERT(compare->value()->representation().IsTagged()); |
1063 | 1068 |
1064 return new LIsSmiAndBranch(Use(compare->value()), | 1069 return new LIsSmiAndBranch(Use(compare->value()), |
1065 first_id, | 1070 first_id, |
1066 second_id); | 1071 second_id); |
1067 } else if (v->IsHasInstanceType()) { | 1072 } else if (v->IsHasInstanceType()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 first_id, | 1106 first_id, |
1102 second_id); | 1107 second_id); |
1103 } else if (v->IsCompareJSObjectEq()) { | 1108 } else if (v->IsCompareJSObjectEq()) { |
1104 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1109 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
1105 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1110 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
1106 UseRegisterAtStart(compare->right()), | 1111 UseRegisterAtStart(compare->right()), |
1107 first_id, | 1112 first_id, |
1108 second_id); | 1113 second_id); |
1109 } else if (v->IsInstanceOf()) { | 1114 } else if (v->IsInstanceOf()) { |
1110 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1115 HInstanceOf* instance_of = HInstanceOf::cast(v); |
1111 LInstruction* result = | 1116 LInstanceOfAndBranch* result = |
1112 new LInstanceOfAndBranch( | 1117 new LInstanceOfAndBranch( |
1113 UseFixed(instance_of->left(), InstanceofStub::left()), | 1118 UseFixed(instance_of->left(), InstanceofStub::left()), |
1114 UseFixed(instance_of->right(), InstanceofStub::right()), | 1119 UseFixed(instance_of->right(), InstanceofStub::right()), |
1115 first_id, | 1120 first_id, |
1116 second_id); | 1121 second_id); |
1117 return MarkAsCall(result, instr); | 1122 return MarkAsCall(result, instr); |
1118 } else if (v->IsTypeofIs()) { | 1123 } else if (v->IsTypeofIs()) { |
1119 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1124 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
1120 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), | 1125 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), |
1121 first_id, | 1126 first_id, |
(...skipping 26 matching lines...) Expand all Loading... |
1148 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1153 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
1149 } | 1154 } |
1150 | 1155 |
1151 | 1156 |
1152 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1157 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
1153 return DefineAsRegister(new LArgumentsElements); | 1158 return DefineAsRegister(new LArgumentsElements); |
1154 } | 1159 } |
1155 | 1160 |
1156 | 1161 |
1157 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1162 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
1158 LInstruction* result = | 1163 LInstanceOf* result = |
1159 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), | 1164 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), |
1160 UseFixed(instr->right(), InstanceofStub::right())); | 1165 UseFixed(instr->right(), InstanceofStub::right())); |
1161 return MarkAsCall(DefineFixed(result, eax), instr); | 1166 return MarkAsCall(DefineFixed(result, eax), instr); |
1162 } | 1167 } |
1163 | 1168 |
1164 | 1169 |
1165 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1170 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
1166 HInstanceOfKnownGlobal* instr) { | 1171 HInstanceOfKnownGlobal* instr) { |
1167 LInstruction* result = | 1172 LInstanceOfKnownGlobal* result = |
1168 new LInstanceOfKnownGlobal( | 1173 new LInstanceOfKnownGlobal( |
1169 UseFixed(instr->value(), InstanceofStub::left()), | 1174 UseFixed(instr->value(), InstanceofStub::left()), |
1170 FixedTemp(edi)); | 1175 FixedTemp(edi)); |
1171 MarkAsSaveDoubles(result); | 1176 MarkAsSaveDoubles(result); |
1172 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); | 1177 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); |
1173 } | 1178 } |
1174 | 1179 |
1175 | 1180 |
1176 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1181 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
1177 LOperand* function = UseFixed(instr->function(), edi); | 1182 LOperand* function = UseFixed(instr->function(), edi); |
1178 LOperand* receiver = UseFixed(instr->receiver(), eax); | 1183 LOperand* receiver = UseFixed(instr->receiver(), eax); |
1179 LOperand* length = UseRegisterAtStart(instr->length()); | 1184 LOperand* length = UseRegisterAtStart(instr->length()); |
1180 LOperand* elements = UseRegisterAtStart(instr->elements()); | 1185 LOperand* elements = UseRegisterAtStart(instr->elements()); |
1181 LInstruction* result = new LApplyArguments(function, | 1186 LApplyArguments* result = new LApplyArguments(function, |
1182 receiver, | 1187 receiver, |
1183 length, | 1188 length, |
1184 elements); | 1189 elements); |
1185 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1190 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
1186 } | 1191 } |
1187 | 1192 |
1188 | 1193 |
1189 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1194 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
1190 ++argument_count_; | 1195 ++argument_count_; |
1191 LOperand* argument = UseOrConstant(instr->argument()); | 1196 LOperand* argument = UseOrConstant(instr->argument()); |
1192 return new LPushArgument(argument); | 1197 return new LPushArgument(argument); |
1193 } | 1198 } |
1194 | 1199 |
(...skipping 12 matching lines...) Expand all Loading... |
1207 HCallConstantFunction* instr) { | 1212 HCallConstantFunction* instr) { |
1208 argument_count_ -= instr->argument_count(); | 1213 argument_count_ -= instr->argument_count(); |
1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); | 1214 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); |
1210 } | 1215 } |
1211 | 1216 |
1212 | 1217 |
1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1218 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
1214 BuiltinFunctionId op = instr->op(); | 1219 BuiltinFunctionId op = instr->op(); |
1215 if (op == kMathLog || op == kMathSin || op == kMathCos) { | 1220 if (op == kMathLog || op == kMathSin || op == kMathCos) { |
1216 LOperand* input = UseFixedDouble(instr->value(), xmm1); | 1221 LOperand* input = UseFixedDouble(instr->value(), xmm1); |
1217 LInstruction* result = new LUnaryMathOperation(input); | 1222 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
1218 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1223 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
1219 } else { | 1224 } else { |
1220 LOperand* input = UseRegisterAtStart(instr->value()); | 1225 LOperand* input = UseRegisterAtStart(instr->value()); |
1221 LInstruction* result = new LUnaryMathOperation(input); | 1226 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
1222 switch (op) { | 1227 switch (op) { |
1223 case kMathAbs: | 1228 case kMathAbs: |
1224 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1229 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
1225 case kMathFloor: | 1230 case kMathFloor: |
1226 return AssignEnvironment(DefineAsRegister(result)); | 1231 return AssignEnvironment(DefineAsRegister(result)); |
1227 case kMathRound: | 1232 case kMathRound: |
1228 return AssignEnvironment(DefineAsRegister(result)); | 1233 return AssignEnvironment(DefineAsRegister(result)); |
1229 case kMathSqrt: | 1234 case kMathSqrt: |
1230 return DefineSameAsFirst(result); | 1235 return DefineSameAsFirst(result); |
1231 case kMathPowHalf: | 1236 case kMathPowHalf: |
(...skipping 28 matching lines...) Expand all Loading... |
1260 | 1265 |
1261 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1266 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
1262 argument_count_ -= instr->argument_count(); | 1267 argument_count_ -= instr->argument_count(); |
1263 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); | 1268 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); |
1264 } | 1269 } |
1265 | 1270 |
1266 | 1271 |
1267 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1272 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
1268 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1273 LOperand* constructor = UseFixed(instr->constructor(), edi); |
1269 argument_count_ -= instr->argument_count(); | 1274 argument_count_ -= instr->argument_count(); |
1270 LInstruction* result = new LCallNew(constructor); | 1275 LCallNew* result = new LCallNew(constructor); |
1271 return MarkAsCall(DefineFixed(result, eax), instr); | 1276 return MarkAsCall(DefineFixed(result, eax), instr); |
1272 } | 1277 } |
1273 | 1278 |
1274 | 1279 |
1275 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1280 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
1276 argument_count_ -= instr->argument_count(); | 1281 argument_count_ -= instr->argument_count(); |
1277 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); | 1282 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); |
1278 } | 1283 } |
1279 | 1284 |
1280 | 1285 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 | 1345 |
1341 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1342 if (instr->representation().IsInteger32()) { | 1347 if (instr->representation().IsInteger32()) { |
1343 ASSERT(instr->left()->representation().IsInteger32()); | 1348 ASSERT(instr->left()->representation().IsInteger32()); |
1344 ASSERT(instr->right()->representation().IsInteger32()); | 1349 ASSERT(instr->right()->representation().IsInteger32()); |
1345 // The temporary operand is necessary to ensure that right is not allocated | 1350 // The temporary operand is necessary to ensure that right is not allocated |
1346 // into edx. | 1351 // into edx. |
1347 FixedTemp(edx); | 1352 FixedTemp(edx); |
1348 LOperand* value = UseFixed(instr->left(), eax); | 1353 LOperand* value = UseFixed(instr->left(), eax); |
1349 LOperand* divisor = UseRegister(instr->right()); | 1354 LOperand* divisor = UseRegister(instr->right()); |
1350 LInstruction* result = DefineFixed(new LModI(value, divisor), edx); | 1355 LModI* mod = new LModI(value, divisor); |
1351 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1356 LInstruction* result = DefineFixed(mod, edx); |
1352 instr->CheckFlag(HValue::kCanBeDivByZero)) { | 1357 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1353 result = AssignEnvironment(result); | 1358 instr->CheckFlag(HValue::kCanBeDivByZero)) |
1354 } | 1359 ? AssignEnvironment(result) |
1355 return result; | 1360 : result; |
1356 } else if (instr->representation().IsTagged()) { | 1361 } else if (instr->representation().IsTagged()) { |
1357 return DoArithmeticT(Token::MOD, instr); | 1362 return DoArithmeticT(Token::MOD, instr); |
1358 } else { | 1363 } else { |
1359 ASSERT(instr->representation().IsDouble()); | 1364 ASSERT(instr->representation().IsDouble()); |
1360 // We call a C function for double modulo. It can't trigger a GC. | 1365 // We call a C function for double modulo. It can't trigger a GC. |
1361 // We need to use fixed result register for the call. | 1366 // We need to use fixed result register for the call. |
1362 // TODO(fschneider): Allow any register as input registers. | 1367 // TODO(fschneider): Allow any register as input registers. |
1363 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1368 LOperand* left = UseFixedDouble(instr->left(), xmm1); |
1364 LOperand* right = UseFixedDouble(instr->right(), xmm2); | 1369 LOperand* right = UseFixedDouble(instr->right(), xmm2); |
1365 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); | 1370 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 return DefineAsRegister(new LCmpID(op, left, right, false)); | 1461 return DefineAsRegister(new LCmpID(op, left, right, false)); |
1457 } else if (instr->left()->representation().IsDouble()) { | 1462 } else if (instr->left()->representation().IsDouble()) { |
1458 ASSERT(instr->right()->representation().IsDouble()); | 1463 ASSERT(instr->right()->representation().IsDouble()); |
1459 LOperand* left = UseRegisterAtStart(instr->left()); | 1464 LOperand* left = UseRegisterAtStart(instr->left()); |
1460 LOperand* right = UseRegisterAtStart(instr->right()); | 1465 LOperand* right = UseRegisterAtStart(instr->right()); |
1461 return DefineAsRegister(new LCmpID(op, left, right, true)); | 1466 return DefineAsRegister(new LCmpID(op, left, right, true)); |
1462 } else { | 1467 } else { |
1463 bool reversed = (op == Token::GT || op == Token::LTE); | 1468 bool reversed = (op == Token::GT || op == Token::LTE); |
1464 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); | 1469 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); |
1465 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); | 1470 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); |
1466 LInstruction* result = new LCmpT(left, right); | 1471 LCmpT* result = new LCmpT(left, right); |
1467 return MarkAsCall(DefineFixed(result, eax), instr); | 1472 return MarkAsCall(DefineFixed(result, eax), instr); |
1468 } | 1473 } |
1469 } | 1474 } |
1470 | 1475 |
1471 | 1476 |
1472 LInstruction* LChunkBuilder::DoCompareJSObjectEq( | 1477 LInstruction* LChunkBuilder::DoCompareJSObjectEq( |
1473 HCompareJSObjectEq* instr) { | 1478 HCompareJSObjectEq* instr) { |
1474 LOperand* left = UseRegisterAtStart(instr->left()); | 1479 LOperand* left = UseRegisterAtStart(instr->left()); |
1475 LOperand* right = UseRegisterAtStart(instr->right()); | 1480 LOperand* right = UseRegisterAtStart(instr->right()); |
1476 LInstruction* result = new LCmpJSObjectEq(left, right); | 1481 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); |
1477 return DefineAsRegister(result); | 1482 return DefineAsRegister(result); |
1478 } | 1483 } |
1479 | 1484 |
1480 | 1485 |
1481 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { | 1486 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { |
1482 ASSERT(instr->value()->representation().IsTagged()); | 1487 ASSERT(instr->value()->representation().IsTagged()); |
1483 LOperand* value = UseRegisterAtStart(instr->value()); | 1488 LOperand* value = UseRegisterAtStart(instr->value()); |
1484 | 1489 |
1485 return DefineAsRegister(new LIsNull(value, | 1490 return DefineAsRegister(new LIsNull(value, |
1486 instr->is_strict())); | 1491 instr->is_strict())); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 | 1540 |
1536 | 1541 |
1537 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1542 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
1538 LOperand* array = UseRegisterAtStart(instr->value()); | 1543 LOperand* array = UseRegisterAtStart(instr->value()); |
1539 return DefineAsRegister(new LFixedArrayLength(array)); | 1544 return DefineAsRegister(new LFixedArrayLength(array)); |
1540 } | 1545 } |
1541 | 1546 |
1542 | 1547 |
1543 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1548 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
1544 LOperand* object = UseRegister(instr->value()); | 1549 LOperand* object = UseRegister(instr->value()); |
1545 LInstruction* result = new LValueOf(object, TempRegister()); | 1550 LValueOf* result = new LValueOf(object, TempRegister()); |
1546 return AssignEnvironment(DefineSameAsFirst(result)); | 1551 return AssignEnvironment(DefineSameAsFirst(result)); |
1547 } | 1552 } |
1548 | 1553 |
1549 | 1554 |
1550 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1555 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
1551 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1556 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
1552 Use(instr->length()))); | 1557 Use(instr->length()))); |
1553 } | 1558 } |
1554 | 1559 |
1555 | 1560 |
1556 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1561 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
1557 LOperand* value = UseFixed(instr->value(), eax); | 1562 LOperand* value = UseFixed(instr->value(), eax); |
1558 return MarkAsCall(new LThrow(value), instr); | 1563 return MarkAsCall(new LThrow(value), instr); |
1559 } | 1564 } |
1560 | 1565 |
1561 | 1566 |
1562 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1567 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
1563 Representation from = instr->from(); | 1568 Representation from = instr->from(); |
1564 Representation to = instr->to(); | 1569 Representation to = instr->to(); |
1565 if (from.IsTagged()) { | 1570 if (from.IsTagged()) { |
1566 if (to.IsDouble()) { | 1571 if (to.IsDouble()) { |
1567 LOperand* value = UseRegister(instr->value()); | 1572 LOperand* value = UseRegister(instr->value()); |
1568 LInstruction* res = new LNumberUntagD(value); | 1573 LNumberUntagD* res = new LNumberUntagD(value); |
1569 return AssignEnvironment(DefineAsRegister(res)); | 1574 return AssignEnvironment(DefineAsRegister(res)); |
1570 } else { | 1575 } else { |
1571 ASSERT(to.IsInteger32()); | 1576 ASSERT(to.IsInteger32()); |
1572 LOperand* value = UseRegister(instr->value()); | 1577 LOperand* value = UseRegister(instr->value()); |
1573 bool needs_check = !instr->value()->type().IsSmi(); | 1578 bool needs_check = !instr->value()->type().IsSmi(); |
1574 if (needs_check) { | 1579 if (needs_check) { |
1575 LOperand* xmm_temp = | 1580 LOperand* xmm_temp = |
1576 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) | 1581 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) |
1577 ? NULL | 1582 ? NULL |
1578 : FixedTemp(xmm1); | 1583 : FixedTemp(xmm1); |
1579 LInstruction* res = new LTaggedToI(value, xmm_temp); | 1584 LTaggedToI* res = new LTaggedToI(value, xmm_temp); |
1580 return AssignEnvironment(DefineSameAsFirst(res)); | 1585 return AssignEnvironment(DefineSameAsFirst(res)); |
1581 } else { | 1586 } else { |
1582 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); | 1587 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
1583 } | 1588 } |
1584 } | 1589 } |
1585 } else if (from.IsDouble()) { | 1590 } else if (from.IsDouble()) { |
1586 if (to.IsTagged()) { | 1591 if (to.IsTagged()) { |
1587 LOperand* value = UseRegister(instr->value()); | 1592 LOperand* value = UseRegister(instr->value()); |
1588 LOperand* temp = TempRegister(); | 1593 LOperand* temp = TempRegister(); |
1589 | 1594 |
1590 // Make sure that temp and result_temp are different registers. | 1595 // Make sure that temp and result_temp are different registers. |
1591 LUnallocated* result_temp = TempRegister(); | 1596 LUnallocated* result_temp = TempRegister(); |
1592 LInstruction* result = new LNumberTagD(value, temp); | 1597 LNumberTagD* result = new LNumberTagD(value, temp); |
1593 return AssignPointerMap(Define(result, result_temp)); | 1598 return AssignPointerMap(Define(result, result_temp)); |
1594 } else { | 1599 } else { |
1595 ASSERT(to.IsInteger32()); | 1600 ASSERT(to.IsInteger32()); |
1596 LOperand* value = UseRegister(instr->value()); | 1601 LOperand* value = UseRegister(instr->value()); |
1597 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); | 1602 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); |
1598 } | 1603 } |
1599 } else if (from.IsInteger32()) { | 1604 } else if (from.IsInteger32()) { |
1600 if (to.IsTagged()) { | 1605 if (to.IsTagged()) { |
1601 HValue* val = instr->value(); | 1606 HValue* val = instr->value(); |
1602 LOperand* value = UseRegister(val); | 1607 LOperand* value = UseRegister(val); |
1603 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1608 if (val->HasRange() && val->range()->IsInSmiRange()) { |
1604 return DefineSameAsFirst(new LSmiTag(value)); | 1609 return DefineSameAsFirst(new LSmiTag(value)); |
1605 } else { | 1610 } else { |
1606 LInstruction* result = new LNumberTagI(value); | 1611 LNumberTagI* result = new LNumberTagI(value); |
1607 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1612 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
1608 } | 1613 } |
1609 } else { | 1614 } else { |
1610 ASSERT(to.IsDouble()); | 1615 ASSERT(to.IsDouble()); |
1611 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); | 1616 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
1612 } | 1617 } |
1613 } | 1618 } |
1614 UNREACHABLE(); | 1619 UNREACHABLE(); |
1615 return NULL; | 1620 return NULL; |
1616 } | 1621 } |
1617 | 1622 |
1618 | 1623 |
1619 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1624 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
1620 LOperand* value = UseRegisterAtStart(instr->value()); | 1625 LOperand* value = UseRegisterAtStart(instr->value()); |
1621 return AssignEnvironment(new LCheckSmi(value, zero)); | 1626 return AssignEnvironment(new LCheckSmi(value, zero)); |
1622 } | 1627 } |
1623 | 1628 |
1624 | 1629 |
1625 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1630 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
1626 LOperand* value = UseRegisterAtStart(instr->value()); | 1631 LOperand* value = UseRegisterAtStart(instr->value()); |
1627 LOperand* temp = TempRegister(); | 1632 LOperand* temp = TempRegister(); |
1628 LInstruction* result = new LCheckInstanceType(value, temp); | 1633 LCheckInstanceType* result = new LCheckInstanceType(value, temp); |
1629 return AssignEnvironment(result); | 1634 return AssignEnvironment(result); |
1630 } | 1635 } |
1631 | 1636 |
1632 | 1637 |
1633 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1638 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
1634 LOperand* temp = TempRegister(); | 1639 LOperand* temp = TempRegister(); |
1635 LInstruction* result = | 1640 LCheckPrototypeMaps* result = |
1636 new LCheckPrototypeMaps(temp, | 1641 new LCheckPrototypeMaps(temp, |
1637 instr->holder(), | 1642 instr->holder(), |
1638 instr->receiver_map()); | 1643 instr->receiver_map()); |
1639 return AssignEnvironment(result); | 1644 return AssignEnvironment(result); |
1640 } | 1645 } |
1641 | 1646 |
1642 | 1647 |
1643 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1648 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
1644 LOperand* value = UseRegisterAtStart(instr->value()); | 1649 LOperand* value = UseRegisterAtStart(instr->value()); |
1645 return AssignEnvironment(new LCheckSmi(value, not_zero)); | 1650 return AssignEnvironment(new LCheckSmi(value, not_zero)); |
1646 } | 1651 } |
1647 | 1652 |
1648 | 1653 |
1649 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1654 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
1650 LOperand* value = UseRegisterAtStart(instr->value()); | 1655 LOperand* value = UseRegisterAtStart(instr->value()); |
1651 return AssignEnvironment(new LCheckFunction(value)); | 1656 return AssignEnvironment(new LCheckFunction(value)); |
1652 } | 1657 } |
1653 | 1658 |
1654 | 1659 |
1655 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1660 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
1656 LOperand* value = UseRegisterAtStart(instr->value()); | 1661 LOperand* value = UseRegisterAtStart(instr->value()); |
1657 LInstruction* result = new LCheckMap(value); | 1662 LCheckMap* result = new LCheckMap(value); |
1658 return AssignEnvironment(result); | 1663 return AssignEnvironment(result); |
1659 } | 1664 } |
1660 | 1665 |
1661 | 1666 |
1662 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1667 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
1663 return new LReturn(UseFixed(instr->value(), eax)); | 1668 return new LReturn(UseFixed(instr->value(), eax)); |
1664 } | 1669 } |
1665 | 1670 |
1666 | 1671 |
1667 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1672 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1668 Representation r = instr->representation(); | 1673 Representation r = instr->representation(); |
1669 if (r.IsInteger32()) { | 1674 if (r.IsInteger32()) { |
1670 int32_t value = instr->Integer32Value(); | 1675 int32_t value = instr->Integer32Value(); |
1671 return DefineAsRegister(new LConstantI(value)); | 1676 return DefineAsRegister(new LConstantI(value)); |
1672 } else if (r.IsDouble()) { | 1677 } else if (r.IsDouble()) { |
1673 double value = instr->DoubleValue(); | 1678 double value = instr->DoubleValue(); |
1674 return DefineAsRegister(new LConstantD(value)); | 1679 return DefineAsRegister(new LConstantD(value)); |
1675 } else if (r.IsTagged()) { | 1680 } else if (r.IsTagged()) { |
1676 return DefineAsRegister(new LConstantT(instr->handle())); | 1681 return DefineAsRegister(new LConstantT(instr->handle())); |
1677 } else { | 1682 } else { |
1678 Abort("unsupported constant of type double"); | 1683 Abort("unsupported constant of type double"); |
1679 return NULL; | 1684 return NULL; |
1680 } | 1685 } |
1681 } | 1686 } |
1682 | 1687 |
1683 | 1688 |
1684 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1689 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
1685 LInstruction* result = new LLoadGlobal; | 1690 LLoadGlobal* result = new LLoadGlobal; |
1686 return instr->check_hole_value() | 1691 return instr->check_hole_value() |
1687 ? AssignEnvironment(DefineAsRegister(result)) | 1692 ? AssignEnvironment(DefineAsRegister(result)) |
1688 : DefineAsRegister(result); | 1693 : DefineAsRegister(result); |
1689 } | 1694 } |
1690 | 1695 |
1691 | 1696 |
1692 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1697 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
1693 return new LStoreGlobal(UseRegisterAtStart(instr->value())); | 1698 return new LStoreGlobal(UseRegisterAtStart(instr->value())); |
1694 } | 1699 } |
1695 | 1700 |
1696 | 1701 |
1697 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1702 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
1698 return DefineAsRegister( | 1703 return DefineAsRegister( |
1699 new LLoadNamedField(UseRegisterAtStart(instr->object()))); | 1704 new LLoadNamedField(UseRegisterAtStart(instr->object()))); |
1700 } | 1705 } |
1701 | 1706 |
1702 | 1707 |
1703 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1708 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
1704 LOperand* object = UseFixed(instr->object(), eax); | 1709 LOperand* object = UseFixed(instr->object(), eax); |
1705 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); | 1710 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
1706 return MarkAsCall(result, instr); | 1711 return MarkAsCall(DefineFixed(result, eax), instr); |
1707 } | 1712 } |
1708 | 1713 |
1709 | 1714 |
1710 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1715 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
1711 HLoadFunctionPrototype* instr) { | 1716 HLoadFunctionPrototype* instr) { |
1712 return AssignEnvironment(DefineAsRegister( | 1717 return AssignEnvironment(DefineAsRegister( |
1713 new LLoadFunctionPrototype(UseRegister(instr->function()), | 1718 new LLoadFunctionPrototype(UseRegister(instr->function()), |
1714 TempRegister()))); | 1719 TempRegister()))); |
1715 } | 1720 } |
1716 | 1721 |
1717 | 1722 |
1718 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1723 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
1719 LOperand* input = UseRegisterAtStart(instr->value()); | 1724 LOperand* input = UseRegisterAtStart(instr->value()); |
1720 return DefineSameAsFirst(new LLoadElements(input)); | 1725 return DefineSameAsFirst(new LLoadElements(input)); |
1721 } | 1726 } |
1722 | 1727 |
1723 | 1728 |
1724 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1729 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
1725 HLoadKeyedFastElement* instr) { | 1730 HLoadKeyedFastElement* instr) { |
1726 Representation r = instr->representation(); | 1731 Representation r = instr->representation(); |
1727 LOperand* obj = UseRegisterAtStart(instr->object()); | 1732 LOperand* obj = UseRegisterAtStart(instr->object()); |
1728 ASSERT(instr->key()->representation().IsInteger32()); | 1733 ASSERT(instr->key()->representation().IsInteger32()); |
1729 LOperand* key = UseRegisterAtStart(instr->key()); | 1734 LOperand* key = UseRegisterAtStart(instr->key()); |
1730 LOperand* load_result = NULL; | 1735 LOperand* load_result = NULL; |
1731 // Double needs an extra temp, because the result is converted from heap | 1736 // Double needs an extra temp, because the result is converted from heap |
1732 // number to a double register. | 1737 // number to a double register. |
1733 if (r.IsDouble()) load_result = TempRegister(); | 1738 if (r.IsDouble()) load_result = TempRegister(); |
1734 LInstruction* result = new LLoadKeyedFastElement(obj, | 1739 LLoadKeyedFastElement* load = new LLoadKeyedFastElement(obj, |
1735 key, | 1740 key, |
1736 load_result); | 1741 load_result); |
1737 if (r.IsDouble()) { | 1742 LInstruction* result = r.IsDouble() |
1738 result = DefineAsRegister(result); | 1743 ? DefineAsRegister(load) |
1739 } else { | 1744 : DefineSameAsFirst(load); |
1740 result = DefineSameAsFirst(result); | |
1741 } | |
1742 return AssignEnvironment(result); | 1745 return AssignEnvironment(result); |
1743 } | 1746 } |
1744 | 1747 |
1745 | 1748 |
1746 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1749 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
1747 LOperand* object = UseFixed(instr->object(), edx); | 1750 LOperand* object = UseFixed(instr->object(), edx); |
1748 LOperand* key = UseFixed(instr->key(), eax); | 1751 LOperand* key = UseFixed(instr->key(), eax); |
1749 | 1752 |
1750 LInstruction* result = | 1753 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); |
1751 DefineFixed(new LLoadKeyedGeneric(object, key), eax); | 1754 return MarkAsCall(DefineFixed(result, eax), instr); |
1752 return MarkAsCall(result, instr); | |
1753 } | 1755 } |
1754 | 1756 |
1755 | 1757 |
1756 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1758 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
1757 HStoreKeyedFastElement* instr) { | 1759 HStoreKeyedFastElement* instr) { |
1758 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1760 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
1759 ASSERT(instr->value()->representation().IsTagged()); | 1761 ASSERT(instr->value()->representation().IsTagged()); |
1760 ASSERT(instr->object()->representation().IsTagged()); | 1762 ASSERT(instr->object()->representation().IsTagged()); |
1761 ASSERT(instr->key()->representation().IsInteger32()); | 1763 ASSERT(instr->key()->representation().IsInteger32()); |
1762 | 1764 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1809 temp, | 1811 temp, |
1810 needs_write_barrier, | 1812 needs_write_barrier, |
1811 instr->transition()); | 1813 instr->transition()); |
1812 } | 1814 } |
1813 | 1815 |
1814 | 1816 |
1815 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1817 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
1816 LOperand* obj = UseFixed(instr->object(), edx); | 1818 LOperand* obj = UseFixed(instr->object(), edx); |
1817 LOperand* val = UseFixed(instr->value(), eax); | 1819 LOperand* val = UseFixed(instr->value(), eax); |
1818 | 1820 |
1819 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); | 1821 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, instr->name(), val); |
1820 return MarkAsCall(result, instr); | 1822 return MarkAsCall(result, instr); |
1821 } | 1823 } |
1822 | 1824 |
1823 | 1825 |
1824 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1826 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
1825 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1827 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
1826 } | 1828 } |
1827 | 1829 |
1828 | 1830 |
1829 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1831 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
1830 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1832 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); |
1831 } | 1833 } |
1832 | 1834 |
1833 | 1835 |
1834 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1836 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
1835 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 1837 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); |
1836 } | 1838 } |
1837 | 1839 |
1838 | 1840 |
1839 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1841 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
1840 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 1842 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); |
1841 } | 1843 } |
1842 | 1844 |
1843 | 1845 |
1844 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1846 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
1845 LInstruction* result = new LDeleteProperty(Use(instr->object()), | 1847 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()), |
1846 UseOrConstant(instr->key())); | 1848 UseOrConstant(instr->key())); |
1847 return MarkAsCall(DefineFixed(result, eax), instr); | 1849 return MarkAsCall(DefineFixed(result, eax), instr); |
1848 } | 1850 } |
1849 | 1851 |
1850 | 1852 |
1851 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1853 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
1852 allocator_->MarkAsOsrEntry(); | 1854 allocator_->MarkAsOsrEntry(); |
1853 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1855 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
1854 return AssignEnvironment(new LOsrEntry); | 1856 return AssignEnvironment(new LOsrEntry); |
1855 } | 1857 } |
1856 | 1858 |
(...skipping 20 matching lines...) Expand all Loading... |
1877 // There are no real uses of the arguments object (we bail out in all other | 1879 // There are no real uses of the arguments object (we bail out in all other |
1878 // cases). | 1880 // cases). |
1879 return NULL; | 1881 return NULL; |
1880 } | 1882 } |
1881 | 1883 |
1882 | 1884 |
1883 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1885 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
1884 LOperand* arguments = UseRegister(instr->arguments()); | 1886 LOperand* arguments = UseRegister(instr->arguments()); |
1885 LOperand* length = UseTempRegister(instr->length()); | 1887 LOperand* length = UseTempRegister(instr->length()); |
1886 LOperand* index = Use(instr->index()); | 1888 LOperand* index = Use(instr->index()); |
1887 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); | 1889 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
1888 return DefineAsRegister(AssignEnvironment(result)); | 1890 return AssignEnvironment(DefineAsRegister(result)); |
1889 } | 1891 } |
1890 | 1892 |
1891 | 1893 |
1892 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1894 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
1893 LInstruction* result = new LTypeof(UseAtStart(instr->value())); | 1895 LTypeof* result = new LTypeof(UseAtStart(instr->value())); |
1894 return MarkAsCall(DefineFixed(result, eax), instr); | 1896 return MarkAsCall(DefineFixed(result, eax), instr); |
1895 } | 1897 } |
1896 | 1898 |
1897 | 1899 |
1898 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1900 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
1899 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 1901 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
1900 } | 1902 } |
1901 | 1903 |
1902 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1904 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
1903 HEnvironment* env = current_block_->last_environment(); | 1905 HEnvironment* env = current_block_->last_environment(); |
1904 ASSERT(env != NULL); | 1906 ASSERT(env != NULL); |
1905 | 1907 |
1906 env->set_ast_id(instr->ast_id()); | 1908 env->set_ast_id(instr->ast_id()); |
1907 | 1909 |
1908 env->Drop(instr->pop_count()); | 1910 env->Drop(instr->pop_count()); |
1909 for (int i = 0; i < instr->values()->length(); ++i) { | 1911 for (int i = 0; i < instr->values()->length(); ++i) { |
1910 HValue* value = instr->values()->at(i); | 1912 HValue* value = instr->values()->at(i); |
1911 if (instr->HasAssignedIndexAt(i)) { | 1913 if (instr->HasAssignedIndexAt(i)) { |
1912 env->Bind(instr->GetAssignedIndexAt(i), value); | 1914 env->Bind(instr->GetAssignedIndexAt(i), value); |
1913 } else { | 1915 } else { |
1914 env->Push(value); | 1916 env->Push(value); |
1915 } | 1917 } |
1916 } | 1918 } |
1917 ASSERT(env->length() == instr->environment_length()); | 1919 ASSERT(env->length() == instr->environment_length()); |
1918 | 1920 |
1919 // If there is an instruction pending deoptimization environment create a | 1921 // If there is an instruction pending deoptimization environment create a |
1920 // lazy bailout instruction to capture the environment. | 1922 // lazy bailout instruction to capture the environment. |
1921 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 1923 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
1922 LInstruction* result = new LLazyBailout; | 1924 LLazyBailout* lazy_bailout = new LLazyBailout; |
1923 result = AssignEnvironment(result); | 1925 LInstruction* result = AssignEnvironment(lazy_bailout); |
1924 instructions_pending_deoptimization_environment_-> | 1926 instructions_pending_deoptimization_environment_-> |
1925 set_deoptimization_environment(result->environment()); | 1927 set_deoptimization_environment(result->environment()); |
1926 ClearInstructionPendingDeoptimizationEnvironment(); | 1928 ClearInstructionPendingDeoptimizationEnvironment(); |
1927 return result; | 1929 return result; |
1928 } | 1930 } |
1929 | 1931 |
1930 return NULL; | 1932 return NULL; |
1931 } | 1933 } |
1932 | 1934 |
1933 | 1935 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 void LPointerMap::PrintTo(StringStream* stream) const { | 1969 void LPointerMap::PrintTo(StringStream* stream) const { |
1968 stream->Add("{"); | 1970 stream->Add("{"); |
1969 for (int i = 0; i < pointer_operands_.length(); ++i) { | 1971 for (int i = 0; i < pointer_operands_.length(); ++i) { |
1970 if (i != 0) stream->Add(";"); | 1972 if (i != 0) stream->Add(";"); |
1971 pointer_operands_[i]->PrintTo(stream); | 1973 pointer_operands_[i]->PrintTo(stream); |
1972 } | 1974 } |
1973 stream->Add("} @%d", position()); | 1975 stream->Add("} @%d", position()); |
1974 } | 1976 } |
1975 | 1977 |
1976 } } // namespace v8::internal | 1978 } } // namespace v8::internal |
OLD | NEW |