| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 } | 774 } |
| 775 } | 775 } |
| 776 | 776 |
| 777 | 777 |
| 778 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 778 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 779 HBinaryOperation* instr) { | 779 HBinaryOperation* instr) { |
| 780 HValue* left = instr->left(); | 780 HValue* left = instr->left(); |
| 781 HValue* right = instr->right(); | 781 HValue* right = instr->right(); |
| 782 ASSERT(left->representation().IsTagged()); | 782 ASSERT(left->representation().IsTagged()); |
| 783 ASSERT(right->representation().IsTagged()); | 783 ASSERT(right->representation().IsTagged()); |
| 784 LOperand* context = UseFixed(instr->context(), rsi); |
| 784 LOperand* left_operand = UseFixed(left, rdx); | 785 LOperand* left_operand = UseFixed(left, rdx); |
| 785 LOperand* right_operand = UseFixed(right, rax); | 786 LOperand* right_operand = UseFixed(right, rax); |
| 786 LArithmeticT* result = | 787 LArithmeticT* result = |
| 787 new(zone()) LArithmeticT(op, left_operand, right_operand); | 788 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 788 return MarkAsCall(DefineFixed(result, rax), instr); | 789 return MarkAsCall(DefineFixed(result, rax), instr); |
| 789 } | 790 } |
| 790 | 791 |
| 791 | 792 |
| 792 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 793 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 793 ASSERT(is_building()); | 794 ASSERT(is_building()); |
| 794 current_block_ = block; | 795 current_block_ = block; |
| 795 next_block_ = next_block; | 796 next_block_ = next_block; |
| 796 if (block->IsStartBlock()) { | 797 if (block->IsStartBlock()) { |
| 797 block->UpdateEnvironment(graph_->start_environment()); | 798 block->UpdateEnvironment(graph_->start_environment()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 current_block_ = NULL; | 856 current_block_ = NULL; |
| 856 } | 857 } |
| 857 | 858 |
| 858 | 859 |
| 859 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 860 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 860 HInstruction* old_current = current_instruction_; | 861 HInstruction* old_current = current_instruction_; |
| 861 current_instruction_ = current; | 862 current_instruction_ = current; |
| 862 | 863 |
| 863 LInstruction* instr = NULL; | 864 LInstruction* instr = NULL; |
| 864 if (current->CanReplaceWithDummyUses()) { | 865 if (current->CanReplaceWithDummyUses()) { |
| 865 HValue* first_operand = current->OperandCount() == 0 | 866 if (current->OperandCount() == 0) { |
| 866 ? graph()->GetConstant1() | 867 instr = DefineAsRegister(new(zone()) LDummy()); |
| 867 : current->OperandAt(0); | 868 } else { |
| 868 instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); | 869 instr = DefineAsRegister(new(zone()) |
| 870 LDummyUse(UseAny(current->OperandAt(0)))); |
| 871 } |
| 869 for (int i = 1; i < current->OperandCount(); ++i) { | 872 for (int i = 1; i < current->OperandCount(); ++i) { |
| 870 LInstruction* dummy = | 873 LInstruction* dummy = |
| 871 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 874 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 872 dummy->set_hydrogen_value(current); | 875 dummy->set_hydrogen_value(current); |
| 873 chunk_->AddInstruction(dummy, current_block_); | 876 chunk_->AddInstruction(dummy, current_block_); |
| 874 } | 877 } |
| 875 } else { | 878 } else { |
| 876 instr = current->CompileToLithium(this); | 879 instr = current->CompileToLithium(this); |
| 877 } | 880 } |
| 878 | 881 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 | 1057 |
| 1055 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1058 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 1056 info()->MarkAsRequiresFrame(); | 1059 info()->MarkAsRequiresFrame(); |
| 1057 return DefineAsRegister(new(zone()) LArgumentsElements); | 1060 return DefineAsRegister(new(zone()) LArgumentsElements); |
| 1058 } | 1061 } |
| 1059 | 1062 |
| 1060 | 1063 |
| 1061 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1064 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
| 1062 LOperand* left = UseFixed(instr->left(), rax); | 1065 LOperand* left = UseFixed(instr->left(), rax); |
| 1063 LOperand* right = UseFixed(instr->right(), rdx); | 1066 LOperand* right = UseFixed(instr->right(), rdx); |
| 1064 LInstanceOf* result = new(zone()) LInstanceOf(left, right); | 1067 LOperand* context = UseFixed(instr->context(), rsi); |
| 1068 LInstanceOf* result = new(zone()) LInstanceOf(context, left, right); |
| 1065 return MarkAsCall(DefineFixed(result, rax), instr); | 1069 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1066 } | 1070 } |
| 1067 | 1071 |
| 1068 | 1072 |
| 1069 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1073 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1070 HInstanceOfKnownGlobal* instr) { | 1074 HInstanceOfKnownGlobal* instr) { |
| 1071 LInstanceOfKnownGlobal* result = | 1075 LInstanceOfKnownGlobal* result = |
| 1072 new(zone()) LInstanceOfKnownGlobal(UseFixed(instr->left(), rax), | 1076 new(zone()) LInstanceOfKnownGlobal(UseFixed(instr->context(), rsi), |
| 1077 UseFixed(instr->left(), rax), |
| 1073 FixedTemp(rdi)); | 1078 FixedTemp(rdi)); |
| 1074 return MarkAsCall(DefineFixed(result, rax), instr); | 1079 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1075 } | 1080 } |
| 1076 | 1081 |
| 1077 | 1082 |
| 1078 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 1083 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
| 1079 LOperand* receiver = UseRegister(instr->receiver()); | 1084 LOperand* receiver = UseRegister(instr->receiver()); |
| 1080 LOperand* function = UseRegisterAtStart(instr->function()); | 1085 LOperand* function = UseRegisterAtStart(instr->function()); |
| 1081 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); | 1086 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); |
| 1082 return AssignEnvironment(DefineSameAsFirst(result)); | 1087 return AssignEnvironment(DefineSameAsFirst(result)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 | 1125 |
| 1121 | 1126 |
| 1122 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { | 1127 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { |
| 1123 return instr->HasNoUses() | 1128 return instr->HasNoUses() |
| 1124 ? NULL | 1129 ? NULL |
| 1125 : DefineAsRegister(new(zone()) LThisFunction); | 1130 : DefineAsRegister(new(zone()) LThisFunction); |
| 1126 } | 1131 } |
| 1127 | 1132 |
| 1128 | 1133 |
| 1129 LInstruction* LChunkBuilder::DoContext(HContext* instr) { | 1134 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1130 // If there is a non-return use, the context must be allocated in a register. | 1135 if (instr->HasNoUses()) return NULL; |
| 1131 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 1136 |
| 1132 if (!it.value()->IsReturn()) { | 1137 if (info()->IsStub()) { |
| 1133 return DefineAsRegister(new(zone()) LContext); | 1138 return DefineFixed(new(zone()) LContext, rsi); |
| 1134 } | |
| 1135 } | 1139 } |
| 1136 | 1140 |
| 1137 return NULL; | 1141 return DefineAsRegister(new(zone()) LContext); |
| 1138 } | 1142 } |
| 1139 | 1143 |
| 1140 | 1144 |
| 1141 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | 1145 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1142 LOperand* context = UseRegisterAtStart(instr->value()); | 1146 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1143 return DefineAsRegister(new(zone()) LOuterContext(context)); | 1147 return DefineAsRegister(new(zone()) LOuterContext(context)); |
| 1144 } | 1148 } |
| 1145 | 1149 |
| 1146 | 1150 |
| 1147 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { | 1151 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { |
| 1148 return MarkAsCall(new(zone()) LDeclareGlobals, instr); | 1152 LOperand* context = UseFixed(instr->context(), rsi); |
| 1153 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1149 } | 1154 } |
| 1150 | 1155 |
| 1151 | 1156 |
| 1152 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1157 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 1153 return DefineAsRegister(new(zone()) LGlobalObject); | 1158 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1159 return DefineAsRegister(new(zone()) LGlobalObject(context)); |
| 1154 } | 1160 } |
| 1155 | 1161 |
| 1156 | 1162 |
| 1157 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1163 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1158 LOperand* global_object = UseRegisterAtStart(instr->value()); | 1164 LOperand* global_object = UseRegisterAtStart(instr->value()); |
| 1159 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | 1165 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); |
| 1160 } | 1166 } |
| 1161 | 1167 |
| 1162 | 1168 |
| 1163 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1169 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1164 HCallConstantFunction* instr) { | 1170 HCallConstantFunction* instr) { |
| 1165 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr); | 1171 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr); |
| 1166 } | 1172 } |
| 1167 | 1173 |
| 1168 | 1174 |
| 1169 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { | 1175 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
| 1176 LOperand* context = UseFixed(instr->context(), rsi); |
| 1170 LOperand* function = UseFixed(instr->function(), rdi); | 1177 LOperand* function = UseFixed(instr->function(), rdi); |
| 1171 LInvokeFunction* result = new(zone()) LInvokeFunction(function); | 1178 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); |
| 1172 return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1179 return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
| 1173 } | 1180 } |
| 1174 | 1181 |
| 1175 | 1182 |
| 1176 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1183 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1177 switch (instr->op()) { | 1184 switch (instr->op()) { |
| 1178 case kMathFloor: return DoMathFloor(instr); | 1185 case kMathFloor: return DoMathFloor(instr); |
| 1179 case kMathRound: return DoMathRound(instr); | 1186 case kMathRound: return DoMathRound(instr); |
| 1180 case kMathAbs: return DoMathAbs(instr); | 1187 case kMathAbs: return DoMathAbs(instr); |
| 1181 case kMathLog: return DoMathLog(instr); | 1188 case kMathLog: return DoMathLog(instr); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1200 | 1207 |
| 1201 | 1208 |
| 1202 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { | 1209 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { |
| 1203 LOperand* input = UseRegisterAtStart(instr->value()); | 1210 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1204 LMathRound* result = new(zone()) LMathRound(input); | 1211 LMathRound* result = new(zone()) LMathRound(input); |
| 1205 return AssignEnvironment(DefineAsRegister(result)); | 1212 return AssignEnvironment(DefineAsRegister(result)); |
| 1206 } | 1213 } |
| 1207 | 1214 |
| 1208 | 1215 |
| 1209 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { | 1216 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { |
| 1217 LOperand* context = UseAny(instr->context()); |
| 1210 LOperand* input = UseRegisterAtStart(instr->value()); | 1218 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1211 LMathAbs* result = new(zone()) LMathAbs(input); | 1219 LMathAbs* result = new(zone()) LMathAbs(context, input); |
| 1212 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1220 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1213 } | 1221 } |
| 1214 | 1222 |
| 1215 | 1223 |
| 1216 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1224 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
| 1217 ASSERT(instr->representation().IsDouble()); | 1225 ASSERT(instr->representation().IsDouble()); |
| 1218 ASSERT(instr->value()->representation().IsDouble()); | 1226 ASSERT(instr->value()->representation().IsDouble()); |
| 1219 LOperand* input = UseRegisterAtStart(instr->value()); | 1227 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1220 LMathLog* result = new(zone()) LMathLog(input); | 1228 LMathLog* result = new(zone()) LMathLog(input); |
| 1221 return DefineSameAsFirst(result); | 1229 return DefineSameAsFirst(result); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1263 | 1271 |
| 1264 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { | 1272 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { |
| 1265 LOperand* input = UseRegisterAtStart(instr->value()); | 1273 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1266 LMathPowHalf* result = new(zone()) LMathPowHalf(input); | 1274 LMathPowHalf* result = new(zone()) LMathPowHalf(input); |
| 1267 return DefineSameAsFirst(result); | 1275 return DefineSameAsFirst(result); |
| 1268 } | 1276 } |
| 1269 | 1277 |
| 1270 | 1278 |
| 1271 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1279 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1272 ASSERT(instr->key()->representation().IsTagged()); | 1280 ASSERT(instr->key()->representation().IsTagged()); |
| 1281 LOperand* context = UseFixed(instr->context(), rsi); |
| 1273 LOperand* key = UseFixed(instr->key(), rcx); | 1282 LOperand* key = UseFixed(instr->key(), rcx); |
| 1274 LCallKeyed* result = new(zone()) LCallKeyed(key); | 1283 LCallKeyed* result = new(zone()) LCallKeyed(context, key); |
| 1275 return MarkAsCall(DefineFixed(result, rax), instr); | 1284 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1276 } | 1285 } |
| 1277 | 1286 |
| 1278 | 1287 |
| 1279 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1288 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1280 return MarkAsCall(DefineFixed(new(zone()) LCallNamed, rax), instr); | 1289 LOperand* context = UseFixed(instr->context(), rsi); |
| 1290 LCallNamed* result = new(zone()) LCallNamed(context); |
| 1291 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1281 } | 1292 } |
| 1282 | 1293 |
| 1283 | 1294 |
| 1284 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1295 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| 1285 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, rax), instr); | 1296 LOperand* context = UseFixed(instr->context(), rsi); |
| 1297 LCallGlobal* result = new(zone()) LCallGlobal(context); |
| 1298 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1286 } | 1299 } |
| 1287 | 1300 |
| 1288 | 1301 |
| 1289 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1302 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1290 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr); | 1303 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr); |
| 1291 } | 1304 } |
| 1292 | 1305 |
| 1293 | 1306 |
| 1294 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1307 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1308 LOperand* context = UseFixed(instr->context(), rsi); |
| 1295 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1309 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
| 1296 LCallNew* result = new(zone()) LCallNew(constructor); | 1310 LCallNew* result = new(zone()) LCallNew(context, constructor); |
| 1297 return MarkAsCall(DefineFixed(result, rax), instr); | 1311 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1298 } | 1312 } |
| 1299 | 1313 |
| 1300 | 1314 |
| 1301 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { | 1315 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
| 1316 LOperand* context = UseFixed(instr->context(), rsi); |
| 1302 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1317 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
| 1303 LCallNewArray* result = new(zone()) LCallNewArray(constructor); | 1318 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
| 1304 return MarkAsCall(DefineFixed(result, rax), instr); | 1319 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1305 } | 1320 } |
| 1306 | 1321 |
| 1307 | 1322 |
| 1308 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1323 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1324 LOperand* context = UseFixed(instr->context(), rsi); |
| 1309 LOperand* function = UseFixed(instr->function(), rdi); | 1325 LOperand* function = UseFixed(instr->function(), rdi); |
| 1310 LCallFunction* result = new(zone()) LCallFunction(function); | 1326 LCallFunction* result = new(zone()) LCallFunction(context, function); |
| 1311 return MarkAsCall(DefineFixed(result, rax), instr); | 1327 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1312 } | 1328 } |
| 1313 | 1329 |
| 1314 | 1330 |
| 1315 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1331 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1316 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr); | 1332 LOperand* context = UseFixed(instr->context(), rsi); |
| 1333 LCallRuntime* result = new(zone()) LCallRuntime(context); |
| 1334 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1317 } | 1335 } |
| 1318 | 1336 |
| 1319 | 1337 |
| 1320 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1338 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
| 1321 return DoShift(Token::ROR, instr); | 1339 return DoShift(Token::ROR, instr); |
| 1322 } | 1340 } |
| 1323 | 1341 |
| 1324 | 1342 |
| 1325 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1343 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| 1326 return DoShift(Token::SHR, instr); | 1344 return DoShift(Token::SHR, instr); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 LOperand* scratch3 = TempRegister(); | 1613 LOperand* scratch3 = TempRegister(); |
| 1596 LRandom* result = new(zone()) LRandom( | 1614 LRandom* result = new(zone()) LRandom( |
| 1597 global_object, scratch, scratch2, scratch3); | 1615 global_object, scratch, scratch2, scratch3); |
| 1598 return DefineFixedDouble(result, xmm1); | 1616 return DefineFixedDouble(result, xmm1); |
| 1599 } | 1617 } |
| 1600 | 1618 |
| 1601 | 1619 |
| 1602 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1620 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1603 ASSERT(instr->left()->representation().IsTagged()); | 1621 ASSERT(instr->left()->representation().IsTagged()); |
| 1604 ASSERT(instr->right()->representation().IsTagged()); | 1622 ASSERT(instr->right()->representation().IsTagged()); |
| 1623 LOperand* context = UseFixed(instr->context(), rsi); |
| 1605 LOperand* left = UseFixed(instr->left(), rdx); | 1624 LOperand* left = UseFixed(instr->left(), rdx); |
| 1606 LOperand* right = UseFixed(instr->right(), rax); | 1625 LOperand* right = UseFixed(instr->right(), rax); |
| 1607 LCmpT* result = new(zone()) LCmpT(left, right); | 1626 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1608 return MarkAsCall(DefineFixed(result, rax), instr); | 1627 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1609 } | 1628 } |
| 1610 | 1629 |
| 1611 | 1630 |
| 1612 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1631 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1613 HCompareNumericAndBranch* instr) { | 1632 HCompareNumericAndBranch* instr) { |
| 1614 Representation r = instr->representation(); | 1633 Representation r = instr->representation(); |
| 1615 if (r.IsSmiOrInteger32()) { | 1634 if (r.IsSmiOrInteger32()) { |
| 1616 ASSERT(instr->left()->representation().Equals(r)); | 1635 ASSERT(instr->left()->representation().Equals(r)); |
| 1617 ASSERT(instr->right()->representation().Equals(r)); | 1636 ASSERT(instr->right()->representation().Equals(r)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1646 } | 1665 } |
| 1647 | 1666 |
| 1648 | 1667 |
| 1649 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1668 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
| 1650 HCompareHoleAndBranch* instr) { | 1669 HCompareHoleAndBranch* instr) { |
| 1651 LOperand* value = UseRegisterAtStart(instr->value()); | 1670 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1652 return new(zone()) LCmpHoleAndBranch(value); | 1671 return new(zone()) LCmpHoleAndBranch(value); |
| 1653 } | 1672 } |
| 1654 | 1673 |
| 1655 | 1674 |
| 1675 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1676 HCompareMinusZeroAndBranch* instr) { |
| 1677 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 1678 if (goto_instr != NULL) return goto_instr; |
| 1679 LOperand* value = UseRegister(instr->value()); |
| 1680 return new(zone()) LCompareMinusZeroAndBranch(value); |
| 1681 } |
| 1682 |
| 1683 |
| 1656 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1684 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1657 ASSERT(instr->value()->representation().IsTagged()); | 1685 ASSERT(instr->value()->representation().IsTagged()); |
| 1658 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); | 1686 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); |
| 1659 } | 1687 } |
| 1660 | 1688 |
| 1661 | 1689 |
| 1662 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1690 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
| 1663 ASSERT(instr->value()->representation().IsTagged()); | 1691 ASSERT(instr->value()->representation().IsTagged()); |
| 1664 LOperand* value = UseRegisterAtStart(instr->value()); | 1692 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1665 LOperand* temp = TempRegister(); | 1693 LOperand* temp = TempRegister(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1680 LOperand* temp = TempRegister(); | 1708 LOperand* temp = TempRegister(); |
| 1681 return new(zone()) LIsUndetectableAndBranch(value, temp); | 1709 return new(zone()) LIsUndetectableAndBranch(value, temp); |
| 1682 } | 1710 } |
| 1683 | 1711 |
| 1684 | 1712 |
| 1685 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1713 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 1686 HStringCompareAndBranch* instr) { | 1714 HStringCompareAndBranch* instr) { |
| 1687 | 1715 |
| 1688 ASSERT(instr->left()->representation().IsTagged()); | 1716 ASSERT(instr->left()->representation().IsTagged()); |
| 1689 ASSERT(instr->right()->representation().IsTagged()); | 1717 ASSERT(instr->right()->representation().IsTagged()); |
| 1718 LOperand* context = UseFixed(instr->context(), rsi); |
| 1690 LOperand* left = UseFixed(instr->left(), rdx); | 1719 LOperand* left = UseFixed(instr->left(), rdx); |
| 1691 LOperand* right = UseFixed(instr->right(), rax); | 1720 LOperand* right = UseFixed(instr->right(), rax); |
| 1692 LStringCompareAndBranch* result = | 1721 LStringCompareAndBranch* result = |
| 1693 new(zone()) LStringCompareAndBranch(left, right); | 1722 new(zone()) LStringCompareAndBranch(context, left, right); |
| 1694 | 1723 |
| 1695 return MarkAsCall(result, instr); | 1724 return MarkAsCall(result, instr); |
| 1696 } | 1725 } |
| 1697 | 1726 |
| 1698 | 1727 |
| 1699 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1728 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1700 HHasInstanceTypeAndBranch* instr) { | 1729 HHasInstanceTypeAndBranch* instr) { |
| 1701 ASSERT(instr->value()->representation().IsTagged()); | 1730 ASSERT(instr->value()->representation().IsTagged()); |
| 1702 LOperand* value = UseRegisterAtStart(instr->value()); | 1731 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1703 return new(zone()) LHasInstanceTypeAndBranch(value); | 1732 return new(zone()) LHasInstanceTypeAndBranch(value); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 } | 1778 } |
| 1750 | 1779 |
| 1751 | 1780 |
| 1752 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { | 1781 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { |
| 1753 LOperand* object = UseFixed(instr->value(), rax); | 1782 LOperand* object = UseFixed(instr->value(), rax); |
| 1754 LDateField* result = new(zone()) LDateField(object, instr->index()); | 1783 LDateField* result = new(zone()) LDateField(object, instr->index()); |
| 1755 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1784 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1756 } | 1785 } |
| 1757 | 1786 |
| 1758 | 1787 |
| 1788 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { |
| 1789 LOperand* string = UseRegisterAtStart(instr->string()); |
| 1790 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); |
| 1791 return DefineAsRegister(new(zone()) LSeqStringGetChar(string, index)); |
| 1792 } |
| 1793 |
| 1794 |
| 1759 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { | 1795 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { |
| 1760 LOperand* string = UseRegister(instr->string()); | 1796 LOperand* string = UseRegisterAtStart(instr->string()); |
| 1761 LOperand* index = UseRegister(instr->index()); | 1797 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); |
| 1762 ASSERT(rcx.is_byte_register()); | 1798 LOperand* value = UseRegisterOrConstantAtStart(instr->value()); |
| 1763 LOperand* value = UseFixed(instr->value(), rcx); | 1799 return new(zone()) LSeqStringSetChar(string, index, value); |
| 1764 LSeqStringSetChar* result = | |
| 1765 new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); | |
| 1766 return DefineSameAsFirst(result); | |
| 1767 } | 1800 } |
| 1768 | 1801 |
| 1769 | 1802 |
| 1770 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1803 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1771 LOperand* value = UseRegisterOrConstantAtStart(instr->index()); | 1804 LOperand* value = UseRegisterOrConstantAtStart(instr->index()); |
| 1772 LOperand* length = Use(instr->length()); | 1805 LOperand* length = Use(instr->length()); |
| 1773 return AssignEnvironment(new(zone()) LBoundsCheck(value, length)); | 1806 return AssignEnvironment(new(zone()) LBoundsCheck(value, length)); |
| 1774 } | 1807 } |
| 1775 | 1808 |
| 1776 | 1809 |
| 1777 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( | 1810 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( |
| 1778 HBoundsCheckBaseIndexInformation* instr) { | 1811 HBoundsCheckBaseIndexInformation* instr) { |
| 1779 UNREACHABLE(); | 1812 UNREACHABLE(); |
| 1780 return NULL; | 1813 return NULL; |
| 1781 } | 1814 } |
| 1782 | 1815 |
| 1783 | 1816 |
| 1784 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1817 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1785 // The control instruction marking the end of a block that completed | 1818 // The control instruction marking the end of a block that completed |
| 1786 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1819 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1787 return NULL; | 1820 return NULL; |
| 1788 } | 1821 } |
| 1789 | 1822 |
| 1790 | 1823 |
| 1791 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1824 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1825 LOperand* context = UseFixed(instr->context(), rsi); |
| 1792 LOperand* value = UseFixed(instr->value(), rax); | 1826 LOperand* value = UseFixed(instr->value(), rax); |
| 1793 return MarkAsCall(new(zone()) LThrow(value), instr); | 1827 return MarkAsCall(new(zone()) LThrow(context, value), instr); |
| 1794 } | 1828 } |
| 1795 | 1829 |
| 1796 | 1830 |
| 1797 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { | 1831 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { |
| 1798 return NULL; | 1832 return NULL; |
| 1799 } | 1833 } |
| 1800 | 1834 |
| 1801 | 1835 |
| 1802 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { | 1836 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { |
| 1803 // All HForceRepresentation instructions should be eliminated in the | 1837 // All HForceRepresentation instructions should be eliminated in the |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1910 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1877 } else if (val->HasRange() && val->range()->IsInSmiRange()) { | 1911 } else if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1878 return DefineSameAsFirst(new(zone()) LSmiTag(value)); | 1912 return DefineSameAsFirst(new(zone()) LSmiTag(value)); |
| 1879 } else { | 1913 } else { |
| 1880 LNumberTagI* result = new(zone()) LNumberTagI(value); | 1914 LNumberTagI* result = new(zone()) LNumberTagI(value); |
| 1881 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1915 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1882 } | 1916 } |
| 1883 } else if (to.IsSmi()) { | 1917 } else if (to.IsSmi()) { |
| 1884 HValue* val = instr->value(); | 1918 HValue* val = instr->value(); |
| 1885 LOperand* value = UseRegister(val); | 1919 LOperand* value = UseRegister(val); |
| 1886 LInstruction* result = | 1920 LInstruction* result = NULL; |
| 1887 DefineAsRegister(new(zone()) LInteger32ToSmi(value)); | 1921 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1888 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1922 result = DefineAsRegister(new(zone()) LUint32ToSmi(value)); |
| 1889 return result; | 1923 if (val->HasRange() && val->range()->IsInSmiRange() && |
| 1924 val->range()->upper() != kMaxInt) { |
| 1925 return result; |
| 1926 } |
| 1927 } else { |
| 1928 result = DefineAsRegister(new(zone()) LInteger32ToSmi(value)); |
| 1929 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1930 return result; |
| 1931 } |
| 1890 } | 1932 } |
| 1891 return AssignEnvironment(result); | 1933 return AssignEnvironment(result); |
| 1892 } else { | 1934 } else { |
| 1893 if (instr->value()->CheckFlag(HInstruction::kUint32)) { | 1935 if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
| 1894 LOperand* temp = FixedTemp(xmm1); | 1936 LOperand* temp = FixedTemp(xmm1); |
| 1895 return DefineAsRegister( | 1937 return DefineAsRegister( |
| 1896 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp)); | 1938 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp)); |
| 1897 } else { | 1939 } else { |
| 1898 ASSERT(to.IsDouble()); | 1940 ASSERT(to.IsDouble()); |
| 1899 LOperand* value = Use(instr->value()); | 1941 LOperand* value = Use(instr->value()); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 // Register allocator doesn't (yet) support allocation of double | 2001 // Register allocator doesn't (yet) support allocation of double |
| 1960 // temps. Reserve xmm1 explicitly. | 2002 // temps. Reserve xmm1 explicitly. |
| 1961 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, | 2003 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, |
| 1962 FixedTemp(xmm1)); | 2004 FixedTemp(xmm1)); |
| 1963 return AssignEnvironment(DefineSameAsFirst(result)); | 2005 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1964 } | 2006 } |
| 1965 } | 2007 } |
| 1966 | 2008 |
| 1967 | 2009 |
| 1968 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 2010 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 2011 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), rsi) : NULL; |
| 1969 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); | 2012 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); |
| 1970 return new(zone()) LReturn(UseFixed(instr->value(), rax), | 2013 return new(zone()) LReturn( |
| 1971 parameter_count); | 2014 UseFixed(instr->value(), rax), context, parameter_count); |
| 1972 } | 2015 } |
| 1973 | 2016 |
| 1974 | 2017 |
| 1975 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 2018 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1976 Representation r = instr->representation(); | 2019 Representation r = instr->representation(); |
| 1977 if (r.IsSmi()) { | 2020 if (r.IsSmi()) { |
| 1978 return DefineAsRegister(new(zone()) LConstantS); | 2021 return DefineAsRegister(new(zone()) LConstantS); |
| 1979 } else if (r.IsInteger32()) { | 2022 } else if (r.IsInteger32()) { |
| 1980 return DefineAsRegister(new(zone()) LConstantI); | 2023 return DefineAsRegister(new(zone()) LConstantI); |
| 1981 } else if (r.IsDouble()) { | 2024 } else if (r.IsDouble()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1994 | 2037 |
| 1995 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { | 2038 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { |
| 1996 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; | 2039 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; |
| 1997 return instr->RequiresHoleCheck() | 2040 return instr->RequiresHoleCheck() |
| 1998 ? AssignEnvironment(DefineAsRegister(result)) | 2041 ? AssignEnvironment(DefineAsRegister(result)) |
| 1999 : DefineAsRegister(result); | 2042 : DefineAsRegister(result); |
| 2000 } | 2043 } |
| 2001 | 2044 |
| 2002 | 2045 |
| 2003 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { | 2046 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { |
| 2047 LOperand* context = UseFixed(instr->context(), rsi); |
| 2004 LOperand* global_object = UseFixed(instr->global_object(), rax); | 2048 LOperand* global_object = UseFixed(instr->global_object(), rax); |
| 2005 LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); | 2049 LLoadGlobalGeneric* result = |
| 2050 new(zone()) LLoadGlobalGeneric(context, global_object); |
| 2006 return MarkAsCall(DefineFixed(result, rax), instr); | 2051 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2007 } | 2052 } |
| 2008 | 2053 |
| 2009 | 2054 |
| 2010 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { | 2055 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { |
| 2011 LOperand* value = UseRegister(instr->value()); | 2056 LOperand* value = UseRegister(instr->value()); |
| 2012 // Use a temp to avoid reloading the cell value address in the case where | 2057 // Use a temp to avoid reloading the cell value address in the case where |
| 2013 // we perform a hole check. | 2058 // we perform a hole check. |
| 2014 return instr->RequiresHoleCheck() | 2059 return instr->RequiresHoleCheck() |
| 2015 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) | 2060 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) |
| 2016 : new(zone()) LStoreGlobalCell(value, NULL); | 2061 : new(zone()) LStoreGlobalCell(value, NULL); |
| 2017 } | 2062 } |
| 2018 | 2063 |
| 2019 | 2064 |
| 2020 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { | 2065 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { |
| 2066 LOperand* context = UseFixed(instr->context(), rsi); |
| 2021 LOperand* global_object = UseFixed(instr->global_object(), rdx); | 2067 LOperand* global_object = UseFixed(instr->global_object(), rdx); |
| 2022 LOperand* value = UseFixed(instr->value(), rax); | 2068 LOperand* value = UseFixed(instr->value(), rax); |
| 2023 LStoreGlobalGeneric* result = new(zone()) LStoreGlobalGeneric(global_object, | 2069 LStoreGlobalGeneric* result = |
| 2024 value); | 2070 new(zone()) LStoreGlobalGeneric(context, global_object, value); |
| 2025 return MarkAsCall(result, instr); | 2071 return MarkAsCall(result, instr); |
| 2026 } | 2072 } |
| 2027 | 2073 |
| 2028 | 2074 |
| 2029 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 2075 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 2030 LOperand* context = UseRegisterAtStart(instr->value()); | 2076 LOperand* context = UseRegisterAtStart(instr->value()); |
| 2031 LInstruction* result = | 2077 LInstruction* result = |
| 2032 DefineAsRegister(new(zone()) LLoadContextSlot(context)); | 2078 DefineAsRegister(new(zone()) LLoadContextSlot(context)); |
| 2033 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; | 2079 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
| 2034 } | 2080 } |
| 2035 | 2081 |
| 2036 | 2082 |
| 2037 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { | 2083 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
| 2038 LOperand* context; | 2084 LOperand* context; |
| 2039 LOperand* value; | 2085 LOperand* value; |
| 2040 LOperand* temp; | 2086 LOperand* temp; |
| 2087 context = UseRegister(instr->context()); |
| 2041 if (instr->NeedsWriteBarrier()) { | 2088 if (instr->NeedsWriteBarrier()) { |
| 2042 context = UseTempRegister(instr->context()); | |
| 2043 value = UseTempRegister(instr->value()); | 2089 value = UseTempRegister(instr->value()); |
| 2044 temp = TempRegister(); | 2090 temp = TempRegister(); |
| 2045 } else { | 2091 } else { |
| 2046 context = UseRegister(instr->context()); | |
| 2047 value = UseRegister(instr->value()); | 2092 value = UseRegister(instr->value()); |
| 2048 temp = NULL; | 2093 temp = NULL; |
| 2049 } | 2094 } |
| 2050 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); | 2095 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); |
| 2051 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; | 2096 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
| 2052 } | 2097 } |
| 2053 | 2098 |
| 2054 | 2099 |
| 2055 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 2100 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 2056 // Use the special mov rax, moffs64 encoding for external | 2101 // Use the special mov rax, moffs64 encoding for external |
| 2057 // memory accesses with 64-bit word-sized values. | 2102 // memory accesses with 64-bit word-sized values. |
| 2058 if (instr->access().IsExternalMemory() && | 2103 if (instr->access().IsExternalMemory() && |
| 2059 instr->access().offset() == 0 && | 2104 instr->access().offset() == 0 && |
| 2060 (instr->access().representation().IsSmi() || | 2105 (instr->access().representation().IsSmi() || |
| 2061 instr->access().representation().IsTagged() || | 2106 instr->access().representation().IsTagged() || |
| 2062 instr->access().representation().IsHeapObject() || | 2107 instr->access().representation().IsHeapObject() || |
| 2063 instr->access().representation().IsExternal())) { | 2108 instr->access().representation().IsExternal())) { |
| 2064 LOperand* obj = UseRegisterOrConstantAtStart(instr->object()); | 2109 LOperand* obj = UseRegisterOrConstantAtStart(instr->object()); |
| 2065 return DefineFixed(new(zone()) LLoadNamedField(obj), rax); | 2110 return DefineFixed(new(zone()) LLoadNamedField(obj), rax); |
| 2066 } | 2111 } |
| 2067 LOperand* obj = UseRegisterAtStart(instr->object()); | 2112 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 2068 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); | 2113 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); |
| 2069 } | 2114 } |
| 2070 | 2115 |
| 2071 | 2116 |
| 2072 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 2117 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 2118 LOperand* context = UseFixed(instr->context(), rsi); |
| 2073 LOperand* object = UseFixed(instr->object(), rax); | 2119 LOperand* object = UseFixed(instr->object(), rax); |
| 2074 LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(object); | 2120 LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object); |
| 2075 return MarkAsCall(DefineFixed(result, rax), instr); | 2121 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2076 } | 2122 } |
| 2077 | 2123 |
| 2078 | 2124 |
| 2079 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 2125 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 2080 HLoadFunctionPrototype* instr) { | 2126 HLoadFunctionPrototype* instr) { |
| 2081 return AssignEnvironment(DefineAsRegister( | 2127 return AssignEnvironment(DefineAsRegister( |
| 2082 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); | 2128 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 2083 } | 2129 } |
| 2084 | 2130 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 DefineAsRegister(result); | 2165 DefineAsRegister(result); |
| 2120 bool can_deoptimize = instr->RequiresHoleCheck() || | 2166 bool can_deoptimize = instr->RequiresHoleCheck() || |
| 2121 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); | 2167 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); |
| 2122 // An unsigned int array load might overflow and cause a deopt, make sure it | 2168 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 2123 // has an environment. | 2169 // has an environment. |
| 2124 return can_deoptimize ? AssignEnvironment(result) : result; | 2170 return can_deoptimize ? AssignEnvironment(result) : result; |
| 2125 } | 2171 } |
| 2126 | 2172 |
| 2127 | 2173 |
| 2128 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 2174 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 2175 LOperand* context = UseFixed(instr->context(), rsi); |
| 2129 LOperand* object = UseFixed(instr->object(), rdx); | 2176 LOperand* object = UseFixed(instr->object(), rdx); |
| 2130 LOperand* key = UseFixed(instr->key(), rax); | 2177 LOperand* key = UseFixed(instr->key(), rax); |
| 2131 | 2178 |
| 2132 LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(object, key); | 2179 LLoadKeyedGeneric* result = |
| 2180 new(zone()) LLoadKeyedGeneric(context, object, key); |
| 2133 return MarkAsCall(DefineFixed(result, rax), instr); | 2181 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2134 } | 2182 } |
| 2135 | 2183 |
| 2136 | 2184 |
| 2137 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2185 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2138 ElementsKind elements_kind = instr->elements_kind(); | 2186 ElementsKind elements_kind = instr->elements_kind(); |
| 2139 | 2187 |
| 2140 if (!instr->is_external()) { | 2188 if (!instr->is_external()) { |
| 2141 ASSERT(instr->elements()->representation().IsTagged()); | 2189 ASSERT(instr->elements()->representation().IsTagged()); |
| 2142 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2190 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2176 elements_kind == EXTERNAL_FLOAT_ELEMENTS; | 2224 elements_kind == EXTERNAL_FLOAT_ELEMENTS; |
| 2177 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) | 2225 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) |
| 2178 : UseRegister(instr->value()); | 2226 : UseRegister(instr->value()); |
| 2179 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2227 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2180 LOperand* external_pointer = UseRegister(instr->elements()); | 2228 LOperand* external_pointer = UseRegister(instr->elements()); |
| 2181 return new(zone()) LStoreKeyed(external_pointer, key, val); | 2229 return new(zone()) LStoreKeyed(external_pointer, key, val); |
| 2182 } | 2230 } |
| 2183 | 2231 |
| 2184 | 2232 |
| 2185 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2233 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2234 LOperand* context = UseFixed(instr->context(), rsi); |
| 2186 LOperand* object = UseFixed(instr->object(), rdx); | 2235 LOperand* object = UseFixed(instr->object(), rdx); |
| 2187 LOperand* key = UseFixed(instr->key(), rcx); | 2236 LOperand* key = UseFixed(instr->key(), rcx); |
| 2188 LOperand* value = UseFixed(instr->value(), rax); | 2237 LOperand* value = UseFixed(instr->value(), rax); |
| 2189 | 2238 |
| 2190 ASSERT(instr->object()->representation().IsTagged()); | 2239 ASSERT(instr->object()->representation().IsTagged()); |
| 2191 ASSERT(instr->key()->representation().IsTagged()); | 2240 ASSERT(instr->key()->representation().IsTagged()); |
| 2192 ASSERT(instr->value()->representation().IsTagged()); | 2241 ASSERT(instr->value()->representation().IsTagged()); |
| 2193 | 2242 |
| 2194 LStoreKeyedGeneric* result = | 2243 LStoreKeyedGeneric* result = |
| 2195 new(zone()) LStoreKeyedGeneric(object, key, value); | 2244 new(zone()) LStoreKeyedGeneric(context, object, key, value); |
| 2196 return MarkAsCall(result, instr); | 2245 return MarkAsCall(result, instr); |
| 2197 } | 2246 } |
| 2198 | 2247 |
| 2199 | 2248 |
| 2200 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2249 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2201 HTransitionElementsKind* instr) { | 2250 HTransitionElementsKind* instr) { |
| 2202 LOperand* object = UseRegister(instr->object()); | 2251 LOperand* object = UseRegister(instr->object()); |
| 2203 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2252 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| 2204 LOperand* object = UseRegister(instr->object()); | 2253 LOperand* object = UseRegister(instr->object()); |
| 2205 LOperand* new_map_reg = TempRegister(); | 2254 LOperand* new_map_reg = TempRegister(); |
| 2206 LOperand* temp_reg = TempRegister(); | 2255 LOperand* temp_reg = TempRegister(); |
| 2207 LTransitionElementsKind* result = | 2256 LTransitionElementsKind* result = new(zone()) LTransitionElementsKind( |
| 2208 new(zone()) LTransitionElementsKind(object, new_map_reg, temp_reg); | 2257 object, NULL, new_map_reg, temp_reg); |
| 2209 return result; | 2258 return result; |
| 2210 } else { | 2259 } else { |
| 2260 LOperand* context = UseAny(instr->context()); |
| 2211 LTransitionElementsKind* result = | 2261 LTransitionElementsKind* result = |
| 2212 new(zone()) LTransitionElementsKind(object, NULL, NULL); | 2262 new(zone()) LTransitionElementsKind(object, context, NULL, NULL); |
| 2213 return AssignPointerMap(result); | 2263 return AssignPointerMap(result); |
| 2214 } | 2264 } |
| 2215 } | 2265 } |
| 2216 | 2266 |
| 2217 | 2267 |
| 2218 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2268 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
| 2219 HTrapAllocationMemento* instr) { | 2269 HTrapAllocationMemento* instr) { |
| 2220 LOperand* object = UseRegister(instr->object()); | 2270 LOperand* object = UseRegister(instr->object()); |
| 2221 LOperand* temp = TempRegister(); | 2271 LOperand* temp = TempRegister(); |
| 2222 LTrapAllocationMemento* result = | 2272 LTrapAllocationMemento* result = |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2279 instr->field_representation().IsHeapObject()) { | 2329 instr->field_representation().IsHeapObject()) { |
| 2280 if (!instr->value()->type().IsHeapObject()) { | 2330 if (!instr->value()->type().IsHeapObject()) { |
| 2281 return AssignEnvironment(result); | 2331 return AssignEnvironment(result); |
| 2282 } | 2332 } |
| 2283 } | 2333 } |
| 2284 return result; | 2334 return result; |
| 2285 } | 2335 } |
| 2286 | 2336 |
| 2287 | 2337 |
| 2288 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 2338 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 2339 LOperand* context = UseFixed(instr->context(), rsi); |
| 2289 LOperand* object = UseFixed(instr->object(), rdx); | 2340 LOperand* object = UseFixed(instr->object(), rdx); |
| 2290 LOperand* value = UseFixed(instr->value(), rax); | 2341 LOperand* value = UseFixed(instr->value(), rax); |
| 2291 | 2342 |
| 2292 LStoreNamedGeneric* result = new(zone()) LStoreNamedGeneric(object, value); | 2343 LStoreNamedGeneric* result = |
| 2344 new(zone()) LStoreNamedGeneric(context, object, value); |
| 2293 return MarkAsCall(result, instr); | 2345 return MarkAsCall(result, instr); |
| 2294 } | 2346 } |
| 2295 | 2347 |
| 2296 | 2348 |
| 2297 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2349 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2298 LOperand* left = UseOrConstantAtStart(instr->left()); | 2350 LOperand* context = UseFixed(instr->context(), rsi); |
| 2299 LOperand* right = UseOrConstantAtStart(instr->right()); | 2351 LOperand* left = FLAG_new_string_add |
| 2300 return MarkAsCall(DefineFixed(new(zone()) LStringAdd(left, right), rax), | 2352 ? UseFixed(instr->left(), rdx) |
| 2301 instr); | 2353 : UseOrConstantAtStart(instr->left()); |
| 2354 LOperand* right = FLAG_new_string_add |
| 2355 ? UseFixed(instr->right(), rax) |
| 2356 : UseOrConstantAtStart(instr->right()); |
| 2357 return MarkAsCall( |
| 2358 DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr); |
| 2302 } | 2359 } |
| 2303 | 2360 |
| 2304 | 2361 |
| 2305 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2362 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2306 LOperand* string = UseTempRegister(instr->string()); | 2363 LOperand* string = UseTempRegister(instr->string()); |
| 2307 LOperand* index = UseTempRegister(instr->index()); | 2364 LOperand* index = UseTempRegister(instr->index()); |
| 2308 LStringCharCodeAt* result = new(zone()) LStringCharCodeAt(string, index); | 2365 LOperand* context = UseAny(instr->context()); |
| 2366 LStringCharCodeAt* result = |
| 2367 new(zone()) LStringCharCodeAt(context, string, index); |
| 2309 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 2368 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 2310 } | 2369 } |
| 2311 | 2370 |
| 2312 | 2371 |
| 2313 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { | 2372 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 2314 LOperand* char_code = UseRegister(instr->value()); | 2373 LOperand* char_code = UseRegister(instr->value()); |
| 2315 LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code); | 2374 LOperand* context = UseAny(instr->context()); |
| 2375 LStringCharFromCode* result = |
| 2376 new(zone()) LStringCharFromCode(context, char_code); |
| 2316 return AssignPointerMap(DefineAsRegister(result)); | 2377 return AssignPointerMap(DefineAsRegister(result)); |
| 2317 } | 2378 } |
| 2318 | 2379 |
| 2319 | 2380 |
| 2320 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 2381 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
| 2321 info()->MarkAsDeferredCalling(); | 2382 info()->MarkAsDeferredCalling(); |
| 2383 LOperand* context = UseAny(instr->context()); |
| 2322 LOperand* size = instr->size()->IsConstant() | 2384 LOperand* size = instr->size()->IsConstant() |
| 2323 ? UseConstant(instr->size()) | 2385 ? UseConstant(instr->size()) |
| 2324 : UseTempRegister(instr->size()); | 2386 : UseTempRegister(instr->size()); |
| 2325 LOperand* temp = TempRegister(); | 2387 LOperand* temp = TempRegister(); |
| 2326 LAllocate* result = new(zone()) LAllocate(size, temp); | 2388 LAllocate* result = new(zone()) LAllocate(context, size, temp); |
| 2327 return AssignPointerMap(DefineAsRegister(result)); | 2389 return AssignPointerMap(DefineAsRegister(result)); |
| 2328 } | 2390 } |
| 2329 | 2391 |
| 2330 | 2392 |
| 2331 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 2393 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 2332 return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, rax), instr); | 2394 LOperand* context = UseFixed(instr->context(), rsi); |
| 2395 LRegExpLiteral* result = new(zone()) LRegExpLiteral(context); |
| 2396 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2333 } | 2397 } |
| 2334 | 2398 |
| 2335 | 2399 |
| 2336 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2400 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2337 return MarkAsCall(DefineFixed(new(zone()) LFunctionLiteral, rax), instr); | 2401 LOperand* context = UseFixed(instr->context(), rsi); |
| 2402 LFunctionLiteral* result = new(zone()) LFunctionLiteral(context); |
| 2403 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2338 } | 2404 } |
| 2339 | 2405 |
| 2340 | 2406 |
| 2341 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2407 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2342 ASSERT(argument_count_ == 0); | 2408 ASSERT(argument_count_ == 0); |
| 2343 allocator_->MarkAsOsrEntry(); | 2409 allocator_->MarkAsOsrEntry(); |
| 2344 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2410 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2345 return AssignEnvironment(new(zone()) LOsrEntry); | 2411 return AssignEnvironment(new(zone()) LOsrEntry); |
| 2346 } | 2412 } |
| 2347 | 2413 |
| 2348 | 2414 |
| 2349 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2415 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 2350 LParameter* result = new(zone()) LParameter; | 2416 LParameter* result = new(zone()) LParameter; |
| 2351 if (instr->kind() == HParameter::STACK_PARAMETER) { | 2417 if (instr->kind() == HParameter::STACK_PARAMETER) { |
| 2352 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2418 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 2353 return DefineAsSpilled(result, spill_index); | 2419 return DefineAsSpilled(result, spill_index); |
| 2354 } else { | 2420 } else { |
| 2355 ASSERT(info()->IsStub()); | 2421 ASSERT(info()->IsStub()); |
| 2356 CodeStubInterfaceDescriptor* descriptor = | 2422 CodeStubInterfaceDescriptor* descriptor = |
| 2357 info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); | 2423 info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); |
| 2358 int index = static_cast<int>(instr->index()); | 2424 int index = static_cast<int>(instr->index()); |
| 2359 Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); | 2425 Register reg = descriptor->GetParameterRegister(index); |
| 2360 return DefineFixed(result, reg); | 2426 return DefineFixed(result, reg); |
| 2361 } | 2427 } |
| 2362 } | 2428 } |
| 2363 | 2429 |
| 2364 | 2430 |
| 2365 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2431 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 2366 // Use an index that corresponds to the location in the unoptimized frame, | 2432 // Use an index that corresponds to the location in the unoptimized frame, |
| 2367 // which the optimized frame will subsume. | 2433 // which the optimized frame will subsume. |
| 2368 int env_index = instr->index(); | 2434 int env_index = instr->index(); |
| 2369 int spill_index = 0; | 2435 int spill_index = 0; |
| 2370 if (instr->environment()->is_parameter_index(env_index)) { | 2436 if (instr->environment()->is_parameter_index(env_index)) { |
| 2371 spill_index = chunk()->GetParameterStackSlot(env_index); | 2437 spill_index = chunk()->GetParameterStackSlot(env_index); |
| 2372 } else { | 2438 } else { |
| 2373 spill_index = env_index - instr->environment()->first_local_index(); | 2439 spill_index = env_index - instr->environment()->first_local_index(); |
| 2374 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { | 2440 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
| 2375 Abort(kTooManySpillSlotsNeededForOSR); | 2441 Abort(kTooManySpillSlotsNeededForOSR); |
| 2376 spill_index = 0; | 2442 spill_index = 0; |
| 2377 } | 2443 } |
| 2378 } | 2444 } |
| 2379 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2445 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
| 2380 } | 2446 } |
| 2381 | 2447 |
| 2382 | 2448 |
| 2383 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2449 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 2384 return MarkAsCall(DefineFixed(new(zone()) LCallStub, rax), instr); | 2450 LOperand* context = UseFixed(instr->context(), rsi); |
| 2451 LCallStub* result = new(zone()) LCallStub(context); |
| 2452 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2385 } | 2453 } |
| 2386 | 2454 |
| 2387 | 2455 |
| 2388 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2456 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 2389 // There are no real uses of the arguments object. | 2457 // There are no real uses of the arguments object. |
| 2390 // arguments.length and element access are supported directly on | 2458 // arguments.length and element access are supported directly on |
| 2391 // stack arguments, and any real arguments object use causes a bailout. | 2459 // stack arguments, and any real arguments object use causes a bailout. |
| 2392 // So this value is never used. | 2460 // So this value is never used. |
| 2393 return NULL; | 2461 return NULL; |
| 2394 } | 2462 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2419 | 2487 |
| 2420 | 2488 |
| 2421 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { | 2489 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { |
| 2422 LOperand* object = UseFixed(instr->value(), rax); | 2490 LOperand* object = UseFixed(instr->value(), rax); |
| 2423 LToFastProperties* result = new(zone()) LToFastProperties(object); | 2491 LToFastProperties* result = new(zone()) LToFastProperties(object); |
| 2424 return MarkAsCall(DefineFixed(result, rax), instr); | 2492 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2425 } | 2493 } |
| 2426 | 2494 |
| 2427 | 2495 |
| 2428 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2496 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 2429 LTypeof* result = new(zone()) LTypeof(UseAtStart(instr->value())); | 2497 LOperand* context = UseFixed(instr->context(), rsi); |
| 2498 LOperand* value = UseAtStart(instr->value()); |
| 2499 LTypeof* result = new(zone()) LTypeof(context, value); |
| 2430 return MarkAsCall(DefineFixed(result, rax), instr); | 2500 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2431 } | 2501 } |
| 2432 | 2502 |
| 2433 | 2503 |
| 2434 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2504 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
| 2435 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); | 2505 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); |
| 2436 } | 2506 } |
| 2437 | 2507 |
| 2438 | 2508 |
| 2439 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2509 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2459 return result; | 2529 return result; |
| 2460 } | 2530 } |
| 2461 | 2531 |
| 2462 return NULL; | 2532 return NULL; |
| 2463 } | 2533 } |
| 2464 | 2534 |
| 2465 | 2535 |
| 2466 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2536 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2467 info()->MarkAsDeferredCalling(); | 2537 info()->MarkAsDeferredCalling(); |
| 2468 if (instr->is_function_entry()) { | 2538 if (instr->is_function_entry()) { |
| 2469 return MarkAsCall(new(zone()) LStackCheck, instr); | 2539 LOperand* context = UseFixed(instr->context(), rsi); |
| 2540 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2470 } else { | 2541 } else { |
| 2471 ASSERT(instr->is_backwards_branch()); | 2542 ASSERT(instr->is_backwards_branch()); |
| 2472 return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); | 2543 LOperand* context = UseAny(instr->context()); |
| 2544 return AssignEnvironment( |
| 2545 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2473 } | 2546 } |
| 2474 } | 2547 } |
| 2475 | 2548 |
| 2476 | 2549 |
| 2477 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2550 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2478 HEnvironment* outer = current_block_->last_environment(); | 2551 HEnvironment* outer = current_block_->last_environment(); |
| 2479 HConstant* undefined = graph()->GetConstantUndefined(); | 2552 HConstant* undefined = graph()->GetConstantUndefined(); |
| 2480 HEnvironment* inner = outer->CopyForInlining(instr->closure(), | 2553 HEnvironment* inner = outer->CopyForInlining(instr->closure(), |
| 2481 instr->arguments_count(), | 2554 instr->arguments_count(), |
| 2482 instr->function(), | 2555 instr->function(), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2507 | 2580 |
| 2508 HEnvironment* outer = current_block_->last_environment()-> | 2581 HEnvironment* outer = current_block_->last_environment()-> |
| 2509 DiscardInlined(false); | 2582 DiscardInlined(false); |
| 2510 current_block_->UpdateEnvironment(outer); | 2583 current_block_->UpdateEnvironment(outer); |
| 2511 | 2584 |
| 2512 return pop; | 2585 return pop; |
| 2513 } | 2586 } |
| 2514 | 2587 |
| 2515 | 2588 |
| 2516 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { | 2589 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
| 2590 LOperand* context = UseFixed(instr->context(), rsi); |
| 2517 LOperand* object = UseFixed(instr->enumerable(), rax); | 2591 LOperand* object = UseFixed(instr->enumerable(), rax); |
| 2518 LForInPrepareMap* result = new(zone()) LForInPrepareMap(object); | 2592 LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object); |
| 2519 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); | 2593 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 2520 } | 2594 } |
| 2521 | 2595 |
| 2522 | 2596 |
| 2523 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { | 2597 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { |
| 2524 LOperand* map = UseRegister(instr->map()); | 2598 LOperand* map = UseRegister(instr->map()); |
| 2525 return AssignEnvironment(DefineAsRegister( | 2599 return AssignEnvironment(DefineAsRegister( |
| 2526 new(zone()) LForInCacheArray(map))); | 2600 new(zone()) LForInCacheArray(map))); |
| 2527 } | 2601 } |
| 2528 | 2602 |
| 2529 | 2603 |
| 2530 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { | 2604 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { |
| 2531 LOperand* value = UseRegisterAtStart(instr->value()); | 2605 LOperand* value = UseRegisterAtStart(instr->value()); |
| 2532 LOperand* map = UseRegisterAtStart(instr->map()); | 2606 LOperand* map = UseRegisterAtStart(instr->map()); |
| 2533 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); | 2607 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); |
| 2534 } | 2608 } |
| 2535 | 2609 |
| 2536 | 2610 |
| 2537 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2611 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2538 LOperand* object = UseRegister(instr->object()); | 2612 LOperand* object = UseRegister(instr->object()); |
| 2539 LOperand* index = UseTempRegister(instr->index()); | 2613 LOperand* index = UseTempRegister(instr->index()); |
| 2540 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2614 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2541 } | 2615 } |
| 2542 | 2616 |
| 2543 | 2617 |
| 2544 } } // namespace v8::internal | 2618 } } // namespace v8::internal |
| 2545 | 2619 |
| 2546 #endif // V8_TARGET_ARCH_X64 | 2620 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |