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

Side by Side Diff: src/arm/lithium-arm.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/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 #ifdef DEBUG 62 #ifdef DEBUG
63 void LInstruction::VerifyCall() { 63 void LInstruction::VerifyCall() {
64 // Call instructions can use only fixed registers as temporaries and 64 // Call instructions can use only fixed registers as temporaries and
65 // outputs because all registers are blocked by the calling convention. 65 // outputs because all registers are blocked by the calling convention.
66 // Inputs operands must use a fixed register or use-at-start policy or 66 // Inputs operands must use a fixed register or use-at-start policy or
67 // a non-register policy. 67 // a non-register policy.
68 ASSERT(Output() == NULL || 68 ASSERT(Output() == NULL ||
69 LUnallocated::cast(Output())->HasFixedPolicy() || 69 LUnallocated::cast(Output())->HasFixedPolicy() ||
70 !LUnallocated::cast(Output())->HasRegisterPolicy()); 70 !LUnallocated::cast(Output())->HasRegisterPolicy());
71 for (UseIterator it(this); it.HasNext(); it.Advance()) { 71 for (UseIterator it(this); !it.Done(); it.Advance()) {
72 LUnallocated* operand = LUnallocated::cast(it.Next()); 72 LUnallocated* operand = LUnallocated::cast(it.Current());
73 ASSERT(operand->HasFixedPolicy() || 73 ASSERT(operand->HasFixedPolicy() ||
74 operand->IsUsedAtStart()); 74 operand->IsUsedAtStart());
75 } 75 }
76 for (TempIterator it(this); it.HasNext(); it.Advance()) { 76 for (TempIterator it(this); !it.Done(); it.Advance()) {
77 LUnallocated* operand = LUnallocated::cast(it.Next()); 77 LUnallocated* operand = LUnallocated::cast(it.Current());
78 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); 78 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
79 } 79 }
80 } 80 }
81 #endif 81 #endif
82 82
83 83
84 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 84 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
85 LOperand* spill_operand) { 85 LOperand* spill_operand) {
86 ASSERT(spill_operand->IsDoubleStackSlot()); 86 ASSERT(spill_operand->IsDoubleStackSlot());
87 ASSERT(double_register_spills_[allocation_index] == NULL); 87 ASSERT(double_register_spills_[allocation_index] == NULL);
(...skipping 16 matching lines...) Expand all
104 if (HasPointerMap()) { 104 if (HasPointerMap()) {
105 stream->Add(" "); 105 stream->Add(" ");
106 pointer_map()->PrintTo(stream); 106 pointer_map()->PrintTo(stream);
107 } 107 }
108 } 108 }
109 109
110 110
111 template<int R, int I, int T> 111 template<int R, int I, int T>
112 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { 112 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
113 stream->Add("= "); 113 stream->Add("= ");
114 inputs_.PrintOperandsTo(stream); 114 for (int i = 0; i < inputs_.length(); i++) {
115 if (i > 0) stream->Add(" ");
116 inputs_[i]->PrintTo(stream);
117 }
115 } 118 }
116 119
117 120
118 template<int R, int I, int T> 121 template<int R, int I, int T>
119 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { 122 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
120 results_.PrintOperandsTo(stream); 123 for (int i = 0; i < results_.length(); i++) {
121 }
122
123
124 template<typename T, int N>
125 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
126 for (int i = 0; i < N; i++) {
127 if (i > 0) stream->Add(" "); 124 if (i > 0) stream->Add(" ");
128 elems_[i]->PrintTo(stream); 125 results_[i]->PrintTo(stream);
129 } 126 }
130 } 127 }
131 128
132 129
133 void LLabel::PrintDataTo(StringStream* stream) { 130 void LLabel::PrintDataTo(StringStream* stream) {
134 LGap::PrintDataTo(stream); 131 LGap::PrintDataTo(stream);
135 LLabel* rep = replacement(); 132 LLabel* rep = replacement();
136 if (rep != NULL) { 133 if (rep != NULL) {
137 stream->Add(" Dead block replaced with B%d", rep->block_id()); 134 stream->Add(" Dead block replaced with B%d", rep->block_id());
138 } 135 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { 258 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
262 stream->Add("if class_of_test("); 259 stream->Add("if class_of_test(");
263 InputAt(0)->PrintTo(stream); 260 InputAt(0)->PrintTo(stream);
264 stream->Add(", \"%o\") then B%d else B%d", 261 stream->Add(", \"%o\") then B%d else B%d",
265 *hydrogen()->class_name(), 262 *hydrogen()->class_name(),
266 true_block_id(), 263 true_block_id(),
267 false_block_id()); 264 false_block_id());
268 } 265 }
269 266
270 267
271 void LTypeofIs::PrintDataTo(StringStream* stream) {
272 InputAt(0)->PrintTo(stream);
273 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
274 }
275
276
277 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { 268 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
278 stream->Add("if typeof "); 269 stream->Add("if typeof ");
279 InputAt(0)->PrintTo(stream); 270 InputAt(0)->PrintTo(stream);
280 stream->Add(" == \"%s\" then B%d else B%d", 271 stream->Add(" == \"%s\" then B%d else B%d",
281 *hydrogen()->type_literal()->ToCString(), 272 *hydrogen()->type_literal()->ToCString(),
282 true_block_id(), false_block_id()); 273 true_block_id(), false_block_id());
283 } 274 }
284 275
285 276
286 void LCallConstantFunction::PrintDataTo(StringStream* stream) { 277 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 } 327 }
337 328
338 329
339 void LCallNew::PrintDataTo(StringStream* stream) { 330 void LCallNew::PrintDataTo(StringStream* stream) {
340 stream->Add("= "); 331 stream->Add("= ");
341 InputAt(0)->PrintTo(stream); 332 InputAt(0)->PrintTo(stream);
342 stream->Add(" #%d / ", arity()); 333 stream->Add(" #%d / ", arity());
343 } 334 }
344 335
345 336
346 void LClassOfTest::PrintDataTo(StringStream* stream) {
347 stream->Add("= class_of_test(");
348 InputAt(0)->PrintTo(stream);
349 stream->Add(", \"%o\")", *hydrogen()->class_name());
350 }
351
352
353 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { 337 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
354 arguments()->PrintTo(stream); 338 arguments()->PrintTo(stream);
355 339
356 stream->Add(" length "); 340 stream->Add(" length ");
357 length()->PrintTo(stream); 341 length()->PrintTo(stream);
358 342
359 stream->Add(" index "); 343 stream->Add(" index ");
360 index()->PrintTo(stream); 344 index()->PrintTo(stream);
361 } 345 }
362 346
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 for (int i = 0; i < graph()->blocks()->length(); ++i) { 413 for (int i = 0; i < graph()->blocks()->length(); ++i) {
430 HBasicBlock* block = graph()->blocks()->at(i); 414 HBasicBlock* block = graph()->blocks()->at(i);
431 int first = block->first_instruction_index(); 415 int first = block->first_instruction_index();
432 int last = block->last_instruction_index(); 416 int last = block->last_instruction_index();
433 LInstruction* first_instr = instructions()->at(first); 417 LInstruction* first_instr = instructions()->at(first);
434 LInstruction* last_instr = instructions()->at(last); 418 LInstruction* last_instr = instructions()->at(last);
435 419
436 LLabel* label = LLabel::cast(first_instr); 420 LLabel* label = LLabel::cast(first_instr);
437 if (last_instr->IsGoto()) { 421 if (last_instr->IsGoto()) {
438 LGoto* goto_instr = LGoto::cast(last_instr); 422 LGoto* goto_instr = LGoto::cast(last_instr);
439 if (!goto_instr->include_stack_check() && 423 if (label->IsRedundant() &&
440 label->IsRedundant() &&
441 !label->is_loop_header()) { 424 !label->is_loop_header()) {
442 bool can_eliminate = true; 425 bool can_eliminate = true;
443 for (int i = first + 1; i < last && can_eliminate; ++i) { 426 for (int i = first + 1; i < last && can_eliminate; ++i) {
444 LInstruction* cur = instructions()->at(i); 427 LInstruction* cur = instructions()->at(i);
445 if (cur->IsGap()) { 428 if (cur->IsGap()) {
446 LGap* gap = LGap::cast(cur); 429 LGap* gap = LGap::cast(cur);
447 if (!gap->IsRedundant()) { 430 if (!gap->IsRedundant()) {
448 can_eliminate = false; 431 can_eliminate = false;
449 } 432 }
450 } else { 433 } else {
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 allocator_->RecordTemporary(operand); 784 allocator_->RecordTemporary(operand);
802 return operand; 785 return operand;
803 } 786 }
804 787
805 788
806 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { 789 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
807 return new LLabel(instr->block()); 790 return new LLabel(instr->block());
808 } 791 }
809 792
810 793
794 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
795 return AssignEnvironment(new LDeoptimize);
796 }
797
798
811 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 799 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
812 return AssignEnvironment(new LDeoptimize); 800 return AssignEnvironment(new LDeoptimize);
813 } 801 }
814 802
815 803
816 LInstruction* LChunkBuilder::DoBit(Token::Value op, 804 LInstruction* LChunkBuilder::DoBit(Token::Value op,
817 HBitwiseBinaryOperation* instr) { 805 HBitwiseBinaryOperation* instr) {
818 if (instr->representation().IsInteger32()) { 806 if (instr->representation().IsInteger32()) {
819 ASSERT(instr->left()->representation().IsInteger32()); 807 ASSERT(instr->left()->representation().IsInteger32());
820 ASSERT(instr->right()->representation().IsInteger32()); 808 ASSERT(instr->right()->representation().IsInteger32());
821 809
822 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 810 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
823 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 811 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
824 return DefineSameAsFirst(new LBitI(op, left, right)); 812 return DefineAsRegister(new LBitI(op, left, right));
825 } else { 813 } else {
826 ASSERT(instr->representation().IsTagged()); 814 ASSERT(instr->representation().IsTagged());
827 ASSERT(instr->left()->representation().IsTagged()); 815 ASSERT(instr->left()->representation().IsTagged());
828 ASSERT(instr->right()->representation().IsTagged()); 816 ASSERT(instr->right()->representation().IsTagged());
829 817
830 LOperand* left = UseFixed(instr->left(), r1); 818 LOperand* left = UseFixed(instr->left(), r1);
831 LOperand* right = UseFixed(instr->right(), r0); 819 LOperand* right = UseFixed(instr->right(), r0);
832 LArithmeticT* result = new LArithmeticT(op, left, right); 820 LArithmeticT* result = new LArithmeticT(op, left, right);
833 return MarkAsCall(DefineFixed(result, r0), instr); 821 return MarkAsCall(DefineFixed(result, r0), instr);
834 } 822 }
835 } 823 }
836 824
837 825
838 LInstruction* LChunkBuilder::DoShift(Token::Value op, 826 LInstruction* LChunkBuilder::DoShift(Token::Value op,
839 HBitwiseBinaryOperation* instr) { 827 HBitwiseBinaryOperation* instr) {
840 if (instr->representation().IsTagged()) { 828 if (instr->representation().IsTagged()) {
841 ASSERT(instr->left()->representation().IsTagged()); 829 ASSERT(instr->left()->representation().IsTagged());
842 ASSERT(instr->right()->representation().IsTagged()); 830 ASSERT(instr->right()->representation().IsTagged());
843 831
844 LOperand* left = UseFixed(instr->left(), r1); 832 LOperand* left = UseFixed(instr->left(), r1);
845 LOperand* right = UseFixed(instr->right(), r0); 833 LOperand* right = UseFixed(instr->right(), r0);
846 LArithmeticT* result = new LArithmeticT(op, left, right); 834 LArithmeticT* result = new LArithmeticT(op, left, right);
847 return MarkAsCall(DefineFixed(result, r0), instr); 835 return MarkAsCall(DefineFixed(result, r0), instr);
848 } 836 }
849 837
850 ASSERT(instr->representation().IsInteger32()); 838 ASSERT(instr->representation().IsInteger32());
851 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 839 ASSERT(instr->left()->representation().IsInteger32());
852 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 840 ASSERT(instr->right()->representation().IsInteger32());
853 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 841 LOperand* left = UseRegisterAtStart(instr->left());
854 842
855 HValue* right_value = instr->OperandAt(1); 843 HValue* right_value = instr->right();
856 LOperand* right = NULL; 844 LOperand* right = NULL;
857 int constant_value = 0; 845 int constant_value = 0;
858 if (right_value->IsConstant()) { 846 if (right_value->IsConstant()) {
859 HConstant* constant = HConstant::cast(right_value); 847 HConstant* constant = HConstant::cast(right_value);
860 right = chunk_->DefineConstantOperand(constant); 848 right = chunk_->DefineConstantOperand(constant);
861 constant_value = constant->Integer32Value() & 0x1f; 849 constant_value = constant->Integer32Value() & 0x1f;
862 } else { 850 } else {
863 right = UseRegister(right_value); 851 right = UseRegisterAtStart(right_value);
864 } 852 }
865 853
866 // Shift operations can only deoptimize if we do a logical shift 854 // Shift operations can only deoptimize if we do a logical shift
867 // by 0 and the result cannot be truncated to int32. 855 // by 0 and the result cannot be truncated to int32.
868 bool may_deopt = (op == Token::SHR && constant_value == 0); 856 bool may_deopt = (op == Token::SHR && constant_value == 0);
869 bool does_deopt = false; 857 bool does_deopt = false;
870 if (may_deopt) { 858 if (may_deopt) {
871 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { 859 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
872 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { 860 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
873 does_deopt = true; 861 does_deopt = true;
874 break; 862 break;
875 } 863 }
876 } 864 }
877 } 865 }
878 866
879 LInstruction* result = 867 LInstruction* result =
880 DefineSameAsFirst(new LShiftI(op, left, right, does_deopt)); 868 DefineAsRegister(new LShiftI(op, left, right, does_deopt));
881 return does_deopt ? AssignEnvironment(result) : result; 869 return does_deopt ? AssignEnvironment(result) : result;
882 } 870 }
883 871
884 872
885 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 873 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
886 HArithmeticBinaryOperation* instr) { 874 HArithmeticBinaryOperation* instr) {
887 ASSERT(instr->representation().IsDouble()); 875 ASSERT(instr->representation().IsDouble());
888 ASSERT(instr->left()->representation().IsDouble()); 876 ASSERT(instr->left()->representation().IsDouble());
889 ASSERT(instr->right()->representation().IsDouble()); 877 ASSERT(instr->right()->representation().IsDouble());
890 ASSERT(op != Token::MOD); 878 ASSERT(op != Token::MOD);
891 LOperand* left = UseRegisterAtStart(instr->left()); 879 LOperand* left = UseRegisterAtStart(instr->left());
892 LOperand* right = UseRegisterAtStart(instr->right()); 880 LOperand* right = UseRegisterAtStart(instr->right());
893 LArithmeticD* result = new LArithmeticD(op, left, right); 881 LArithmeticD* result = new LArithmeticD(op, left, right);
894 return DefineSameAsFirst(result); 882 return DefineAsRegister(result);
895 } 883 }
896 884
897 885
898 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 886 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
899 HArithmeticBinaryOperation* instr) { 887 HArithmeticBinaryOperation* instr) {
900 ASSERT(op == Token::ADD || 888 ASSERT(op == Token::ADD ||
901 op == Token::DIV || 889 op == Token::DIV ||
902 op == Token::MOD || 890 op == Token::MOD ||
903 op == Token::MUL || 891 op == Token::MUL ||
904 op == Token::SUB); 892 op == Token::SUB);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 if (current->has_position()) position_ = current->position(); 970 if (current->has_position()) position_ = current->position();
983 LInstruction* instr = current->CompileToLithium(this); 971 LInstruction* instr = current->CompileToLithium(this);
984 972
985 if (instr != NULL) { 973 if (instr != NULL) {
986 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 974 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
987 instr = AssignPointerMap(instr); 975 instr = AssignPointerMap(instr);
988 } 976 }
989 if (FLAG_stress_environments && !instr->HasEnvironment()) { 977 if (FLAG_stress_environments && !instr->HasEnvironment()) {
990 instr = AssignEnvironment(instr); 978 instr = AssignEnvironment(instr);
991 } 979 }
992 if (current->IsTest() && !instr->IsGoto()) { 980 instr->set_hydrogen_value(current);
993 ASSERT(instr->IsControl());
994 HTest* test = HTest::cast(current);
995 instr->set_hydrogen_value(test->value());
996 HBasicBlock* first = test->FirstSuccessor();
997 HBasicBlock* second = test->SecondSuccessor();
998 ASSERT(first != NULL && second != NULL);
999 instr->SetBranchTargets(first->block_id(), second->block_id());
1000 } else {
1001 instr->set_hydrogen_value(current);
1002 }
1003
1004 chunk_->AddInstruction(instr, current_block_); 981 chunk_->AddInstruction(instr, current_block_);
1005 } 982 }
1006 current_instruction_ = old_current; 983 current_instruction_ = old_current;
1007 } 984 }
1008 985
1009 986
1010 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 987 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1011 if (hydrogen_env == NULL) return NULL; 988 if (hydrogen_env == NULL) return NULL;
1012 989
1013 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 990 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
(...skipping 20 matching lines...) Expand all
1034 op = UseAny(value); 1011 op = UseAny(value);
1035 } 1012 }
1036 result->AddValue(op, value->representation()); 1013 result->AddValue(op, value->representation());
1037 } 1014 }
1038 1015
1039 return result; 1016 return result;
1040 } 1017 }
1041 1018
1042 1019
1043 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1020 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1044 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), 1021 return new LGoto(instr->FirstSuccessor()->block_id());
1045 instr->include_stack_check());
1046 if (instr->include_stack_check()) result = AssignPointerMap(result);
1047 return result;
1048 } 1022 }
1049 1023
1050 1024
1051 LInstruction* LChunkBuilder::DoTest(HTest* instr) { 1025 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1052 HValue* v = instr->value(); 1026 HValue* v = instr->value();
1053 if (!v->EmitAtUses()) { 1027 if (v->EmitAtUses()) {
1054 return new LBranch(UseRegisterAtStart(v));
1055 } else if (v->IsClassOfTest()) {
1056 HClassOfTest* compare = HClassOfTest::cast(v);
1057 ASSERT(compare->value()->representation().IsTagged());
1058 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1059 TempRegister());
1060 } else if (v->IsCompare()) {
1061 HCompare* compare = HCompare::cast(v);
1062 Token::Value op = compare->token();
1063 HValue* left = compare->left();
1064 HValue* right = compare->right();
1065 Representation r = compare->GetInputRepresentation();
1066 if (r.IsInteger32()) {
1067 ASSERT(left->representation().IsInteger32());
1068 ASSERT(right->representation().IsInteger32());
1069 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1070 UseRegisterAtStart(right));
1071 } else if (r.IsDouble()) {
1072 ASSERT(left->representation().IsDouble());
1073 ASSERT(right->representation().IsDouble());
1074 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1075 UseRegisterAtStart(right));
1076 } else {
1077 ASSERT(left->representation().IsTagged());
1078 ASSERT(right->representation().IsTagged());
1079 bool reversed = op == Token::GT || op == Token::LTE;
1080 LOperand* left_operand = UseFixed(left, reversed ? r0 : r1);
1081 LOperand* right_operand = UseFixed(right, reversed ? r1 : r0);
1082 LInstruction* result = new LCmpTAndBranch(left_operand, right_operand);
1083 return MarkAsCall(result, instr);
1084 }
1085 } else if (v->IsIsSmi()) {
1086 HIsSmi* compare = HIsSmi::cast(v);
1087 ASSERT(compare->value()->representation().IsTagged());
1088 return new LIsSmiAndBranch(Use(compare->value()));
1089 } else if (v->IsIsUndetectable()) {
1090 HIsUndetectable* compare = HIsUndetectable::cast(v);
1091 ASSERT(compare->value()->representation().IsTagged());
1092 return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
1093 TempRegister());
1094 } else if (v->IsHasInstanceType()) {
1095 HHasInstanceType* compare = HHasInstanceType::cast(v);
1096 ASSERT(compare->value()->representation().IsTagged());
1097 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()));
1098 } else if (v->IsHasCachedArrayIndex()) {
1099 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
1100 ASSERT(compare->value()->representation().IsTagged());
1101 return new LHasCachedArrayIndexAndBranch(
1102 UseRegisterAtStart(compare->value()));
1103 } else if (v->IsIsNull()) {
1104 HIsNull* compare = HIsNull::cast(v);
1105 ASSERT(compare->value()->representation().IsTagged());
1106 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()));
1107 } else if (v->IsIsObject()) {
1108 HIsObject* compare = HIsObject::cast(v);
1109 ASSERT(compare->value()->representation().IsTagged());
1110 LOperand* temp = TempRegister();
1111 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
1112 } else if (v->IsCompareJSObjectEq()) {
1113 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1114 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1115 UseRegisterAtStart(compare->right()));
1116 } else if (v->IsCompareSymbolEq()) {
1117 HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
1118 return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
1119 UseRegisterAtStart(compare->right()));
1120 } else if (v->IsInstanceOf()) {
1121 HInstanceOf* instance_of = HInstanceOf::cast(v);
1122 LInstruction* result =
1123 new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0),
1124 UseFixed(instance_of->right(), r1));
1125 return MarkAsCall(result, instr);
1126 } else if (v->IsTypeofIs()) {
1127 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1128 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1129 } else if (v->IsIsConstructCall()) {
1130 return new LIsConstructCallAndBranch(TempRegister());
1131 } else if (v->IsConstant()) {
1132 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() 1028 HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
1133 ? instr->FirstSuccessor() 1029 ? instr->FirstSuccessor()
1134 : instr->SecondSuccessor(); 1030 : instr->SecondSuccessor();
1135 return new LGoto(successor->block_id()); 1031 return new LGoto(successor->block_id());
1136 } else {
1137 Abort("Undefined compare before branch");
1138 return NULL;
1139 } 1032 }
1033 return new LBranch(UseRegisterAtStart(v));
1140 } 1034 }
1141 1035
1142 1036
1143 1037
1144 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 1038 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1145 ASSERT(instr->value()->representation().IsTagged()); 1039 ASSERT(instr->value()->representation().IsTagged());
1146 LOperand* value = UseRegisterAtStart(instr->value()); 1040 LOperand* value = UseRegisterAtStart(instr->value());
1147 LOperand* temp = TempRegister(); 1041 LOperand* temp = TempRegister();
1148 return new LCmpMapAndBranch(value, temp); 1042 return new LCmpMapAndBranch(value, temp);
1149 } 1043 }
(...skipping 13 matching lines...) Expand all
1163 LInstanceOf* result = 1057 LInstanceOf* result =
1164 new LInstanceOf(UseFixed(instr->left(), r0), 1058 new LInstanceOf(UseFixed(instr->left(), r0),
1165 UseFixed(instr->right(), r1)); 1059 UseFixed(instr->right(), r1));
1166 return MarkAsCall(DefineFixed(result, r0), instr); 1060 return MarkAsCall(DefineFixed(result, r0), instr);
1167 } 1061 }
1168 1062
1169 1063
1170 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1064 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1171 HInstanceOfKnownGlobal* instr) { 1065 HInstanceOfKnownGlobal* instr) {
1172 LInstanceOfKnownGlobal* result = 1066 LInstanceOfKnownGlobal* result =
1173 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4)); 1067 new LInstanceOfKnownGlobal(UseFixed(instr->left(), r0), FixedTemp(r4));
1174 return MarkAsCall(DefineFixed(result, r0), instr); 1068 return MarkAsCall(DefineFixed(result, r0), instr);
1175 } 1069 }
1176 1070
1177 1071
1178 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1072 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1179 LOperand* function = UseFixed(instr->function(), r1); 1073 LOperand* function = UseFixed(instr->function(), r1);
1180 LOperand* receiver = UseFixed(instr->receiver(), r0); 1074 LOperand* receiver = UseFixed(instr->receiver(), r0);
1181 LOperand* length = UseFixed(instr->length(), r2); 1075 LOperand* length = UseFixed(instr->length(), r2);
1182 LOperand* elements = UseFixed(instr->elements(), r3); 1076 LOperand* elements = UseFixed(instr->elements(), r3);
1183 LApplyArguments* result = new LApplyArguments(function, 1077 LApplyArguments* result = new LApplyArguments(function,
1184 receiver, 1078 receiver,
1185 length, 1079 length,
1186 elements); 1080 elements);
1187 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1081 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1188 } 1082 }
1189 1083
1190 1084
1191 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1085 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1192 ++argument_count_; 1086 ++argument_count_;
1193 LOperand* argument = Use(instr->argument()); 1087 LOperand* argument = Use(instr->argument());
1194 return new LPushArgument(argument); 1088 return new LPushArgument(argument);
1195 } 1089 }
1196 1090
1197 1091
1092 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1093 return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
1094 }
1095
1096
1198 LInstruction* LChunkBuilder::DoContext(HContext* instr) { 1097 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1199 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); 1098 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
1200 } 1099 }
1201 1100
1202 1101
1203 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { 1102 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1204 LOperand* context = UseRegisterAtStart(instr->value()); 1103 LOperand* context = UseRegisterAtStart(instr->value());
1205 return DefineAsRegister(new LOuterContext(context)); 1104 return DefineAsRegister(new LOuterContext(context));
1206 } 1105 }
1207 1106
(...skipping 30 matching lines...) Expand all
1238 if (op == kMathLog || op == kMathSin || op == kMathCos) { 1137 if (op == kMathLog || op == kMathSin || op == kMathCos) {
1239 LOperand* input = UseFixedDouble(instr->value(), d2); 1138 LOperand* input = UseFixedDouble(instr->value(), d2);
1240 LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL); 1139 LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL);
1241 return MarkAsCall(DefineFixedDouble(result, d2), instr); 1140 return MarkAsCall(DefineFixedDouble(result, d2), instr);
1242 } else { 1141 } else {
1243 LOperand* input = UseRegisterAtStart(instr->value()); 1142 LOperand* input = UseRegisterAtStart(instr->value());
1244 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL; 1143 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1245 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp); 1144 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
1246 switch (op) { 1145 switch (op) {
1247 case kMathAbs: 1146 case kMathAbs:
1248 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1147 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1249 case kMathFloor: 1148 case kMathFloor:
1250 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1149 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1251 case kMathSqrt: 1150 case kMathSqrt:
1252 return DefineSameAsFirst(result); 1151 return DefineAsRegister(result);
1253 case kMathRound: 1152 case kMathRound:
1254 return AssignEnvironment(DefineAsRegister(result)); 1153 return AssignEnvironment(DefineAsRegister(result));
1255 case kMathPowHalf: 1154 case kMathPowHalf:
1256 return DefineSameAsFirst(result); 1155 return DefineAsRegister(result);
1257 default: 1156 default:
1258 UNREACHABLE(); 1157 UNREACHABLE();
1259 return NULL; 1158 return NULL;
1260 } 1159 }
1261 } 1160 }
1262 } 1161 }
1263 1162
1264 1163
1265 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1164 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1266 ASSERT(instr->key()->representation().IsTagged()); 1165 ASSERT(instr->key()->representation().IsTagged());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 1223
1325 1224
1326 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { 1225 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
1327 return DoBit(Token::BIT_AND, instr); 1226 return DoBit(Token::BIT_AND, instr);
1328 } 1227 }
1329 1228
1330 1229
1331 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { 1230 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1332 ASSERT(instr->value()->representation().IsInteger32()); 1231 ASSERT(instr->value()->representation().IsInteger32());
1333 ASSERT(instr->representation().IsInteger32()); 1232 ASSERT(instr->representation().IsInteger32());
1334 return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value()))); 1233 return DefineAsRegister(new LBitNotI(UseRegisterAtStart(instr->value())));
1335 } 1234 }
1336 1235
1337 1236
1338 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { 1237 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
1339 return DoBit(Token::BIT_OR, instr); 1238 return DoBit(Token::BIT_OR, instr);
1340 } 1239 }
1341 1240
1342 1241
1343 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { 1242 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1344 return DoBit(Token::BIT_XOR, instr); 1243 return DoBit(Token::BIT_XOR, instr);
(...skipping 24 matching lines...) Expand all
1369 ASSERT(instr->left()->representation().IsInteger32()); 1268 ASSERT(instr->left()->representation().IsInteger32());
1370 ASSERT(instr->right()->representation().IsInteger32()); 1269 ASSERT(instr->right()->representation().IsInteger32());
1371 1270
1372 LModI* mod; 1271 LModI* mod;
1373 if (instr->HasPowerOf2Divisor()) { 1272 if (instr->HasPowerOf2Divisor()) {
1374 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); 1273 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1375 LOperand* value = UseRegisterAtStart(instr->left()); 1274 LOperand* value = UseRegisterAtStart(instr->left());
1376 mod = new LModI(value, UseOrConstant(instr->right())); 1275 mod = new LModI(value, UseOrConstant(instr->right()));
1377 } else { 1276 } else {
1378 LOperand* dividend = UseRegister(instr->left()); 1277 LOperand* dividend = UseRegister(instr->left());
1379 LOperand* divisor = UseRegisterAtStart(instr->right()); 1278 LOperand* divisor = UseRegister(instr->right());
1380 mod = new LModI(dividend, 1279 mod = new LModI(dividend,
1381 divisor, 1280 divisor,
1382 TempRegister(), 1281 TempRegister(),
1383 FixedTemp(d1), 1282 FixedTemp(d10),
1384 FixedTemp(d2)); 1283 FixedTemp(d11));
1385 } 1284 }
1386 1285
1387 return AssignEnvironment(DefineSameAsFirst(mod)); 1286 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1287 instr->CheckFlag(HValue::kCanBeDivByZero)) {
1288 return AssignEnvironment(DefineAsRegister(mod));
1289 } else {
1290 return DefineAsRegister(mod);
1291 }
1388 } else if (instr->representation().IsTagged()) { 1292 } else if (instr->representation().IsTagged()) {
1389 return DoArithmeticT(Token::MOD, instr); 1293 return DoArithmeticT(Token::MOD, instr);
1390 } else { 1294 } else {
1391 ASSERT(instr->representation().IsDouble()); 1295 ASSERT(instr->representation().IsDouble());
1392 // We call a C function for double modulo. It can't trigger a GC. 1296 // We call a C function for double modulo. It can't trigger a GC.
1393 // We need to use fixed result register for the call. 1297 // We need to use fixed result register for the call.
1394 // TODO(fschneider): Allow any register as input registers. 1298 // TODO(fschneider): Allow any register as input registers.
1395 LOperand* left = UseFixedDouble(instr->left(), d1); 1299 LOperand* left = UseFixedDouble(instr->left(), d1);
1396 LOperand* right = UseFixedDouble(instr->right(), d2); 1300 LOperand* right = UseFixedDouble(instr->right(), d2);
1397 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); 1301 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
1398 return MarkAsCall(DefineFixedDouble(result, d1), instr); 1302 return MarkAsCall(DefineFixedDouble(result, d1), instr);
1399 } 1303 }
1400 } 1304 }
1401 1305
1402 1306
1403 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1307 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1404 if (instr->representation().IsInteger32()) { 1308 if (instr->representation().IsInteger32()) {
1405 ASSERT(instr->left()->representation().IsInteger32()); 1309 ASSERT(instr->left()->representation().IsInteger32());
1406 ASSERT(instr->right()->representation().IsInteger32()); 1310 ASSERT(instr->right()->representation().IsInteger32());
1407 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1311 LOperand* left;
1408 LOperand* right = UseOrConstant(instr->MostConstantOperand()); 1312 LOperand* right = UseOrConstant(instr->MostConstantOperand());
1409 LOperand* temp = NULL; 1313 LOperand* temp = NULL;
1410 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1314 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
1315 (instr->CheckFlag(HValue::kCanOverflow) ||
1316 !right->IsConstantOperand())) {
1317 left = UseRegister(instr->LeastConstantOperand());
1411 temp = TempRegister(); 1318 temp = TempRegister();
1319 } else {
1320 left = UseRegisterAtStart(instr->LeastConstantOperand());
1412 } 1321 }
1413 LMulI* mul = new LMulI(left, right, temp); 1322 return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
1414 return AssignEnvironment(DefineSameAsFirst(mul)); 1323
1415 } else if (instr->representation().IsDouble()) { 1324 } else if (instr->representation().IsDouble()) {
1416 return DoArithmeticD(Token::MUL, instr); 1325 return DoArithmeticD(Token::MUL, instr);
1326
1417 } else { 1327 } else {
1418 return DoArithmeticT(Token::MUL, instr); 1328 return DoArithmeticT(Token::MUL, instr);
1419 } 1329 }
1420 } 1330 }
1421 1331
1422 1332
1423 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1333 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1424 if (instr->representation().IsInteger32()) { 1334 if (instr->representation().IsInteger32()) {
1425 ASSERT(instr->left()->representation().IsInteger32()); 1335 ASSERT(instr->left()->representation().IsInteger32());
1426 ASSERT(instr->right()->representation().IsInteger32()); 1336 ASSERT(instr->right()->representation().IsInteger32());
1427 LOperand* left = UseRegisterAtStart(instr->left()); 1337 LOperand* left = UseRegisterAtStart(instr->left());
1428 LOperand* right = UseOrConstantAtStart(instr->right()); 1338 LOperand* right = UseOrConstantAtStart(instr->right());
1429 LSubI* sub = new LSubI(left, right); 1339 LSubI* sub = new LSubI(left, right);
1430 LInstruction* result = DefineSameAsFirst(sub); 1340 LInstruction* result = DefineAsRegister(sub);
1431 if (instr->CheckFlag(HValue::kCanOverflow)) { 1341 if (instr->CheckFlag(HValue::kCanOverflow)) {
1432 result = AssignEnvironment(result); 1342 result = AssignEnvironment(result);
1433 } 1343 }
1434 return result; 1344 return result;
1435 } else if (instr->representation().IsDouble()) { 1345 } else if (instr->representation().IsDouble()) {
1436 return DoArithmeticD(Token::SUB, instr); 1346 return DoArithmeticD(Token::SUB, instr);
1437 } else { 1347 } else {
1438 return DoArithmeticT(Token::SUB, instr); 1348 return DoArithmeticT(Token::SUB, instr);
1439 } 1349 }
1440 } 1350 }
1441 1351
1442 1352
1443 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 1353 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1444 if (instr->representation().IsInteger32()) { 1354 if (instr->representation().IsInteger32()) {
1445 ASSERT(instr->left()->representation().IsInteger32()); 1355 ASSERT(instr->left()->representation().IsInteger32());
1446 ASSERT(instr->right()->representation().IsInteger32()); 1356 ASSERT(instr->right()->representation().IsInteger32());
1447 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1357 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1448 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 1358 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
1449 LAddI* add = new LAddI(left, right); 1359 LAddI* add = new LAddI(left, right);
1450 LInstruction* result = DefineSameAsFirst(add); 1360 LInstruction* result = DefineAsRegister(add);
1451 if (instr->CheckFlag(HValue::kCanOverflow)) { 1361 if (instr->CheckFlag(HValue::kCanOverflow)) {
1452 result = AssignEnvironment(result); 1362 result = AssignEnvironment(result);
1453 } 1363 }
1454 return result; 1364 return result;
1455 } else if (instr->representation().IsDouble()) { 1365 } else if (instr->representation().IsDouble()) {
1456 return DoArithmeticD(Token::ADD, instr); 1366 return DoArithmeticD(Token::ADD, instr);
1457 } else { 1367 } else {
1458 ASSERT(instr->representation().IsTagged()); 1368 ASSERT(instr->representation().IsTagged());
1459 return DoArithmeticT(Token::ADD, instr); 1369 return DoArithmeticT(Token::ADD, instr);
1460 } 1370 }
(...skipping 10 matching lines...) Expand all
1471 LOperand* right = exponent_type.IsDouble() ? 1381 LOperand* right = exponent_type.IsDouble() ?
1472 UseFixedDouble(instr->right(), d2) : 1382 UseFixedDouble(instr->right(), d2) :
1473 UseFixed(instr->right(), r0); 1383 UseFixed(instr->right(), r0);
1474 LPower* result = new LPower(left, right); 1384 LPower* result = new LPower(left, right);
1475 return MarkAsCall(DefineFixedDouble(result, d3), 1385 return MarkAsCall(DefineFixedDouble(result, d3),
1476 instr, 1386 instr,
1477 CAN_DEOPTIMIZE_EAGERLY); 1387 CAN_DEOPTIMIZE_EAGERLY);
1478 } 1388 }
1479 1389
1480 1390
1481 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1391 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1482 Token::Value op = instr->token(); 1392 Token::Value op = instr->token();
1483 Representation r = instr->GetInputRepresentation(); 1393 Representation r = instr->GetInputRepresentation();
1394 ASSERT(instr->left()->representation().IsTagged());
1395 ASSERT(instr->right()->representation().IsTagged());
1396 bool reversed = (op == Token::GT || op == Token::LTE);
1397 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
1398 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
1399 LCmpT* result = new LCmpT(left, right);
1400 return MarkAsCall(DefineFixed(result, r0), instr);
1401 }
1402
1403
1404 LInstruction* LChunkBuilder::DoCompareIDAndBranch(
1405 HCompareIDAndBranch* instr) {
1406 Representation r = instr->GetInputRepresentation();
1484 if (r.IsInteger32()) { 1407 if (r.IsInteger32()) {
1485 ASSERT(instr->left()->representation().IsInteger32()); 1408 ASSERT(instr->left()->representation().IsInteger32());
1486 ASSERT(instr->right()->representation().IsInteger32()); 1409 ASSERT(instr->right()->representation().IsInteger32());
1487 LOperand* left = UseRegisterAtStart(instr->left()); 1410 LOperand* left = UseRegisterAtStart(instr->left());
1488 LOperand* right = UseRegisterAtStart(instr->right()); 1411 LOperand* right = UseRegisterAtStart(instr->right());
1489 return DefineAsRegister(new LCmpID(left, right)); 1412 return new LCmpIDAndBranch(left, right);
1490 } else if (r.IsDouble()) { 1413 } else {
1414 ASSERT(r.IsDouble());
1491 ASSERT(instr->left()->representation().IsDouble()); 1415 ASSERT(instr->left()->representation().IsDouble());
1492 ASSERT(instr->right()->representation().IsDouble()); 1416 ASSERT(instr->right()->representation().IsDouble());
1493 LOperand* left = UseRegisterAtStart(instr->left()); 1417 LOperand* left = UseRegisterAtStart(instr->left());
1494 LOperand* right = UseRegisterAtStart(instr->right()); 1418 LOperand* right = UseRegisterAtStart(instr->right());
1495 return DefineAsRegister(new LCmpID(left, right)); 1419 return new LCmpIDAndBranch(left, right);
1496 } else {
1497 ASSERT(instr->left()->representation().IsTagged());
1498 ASSERT(instr->right()->representation().IsTagged());
1499 bool reversed = (op == Token::GT || op == Token::LTE);
1500 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
1501 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
1502 LCmpT* result = new LCmpT(left, right);
1503 return MarkAsCall(DefineFixed(result, r0), instr);
1504 } 1420 }
1505 } 1421 }
1506 1422
1507 1423
1508 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1424 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1509 HCompareJSObjectEq* instr) { 1425 HCompareObjectEqAndBranch* instr) {
1510 LOperand* left = UseRegisterAtStart(instr->left()); 1426 LOperand* left = UseRegisterAtStart(instr->left());
1511 LOperand* right = UseRegisterAtStart(instr->right()); 1427 LOperand* right = UseRegisterAtStart(instr->right());
1512 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); 1428 return new LCmpObjectEqAndBranch(left, right);
1513 return DefineAsRegister(result);
1514 } 1429 }
1515 1430
1516 1431
1517 LInstruction* LChunkBuilder::DoCompareSymbolEq( 1432 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
1518 HCompareSymbolEq* instr) { 1433 HCompareConstantEqAndBranch* instr) {
1519 LOperand* left = UseRegisterAtStart(instr->left()); 1434 return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
1520 LOperand* right = UseRegisterAtStart(instr->right());
1521 LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
1522 return DefineAsRegister(result);
1523 } 1435 }
1524 1436
1525 1437
1526 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1438 LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
1527 ASSERT(instr->value()->representation().IsTagged()); 1439 ASSERT(instr->value()->representation().IsTagged());
1528 LOperand* value = UseRegisterAtStart(instr->value()); 1440 return new LIsNullAndBranch(UseRegisterAtStart(instr->value()));
1529
1530 return DefineAsRegister(new LIsNull(value));
1531 } 1441 }
1532 1442
1533 1443
1534 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { 1444 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1535 ASSERT(instr->value()->representation().IsTagged()); 1445 ASSERT(instr->value()->representation().IsTagged());
1536 LOperand* value = UseRegisterAtStart(instr->value()); 1446 LOperand* temp = TempRegister();
1537 1447 return new LIsObjectAndBranch(UseRegisterAtStart(instr->value()), temp);
1538 return DefineAsRegister(new LIsObject(value));
1539 } 1448 }
1540 1449
1541 1450
1542 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { 1451 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1543 ASSERT(instr->value()->representation().IsTagged()); 1452 ASSERT(instr->value()->representation().IsTagged());
1544 LOperand* value = UseAtStart(instr->value()); 1453 return new LIsSmiAndBranch(Use(instr->value()));
1545
1546 return DefineAsRegister(new LIsSmi(value));
1547 } 1454 }
1548 1455
1549 1456
1550 LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) { 1457 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1458 HIsUndetectableAndBranch* instr) {
1551 ASSERT(instr->value()->representation().IsTagged()); 1459 ASSERT(instr->value()->representation().IsTagged());
1552 LOperand* value = UseRegisterAtStart(instr->value()); 1460 return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
1553 1461 TempRegister());
1554 return DefineAsRegister(new LIsUndetectable(value));
1555 } 1462 }
1556 1463
1557 1464
1558 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { 1465 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1466 HHasInstanceTypeAndBranch* instr) {
1559 ASSERT(instr->value()->representation().IsTagged()); 1467 ASSERT(instr->value()->representation().IsTagged());
1560 LOperand* value = UseRegisterAtStart(instr->value()); 1468 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()));
1561
1562 return DefineAsRegister(new LHasInstanceType(value));
1563 } 1469 }
1564 1470
1565 1471
1566 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( 1472 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1567 HGetCachedArrayIndex* instr) { 1473 HGetCachedArrayIndex* instr) {
1568 ASSERT(instr->value()->representation().IsTagged()); 1474 ASSERT(instr->value()->representation().IsTagged());
1569 LOperand* value = UseRegisterAtStart(instr->value()); 1475 LOperand* value = UseRegisterAtStart(instr->value());
1570 1476
1571 return DefineAsRegister(new LGetCachedArrayIndex(value)); 1477 return DefineAsRegister(new LGetCachedArrayIndex(value));
1572 } 1478 }
1573 1479
1574 1480
1575 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( 1481 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1576 HHasCachedArrayIndex* instr) { 1482 HHasCachedArrayIndexAndBranch* instr) {
1577 ASSERT(instr->value()->representation().IsTagged()); 1483 ASSERT(instr->value()->representation().IsTagged());
1578 LOperand* value = UseRegister(instr->value()); 1484 return new LHasCachedArrayIndexAndBranch(
1579 1485 UseRegisterAtStart(instr->value()));
1580 return DefineAsRegister(new LHasCachedArrayIndex(value));
1581 } 1486 }
1582 1487
1583 1488
1584 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1489 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1490 HClassOfTestAndBranch* instr) {
1585 ASSERT(instr->value()->representation().IsTagged()); 1491 ASSERT(instr->value()->representation().IsTagged());
1586 LOperand* value = UseTempRegister(instr->value()); 1492 return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
1587 return DefineSameAsFirst(new LClassOfTest(value)); 1493 TempRegister());
1588 } 1494 }
1589 1495
1590 1496
1591 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1497 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1592 LOperand* array = UseRegisterAtStart(instr->value()); 1498 LOperand* array = UseRegisterAtStart(instr->value());
1593 return DefineAsRegister(new LJSArrayLength(array)); 1499 return DefineAsRegister(new LJSArrayLength(array));
1594 } 1500 }
1595 1501
1596 1502
1597 LInstruction* LChunkBuilder::DoExternalArrayLength( 1503 LInstruction* LChunkBuilder::DoExternalArrayLength(
1598 HExternalArrayLength* instr) { 1504 HExternalArrayLength* instr) {
1599 LOperand* array = UseRegisterAtStart(instr->value()); 1505 LOperand* array = UseRegisterAtStart(instr->value());
1600 return DefineAsRegister(new LExternalArrayLength(array)); 1506 return DefineAsRegister(new LExternalArrayLength(array));
1601 } 1507 }
1602 1508
1603 1509
1604 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1510 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1605 LOperand* array = UseRegisterAtStart(instr->value()); 1511 LOperand* array = UseRegisterAtStart(instr->value());
1606 return DefineAsRegister(new LFixedArrayLength(array)); 1512 return DefineAsRegister(new LFixedArrayLength(array));
1607 } 1513 }
1608 1514
1609 1515
1516 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
1517 LOperand* object = UseRegisterAtStart(instr->value());
1518 return DefineAsRegister(new LElementsKind(object));
1519 }
1520
1521
1610 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1522 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1611 LOperand* object = UseRegister(instr->value()); 1523 LOperand* object = UseRegister(instr->value());
1612 LValueOf* result = new LValueOf(object, TempRegister()); 1524 LValueOf* result = new LValueOf(object, TempRegister());
1613 return AssignEnvironment(DefineSameAsFirst(result)); 1525 return AssignEnvironment(DefineAsRegister(result));
1614 } 1526 }
1615 1527
1616 1528
1617 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1529 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1618 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1530 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1619 UseRegister(instr->length()))); 1531 UseRegister(instr->length())));
1620 } 1532 }
1621 1533
1622 1534
1623 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1535 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1624 // The control instruction marking the end of a block that completed 1536 // The control instruction marking the end of a block that completed
1625 // abruptly (e.g., threw an exception). There is nothing specific to do. 1537 // abruptly (e.g., threw an exception). There is nothing specific to do.
1626 return NULL; 1538 return NULL;
1627 } 1539 }
1628 1540
1629 1541
1630 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1542 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1631 LOperand* value = UseFixed(instr->value(), r0); 1543 LOperand* value = UseFixed(instr->value(), r0);
1632 return MarkAsCall(new LThrow(value), instr); 1544 return MarkAsCall(new LThrow(value), instr);
1633 } 1545 }
1634 1546
1635 1547
1548 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1549 return NULL;
1550 }
1551
1552
1636 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { 1553 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1637 // All HForceRepresentation instructions should be eliminated in the 1554 // All HForceRepresentation instructions should be eliminated in the
1638 // representation change phase of Hydrogen. 1555 // representation change phase of Hydrogen.
1639 UNREACHABLE(); 1556 UNREACHABLE();
1640 return NULL; 1557 return NULL;
1641 } 1558 }
1642 1559
1643 1560
1644 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1561 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1645 Representation from = instr->from(); 1562 Representation from = instr->from();
1646 Representation to = instr->to(); 1563 Representation to = instr->to();
1647 if (from.IsTagged()) { 1564 if (from.IsTagged()) {
1648 if (to.IsDouble()) { 1565 if (to.IsDouble()) {
1649 LOperand* value = UseRegister(instr->value()); 1566 LOperand* value = UseRegister(instr->value());
1650 LNumberUntagD* res = new LNumberUntagD(value); 1567 LNumberUntagD* res = new LNumberUntagD(value);
1651 return AssignEnvironment(DefineAsRegister(res)); 1568 return AssignEnvironment(DefineAsRegister(res));
1652 } else { 1569 } else {
1653 ASSERT(to.IsInteger32()); 1570 ASSERT(to.IsInteger32());
1654 LOperand* value = UseRegister(instr->value()); 1571 LOperand* value = UseRegister(instr->value());
1655 bool needs_check = !instr->value()->type().IsSmi(); 1572 bool needs_check = !instr->value()->type().IsSmi();
1656 LInstruction* res = NULL; 1573 LInstruction* res = NULL;
1657 if (!needs_check) { 1574 if (!needs_check) {
1658 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1575 res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
1659 } else { 1576 } else {
1660 LOperand* temp1 = TempRegister(); 1577 LOperand* temp1 = TempRegister();
1661 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() 1578 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
1662 : NULL; 1579 : NULL;
1663 LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3) 1580 LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d11)
1664 : NULL; 1581 : NULL;
1665 res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3)); 1582 res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3));
1666 res = AssignEnvironment(res); 1583 res = AssignEnvironment(res);
1667 } 1584 }
1668 return res; 1585 return res;
1669 } 1586 }
1670 } else if (from.IsDouble()) { 1587 } else if (from.IsDouble()) {
1671 if (to.IsTagged()) { 1588 if (to.IsTagged()) {
1672 LOperand* value = UseRegister(instr->value()); 1589 LOperand* value = UseRegister(instr->value());
1673 LOperand* temp1 = TempRegister(); 1590 LOperand* temp1 = TempRegister();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 LInstruction* result = new LCheckMap(value); 1664 LInstruction* result = new LCheckMap(value);
1748 return AssignEnvironment(result); 1665 return AssignEnvironment(result);
1749 } 1666 }
1750 1667
1751 1668
1752 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { 1669 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1753 HValue* value = instr->value(); 1670 HValue* value = instr->value();
1754 Representation input_rep = value->representation(); 1671 Representation input_rep = value->representation();
1755 LOperand* reg = UseRegister(value); 1672 LOperand* reg = UseRegister(value);
1756 if (input_rep.IsDouble()) { 1673 if (input_rep.IsDouble()) {
1757 return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d1))); 1674 return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d11)));
1758 } else if (input_rep.IsInteger32()) { 1675 } else if (input_rep.IsInteger32()) {
1759 return DefineAsRegister(new LClampIToUint8(reg)); 1676 return DefineAsRegister(new LClampIToUint8(reg));
1760 } else { 1677 } else {
1761 ASSERT(input_rep.IsTagged()); 1678 ASSERT(input_rep.IsTagged());
1762 // Register allocator doesn't (yet) support allocation of double 1679 // Register allocator doesn't (yet) support allocation of double
1763 // temps. Reserve d1 explicitly. 1680 // temps. Reserve d1 explicitly.
1764 LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d1)); 1681 LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d11));
1765 return AssignEnvironment(DefineAsRegister(result)); 1682 return AssignEnvironment(DefineAsRegister(result));
1766 } 1683 }
1767 } 1684 }
1768 1685
1769 1686
1687 LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
1688 HValue* value = instr->value();
1689 Representation input_rep = value->representation();
1690 LOperand* reg = UseRegister(value);
1691 if (input_rep.IsDouble()) {
1692 LOperand* temp1 = TempRegister();
1693 LOperand* temp2 = TempRegister();
1694 LDoubleToI* res = new LDoubleToI(reg, temp1, temp2);
1695 return AssignEnvironment(DefineAsRegister(res));
1696 } else if (input_rep.IsInteger32()) {
1697 // Canonicalization should already have removed the hydrogen instruction in
1698 // this case, since it is a noop.
1699 UNREACHABLE();
1700 return NULL;
1701 } else {
1702 ASSERT(input_rep.IsTagged());
1703 LOperand* temp1 = TempRegister();
1704 LOperand* temp2 = TempRegister();
1705 LOperand* temp3 = FixedTemp(d11);
1706 LTaggedToI* res = new LTaggedToI(reg, temp1, temp2, temp3);
1707 return AssignEnvironment(DefineSameAsFirst(res));
1708 }
1709 }
1710
1711
1770 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1712 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1771 return new LReturn(UseFixed(instr->value(), r0)); 1713 return new LReturn(UseFixed(instr->value(), r0));
1772 } 1714 }
1773 1715
1774 1716
1775 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1717 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1776 Representation r = instr->representation(); 1718 Representation r = instr->representation();
1777 if (r.IsInteger32()) { 1719 if (r.IsInteger32()) {
1778 return DefineAsRegister(new LConstantI); 1720 return DefineAsRegister(new LConstantI);
1779 } else if (r.IsDouble()) { 1721 } else if (r.IsDouble()) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 } 1833 }
1892 1834
1893 1835
1894 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1836 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1895 HLoadKeyedFastElement* instr) { 1837 HLoadKeyedFastElement* instr) {
1896 ASSERT(instr->representation().IsTagged()); 1838 ASSERT(instr->representation().IsTagged());
1897 ASSERT(instr->key()->representation().IsInteger32()); 1839 ASSERT(instr->key()->representation().IsInteger32());
1898 LOperand* obj = UseRegisterAtStart(instr->object()); 1840 LOperand* obj = UseRegisterAtStart(instr->object());
1899 LOperand* key = UseRegisterAtStart(instr->key()); 1841 LOperand* key = UseRegisterAtStart(instr->key());
1900 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1842 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1901 return AssignEnvironment(DefineSameAsFirst(result)); 1843 return AssignEnvironment(DefineAsRegister(result));
1902 } 1844 }
1903 1845
1904 1846
1905 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( 1847 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1906 HLoadKeyedSpecializedArrayElement* instr) { 1848 HLoadKeyedSpecializedArrayElement* instr) {
1907 ExternalArrayType array_type = instr->array_type(); 1849 JSObject::ElementsKind elements_kind = instr->elements_kind();
1908 Representation representation(instr->representation()); 1850 Representation representation(instr->representation());
1909 ASSERT( 1851 ASSERT(
1910 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1852 (representation.IsInteger32() &&
1911 array_type != kExternalDoubleArray)) || 1853 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1912 (representation.IsDouble() && (array_type == kExternalFloatArray || 1854 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1913 array_type == kExternalDoubleArray))); 1855 (representation.IsDouble() &&
1856 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1857 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
1914 ASSERT(instr->key()->representation().IsInteger32()); 1858 ASSERT(instr->key()->representation().IsInteger32());
1915 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1859 LOperand* external_pointer = UseRegister(instr->external_pointer());
1916 LOperand* key = UseRegisterOrConstant(instr->key()); 1860 LOperand* key = UseRegisterOrConstant(instr->key());
1917 LLoadKeyedSpecializedArrayElement* result = 1861 LLoadKeyedSpecializedArrayElement* result =
1918 new LLoadKeyedSpecializedArrayElement(external_pointer, key); 1862 new LLoadKeyedSpecializedArrayElement(external_pointer, key);
1919 LInstruction* load_instr = DefineAsRegister(result); 1863 LInstruction* load_instr = DefineAsRegister(result);
1920 // An unsigned int array load might overflow and cause a deopt, make sure it 1864 // An unsigned int array load might overflow and cause a deopt, make sure it
1921 // has an environment. 1865 // has an environment.
1922 return (array_type == kExternalUnsignedIntArray) ? 1866 return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ?
1923 AssignEnvironment(load_instr) : load_instr; 1867 AssignEnvironment(load_instr) : load_instr;
1924 } 1868 }
1925 1869
1926 1870
1927 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1871 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1928 LOperand* object = UseFixed(instr->object(), r1); 1872 LOperand* object = UseFixed(instr->object(), r1);
1929 LOperand* key = UseFixed(instr->key(), r0); 1873 LOperand* key = UseFixed(instr->key(), r0);
1930 1874
1931 LInstruction* result = 1875 LInstruction* result =
1932 DefineFixed(new LLoadKeyedGeneric(object, key), r0); 1876 DefineFixed(new LLoadKeyedGeneric(object, key), r0);
(...skipping 16 matching lines...) Expand all
1949 ? UseTempRegister(instr->key()) 1893 ? UseTempRegister(instr->key())
1950 : UseRegisterOrConstantAtStart(instr->key()); 1894 : UseRegisterOrConstantAtStart(instr->key());
1951 1895
1952 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1896 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1953 } 1897 }
1954 1898
1955 1899
1956 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( 1900 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1957 HStoreKeyedSpecializedArrayElement* instr) { 1901 HStoreKeyedSpecializedArrayElement* instr) {
1958 Representation representation(instr->value()->representation()); 1902 Representation representation(instr->value()->representation());
1959 ExternalArrayType array_type = instr->array_type(); 1903 JSObject::ElementsKind elements_kind = instr->elements_kind();
1960 ASSERT( 1904 ASSERT(
1961 (representation.IsInteger32() && (array_type != kExternalFloatArray && 1905 (representation.IsInteger32() &&
1962 array_type != kExternalDoubleArray)) || 1906 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
1963 (representation.IsDouble() && (array_type == kExternalFloatArray || 1907 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
1964 array_type == kExternalDoubleArray))); 1908 (representation.IsDouble() &&
1909 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
1910 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
1965 ASSERT(instr->external_pointer()->representation().IsExternal()); 1911 ASSERT(instr->external_pointer()->representation().IsExternal());
1966 ASSERT(instr->key()->representation().IsInteger32()); 1912 ASSERT(instr->key()->representation().IsInteger32());
1967 1913
1968 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1914 LOperand* external_pointer = UseRegister(instr->external_pointer());
1969 bool val_is_temp_register = array_type == kExternalPixelArray || 1915 bool val_is_temp_register =
1970 array_type == kExternalFloatArray; 1916 elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS ||
1917 elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS;
1971 LOperand* val = val_is_temp_register 1918 LOperand* val = val_is_temp_register
1972 ? UseTempRegister(instr->value()) 1919 ? UseTempRegister(instr->value())
1973 : UseRegister(instr->value()); 1920 : UseRegister(instr->value());
1974 LOperand* key = UseRegisterOrConstant(instr->key()); 1921 LOperand* key = UseRegisterOrConstant(instr->key());
1975 1922
1976 return new LStoreKeyedSpecializedArrayElement(external_pointer, 1923 return new LStoreKeyedSpecializedArrayElement(external_pointer,
1977 key, 1924 key,
1978 val); 1925 val);
1979 } 1926 }
1980 1927
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 2027
2081 2028
2082 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 2029 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2083 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 2030 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2084 return DefineAsSpilled(new LParameter, spill_index); 2031 return DefineAsSpilled(new LParameter, spill_index);
2085 } 2032 }
2086 2033
2087 2034
2088 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 2035 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2089 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. 2036 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
2037 if (spill_index > LUnallocated::kMaxFixedIndex) {
2038 Abort("Too many spill slots needed for OSR");
2039 spill_index = 0;
2040 }
2090 return DefineAsSpilled(new LUnknownOSRValue, spill_index); 2041 return DefineAsSpilled(new LUnknownOSRValue, spill_index);
2091 } 2042 }
2092 2043
2093 2044
2094 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2045 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2095 argument_count_ -= instr->argument_count(); 2046 argument_count_ -= instr->argument_count();
2096 return MarkAsCall(DefineFixed(new LCallStub, r0), instr); 2047 return MarkAsCall(DefineFixed(new LCallStub, r0), instr);
2097 } 2048 }
2098 2049
2099 2050
(...skipping 21 matching lines...) Expand all
2121 return MarkAsCall(DefineFixed(result, r0), instr); 2072 return MarkAsCall(DefineFixed(result, r0), instr);
2122 } 2073 }
2123 2074
2124 2075
2125 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2076 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2126 LTypeof* result = new LTypeof(UseFixed(instr->value(), r0)); 2077 LTypeof* result = new LTypeof(UseFixed(instr->value(), r0));
2127 return MarkAsCall(DefineFixed(result, r0), instr); 2078 return MarkAsCall(DefineFixed(result, r0), instr);
2128 } 2079 }
2129 2080
2130 2081
2131 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 2082 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2132 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 2083 return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
2133 } 2084 }
2134 2085
2135 2086
2136 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { 2087 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2137 return DefineAsRegister(new LIsConstructCall()); 2088 HIsConstructCallAndBranch* instr) {
2089 return new LIsConstructCallAndBranch(TempRegister());
2138 } 2090 }
2139 2091
2140 2092
2141 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2093 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2142 HEnvironment* env = current_block_->last_environment(); 2094 HEnvironment* env = current_block_->last_environment();
2143 ASSERT(env != NULL); 2095 ASSERT(env != NULL);
2144 2096
2145 env->set_ast_id(instr->ast_id()); 2097 env->set_ast_id(instr->ast_id());
2146 2098
2147 env->Drop(instr->pop_count()); 2099 env->Drop(instr->pop_count());
(...skipping 15 matching lines...) Expand all
2163 set_deoptimization_environment(result->environment()); 2115 set_deoptimization_environment(result->environment());
2164 ClearInstructionPendingDeoptimizationEnvironment(); 2116 ClearInstructionPendingDeoptimizationEnvironment();
2165 return result; 2117 return result;
2166 } 2118 }
2167 2119
2168 return NULL; 2120 return NULL;
2169 } 2121 }
2170 2122
2171 2123
2172 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2124 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2173 return MarkAsCall(new LStackCheck, instr); 2125 if (instr->is_function_entry()) {
2126 return MarkAsCall(new LStackCheck, instr);
2127 } else {
2128 ASSERT(instr->is_backwards_branch());
2129 return AssignEnvironment(AssignPointerMap(new LStackCheck));
2130 }
2174 } 2131 }
2175 2132
2176 2133
2177 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2134 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2178 HEnvironment* outer = current_block_->last_environment(); 2135 HEnvironment* outer = current_block_->last_environment();
2179 HConstant* undefined = graph()->GetConstantUndefined(); 2136 HConstant* undefined = graph()->GetConstantUndefined();
2180 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2137 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2181 instr->function(), 2138 instr->function(),
2182 HEnvironment::LITHIUM,
2183 undefined, 2139 undefined,
2184 instr->call_kind()); 2140 instr->call_kind());
2185 current_block_->UpdateEnvironment(inner); 2141 current_block_->UpdateEnvironment(inner);
2186 chunk_->AddInlinedClosure(instr->closure()); 2142 chunk_->AddInlinedClosure(instr->closure());
2187 return NULL; 2143 return NULL;
2188 } 2144 }
2189 2145
2190 2146
2191 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2147 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2192 HEnvironment* outer = current_block_->last_environment()->outer(); 2148 HEnvironment* outer = current_block_->last_environment()->outer();
2193 current_block_->UpdateEnvironment(outer); 2149 current_block_->UpdateEnvironment(outer);
2194 return NULL; 2150 return NULL;
2195 } 2151 }
2196 2152
2197 2153
2198 LInstruction* LChunkBuilder::DoIn(HIn* instr) { 2154 LInstruction* LChunkBuilder::DoIn(HIn* instr) {
2199 LOperand* key = UseRegisterAtStart(instr->key()); 2155 LOperand* key = UseRegisterAtStart(instr->key());
2200 LOperand* object = UseRegisterAtStart(instr->object()); 2156 LOperand* object = UseRegisterAtStart(instr->object());
2201 LIn* result = new LIn(key, object); 2157 LIn* result = new LIn(key, object);
2202 return MarkAsCall(DefineFixed(result, r0), instr); 2158 return MarkAsCall(DefineFixed(result, r0), instr);
2203 } 2159 }
2204 2160
2205 2161
2206 } } // namespace v8::internal 2162 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698