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 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 for (int i = 1; i < current->OperandCount(); ++i) { | 870 for (int i = 1; i < current->OperandCount(); ++i) { |
871 LInstruction* dummy = | 871 LInstruction* dummy = |
872 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 872 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
873 dummy->set_hydrogen_value(current); | 873 dummy->set_hydrogen_value(current); |
874 chunk_->AddInstruction(dummy, current_block_); | 874 chunk_->AddInstruction(dummy, current_block_); |
875 } | 875 } |
876 } else { | 876 } else { |
877 instr = current->CompileToLithium(this); | 877 instr = current->CompileToLithium(this); |
878 } | 878 } |
879 | 879 |
| 880 argument_count_ += current->argument_delta(); |
| 881 ASSERT(argument_count_ >= 0); |
| 882 |
880 if (instr != NULL) { | 883 if (instr != NULL) { |
881 // Associate the hydrogen instruction first, since we may need it for | 884 // Associate the hydrogen instruction first, since we may need it for |
882 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. | 885 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. |
883 instr->set_hydrogen_value(current); | 886 instr->set_hydrogen_value(current); |
884 | 887 |
885 #if DEBUG | 888 #if DEBUG |
886 // Make sure that the lithium instruction has either no fixed register | 889 // Make sure that the lithium instruction has either no fixed register |
887 // constraints in temps or the result OR no uses that are only used at | 890 // constraints in temps or the result OR no uses that are only used at |
888 // start. If this invariant doesn't hold, the register allocator can decide | 891 // start. If this invariant doesn't hold, the register allocator can decide |
889 // to insert a split of a range immediately before the instruction due to an | 892 // to insert a split of a range immediately before the instruction due to an |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 LOperand* elements = UseFixed(instr->elements(), rcx); | 1098 LOperand* elements = UseFixed(instr->elements(), rcx); |
1096 LApplyArguments* result = new(zone()) LApplyArguments(function, | 1099 LApplyArguments* result = new(zone()) LApplyArguments(function, |
1097 receiver, | 1100 receiver, |
1098 length, | 1101 length, |
1099 elements); | 1102 elements); |
1100 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1103 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); |
1101 } | 1104 } |
1102 | 1105 |
1103 | 1106 |
1104 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1107 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
1105 ++argument_count_; | |
1106 LOperand* argument = UseOrConstant(instr->argument()); | 1108 LOperand* argument = UseOrConstant(instr->argument()); |
1107 return new(zone()) LPushArgument(argument); | 1109 return new(zone()) LPushArgument(argument); |
1108 } | 1110 } |
1109 | 1111 |
1110 | 1112 |
1111 LInstruction* LChunkBuilder::DoStoreCodeEntry( | 1113 LInstruction* LChunkBuilder::DoStoreCodeEntry( |
1112 HStoreCodeEntry* store_code_entry) { | 1114 HStoreCodeEntry* store_code_entry) { |
1113 LOperand* function = UseRegister(store_code_entry->function()); | 1115 LOperand* function = UseRegister(store_code_entry->function()); |
1114 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); | 1116 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); |
1115 return new(zone()) LStoreCodeEntry(function, code_object); | 1117 return new(zone()) LStoreCodeEntry(function, code_object); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 | 1163 |
1162 | 1164 |
1163 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1165 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
1164 LOperand* global_object = UseRegisterAtStart(instr->value()); | 1166 LOperand* global_object = UseRegisterAtStart(instr->value()); |
1165 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | 1167 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); |
1166 } | 1168 } |
1167 | 1169 |
1168 | 1170 |
1169 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1171 LInstruction* LChunkBuilder::DoCallConstantFunction( |
1170 HCallConstantFunction* instr) { | 1172 HCallConstantFunction* instr) { |
1171 argument_count_ -= instr->argument_count(); | |
1172 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr); | 1173 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr); |
1173 } | 1174 } |
1174 | 1175 |
1175 | 1176 |
1176 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { | 1177 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
1177 LOperand* function = UseFixed(instr->function(), rdi); | 1178 LOperand* function = UseFixed(instr->function(), rdi); |
1178 argument_count_ -= instr->argument_count(); | |
1179 LInvokeFunction* result = new(zone()) LInvokeFunction(function); | 1179 LInvokeFunction* result = new(zone()) LInvokeFunction(function); |
1180 return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1180 return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
1181 } | 1181 } |
1182 | 1182 |
1183 | 1183 |
1184 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1184 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
1185 switch (instr->op()) { | 1185 switch (instr->op()) { |
1186 case kMathFloor: return DoMathFloor(instr); | 1186 case kMathFloor: return DoMathFloor(instr); |
1187 case kMathRound: return DoMathRound(instr); | 1187 case kMathRound: return DoMathRound(instr); |
1188 case kMathAbs: return DoMathAbs(instr); | 1188 case kMathAbs: return DoMathAbs(instr); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { | 1270 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { |
1271 LOperand* input = UseRegisterAtStart(instr->value()); | 1271 LOperand* input = UseRegisterAtStart(instr->value()); |
1272 LMathPowHalf* result = new(zone()) LMathPowHalf(input); | 1272 LMathPowHalf* result = new(zone()) LMathPowHalf(input); |
1273 return DefineSameAsFirst(result); | 1273 return DefineSameAsFirst(result); |
1274 } | 1274 } |
1275 | 1275 |
1276 | 1276 |
1277 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1277 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
1278 ASSERT(instr->key()->representation().IsTagged()); | 1278 ASSERT(instr->key()->representation().IsTagged()); |
1279 LOperand* key = UseFixed(instr->key(), rcx); | 1279 LOperand* key = UseFixed(instr->key(), rcx); |
1280 argument_count_ -= instr->argument_count(); | |
1281 LCallKeyed* result = new(zone()) LCallKeyed(key); | 1280 LCallKeyed* result = new(zone()) LCallKeyed(key); |
1282 return MarkAsCall(DefineFixed(result, rax), instr); | 1281 return MarkAsCall(DefineFixed(result, rax), instr); |
1283 } | 1282 } |
1284 | 1283 |
1285 | 1284 |
1286 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1285 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
1287 argument_count_ -= instr->argument_count(); | |
1288 return MarkAsCall(DefineFixed(new(zone()) LCallNamed, rax), instr); | 1286 return MarkAsCall(DefineFixed(new(zone()) LCallNamed, rax), instr); |
1289 } | 1287 } |
1290 | 1288 |
1291 | 1289 |
1292 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1290 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
1293 argument_count_ -= instr->argument_count(); | |
1294 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, rax), instr); | 1291 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, rax), instr); |
1295 } | 1292 } |
1296 | 1293 |
1297 | 1294 |
1298 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1295 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
1299 argument_count_ -= instr->argument_count(); | |
1300 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr); | 1296 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr); |
1301 } | 1297 } |
1302 | 1298 |
1303 | 1299 |
1304 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1300 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
1305 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1301 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
1306 argument_count_ -= instr->argument_count(); | |
1307 LCallNew* result = new(zone()) LCallNew(constructor); | 1302 LCallNew* result = new(zone()) LCallNew(constructor); |
1308 return MarkAsCall(DefineFixed(result, rax), instr); | 1303 return MarkAsCall(DefineFixed(result, rax), instr); |
1309 } | 1304 } |
1310 | 1305 |
1311 | 1306 |
1312 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { | 1307 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
1313 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1308 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
1314 argument_count_ -= instr->argument_count(); | |
1315 LCallNewArray* result = new(zone()) LCallNewArray(constructor); | 1309 LCallNewArray* result = new(zone()) LCallNewArray(constructor); |
1316 return MarkAsCall(DefineFixed(result, rax), instr); | 1310 return MarkAsCall(DefineFixed(result, rax), instr); |
1317 } | 1311 } |
1318 | 1312 |
1319 | 1313 |
1320 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1314 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
1321 LOperand* function = UseFixed(instr->function(), rdi); | 1315 LOperand* function = UseFixed(instr->function(), rdi); |
1322 argument_count_ -= instr->argument_count(); | |
1323 LCallFunction* result = new(zone()) LCallFunction(function); | 1316 LCallFunction* result = new(zone()) LCallFunction(function); |
1324 return MarkAsCall(DefineFixed(result, rax), instr); | 1317 return MarkAsCall(DefineFixed(result, rax), instr); |
1325 } | 1318 } |
1326 | 1319 |
1327 | 1320 |
1328 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1321 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
1329 argument_count_ -= instr->argument_count(); | |
1330 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr); | 1322 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr); |
1331 } | 1323 } |
1332 | 1324 |
1333 | 1325 |
1334 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1326 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
1335 return DoShift(Token::ROR, instr); | 1327 return DoShift(Token::ROR, instr); |
1336 } | 1328 } |
1337 | 1329 |
1338 | 1330 |
1339 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1331 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2389 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { | 2381 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
2390 Abort(kTooManySpillSlotsNeededForOSR); | 2382 Abort(kTooManySpillSlotsNeededForOSR); |
2391 spill_index = 0; | 2383 spill_index = 0; |
2392 } | 2384 } |
2393 } | 2385 } |
2394 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2386 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
2395 } | 2387 } |
2396 | 2388 |
2397 | 2389 |
2398 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2390 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
2399 argument_count_ -= instr->argument_count(); | |
2400 return MarkAsCall(DefineFixed(new(zone()) LCallStub, rax), instr); | 2391 return MarkAsCall(DefineFixed(new(zone()) LCallStub, rax), instr); |
2401 } | 2392 } |
2402 | 2393 |
2403 | 2394 |
2404 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2395 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
2405 // There are no real uses of the arguments object. | 2396 // There are no real uses of the arguments object. |
2406 // arguments.length and element access are supported directly on | 2397 // arguments.length and element access are supported directly on |
2407 // stack arguments, and any real arguments object use causes a bailout. | 2398 // stack arguments, and any real arguments object use causes a bailout. |
2408 // So this value is never used. | 2399 // So this value is never used. |
2409 return NULL; | 2400 return NULL; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 | 2502 |
2512 | 2503 |
2513 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2504 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
2514 LInstruction* pop = NULL; | 2505 LInstruction* pop = NULL; |
2515 | 2506 |
2516 HEnvironment* env = current_block_->last_environment(); | 2507 HEnvironment* env = current_block_->last_environment(); |
2517 | 2508 |
2518 if (env->entry()->arguments_pushed()) { | 2509 if (env->entry()->arguments_pushed()) { |
2519 int argument_count = env->arguments_environment()->parameter_count(); | 2510 int argument_count = env->arguments_environment()->parameter_count(); |
2520 pop = new(zone()) LDrop(argument_count); | 2511 pop = new(zone()) LDrop(argument_count); |
2521 argument_count_ -= argument_count; | 2512 ASSERT(instr->argument_delta() == -argument_count); |
2522 } | 2513 } |
2523 | 2514 |
2524 HEnvironment* outer = current_block_->last_environment()-> | 2515 HEnvironment* outer = current_block_->last_environment()-> |
2525 DiscardInlined(false); | 2516 DiscardInlined(false); |
2526 current_block_->UpdateEnvironment(outer); | 2517 current_block_->UpdateEnvironment(outer); |
2527 | 2518 |
2528 return pop; | 2519 return pop; |
2529 } | 2520 } |
2530 | 2521 |
2531 | 2522 |
(...skipping 21 matching lines...) Expand all Loading... |
2553 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2544 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2554 LOperand* object = UseRegister(instr->object()); | 2545 LOperand* object = UseRegister(instr->object()); |
2555 LOperand* index = UseTempRegister(instr->index()); | 2546 LOperand* index = UseTempRegister(instr->index()); |
2556 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2547 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2557 } | 2548 } |
2558 | 2549 |
2559 | 2550 |
2560 } } // namespace v8::internal | 2551 } } // namespace v8::internal |
2561 | 2552 |
2562 #endif // V8_TARGET_ARCH_X64 | 2553 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |