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 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 for (int i = 1; i < current->OperandCount(); ++i) { | 919 for (int i = 1; i < current->OperandCount(); ++i) { |
920 LInstruction* dummy = | 920 LInstruction* dummy = |
921 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 921 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
922 dummy->set_hydrogen_value(current); | 922 dummy->set_hydrogen_value(current); |
923 chunk_->AddInstruction(dummy, current_block_); | 923 chunk_->AddInstruction(dummy, current_block_); |
924 } | 924 } |
925 } else { | 925 } else { |
926 instr = current->CompileToLithium(this); | 926 instr = current->CompileToLithium(this); |
927 } | 927 } |
928 | 928 |
| 929 argument_count_ += current->argument_delta(); |
| 930 ASSERT(argument_count_ >= 0); |
| 931 |
929 if (instr != NULL) { | 932 if (instr != NULL) { |
930 // Associate the hydrogen instruction first, since we may need it for | 933 // Associate the hydrogen instruction first, since we may need it for |
931 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. | 934 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. |
932 instr->set_hydrogen_value(current); | 935 instr->set_hydrogen_value(current); |
933 | 936 |
934 #if DEBUG | 937 #if DEBUG |
935 // Make sure that the lithium instruction has either no fixed register | 938 // Make sure that the lithium instruction has either no fixed register |
936 // constraints in temps or the result OR no uses that are only used at | 939 // constraints in temps or the result OR no uses that are only used at |
937 // start. If this invariant doesn't hold, the register allocator can decide | 940 // start. If this invariant doesn't hold, the register allocator can decide |
938 // to insert a split of a range immediately before the instruction due to an | 941 // to insert a split of a range immediately before the instruction due to an |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 LOperand* elements = UseFixed(instr->elements(), ecx); | 1173 LOperand* elements = UseFixed(instr->elements(), ecx); |
1171 LApplyArguments* result = new(zone()) LApplyArguments(function, | 1174 LApplyArguments* result = new(zone()) LApplyArguments(function, |
1172 receiver, | 1175 receiver, |
1173 length, | 1176 length, |
1174 elements); | 1177 elements); |
1175 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1178 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
1176 } | 1179 } |
1177 | 1180 |
1178 | 1181 |
1179 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1182 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
1180 ++argument_count_; | |
1181 LOperand* argument = UseAny(instr->argument()); | 1183 LOperand* argument = UseAny(instr->argument()); |
1182 return new(zone()) LPushArgument(argument); | 1184 return new(zone()) LPushArgument(argument); |
1183 } | 1185 } |
1184 | 1186 |
1185 | 1187 |
1186 LInstruction* LChunkBuilder::DoStoreCodeEntry( | 1188 LInstruction* LChunkBuilder::DoStoreCodeEntry( |
1187 HStoreCodeEntry* store_code_entry) { | 1189 HStoreCodeEntry* store_code_entry) { |
1188 LOperand* function = UseRegister(store_code_entry->function()); | 1190 LOperand* function = UseRegister(store_code_entry->function()); |
1189 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); | 1191 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); |
1190 return new(zone()) LStoreCodeEntry(function, code_object); | 1192 return new(zone()) LStoreCodeEntry(function, code_object); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 | 1239 |
1238 | 1240 |
1239 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1241 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
1240 LOperand* global_object = UseRegisterAtStart(instr->value()); | 1242 LOperand* global_object = UseRegisterAtStart(instr->value()); |
1241 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | 1243 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); |
1242 } | 1244 } |
1243 | 1245 |
1244 | 1246 |
1245 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1247 LInstruction* LChunkBuilder::DoCallConstantFunction( |
1246 HCallConstantFunction* instr) { | 1248 HCallConstantFunction* instr) { |
1247 argument_count_ -= instr->argument_count(); | |
1248 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, eax), instr); | 1249 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, eax), instr); |
1249 } | 1250 } |
1250 | 1251 |
1251 | 1252 |
1252 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { | 1253 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
1253 LOperand* context = UseFixed(instr->context(), esi); | 1254 LOperand* context = UseFixed(instr->context(), esi); |
1254 LOperand* function = UseFixed(instr->function(), edi); | 1255 LOperand* function = UseFixed(instr->function(), edi); |
1255 argument_count_ -= instr->argument_count(); | |
1256 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); | 1256 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); |
1257 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1257 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
1258 } | 1258 } |
1259 | 1259 |
1260 | 1260 |
1261 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1261 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
1262 switch (instr->op()) { | 1262 switch (instr->op()) { |
1263 case kMathFloor: return DoMathFloor(instr); | 1263 case kMathFloor: return DoMathFloor(instr); |
1264 case kMathRound: return DoMathRound(instr); | 1264 case kMathRound: return DoMathRound(instr); |
1265 case kMathAbs: return DoMathAbs(instr); | 1265 case kMathAbs: return DoMathAbs(instr); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 LOperand* temp = TempRegister(); | 1355 LOperand* temp = TempRegister(); |
1356 LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp); | 1356 LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp); |
1357 return DefineSameAsFirst(result); | 1357 return DefineSameAsFirst(result); |
1358 } | 1358 } |
1359 | 1359 |
1360 | 1360 |
1361 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1361 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
1362 ASSERT(instr->key()->representation().IsTagged()); | 1362 ASSERT(instr->key()->representation().IsTagged()); |
1363 LOperand* context = UseFixed(instr->context(), esi); | 1363 LOperand* context = UseFixed(instr->context(), esi); |
1364 LOperand* key = UseFixed(instr->key(), ecx); | 1364 LOperand* key = UseFixed(instr->key(), ecx); |
1365 argument_count_ -= instr->argument_count(); | |
1366 LCallKeyed* result = new(zone()) LCallKeyed(context, key); | 1365 LCallKeyed* result = new(zone()) LCallKeyed(context, key); |
1367 return MarkAsCall(DefineFixed(result, eax), instr); | 1366 return MarkAsCall(DefineFixed(result, eax), instr); |
1368 } | 1367 } |
1369 | 1368 |
1370 | 1369 |
1371 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1370 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
1372 LOperand* context = UseFixed(instr->context(), esi); | 1371 LOperand* context = UseFixed(instr->context(), esi); |
1373 argument_count_ -= instr->argument_count(); | |
1374 LCallNamed* result = new(zone()) LCallNamed(context); | 1372 LCallNamed* result = new(zone()) LCallNamed(context); |
1375 return MarkAsCall(DefineFixed(result, eax), instr); | 1373 return MarkAsCall(DefineFixed(result, eax), instr); |
1376 } | 1374 } |
1377 | 1375 |
1378 | 1376 |
1379 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1377 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
1380 LOperand* context = UseFixed(instr->context(), esi); | 1378 LOperand* context = UseFixed(instr->context(), esi); |
1381 argument_count_ -= instr->argument_count(); | |
1382 LCallGlobal* result = new(zone()) LCallGlobal(context); | 1379 LCallGlobal* result = new(zone()) LCallGlobal(context); |
1383 return MarkAsCall(DefineFixed(result, eax), instr); | 1380 return MarkAsCall(DefineFixed(result, eax), instr); |
1384 } | 1381 } |
1385 | 1382 |
1386 | 1383 |
1387 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1384 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
1388 argument_count_ -= instr->argument_count(); | |
1389 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, eax), instr); | 1385 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, eax), instr); |
1390 } | 1386 } |
1391 | 1387 |
1392 | 1388 |
1393 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1389 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
1394 LOperand* context = UseFixed(instr->context(), esi); | 1390 LOperand* context = UseFixed(instr->context(), esi); |
1395 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1391 LOperand* constructor = UseFixed(instr->constructor(), edi); |
1396 argument_count_ -= instr->argument_count(); | |
1397 LCallNew* result = new(zone()) LCallNew(context, constructor); | 1392 LCallNew* result = new(zone()) LCallNew(context, constructor); |
1398 return MarkAsCall(DefineFixed(result, eax), instr); | 1393 return MarkAsCall(DefineFixed(result, eax), instr); |
1399 } | 1394 } |
1400 | 1395 |
1401 | 1396 |
1402 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { | 1397 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
1403 LOperand* context = UseFixed(instr->context(), esi); | 1398 LOperand* context = UseFixed(instr->context(), esi); |
1404 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1399 LOperand* constructor = UseFixed(instr->constructor(), edi); |
1405 argument_count_ -= instr->argument_count(); | |
1406 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); | 1400 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
1407 return MarkAsCall(DefineFixed(result, eax), instr); | 1401 return MarkAsCall(DefineFixed(result, eax), instr); |
1408 } | 1402 } |
1409 | 1403 |
1410 | 1404 |
1411 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1405 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
1412 LOperand* context = UseFixed(instr->context(), esi); | 1406 LOperand* context = UseFixed(instr->context(), esi); |
1413 LOperand* function = UseFixed(instr->function(), edi); | 1407 LOperand* function = UseFixed(instr->function(), edi); |
1414 argument_count_ -= instr->argument_count(); | |
1415 LCallFunction* result = new(zone()) LCallFunction(context, function); | 1408 LCallFunction* result = new(zone()) LCallFunction(context, function); |
1416 return MarkAsCall(DefineFixed(result, eax), instr); | 1409 return MarkAsCall(DefineFixed(result, eax), instr); |
1417 } | 1410 } |
1418 | 1411 |
1419 | 1412 |
1420 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1413 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
1421 argument_count_ -= instr->argument_count(); | |
1422 LOperand* context = UseFixed(instr->context(), esi); | 1414 LOperand* context = UseFixed(instr->context(), esi); |
1423 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr); | 1415 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr); |
1424 } | 1416 } |
1425 | 1417 |
1426 | 1418 |
1427 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1419 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
1428 return DoShift(Token::ROR, instr); | 1420 return DoShift(Token::ROR, instr); |
1429 } | 1421 } |
1430 | 1422 |
1431 | 1423 |
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 // The first local is saved at the end of the unoptimized frame. | 2562 // The first local is saved at the end of the unoptimized frame. |
2571 spill_index = graph()->osr()->UnoptimizedFrameSlots(); | 2563 spill_index = graph()->osr()->UnoptimizedFrameSlots(); |
2572 } | 2564 } |
2573 } | 2565 } |
2574 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2566 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
2575 } | 2567 } |
2576 | 2568 |
2577 | 2569 |
2578 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2570 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
2579 LOperand* context = UseFixed(instr->context(), esi); | 2571 LOperand* context = UseFixed(instr->context(), esi); |
2580 argument_count_ -= instr->argument_count(); | |
2581 LCallStub* result = new(zone()) LCallStub(context); | 2572 LCallStub* result = new(zone()) LCallStub(context); |
2582 return MarkAsCall(DefineFixed(result, eax), instr); | 2573 return MarkAsCall(DefineFixed(result, eax), instr); |
2583 } | 2574 } |
2584 | 2575 |
2585 | 2576 |
2586 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2577 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
2587 // There are no real uses of the arguments object. | 2578 // There are no real uses of the arguments object. |
2588 // arguments.length and element access are supported directly on | 2579 // arguments.length and element access are supported directly on |
2589 // stack arguments, and any real arguments object use causes a bailout. | 2580 // stack arguments, and any real arguments object use causes a bailout. |
2590 // So this value is never used. | 2581 // So this value is never used. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 | 2690 |
2700 | 2691 |
2701 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2692 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
2702 LInstruction* pop = NULL; | 2693 LInstruction* pop = NULL; |
2703 | 2694 |
2704 HEnvironment* env = current_block_->last_environment(); | 2695 HEnvironment* env = current_block_->last_environment(); |
2705 | 2696 |
2706 if (env->entry()->arguments_pushed()) { | 2697 if (env->entry()->arguments_pushed()) { |
2707 int argument_count = env->arguments_environment()->parameter_count(); | 2698 int argument_count = env->arguments_environment()->parameter_count(); |
2708 pop = new(zone()) LDrop(argument_count); | 2699 pop = new(zone()) LDrop(argument_count); |
2709 argument_count_ -= argument_count; | 2700 ASSERT(instr->argument_delta() == -argument_count); |
2710 } | 2701 } |
2711 | 2702 |
2712 HEnvironment* outer = current_block_->last_environment()-> | 2703 HEnvironment* outer = current_block_->last_environment()-> |
2713 DiscardInlined(false); | 2704 DiscardInlined(false); |
2714 current_block_->UpdateEnvironment(outer); | 2705 current_block_->UpdateEnvironment(outer); |
2715 return pop; | 2706 return pop; |
2716 } | 2707 } |
2717 | 2708 |
2718 | 2709 |
2719 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { | 2710 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
(...skipping 21 matching lines...) Expand all Loading... |
2741 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2732 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2742 LOperand* object = UseRegister(instr->object()); | 2733 LOperand* object = UseRegister(instr->object()); |
2743 LOperand* index = UseTempRegister(instr->index()); | 2734 LOperand* index = UseTempRegister(instr->index()); |
2744 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2735 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2745 } | 2736 } |
2746 | 2737 |
2747 | 2738 |
2748 } } // namespace v8::internal | 2739 } } // namespace v8::internal |
2749 | 2740 |
2750 #endif // V8_TARGET_ARCH_IA32 | 2741 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |