Revision f230a1cf deps/v8/src/arm/lithium-arm.cc
deps/v8/src/arm/lithium-arm.cc | ||
---|---|---|
412 | 412 |
} |
413 | 413 |
|
414 | 414 |
|
415 |
int LPlatformChunk::GetNextSpillIndex(bool is_double) {
|
|
415 |
int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
|
|
416 | 416 |
// Skip a slot if for a double-width slot. |
417 |
if (is_double) spill_slot_count_++;
|
|
417 |
if (kind == DOUBLE_REGISTERS) spill_slot_count_++;
|
|
418 | 418 |
return spill_slot_count_++; |
419 | 419 |
} |
420 | 420 |
|
421 | 421 |
|
422 |
LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
|
|
423 |
int index = GetNextSpillIndex(is_double);
|
|
424 |
if (is_double) {
|
|
422 |
LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
|
|
423 |
int index = GetNextSpillIndex(kind);
|
|
424 |
if (kind == DOUBLE_REGISTERS) {
|
|
425 | 425 |
return LDoubleStackSlot::Create(index, zone()); |
426 | 426 |
} else { |
427 |
ASSERT(kind == GENERAL_REGISTERS); |
|
427 | 428 |
return LStackSlot::Create(index, zone()); |
428 | 429 |
} |
429 | 430 |
} |
... | ... | |
439 | 440 |
// which will be subsumed into this frame. |
440 | 441 |
if (graph()->has_osr()) { |
441 | 442 |
for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
442 |
chunk_->GetNextSpillIndex(false);
|
|
443 |
chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
|
|
443 | 444 |
} |
444 | 445 |
} |
445 | 446 |
|
... | ... | |
655 | 656 |
|
656 | 657 |
LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
657 | 658 |
ASSERT(!instr->HasPointerMap()); |
658 |
instr->set_pointer_map(new(zone()) LPointerMap(position_, zone()));
|
|
659 |
instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
|
659 | 660 |
return instr; |
660 | 661 |
} |
661 | 662 |
|
... | ... | |
710 | 711 |
|
711 | 712 |
LInstruction* LChunkBuilder::DoShift(Token::Value op, |
712 | 713 |
HBitwiseBinaryOperation* instr) { |
713 |
if (instr->representation().IsTagged()) { |
|
714 |
ASSERT(instr->left()->representation().IsTagged()); |
|
715 |
ASSERT(instr->right()->representation().IsTagged()); |
|
716 |
|
|
717 |
LOperand* left = UseFixed(instr->left(), r1); |
|
718 |
LOperand* right = UseFixed(instr->right(), r0); |
|
719 |
LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
|
720 |
return MarkAsCall(DefineFixed(result, r0), instr); |
|
721 |
} |
|
722 |
|
|
723 |
ASSERT(instr->representation().IsSmiOrInteger32()); |
|
724 |
ASSERT(instr->left()->representation().Equals(instr->representation())); |
|
725 |
ASSERT(instr->right()->representation().Equals(instr->representation())); |
|
726 |
LOperand* left = UseRegisterAtStart(instr->left()); |
|
714 |
if (instr->representation().IsSmiOrInteger32()) { |
|
715 |
ASSERT(instr->left()->representation().Equals(instr->representation())); |
|
716 |
ASSERT(instr->right()->representation().Equals(instr->representation())); |
|
717 |
LOperand* left = UseRegisterAtStart(instr->left()); |
|
727 | 718 |
|
728 |
HValue* right_value = instr->right(); |
|
729 |
LOperand* right = NULL; |
|
730 |
int constant_value = 0; |
|
731 |
bool does_deopt = false; |
|
732 |
if (right_value->IsConstant()) { |
|
733 |
HConstant* constant = HConstant::cast(right_value); |
|
734 |
right = chunk_->DefineConstantOperand(constant); |
|
735 |
constant_value = constant->Integer32Value() & 0x1f; |
|
736 |
// Left shifts can deoptimize if we shift by > 0 and the result cannot be |
|
737 |
// truncated to smi. |
|
738 |
if (instr->representation().IsSmi() && constant_value > 0) { |
|
739 |
does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); |
|
719 |
HValue* right_value = instr->right(); |
|
720 |
LOperand* right = NULL; |
|
721 |
int constant_value = 0; |
|
722 |
bool does_deopt = false; |
|
723 |
if (right_value->IsConstant()) { |
|
724 |
HConstant* constant = HConstant::cast(right_value); |
|
725 |
right = chunk_->DefineConstantOperand(constant); |
|
726 |
constant_value = constant->Integer32Value() & 0x1f; |
|
727 |
// Left shifts can deoptimize if we shift by > 0 and the result cannot be |
|
728 |
// truncated to smi. |
|
729 |
if (instr->representation().IsSmi() && constant_value > 0) { |
|
730 |
does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); |
|
731 |
} |
|
732 |
} else { |
|
733 |
right = UseRegisterAtStart(right_value); |
|
740 | 734 |
} |
741 |
} else { |
|
742 |
right = UseRegisterAtStart(right_value); |
|
743 |
} |
|
744 | 735 |
|
745 |
// Shift operations can only deoptimize if we do a logical shift |
|
746 |
// by 0 and the result cannot be truncated to int32. |
|
747 |
if (op == Token::SHR && constant_value == 0) { |
|
748 |
if (FLAG_opt_safe_uint32_operations) { |
|
749 |
does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
|
750 |
} else { |
|
751 |
does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); |
|
736 |
// Shift operations can only deoptimize if we do a logical shift |
|
737 |
// by 0 and the result cannot be truncated to int32. |
|
738 |
if (op == Token::SHR && constant_value == 0) { |
|
739 |
if (FLAG_opt_safe_uint32_operations) { |
|
740 |
does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
|
741 |
} else { |
|
742 |
does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); |
|
743 |
} |
|
752 | 744 |
} |
753 |
} |
|
754 | 745 |
|
755 |
LInstruction* result = |
|
756 |
DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); |
|
757 |
return does_deopt ? AssignEnvironment(result) : result; |
|
746 |
LInstruction* result = |
|
747 |
DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); |
|
748 |
return does_deopt ? AssignEnvironment(result) : result; |
|
749 |
} else { |
|
750 |
return DoArithmeticT(op, instr); |
|
751 |
} |
|
758 | 752 |
} |
759 | 753 |
|
760 | 754 |
|
... | ... | |
763 | 757 |
ASSERT(instr->representation().IsDouble()); |
764 | 758 |
ASSERT(instr->left()->representation().IsDouble()); |
765 | 759 |
ASSERT(instr->right()->representation().IsDouble()); |
766 |
ASSERT(op != Token::MOD); |
|
767 |
LOperand* left = UseRegisterAtStart(instr->left()); |
|
768 |
LOperand* right = UseRegisterAtStart(instr->right()); |
|
769 |
LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
|
770 |
return DefineAsRegister(result); |
|
760 |
if (op == Token::MOD) { |
|
761 |
LOperand* left = UseFixedDouble(instr->left(), d1); |
|
762 |
LOperand* right = UseFixedDouble(instr->right(), d2); |
|
763 |
LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
|
764 |
// We call a C function for double modulo. It can't trigger a GC. We need |
|
765 |
// to use fixed result register for the call. |
|
766 |
// TODO(fschneider): Allow any register as input registers. |
|
767 |
return MarkAsCall(DefineFixedDouble(result, d1), instr); |
|
768 |
} else { |
|
769 |
LOperand* left = UseRegisterAtStart(instr->left()); |
|
770 |
LOperand* right = UseRegisterAtStart(instr->right()); |
|
771 |
LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
|
772 |
return DefineAsRegister(result); |
|
773 |
} |
|
771 | 774 |
} |
772 | 775 |
|
773 | 776 |
|
774 | 777 |
LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
775 |
HArithmeticBinaryOperation* instr) { |
|
776 |
ASSERT(op == Token::ADD || |
|
777 |
op == Token::DIV || |
|
778 |
op == Token::MOD || |
|
779 |
op == Token::MUL || |
|
780 |
op == Token::SUB); |
|
778 |
HBinaryOperation* instr) { |
|
781 | 779 |
HValue* left = instr->left(); |
782 | 780 |
HValue* right = instr->right(); |
783 | 781 |
ASSERT(left->representation().IsTagged()); |
784 | 782 |
ASSERT(right->representation().IsTagged()); |
783 |
LOperand* context = UseFixed(instr->context(), cp); |
|
785 | 784 |
LOperand* left_operand = UseFixed(left, r1); |
786 | 785 |
LOperand* right_operand = UseFixed(right, r0); |
787 | 786 |
LArithmeticT* result = |
788 |
new(zone()) LArithmeticT(op, left_operand, right_operand); |
|
787 |
new(zone()) LArithmeticT(op, context, left_operand, right_operand);
|
|
789 | 788 |
return MarkAsCall(DefineFixed(result, r0), instr); |
790 | 789 |
} |
791 | 790 |
|
... | ... | |
861 | 860 |
HInstruction* old_current = current_instruction_; |
862 | 861 |
current_instruction_ = current; |
863 | 862 |
if (current->has_position()) position_ = current->position(); |
864 |
LInstruction* instr = current->CompileToLithium(this); |
|
863 |
|
|
864 |
LInstruction* instr = NULL; |
|
865 |
if (current->CanReplaceWithDummyUses()) { |
|
866 |
HValue* first_operand = current->OperandCount() == 0 |
|
867 |
? graph()->GetConstant1() |
|
868 |
: current->OperandAt(0); |
|
869 |
instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); |
|
870 |
for (int i = 1; i < current->OperandCount(); ++i) { |
|
871 |
LInstruction* dummy = |
|
872 |
new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
|
873 |
dummy->set_hydrogen_value(current); |
|
874 |
chunk_->AddInstruction(dummy, current_block_); |
|
875 |
} |
|
876 |
} else { |
|
877 |
instr = current->CompileToLithium(this); |
|
878 |
} |
|
879 |
|
|
880 |
argument_count_ += current->argument_delta(); |
|
881 |
ASSERT(argument_count_ >= 0); |
|
865 | 882 |
|
866 | 883 |
if (instr != NULL) { |
884 |
// Associate the hydrogen instruction first, since we may need it for |
|
885 |
// the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. |
|
886 |
instr->set_hydrogen_value(current); |
|
887 |
|
|
867 | 888 |
#if DEBUG |
868 | 889 |
// Make sure that the lithium instruction has either no fixed register |
869 | 890 |
// constraints in temps or the result OR no uses that are only used at |
... | ... | |
893 | 914 |
} |
894 | 915 |
#endif |
895 | 916 |
|
896 |
instr->set_position(position_); |
|
897 | 917 |
if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
898 | 918 |
instr = AssignPointerMap(instr); |
899 | 919 |
} |
900 | 920 |
if (FLAG_stress_environments && !instr->HasEnvironment()) { |
901 | 921 |
instr = AssignEnvironment(instr); |
902 | 922 |
} |
903 |
instr->set_hydrogen_value(current); |
|
904 | 923 |
chunk_->AddInstruction(instr, current_block_); |
905 | 924 |
} |
906 | 925 |
current_instruction_ = old_current; |
... | ... | |
992 | 1011 |
|
993 | 1012 |
|
994 | 1013 |
LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
995 |
return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
|
|
1014 |
return new(zone()) LGoto(instr->FirstSuccessor()); |
|
996 | 1015 |
} |
997 | 1016 |
|
998 | 1017 |
|
999 | 1018 |
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
1000 |
HValue* value = instr->value(); |
|
1001 |
if (value->EmitAtUses()) { |
|
1002 |
HBasicBlock* successor = HConstant::cast(value)->BooleanValue() |
|
1003 |
? instr->FirstSuccessor() |
|
1004 |
: instr->SecondSuccessor(); |
|
1005 |
return new(zone()) LGoto(successor->block_id()); |
|
1006 |
} |
|
1019 |
LInstruction* goto_instr = CheckElideControlInstruction(instr); |
|
1020 |
if (goto_instr != NULL) return goto_instr; |
|
1007 | 1021 |
|
1022 |
HValue* value = instr->value(); |
|
1008 | 1023 |
LBranch* result = new(zone()) LBranch(UseRegister(value)); |
1009 | 1024 |
// Tagged values that are not known smis or booleans require a |
1010 | 1025 |
// deoptimization environment. If the instruction is generic no |
... | ... | |
1047 | 1062 |
|
1048 | 1063 |
|
1049 | 1064 |
LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
1065 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1050 | 1066 |
LInstanceOf* result = |
1051 |
new(zone()) LInstanceOf(UseFixed(instr->left(), r0), |
|
1052 |
UseFixed(instr->right(), r1)); |
|
1067 |
new(zone()) LInstanceOf(context, UseFixed(instr->left(), r0),
|
|
1068 |
UseFixed(instr->right(), r1));
|
|
1053 | 1069 |
return MarkAsCall(DefineFixed(result, r0), instr); |
1054 | 1070 |
} |
1055 | 1071 |
|
... | ... | |
1057 | 1073 |
LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
1058 | 1074 |
HInstanceOfKnownGlobal* instr) { |
1059 | 1075 |
LInstanceOfKnownGlobal* result = |
1060 |
new(zone()) LInstanceOfKnownGlobal(UseFixed(instr->left(), r0), |
|
1061 |
FixedTemp(r4)); |
|
1076 |
new(zone()) LInstanceOfKnownGlobal( |
|
1077 |
UseFixed(instr->context(), cp), |
|
1078 |
UseFixed(instr->left(), r0), |
|
1079 |
FixedTemp(r4)); |
|
1062 | 1080 |
return MarkAsCall(DefineFixed(result, r0), instr); |
1063 | 1081 |
} |
1064 | 1082 |
|
1065 | 1083 |
|
1066 |
LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) { |
|
1067 |
LOperand* object = UseRegisterAtStart(instr->object()); |
|
1068 |
return DefineAsRegister(new(zone()) LInstanceSize(object)); |
|
1069 |
} |
|
1070 |
|
|
1071 |
|
|
1072 | 1084 |
LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
1073 | 1085 |
LOperand* receiver = UseRegisterAtStart(instr->receiver()); |
1074 | 1086 |
LOperand* function = UseRegisterAtStart(instr->function()); |
... | ... | |
1091 | 1103 |
|
1092 | 1104 |
|
1093 | 1105 |
LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
1094 |
++argument_count_; |
|
1095 | 1106 |
LOperand* argument = Use(instr->argument()); |
1096 | 1107 |
return new(zone()) LPushArgument(argument); |
1097 | 1108 |
} |
... | ... | |
1122 | 1133 |
|
1123 | 1134 |
|
1124 | 1135 |
LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
1125 |
// If there is a non-return use, the context must be allocated in a register. |
|
1126 |
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { |
|
1127 |
if (!it.value()->IsReturn()) { |
|
1128 |
return DefineAsRegister(new(zone()) LContext); |
|
1129 |
} |
|
1136 |
if (instr->HasNoUses()) return NULL; |
|
1137 |
|
|
1138 |
if (info()->IsStub()) { |
|
1139 |
return DefineFixed(new(zone()) LContext, cp); |
|
1130 | 1140 |
} |
1131 | 1141 |
|
1132 |
return NULL;
|
|
1142 |
return DefineAsRegister(new(zone()) LContext);
|
|
1133 | 1143 |
} |
1134 | 1144 |
|
1135 | 1145 |
|
... | ... | |
1140 | 1150 |
|
1141 | 1151 |
|
1142 | 1152 |
LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { |
1143 |
return MarkAsCall(new(zone()) LDeclareGlobals, instr); |
|
1153 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1154 |
return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
|
1144 | 1155 |
} |
1145 | 1156 |
|
1146 | 1157 |
|
... | ... | |
1158 | 1169 |
|
1159 | 1170 |
LInstruction* LChunkBuilder::DoCallConstantFunction( |
1160 | 1171 |
HCallConstantFunction* instr) { |
1161 |
argument_count_ -= instr->argument_count(); |
|
1162 | 1172 |
return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, r0), instr); |
1163 | 1173 |
} |
1164 | 1174 |
|
1165 | 1175 |
|
1166 | 1176 |
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
1177 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1167 | 1178 |
LOperand* function = UseFixed(instr->function(), r1); |
1168 |
argument_count_ -= instr->argument_count(); |
|
1169 |
LInvokeFunction* result = new(zone()) LInvokeFunction(function); |
|
1179 |
LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); |
|
1170 | 1180 |
return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
1171 | 1181 |
} |
1172 | 1182 |
|
... | ... | |
1206 | 1216 |
|
1207 | 1217 |
|
1208 | 1218 |
LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { |
1219 |
Representation r = instr->value()->representation(); |
|
1220 |
LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) |
|
1221 |
? NULL |
|
1222 |
: UseFixed(instr->context(), cp); |
|
1209 | 1223 |
LOperand* input = UseRegister(instr->value()); |
1210 |
LMathAbs* result = new(zone()) LMathAbs(input); |
|
1224 |
LMathAbs* result = new(zone()) LMathAbs(context, input);
|
|
1211 | 1225 |
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
1212 | 1226 |
} |
1213 | 1227 |
|
... | ... | |
1243 | 1257 |
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
1244 | 1258 |
ASSERT(instr->representation().IsDouble()); |
1245 | 1259 |
ASSERT(instr->value()->representation().IsDouble()); |
1246 |
LOperand* input = UseTempRegister(instr->value());
|
|
1260 |
LOperand* input = UseRegister(instr->value()); |
|
1247 | 1261 |
LOperand* temp1 = TempRegister(); |
1248 | 1262 |
LOperand* temp2 = TempRegister(); |
1249 | 1263 |
LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. |
... | ... | |
1269 | 1283 |
|
1270 | 1284 |
LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
1271 | 1285 |
ASSERT(instr->key()->representation().IsTagged()); |
1272 |
argument_count_ -= instr->argument_count();
|
|
1286 |
LOperand* context = UseFixed(instr->context(), cp);
|
|
1273 | 1287 |
LOperand* key = UseFixed(instr->key(), r2); |
1274 |
return MarkAsCall(DefineFixed(new(zone()) LCallKeyed(key), r0), instr); |
|
1288 |
return MarkAsCall( |
|
1289 |
DefineFixed(new(zone()) LCallKeyed(context, key), r0), instr); |
|
1275 | 1290 |
} |
1276 | 1291 |
|
1277 | 1292 |
|
1278 | 1293 |
LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
1279 |
argument_count_ -= instr->argument_count();
|
|
1280 |
return MarkAsCall(DefineFixed(new(zone()) LCallNamed, r0), instr); |
|
1294 |
LOperand* context = UseFixed(instr->context(), cp);
|
|
1295 |
return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), r0), instr);
|
|
1281 | 1296 |
} |
1282 | 1297 |
|
1283 | 1298 |
|
1284 | 1299 |
LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
1285 |
argument_count_ -= instr->argument_count();
|
|
1286 |
return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, r0), instr); |
|
1300 |
LOperand* context = UseFixed(instr->context(), cp);
|
|
1301 |
return MarkAsCall(DefineFixed(new(zone()) LCallGlobal(context), r0), instr);
|
|
1287 | 1302 |
} |
1288 | 1303 |
|
1289 | 1304 |
|
1290 | 1305 |
LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
1291 |
argument_count_ -= instr->argument_count(); |
|
1292 | 1306 |
return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, r0), instr); |
1293 | 1307 |
} |
1294 | 1308 |
|
1295 | 1309 |
|
1296 | 1310 |
LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
1311 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1297 | 1312 |
LOperand* constructor = UseFixed(instr->constructor(), r1); |
1298 |
argument_count_ -= instr->argument_count(); |
|
1299 |
LCallNew* result = new(zone()) LCallNew(constructor); |
|
1313 |
LCallNew* result = new(zone()) LCallNew(context, constructor); |
|
1300 | 1314 |
return MarkAsCall(DefineFixed(result, r0), instr); |
1301 | 1315 |
} |
1302 | 1316 |
|
1303 | 1317 |
|
1304 | 1318 |
LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
1319 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1305 | 1320 |
LOperand* constructor = UseFixed(instr->constructor(), r1); |
1306 |
argument_count_ -= instr->argument_count(); |
|
1307 |
LCallNewArray* result = new(zone()) LCallNewArray(constructor); |
|
1321 |
LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
|
1308 | 1322 |
return MarkAsCall(DefineFixed(result, r0), instr); |
1309 | 1323 |
} |
1310 | 1324 |
|
1311 | 1325 |
|
1312 | 1326 |
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
1327 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1313 | 1328 |
LOperand* function = UseFixed(instr->function(), r1); |
1314 |
argument_count_ -= instr->argument_count(); |
|
1315 |
return MarkAsCall(DefineFixed(new(zone()) LCallFunction(function), r0), |
|
1316 |
instr); |
|
1329 |
return MarkAsCall( |
|
1330 |
DefineFixed(new(zone()) LCallFunction(context, function), r0), instr); |
|
1317 | 1331 |
} |
1318 | 1332 |
|
1319 | 1333 |
|
1320 | 1334 |
LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
1321 |
argument_count_ -= instr->argument_count();
|
|
1322 |
return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, r0), instr); |
|
1335 |
LOperand* context = UseFixed(instr->context(), cp);
|
|
1336 |
return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr);
|
|
1323 | 1337 |
} |
1324 | 1338 |
|
1325 | 1339 |
|
... | ... | |
1347 | 1361 |
if (instr->representation().IsSmiOrInteger32()) { |
1348 | 1362 |
ASSERT(instr->left()->representation().Equals(instr->representation())); |
1349 | 1363 |
ASSERT(instr->right()->representation().Equals(instr->representation())); |
1364 |
ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); |
|
1350 | 1365 |
|
1351 | 1366 |
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1352 | 1367 |
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1353 | 1368 |
return DefineAsRegister(new(zone()) LBitI(left, right)); |
1354 | 1369 |
} else { |
1355 |
ASSERT(instr->representation().IsTagged()); |
|
1356 |
ASSERT(instr->left()->representation().IsTagged()); |
|
1357 |
ASSERT(instr->right()->representation().IsTagged()); |
|
1358 |
|
|
1359 |
LOperand* left = UseFixed(instr->left(), r1); |
|
1360 |
LOperand* right = UseFixed(instr->right(), r0); |
|
1361 |
LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); |
|
1362 |
return MarkAsCall(DefineFixed(result, r0), instr); |
|
1370 |
return DoArithmeticT(instr->op(), instr); |
|
1363 | 1371 |
} |
1364 | 1372 |
} |
1365 | 1373 |
|
1366 | 1374 |
|
1367 | 1375 |
LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1368 |
if (instr->representation().IsDouble()) { |
|
1369 |
return DoArithmeticD(Token::DIV, instr); |
|
1370 |
} else if (instr->representation().IsSmiOrInteger32()) { |
|
1376 |
if (instr->representation().IsSmiOrInteger32()) { |
|
1371 | 1377 |
ASSERT(instr->left()->representation().Equals(instr->representation())); |
1372 | 1378 |
ASSERT(instr->right()->representation().Equals(instr->representation())); |
1373 | 1379 |
if (instr->HasPowerOf2Divisor()) { |
1374 | 1380 |
ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
1375 | 1381 |
LOperand* value = UseRegisterAtStart(instr->left()); |
1376 |
LDivI* div = |
|
1377 |
new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); |
|
1378 |
return AssignEnvironment(DefineSameAsFirst(div)); |
|
1382 |
LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); |
|
1383 |
return AssignEnvironment(DefineAsRegister(div)); |
|
1379 | 1384 |
} |
1380 | 1385 |
LOperand* dividend = UseRegister(instr->left()); |
1381 | 1386 |
LOperand* divisor = UseRegister(instr->right()); |
1382 | 1387 |
LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); |
1383 | 1388 |
LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
1384 | 1389 |
return AssignEnvironment(DefineAsRegister(div)); |
1390 |
} else if (instr->representation().IsDouble()) { |
|
1391 |
return DoArithmeticD(Token::DIV, instr); |
|
1385 | 1392 |
} else { |
1386 | 1393 |
return DoArithmeticT(Token::DIV, instr); |
1387 | 1394 |
} |
... | ... | |
1502 | 1509 |
? AssignEnvironment(result) |
1503 | 1510 |
: result; |
1504 | 1511 |
} |
1505 |
} else if (instr->representation().IsTagged()) {
|
|
1506 |
return DoArithmeticT(Token::MOD, instr);
|
|
1512 |
} else if (instr->representation().IsDouble()) {
|
|
1513 |
return DoArithmeticD(Token::MOD, instr);
|
|
1507 | 1514 |
} else { |
1508 |
ASSERT(instr->representation().IsDouble()); |
|
1509 |
// We call a C function for double modulo. It can't trigger a GC. We need |
|
1510 |
// to use fixed result register for the call. |
|
1511 |
// TODO(fschneider): Allow any register as input registers. |
|
1512 |
LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, |
|
1513 |
UseFixedDouble(left, d1), |
|
1514 |
UseFixedDouble(right, d2)); |
|
1515 |
return MarkAsCall(DefineFixedDouble(mod, d1), instr); |
|
1515 |
return DoArithmeticT(Token::MOD, instr); |
|
1516 | 1516 |
} |
1517 | 1517 |
} |
1518 | 1518 |
|
... | ... | |
1679 | 1679 |
|
1680 | 1680 |
return DoArithmeticD(Token::ADD, instr); |
1681 | 1681 |
} else { |
1682 |
ASSERT(instr->representation().IsTagged()); |
|
1683 | 1682 |
return DoArithmeticT(Token::ADD, instr); |
1684 | 1683 |
} |
1685 | 1684 |
} |
... | ... | |
1737 | 1736 |
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
1738 | 1737 |
ASSERT(instr->left()->representation().IsTagged()); |
1739 | 1738 |
ASSERT(instr->right()->representation().IsTagged()); |
1739 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1740 | 1740 |
LOperand* left = UseFixed(instr->left(), r1); |
1741 | 1741 |
LOperand* right = UseFixed(instr->right(), r0); |
1742 |
LCmpT* result = new(zone()) LCmpT(left, right); |
|
1742 |
LCmpT* result = new(zone()) LCmpT(context, left, right);
|
|
1743 | 1743 |
return MarkAsCall(DefineFixed(result, r0), instr); |
1744 | 1744 |
} |
1745 | 1745 |
|
... | ... | |
1766 | 1766 |
|
1767 | 1767 |
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1768 | 1768 |
HCompareObjectEqAndBranch* instr) { |
1769 |
LInstruction* goto_instr = CheckElideControlInstruction(instr); |
|
1770 |
if (goto_instr != NULL) return goto_instr; |
|
1769 | 1771 |
LOperand* left = UseRegisterAtStart(instr->left()); |
1770 | 1772 |
LOperand* right = UseRegisterAtStart(instr->right()); |
1771 | 1773 |
return new(zone()) LCmpObjectEqAndBranch(left, right); |
... | ... | |
1774 | 1776 |
|
1775 | 1777 |
LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
1776 | 1778 |
HCompareHoleAndBranch* instr) { |
1777 |
LOperand* object = UseRegisterAtStart(instr->object());
|
|
1778 |
return new(zone()) LCmpHoleAndBranch(object);
|
|
1779 |
LOperand* value = UseRegisterAtStart(instr->value());
|
|
1780 |
return new(zone()) LCmpHoleAndBranch(value);
|
|
1779 | 1781 |
} |
1780 | 1782 |
|
1781 | 1783 |
|
... | ... | |
1813 | 1815 |
HStringCompareAndBranch* instr) { |
1814 | 1816 |
ASSERT(instr->left()->representation().IsTagged()); |
1815 | 1817 |
ASSERT(instr->right()->representation().IsTagged()); |
1818 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1816 | 1819 |
LOperand* left = UseFixed(instr->left(), r1); |
1817 | 1820 |
LOperand* right = UseFixed(instr->right(), r0); |
1818 | 1821 |
LStringCompareAndBranch* result = |
1819 |
new(zone()) LStringCompareAndBranch(left, right); |
|
1822 |
new(zone()) LStringCompareAndBranch(context, left, right);
|
|
1820 | 1823 |
return MarkAsCall(result, instr); |
1821 | 1824 |
} |
1822 | 1825 |
|
... | ... | |
1883 | 1886 |
|
1884 | 1887 |
LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { |
1885 | 1888 |
LOperand* string = UseRegister(instr->string()); |
1886 |
LOperand* index = UseRegister(instr->index()); |
|
1887 |
LOperand* value = UseTempRegister(instr->value()); |
|
1888 |
LSeqStringSetChar* result = |
|
1889 |
new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); |
|
1890 |
return DefineAsRegister(result); |
|
1889 |
LOperand* index = UseRegisterOrConstant(instr->index()); |
|
1890 |
LOperand* value = UseRegister(instr->value()); |
|
1891 |
return new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); |
|
1891 | 1892 |
} |
1892 | 1893 |
|
1893 | 1894 |
|
... | ... | |
1905 | 1906 |
} |
1906 | 1907 |
|
1907 | 1908 |
|
1909 |
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
|
1910 |
// The control instruction marking the end of a block that completed |
|
1911 |
// abruptly (e.g., threw an exception). There is nothing specific to do. |
|
1912 |
return NULL; |
|
1913 |
} |
|
1914 |
|
|
1915 |
|
|
1908 | 1916 |
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
1917 |
LOperand* context = UseFixed(instr->context(), cp); |
|
1909 | 1918 |
LOperand* value = UseFixed(instr->value(), r0); |
1910 |
return MarkAsCall(new(zone()) LThrow(value), instr); |
|
1919 |
return MarkAsCall(new(zone()) LThrow(context, value), instr);
|
|
1911 | 1920 |
} |
1912 | 1921 |
|
1913 | 1922 |
|
... | ... | |
1936 | 1945 |
} |
1937 | 1946 |
if (from.IsTagged()) { |
1938 | 1947 |
if (to.IsDouble()) { |
1939 |
info()->MarkAsDeferredCalling(); |
|
1940 | 1948 |
LOperand* value = UseRegister(instr->value()); |
1941 | 1949 |
LNumberUntagD* res = new(zone()) LNumberUntagD(value); |
1942 | 1950 |
return AssignEnvironment(DefineAsRegister(res)); |
... | ... | |
2006 | 2014 |
} else if (to.IsSmi()) { |
2007 | 2015 |
HValue* val = instr->value(); |
2008 | 2016 |
LOperand* value = UseRegister(val); |
2009 |
LInstruction* result = |
|
2010 |
DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); |
|
2017 |
LInstruction* result = val->CheckFlag(HInstruction::kUint32) |
|
2018 |
? DefineSameAsFirst(new(zone()) LUint32ToSmi(value)) |
|
2019 |
: DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); |
|
2011 | 2020 |
if (val->HasRange() && val->range()->IsInSmiRange()) { |
2012 | 2021 |
return result; |
2013 | 2022 |
} |
... | ... | |
2040 | 2049 |
} |
2041 | 2050 |
|
2042 | 2051 |
|
2043 |
LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) { |
|
2044 |
return new(zone()) |
|
2045 |
LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value())); |
|
2046 |
} |
|
2047 |
|
|
2048 |
|
|
2049 | 2052 |
LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
2050 | 2053 |
LOperand* value = UseRegisterAtStart(instr->value()); |
2051 | 2054 |
LInstruction* result = new(zone()) LCheckInstanceType(value); |
... | ... | |
2093 | 2096 |
|
2094 | 2097 |
|
2095 | 2098 |
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
2099 |
LOperand* context = info()->IsStub() |
|
2100 |
? UseFixed(instr->context(), cp) |
|
2101 |
: NULL; |
|
2096 | 2102 |
LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); |
2097 |
return new(zone()) LReturn(UseFixed(instr->value(), r0), |
|
2103 |
return new(zone()) LReturn(UseFixed(instr->value(), r0), context,
|
|
2098 | 2104 |
parameter_count); |
2099 | 2105 |
} |
2100 | 2106 |
|
... | ... | |
2127 | 2133 |
|
2128 | 2134 |
|
2129 | 2135 |
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { |
2136 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2130 | 2137 |
LOperand* global_object = UseFixed(instr->global_object(), r0); |
2131 |
LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); |
|
2138 |
LLoadGlobalGeneric* result = |
|
2139 |
new(zone()) LLoadGlobalGeneric(context, global_object); |
|
2132 | 2140 |
return MarkAsCall(DefineFixed(result, r0), instr); |
2133 | 2141 |
} |
2134 | 2142 |
|
... | ... | |
2144 | 2152 |
|
2145 | 2153 |
|
2146 | 2154 |
LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { |
2155 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2147 | 2156 |
LOperand* global_object = UseFixed(instr->global_object(), r1); |
2148 | 2157 |
LOperand* value = UseFixed(instr->value(), r0); |
2149 | 2158 |
LStoreGlobalGeneric* result = |
2150 |
new(zone()) LStoreGlobalGeneric(global_object, value); |
|
2159 |
new(zone()) LStoreGlobalGeneric(context, global_object, value);
|
|
2151 | 2160 |
return MarkAsCall(result, instr); |
2152 | 2161 |
} |
2153 | 2162 |
|
... | ... | |
2182 | 2191 |
|
2183 | 2192 |
|
2184 | 2193 |
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
2194 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2185 | 2195 |
LOperand* object = UseFixed(instr->object(), r0); |
2186 |
LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(object), r0); |
|
2196 |
LInstruction* result = |
|
2197 |
DefineFixed(new(zone()) LLoadNamedGeneric(context, object), r0); |
|
2187 | 2198 |
return MarkAsCall(result, instr); |
2188 | 2199 |
} |
2189 | 2200 |
|
... | ... | |
2195 | 2206 |
} |
2196 | 2207 |
|
2197 | 2208 |
|
2209 |
LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
|
2210 |
return DefineAsRegister(new(zone()) LLoadRoot); |
|
2211 |
} |
|
2212 |
|
|
2213 |
|
|
2198 | 2214 |
LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( |
2199 | 2215 |
HLoadExternalArrayPointer* instr) { |
2200 | 2216 |
LOperand* input = UseRegisterAtStart(instr->value()); |
... | ... | |
2211 | 2227 |
if (!instr->is_external()) { |
2212 | 2228 |
LOperand* obj = NULL; |
2213 | 2229 |
if (instr->representation().IsDouble()) { |
2214 |
obj = UseTempRegister(instr->elements());
|
|
2230 |
obj = UseRegister(instr->elements()); |
|
2215 | 2231 |
} else { |
2216 | 2232 |
ASSERT(instr->representation().IsSmiOrTagged()); |
2217 | 2233 |
obj = UseRegisterAtStart(instr->elements()); |
... | ... | |
2239 | 2255 |
|
2240 | 2256 |
|
2241 | 2257 |
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
2258 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2242 | 2259 |
LOperand* object = UseFixed(instr->object(), r1); |
2243 | 2260 |
LOperand* key = UseFixed(instr->key(), r0); |
2244 | 2261 |
|
2245 | 2262 |
LInstruction* result = |
2246 |
DefineFixed(new(zone()) LLoadKeyedGeneric(object, key), r0); |
|
2263 |
DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0);
|
|
2247 | 2264 |
return MarkAsCall(result, instr); |
2248 | 2265 |
} |
2249 | 2266 |
|
2250 | 2267 |
|
2251 | 2268 |
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
2252 |
ElementsKind elements_kind = instr->elements_kind(); |
|
2253 |
|
|
2254 | 2269 |
if (!instr->is_external()) { |
2255 | 2270 |
ASSERT(instr->elements()->representation().IsTagged()); |
2256 | 2271 |
bool needs_write_barrier = instr->NeedsWriteBarrier(); |
... | ... | |
2260 | 2275 |
|
2261 | 2276 |
if (instr->value()->representation().IsDouble()) { |
2262 | 2277 |
object = UseRegisterAtStart(instr->elements()); |
2263 |
val = UseTempRegister(instr->value());
|
|
2278 |
val = UseRegister(instr->value()); |
|
2264 | 2279 |
key = UseRegisterOrConstantAtStart(instr->key()); |
2265 | 2280 |
} else { |
2266 | 2281 |
ASSERT(instr->value()->representation().IsSmiOrTagged()); |
2267 |
object = UseTempRegister(instr->elements()); |
|
2268 |
val = needs_write_barrier ? UseTempRegister(instr->value()) |
|
2269 |
: UseRegisterAtStart(instr->value()); |
|
2270 |
key = needs_write_barrier ? UseTempRegister(instr->key()) |
|
2271 |
: UseRegisterOrConstantAtStart(instr->key()); |
|
2282 |
if (needs_write_barrier) { |
|
2283 |
object = UseTempRegister(instr->elements()); |
|
2284 |
val = UseTempRegister(instr->value()); |
|
2285 |
key = UseTempRegister(instr->key()); |
|
2286 |
} else { |
|
2287 |
object = UseRegisterAtStart(instr->elements()); |
|
2288 |
val = UseRegisterAtStart(instr->value()); |
|
2289 |
key = UseRegisterOrConstantAtStart(instr->key()); |
|
2290 |
} |
|
2272 | 2291 |
} |
2273 | 2292 |
|
2274 | 2293 |
return new(zone()) LStoreKeyed(object, key, val); |
... | ... | |
2276 | 2295 |
|
2277 | 2296 |
ASSERT( |
2278 | 2297 |
(instr->value()->representation().IsInteger32() && |
2279 |
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
|
|
2280 |
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
|
2298 |
(instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) &&
|
|
2299 |
(instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
|
2281 | 2300 |
(instr->value()->representation().IsDouble() && |
2282 |
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
|
|
2283 |
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
|
|
2301 |
((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) ||
|
|
2302 |
(instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS))));
|
|
2284 | 2303 |
ASSERT(instr->elements()->representation().IsExternal()); |
2285 |
bool val_is_temp_register = |
|
2286 |
elements_kind == EXTERNAL_PIXEL_ELEMENTS || |
|
2287 |
elements_kind == EXTERNAL_FLOAT_ELEMENTS; |
|
2288 |
LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) |
|
2289 |
: UseRegister(instr->value()); |
|
2304 |
LOperand* val = UseRegister(instr->value()); |
|
2290 | 2305 |
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
2291 | 2306 |
LOperand* external_pointer = UseRegister(instr->elements()); |
2292 | 2307 |
return new(zone()) LStoreKeyed(external_pointer, key, val); |
... | ... | |
2294 | 2309 |
|
2295 | 2310 |
|
2296 | 2311 |
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
2312 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2297 | 2313 |
LOperand* obj = UseFixed(instr->object(), r2); |
2298 | 2314 |
LOperand* key = UseFixed(instr->key(), r1); |
2299 | 2315 |
LOperand* val = UseFixed(instr->value(), r0); |
... | ... | |
2302 | 2318 |
ASSERT(instr->key()->representation().IsTagged()); |
2303 | 2319 |
ASSERT(instr->value()->representation().IsTagged()); |
2304 | 2320 |
|
2305 |
return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); |
|
2321 |
return MarkAsCall( |
|
2322 |
new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); |
|
2306 | 2323 |
} |
2307 | 2324 |
|
2308 | 2325 |
|
... | ... | |
2312 | 2329 |
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
2313 | 2330 |
LOperand* new_map_reg = TempRegister(); |
2314 | 2331 |
LTransitionElementsKind* result = |
2315 |
new(zone()) LTransitionElementsKind(object, new_map_reg); |
|
2332 |
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
|
|
2316 | 2333 |
return result; |
2317 | 2334 |
} else { |
2335 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2318 | 2336 |
LTransitionElementsKind* result = |
2319 |
new(zone()) LTransitionElementsKind(object, NULL); |
|
2337 |
new(zone()) LTransitionElementsKind(object, context, NULL);
|
|
2320 | 2338 |
return AssignPointerMap(result); |
2321 | 2339 |
} |
2322 | 2340 |
} |
... | ... | |
2375 | 2393 |
|
2376 | 2394 |
|
2377 | 2395 |
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
2396 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2378 | 2397 |
LOperand* obj = UseFixed(instr->object(), r1); |
2379 | 2398 |
LOperand* val = UseFixed(instr->value(), r0); |
2380 | 2399 |
|
2381 |
LInstruction* result = new(zone()) LStoreNamedGeneric(obj, val); |
|
2400 |
LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val);
|
|
2382 | 2401 |
return MarkAsCall(result, instr); |
2383 | 2402 |
} |
2384 | 2403 |
|
2385 | 2404 |
|
2386 | 2405 |
LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
2406 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2387 | 2407 |
LOperand* left = UseRegisterAtStart(instr->left()); |
2388 | 2408 |
LOperand* right = UseRegisterAtStart(instr->right()); |
2389 |
return MarkAsCall(DefineFixed(new(zone()) LStringAdd(left, right), r0), |
|
2390 |
instr); |
|
2409 |
return MarkAsCall( |
|
2410 |
DefineFixed(new(zone()) LStringAdd(context, left, right), r0), |
|
2411 |
instr); |
|
2391 | 2412 |
} |
2392 | 2413 |
|
2393 | 2414 |
|
2394 | 2415 |
LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
2395 | 2416 |
LOperand* string = UseTempRegister(instr->string()); |
2396 | 2417 |
LOperand* index = UseTempRegister(instr->index()); |
2397 |
LStringCharCodeAt* result = new(zone()) LStringCharCodeAt(string, index); |
|
2418 |
LOperand* context = UseAny(instr->context()); |
|
2419 |
LStringCharCodeAt* result = |
|
2420 |
new(zone()) LStringCharCodeAt(context, string, index); |
|
2398 | 2421 |
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
2399 | 2422 |
} |
2400 | 2423 |
|
2401 | 2424 |
|
2402 | 2425 |
LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
2403 | 2426 |
LOperand* char_code = UseRegister(instr->value()); |
2404 |
LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code); |
|
2427 |
LOperand* context = UseAny(instr->context()); |
|
2428 |
LStringCharFromCode* result = |
|
2429 |
new(zone()) LStringCharFromCode(context, char_code); |
|
2405 | 2430 |
return AssignPointerMap(DefineAsRegister(result)); |
2406 | 2431 |
} |
2407 | 2432 |
|
2408 | 2433 |
|
2409 | 2434 |
LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
2410 | 2435 |
info()->MarkAsDeferredCalling(); |
2436 |
LOperand* context = UseAny(instr->context()); |
|
2411 | 2437 |
LOperand* size = instr->size()->IsConstant() |
2412 | 2438 |
? UseConstant(instr->size()) |
2413 | 2439 |
: UseTempRegister(instr->size()); |
2414 | 2440 |
LOperand* temp1 = TempRegister(); |
2415 | 2441 |
LOperand* temp2 = TempRegister(); |
2416 |
LAllocate* result = new(zone()) LAllocate(size, temp1, temp2); |
|
2442 |
LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2);
|
|
2417 | 2443 |
return AssignPointerMap(DefineAsRegister(result)); |
2418 | 2444 |
} |
2419 | 2445 |
|
2420 | 2446 |
|
2421 | 2447 |
LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
2422 |
return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, r0), instr); |
|
2448 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2449 |
return MarkAsCall( |
|
2450 |
DefineFixed(new(zone()) LRegExpLiteral(context), r0), instr); |
|
2423 | 2451 |
} |
2424 | 2452 |
|
2425 | 2453 |
|
2426 | 2454 |
LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
2427 |
return MarkAsCall(DefineFixed(new(zone()) LFunctionLiteral, r0), instr); |
|
2455 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2456 |
return MarkAsCall( |
|
2457 |
DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); |
|
2428 | 2458 |
} |
2429 | 2459 |
|
2430 | 2460 |
|
... | ... | |
2471 | 2501 |
|
2472 | 2502 |
|
2473 | 2503 |
LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
2474 |
argument_count_ -= instr->argument_count();
|
|
2475 |
return MarkAsCall(DefineFixed(new(zone()) LCallStub, r0), instr); |
|
2504 |
LOperand* context = UseFixed(instr->context(), cp);
|
|
2505 |
return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr);
|
|
2476 | 2506 |
} |
2477 | 2507 |
|
2478 | 2508 |
|
... | ... | |
2517 | 2547 |
|
2518 | 2548 |
|
2519 | 2549 |
LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
2520 |
LTypeof* result = new(zone()) LTypeof(UseFixed(instr->value(), r0)); |
|
2550 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2551 |
LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); |
|
2521 | 2552 |
return MarkAsCall(DefineFixed(result, r0), instr); |
2522 | 2553 |
} |
2523 | 2554 |
|
... | ... | |
2556 | 2587 |
|
2557 | 2588 |
LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
2558 | 2589 |
if (instr->is_function_entry()) { |
2559 |
return MarkAsCall(new(zone()) LStackCheck, instr); |
|
2590 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2591 |
return MarkAsCall(new(zone()) LStackCheck(context), instr); |
|
2560 | 2592 |
} else { |
2561 | 2593 |
ASSERT(instr->is_backwards_branch()); |
2562 |
return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); |
|
2594 |
LOperand* context = UseAny(instr->context()); |
|
2595 |
return AssignEnvironment( |
|
2596 |
AssignPointerMap(new(zone()) LStackCheck(context))); |
|
2563 | 2597 |
} |
2564 | 2598 |
} |
2565 | 2599 |
|
... | ... | |
2592 | 2626 |
if (env->entry()->arguments_pushed()) { |
2593 | 2627 |
int argument_count = env->arguments_environment()->parameter_count(); |
2594 | 2628 |
pop = new(zone()) LDrop(argument_count); |
2595 |
argument_count_ -= argument_count;
|
|
2629 |
ASSERT(instr->argument_delta() == -argument_count);
|
|
2596 | 2630 |
} |
2597 | 2631 |
|
2598 | 2632 |
HEnvironment* outer = current_block_->last_environment()-> |
... | ... | |
2604 | 2638 |
|
2605 | 2639 |
|
2606 | 2640 |
LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
2641 |
LOperand* context = UseFixed(instr->context(), cp); |
|
2607 | 2642 |
LOperand* object = UseFixed(instr->enumerable(), r0); |
2608 |
LForInPrepareMap* result = new(zone()) LForInPrepareMap(object); |
|
2643 |
LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object);
|
|
2609 | 2644 |
return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); |
2610 | 2645 |
} |
2611 | 2646 |
|
Also available in: Unified diff