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

Side by Side Diff: src/ia32/lithium-ia32.cc

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 arguments()->PrintTo(stream); 379 arguments()->PrintTo(stream);
380 380
381 stream->Add(" length "); 381 stream->Add(" length ");
382 length()->PrintTo(stream); 382 length()->PrintTo(stream);
383 383
384 stream->Add(" index "); 384 stream->Add(" index ");
385 index()->PrintTo(stream); 385 index()->PrintTo(stream);
386 } 386 }
387 387
388 388
389 int LPlatformChunk::GetNextSpillIndex(bool is_double) { 389 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
390 // Skip a slot if for a double-width slot. 390 // Skip a slot if for a double-width slot.
391 if (is_double) { 391 if (kind == DOUBLE_REGISTERS) {
392 spill_slot_count_++; 392 spill_slot_count_++;
393 spill_slot_count_ |= 1; 393 spill_slot_count_ |= 1;
394 num_double_slots_++; 394 num_double_slots_++;
395 } 395 }
396 return spill_slot_count_++; 396 return spill_slot_count_++;
397 } 397 }
398 398
399 399
400 LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) { 400 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
401 int index = GetNextSpillIndex(is_double); 401 int index = GetNextSpillIndex(kind);
402 if (is_double) { 402 if (kind == DOUBLE_REGISTERS) {
403 return LDoubleStackSlot::Create(index, zone()); 403 return LDoubleStackSlot::Create(index, zone());
404 } else { 404 } else {
405 ASSERT(kind == GENERAL_REGISTERS);
405 return LStackSlot::Create(index, zone()); 406 return LStackSlot::Create(index, zone());
406 } 407 }
407 } 408 }
408 409
409 410
410 void LStoreNamedField::PrintDataTo(StringStream* stream) { 411 void LStoreNamedField::PrintDataTo(StringStream* stream) {
411 object()->PrintTo(stream); 412 object()->PrintTo(stream);
412 hydrogen()->access().PrintTo(stream); 413 hydrogen()->access().PrintTo(stream);
413 stream->Add(" <- "); 414 stream->Add(" <- ");
414 value()->PrintTo(stream); 415 value()->PrintTo(stream);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 473
473 474
474 LPlatformChunk* LChunkBuilder::Build() { 475 LPlatformChunk* LChunkBuilder::Build() {
475 ASSERT(is_unused()); 476 ASSERT(is_unused());
476 chunk_ = new(zone()) LPlatformChunk(info(), graph()); 477 chunk_ = new(zone()) LPlatformChunk(info(), graph());
477 LPhase phase("L_Building chunk", chunk_); 478 LPhase phase("L_Building chunk", chunk_);
478 status_ = BUILDING; 479 status_ = BUILDING;
479 480
480 // Reserve the first spill slot for the state of dynamic alignment. 481 // Reserve the first spill slot for the state of dynamic alignment.
481 if (info()->IsOptimizing()) { 482 if (info()->IsOptimizing()) {
482 int alignment_state_index = chunk_->GetNextSpillIndex(false); 483 int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
483 ASSERT_EQ(alignment_state_index, 0); 484 ASSERT_EQ(alignment_state_index, 0);
484 USE(alignment_state_index); 485 USE(alignment_state_index);
485 } 486 }
486 487
487 // If compiling for OSR, reserve space for the unoptimized frame, 488 // If compiling for OSR, reserve space for the unoptimized frame,
488 // which will be subsumed into this frame. 489 // which will be subsumed into this frame.
489 if (graph()->has_osr()) { 490 if (graph()->has_osr()) {
490 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { 491 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) {
491 chunk_->GetNextSpillIndex(false); 492 chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
492 } 493 }
493 } 494 }
494 495
495 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 496 const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
496 for (int i = 0; i < blocks->length(); i++) { 497 for (int i = 0; i < blocks->length(); i++) {
497 HBasicBlock* next = NULL; 498 HBasicBlock* next = NULL;
498 if (i < blocks->length() - 1) next = blocks->at(i + 1); 499 if (i < blocks->length() - 1) next = blocks->at(i + 1);
499 DoBasicBlock(blocks->at(i), next); 500 DoBasicBlock(blocks->at(i), next);
500 if (is_aborted()) return NULL; 501 if (is_aborted()) return NULL;
501 } 502 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 block->set_argument_count(argument_count_); 902 block->set_argument_count(argument_count_);
902 next_block_ = NULL; 903 next_block_ = NULL;
903 current_block_ = NULL; 904 current_block_ = NULL;
904 } 905 }
905 906
906 907
907 void LChunkBuilder::VisitInstruction(HInstruction* current) { 908 void LChunkBuilder::VisitInstruction(HInstruction* current) {
908 HInstruction* old_current = current_instruction_; 909 HInstruction* old_current = current_instruction_;
909 current_instruction_ = current; 910 current_instruction_ = current;
910 if (current->has_position()) position_ = current->position(); 911 if (current->has_position()) position_ = current->position();
911 LInstruction* instr = current->CompileToLithium(this); 912
913 LInstruction* instr = NULL;
914 if (current->CanReplaceWithDummyUses()) {
915 HValue* first_operand = current->OperandCount() == 0
916 ? graph()->GetConstant1()
917 : current->OperandAt(0);
918 instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
919 for (int i = 1; i < current->OperandCount(); ++i) {
920 LInstruction* dummy =
921 new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
922 dummy->set_hydrogen_value(current);
923 chunk_->AddInstruction(dummy, current_block_);
924 }
925 } else {
926 instr = current->CompileToLithium(this);
927 }
928
929 argument_count_ += current->argument_delta();
930 ASSERT(argument_count_ >= 0);
912 931
913 if (instr != NULL) { 932 if (instr != NULL) {
933 // Associate the hydrogen instruction first, since we may need it for
934 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below.
935 instr->set_hydrogen_value(current);
936
914 #if DEBUG 937 #if DEBUG
915 // Make sure that the lithium instruction has either no fixed register 938 // Make sure that the lithium instruction has either no fixed register
916 // 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
917 // 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
918 // 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
919 // already allocated register needing to be used for the instruction's fixed 942 // already allocated register needing to be used for the instruction's fixed
920 // register constraint. In this case, The register allocator won't see an 943 // register constraint. In this case, The register allocator won't see an
921 // interference between the split child and the use-at-start (it would if 944 // interference between the split child and the use-at-start (it would if
922 // the it was just a plain use), so it is free to move the split child into 945 // the it was just a plain use), so it is free to move the split child into
923 // the same register that is used for the use-at-start. 946 // the same register that is used for the use-at-start.
(...skipping 26 matching lines...) Expand all
950 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() && 973 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() &&
951 LGoto::cast(instr)->jumps_to_join()) { 974 LGoto::cast(instr)->jumps_to_join()) {
952 // TODO(olivf) Since phis of spilled values are joined as registers 975 // TODO(olivf) Since phis of spilled values are joined as registers
953 // (not in the stack slot), we need to allow the goto gaps to keep one 976 // (not in the stack slot), we need to allow the goto gaps to keep one
954 // x87 register alive. To ensure all other values are still spilled, we 977 // x87 register alive. To ensure all other values are still spilled, we
955 // insert a fpu register barrier right before. 978 // insert a fpu register barrier right before.
956 LClobberDoubles* clobber = new(zone()) LClobberDoubles(); 979 LClobberDoubles* clobber = new(zone()) LClobberDoubles();
957 clobber->set_hydrogen_value(current); 980 clobber->set_hydrogen_value(current);
958 chunk_->AddInstruction(clobber, current_block_); 981 chunk_->AddInstruction(clobber, current_block_);
959 } 982 }
960 instr->set_hydrogen_value(current);
961 chunk_->AddInstruction(instr, current_block_); 983 chunk_->AddInstruction(instr, current_block_);
962 } 984 }
963 current_instruction_ = old_current; 985 current_instruction_ = old_current;
964 } 986 }
965 987
966 988
967 LEnvironment* LChunkBuilder::CreateEnvironment( 989 LEnvironment* LChunkBuilder::CreateEnvironment(
968 HEnvironment* hydrogen_env, 990 HEnvironment* hydrogen_env,
969 int* argument_index_accumulator, 991 int* argument_index_accumulator,
970 ZoneList<HValue*>* objects_to_materialize) { 992 ZoneList<HValue*>* objects_to_materialize) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 return result; 1069 return result;
1048 } 1070 }
1049 1071
1050 1072
1051 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1073 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1052 return new(zone()) LGoto(instr->FirstSuccessor()); 1074 return new(zone()) LGoto(instr->FirstSuccessor());
1053 } 1075 }
1054 1076
1055 1077
1056 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 1078 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1057 HValue* value = instr->value(); 1079 LInstruction* goto_instr = CheckElideControlInstruction(instr);
1058 if (value->EmitAtUses()) { 1080 if (goto_instr != NULL) return goto_instr;
1059 ASSERT(value->IsConstant());
1060 ASSERT(!value->representation().IsDouble());
1061 HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
1062 ? instr->FirstSuccessor()
1063 : instr->SecondSuccessor();
1064 return new(zone()) LGoto(successor);
1065 }
1066 1081
1067 ToBooleanStub::Types expected = instr->expected_input_types(); 1082 ToBooleanStub::Types expected = instr->expected_input_types();
1068 1083
1069 // Tagged values that are not known smis or booleans require a 1084 // Tagged values that are not known smis or booleans require a
1070 // deoptimization environment. If the instruction is generic no 1085 // deoptimization environment. If the instruction is generic no
1071 // environment is needed since all cases are handled. 1086 // environment is needed since all cases are handled.
1087 HValue* value = instr->value();
1072 Representation rep = value->representation(); 1088 Representation rep = value->representation();
1073 HType type = value->type(); 1089 HType type = value->type();
1074 if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) { 1090 if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) {
1075 return new(zone()) LBranch(UseRegister(value), NULL); 1091 return new(zone()) LBranch(UseRegister(value), NULL);
1076 } 1092 }
1077 1093
1078 bool needs_temp = expected.NeedsMap() || expected.IsEmpty(); 1094 bool needs_temp = expected.NeedsMap() || expected.IsEmpty();
1079 LOperand* temp = needs_temp ? TempRegister() : NULL; 1095 LOperand* temp = needs_temp ? TempRegister() : NULL;
1080 1096
1081 // The Generic stub does not have a deopt, so we need no environment. 1097 // The Generic stub does not have a deopt, so we need no environment.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 LOperand* elements = UseFixed(instr->elements(), ecx); 1173 LOperand* elements = UseFixed(instr->elements(), ecx);
1158 LApplyArguments* result = new(zone()) LApplyArguments(function, 1174 LApplyArguments* result = new(zone()) LApplyArguments(function,
1159 receiver, 1175 receiver,
1160 length, 1176 length,
1161 elements); 1177 elements);
1162 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); 1178 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1163 } 1179 }
1164 1180
1165 1181
1166 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1182 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1167 ++argument_count_;
1168 LOperand* argument = UseAny(instr->argument()); 1183 LOperand* argument = UseAny(instr->argument());
1169 return new(zone()) LPushArgument(argument); 1184 return new(zone()) LPushArgument(argument);
1170 } 1185 }
1171 1186
1172 1187
1173 LInstruction* LChunkBuilder::DoStoreCodeEntry( 1188 LInstruction* LChunkBuilder::DoStoreCodeEntry(
1174 HStoreCodeEntry* store_code_entry) { 1189 HStoreCodeEntry* store_code_entry) {
1175 LOperand* function = UseRegister(store_code_entry->function()); 1190 LOperand* function = UseRegister(store_code_entry->function());
1176 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); 1191 LOperand* code_object = UseTempRegister(store_code_entry->code_object());
1177 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
1224 1239
1225 1240
1226 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1241 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1227 LOperand* global_object = UseRegisterAtStart(instr->value()); 1242 LOperand* global_object = UseRegisterAtStart(instr->value());
1228 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); 1243 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object));
1229 } 1244 }
1230 1245
1231 1246
1232 LInstruction* LChunkBuilder::DoCallConstantFunction( 1247 LInstruction* LChunkBuilder::DoCallConstantFunction(
1233 HCallConstantFunction* instr) { 1248 HCallConstantFunction* instr) {
1234 argument_count_ -= instr->argument_count();
1235 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, eax), instr); 1249 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, eax), instr);
1236 } 1250 }
1237 1251
1238 1252
1239 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { 1253 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1240 LOperand* context = UseFixed(instr->context(), esi); 1254 LOperand* context = UseFixed(instr->context(), esi);
1241 LOperand* function = UseFixed(instr->function(), edi); 1255 LOperand* function = UseFixed(instr->function(), edi);
1242 argument_count_ -= instr->argument_count();
1243 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); 1256 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function);
1244 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); 1257 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1245 } 1258 }
1246 1259
1247 1260
1248 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1261 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1249 switch (instr->op()) { 1262 switch (instr->op()) {
1250 case kMathFloor: return DoMathFloor(instr); 1263 case kMathFloor: return DoMathFloor(instr);
1251 case kMathRound: return DoMathRound(instr); 1264 case kMathRound: return DoMathRound(instr);
1252 case kMathAbs: return DoMathAbs(instr); 1265 case kMathAbs: return DoMathAbs(instr);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 LOperand* temp = TempRegister(); 1355 LOperand* temp = TempRegister();
1343 LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp); 1356 LMathPowHalf* result = new(zone()) LMathPowHalf(context, input, temp);
1344 return DefineSameAsFirst(result); 1357 return DefineSameAsFirst(result);
1345 } 1358 }
1346 1359
1347 1360
1348 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1361 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1349 ASSERT(instr->key()->representation().IsTagged()); 1362 ASSERT(instr->key()->representation().IsTagged());
1350 LOperand* context = UseFixed(instr->context(), esi); 1363 LOperand* context = UseFixed(instr->context(), esi);
1351 LOperand* key = UseFixed(instr->key(), ecx); 1364 LOperand* key = UseFixed(instr->key(), ecx);
1352 argument_count_ -= instr->argument_count();
1353 LCallKeyed* result = new(zone()) LCallKeyed(context, key); 1365 LCallKeyed* result = new(zone()) LCallKeyed(context, key);
1354 return MarkAsCall(DefineFixed(result, eax), instr); 1366 return MarkAsCall(DefineFixed(result, eax), instr);
1355 } 1367 }
1356 1368
1357 1369
1358 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { 1370 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1359 LOperand* context = UseFixed(instr->context(), esi); 1371 LOperand* context = UseFixed(instr->context(), esi);
1360 argument_count_ -= instr->argument_count();
1361 LCallNamed* result = new(zone()) LCallNamed(context); 1372 LCallNamed* result = new(zone()) LCallNamed(context);
1362 return MarkAsCall(DefineFixed(result, eax), instr); 1373 return MarkAsCall(DefineFixed(result, eax), instr);
1363 } 1374 }
1364 1375
1365 1376
1366 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { 1377 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1367 LOperand* context = UseFixed(instr->context(), esi); 1378 LOperand* context = UseFixed(instr->context(), esi);
1368 argument_count_ -= instr->argument_count();
1369 LCallGlobal* result = new(zone()) LCallGlobal(context); 1379 LCallGlobal* result = new(zone()) LCallGlobal(context);
1370 return MarkAsCall(DefineFixed(result, eax), instr); 1380 return MarkAsCall(DefineFixed(result, eax), instr);
1371 } 1381 }
1372 1382
1373 1383
1374 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { 1384 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1375 argument_count_ -= instr->argument_count();
1376 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, eax), instr); 1385 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, eax), instr);
1377 } 1386 }
1378 1387
1379 1388
1380 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1389 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1381 LOperand* context = UseFixed(instr->context(), esi); 1390 LOperand* context = UseFixed(instr->context(), esi);
1382 LOperand* constructor = UseFixed(instr->constructor(), edi); 1391 LOperand* constructor = UseFixed(instr->constructor(), edi);
1383 argument_count_ -= instr->argument_count();
1384 LCallNew* result = new(zone()) LCallNew(context, constructor); 1392 LCallNew* result = new(zone()) LCallNew(context, constructor);
1385 return MarkAsCall(DefineFixed(result, eax), instr); 1393 return MarkAsCall(DefineFixed(result, eax), instr);
1386 } 1394 }
1387 1395
1388 1396
1389 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { 1397 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1390 LOperand* context = UseFixed(instr->context(), esi); 1398 LOperand* context = UseFixed(instr->context(), esi);
1391 LOperand* constructor = UseFixed(instr->constructor(), edi); 1399 LOperand* constructor = UseFixed(instr->constructor(), edi);
1392 argument_count_ -= instr->argument_count();
1393 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); 1400 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor);
1394 return MarkAsCall(DefineFixed(result, eax), instr); 1401 return MarkAsCall(DefineFixed(result, eax), instr);
1395 } 1402 }
1396 1403
1397 1404
1398 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1405 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1399 LOperand* context = UseFixed(instr->context(), esi); 1406 LOperand* context = UseFixed(instr->context(), esi);
1400 LOperand* function = UseFixed(instr->function(), edi); 1407 LOperand* function = UseFixed(instr->function(), edi);
1401 argument_count_ -= instr->argument_count();
1402 LCallFunction* result = new(zone()) LCallFunction(context, function); 1408 LCallFunction* result = new(zone()) LCallFunction(context, function);
1403 return MarkAsCall(DefineFixed(result, eax), instr); 1409 return MarkAsCall(DefineFixed(result, eax), instr);
1404 } 1410 }
1405 1411
1406 1412
1407 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1413 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1408 argument_count_ -= instr->argument_count();
1409 LOperand* context = UseFixed(instr->context(), esi); 1414 LOperand* context = UseFixed(instr->context(), esi);
1410 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr); 1415 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr);
1411 } 1416 }
1412 1417
1413 1418
1414 LInstruction* LChunkBuilder::DoRor(HRor* instr) { 1419 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1415 return DoShift(Token::ROR, instr); 1420 return DoShift(Token::ROR, instr);
1416 } 1421 }
1417 1422
1418 1423
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 left = UseRegisterAtStart(instr->left()); 1738 left = UseRegisterAtStart(instr->left());
1734 right = UseRegisterAtStart(instr->right()); 1739 right = UseRegisterAtStart(instr->right());
1735 } 1740 }
1736 return new(zone()) LCompareNumericAndBranch(left, right); 1741 return new(zone()) LCompareNumericAndBranch(left, right);
1737 } 1742 }
1738 } 1743 }
1739 1744
1740 1745
1741 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( 1746 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1742 HCompareObjectEqAndBranch* instr) { 1747 HCompareObjectEqAndBranch* instr) {
1748 LInstruction* goto_instr = CheckElideControlInstruction(instr);
1749 if (goto_instr != NULL) return goto_instr;
1743 LOperand* left = UseRegisterAtStart(instr->left()); 1750 LOperand* left = UseRegisterAtStart(instr->left());
1744 LOperand* right = UseOrConstantAtStart(instr->right()); 1751 LOperand* right = UseOrConstantAtStart(instr->right());
1745 return new(zone()) LCmpObjectEqAndBranch(left, right); 1752 return new(zone()) LCmpObjectEqAndBranch(left, right);
1746 } 1753 }
1747 1754
1748 1755
1749 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( 1756 LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
1750 HCompareHoleAndBranch* instr) { 1757 HCompareHoleAndBranch* instr) {
1751 LOperand* value = UseRegisterAtStart(instr->value()); 1758 LOperand* value = UseRegisterAtStart(instr->value());
1752 return new(zone()) LCmpHoleAndBranch(value); 1759 return new(zone()) LCmpHoleAndBranch(value);
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 obj = needs_write_barrier_for_map 2415 obj = needs_write_barrier_for_map
2409 ? UseRegister(instr->object()) 2416 ? UseRegister(instr->object())
2410 : UseRegisterAtStart(instr->object()); 2417 : UseRegisterAtStart(instr->object());
2411 } 2418 }
2412 2419
2413 bool can_be_constant = instr->value()->IsConstant() && 2420 bool can_be_constant = instr->value()->IsConstant() &&
2414 HConstant::cast(instr->value())->NotInNewSpace() && 2421 HConstant::cast(instr->value())->NotInNewSpace() &&
2415 !(FLAG_track_double_fields && instr->field_representation().IsDouble()); 2422 !(FLAG_track_double_fields && instr->field_representation().IsDouble());
2416 2423
2417 LOperand* val; 2424 LOperand* val;
2418 if (needs_write_barrier) { 2425 if (instr->field_representation().IsByte()) {
2426 // mov_b requires a byte register (i.e. any of eax, ebx, ecx, edx).
2427 // Just force the value to be in eax and we're safe here.
2428 val = UseFixed(instr->value(), eax);
2429 } else if (needs_write_barrier) {
2419 val = UseTempRegister(instr->value()); 2430 val = UseTempRegister(instr->value());
2420 } else if (can_be_constant) { 2431 } else if (can_be_constant) {
2421 val = UseRegisterOrConstant(instr->value()); 2432 val = UseRegisterOrConstant(instr->value());
2422 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { 2433 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) {
2423 val = UseTempRegister(instr->value()); 2434 val = UseTempRegister(instr->value());
2424 } else if (FLAG_track_double_fields && 2435 } else if (FLAG_track_double_fields &&
2425 instr->field_representation().IsDouble()) { 2436 instr->field_representation().IsDouble()) {
2426 val = UseRegisterAtStart(instr->value()); 2437 val = UseRegisterAtStart(instr->value());
2427 } else { 2438 } else {
2428 val = UseRegister(instr->value()); 2439 val = UseRegister(instr->value());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 // The first local is saved at the end of the unoptimized frame. 2566 // The first local is saved at the end of the unoptimized frame.
2556 spill_index = graph()->osr()->UnoptimizedFrameSlots(); 2567 spill_index = graph()->osr()->UnoptimizedFrameSlots();
2557 } 2568 }
2558 } 2569 }
2559 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); 2570 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index);
2560 } 2571 }
2561 2572
2562 2573
2563 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2574 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2564 LOperand* context = UseFixed(instr->context(), esi); 2575 LOperand* context = UseFixed(instr->context(), esi);
2565 argument_count_ -= instr->argument_count();
2566 LCallStub* result = new(zone()) LCallStub(context); 2576 LCallStub* result = new(zone()) LCallStub(context);
2567 return MarkAsCall(DefineFixed(result, eax), instr); 2577 return MarkAsCall(DefineFixed(result, eax), instr);
2568 } 2578 }
2569 2579
2570 2580
2571 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 2581 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2572 // There are no real uses of the arguments object. 2582 // There are no real uses of the arguments object.
2573 // arguments.length and element access are supported directly on 2583 // arguments.length and element access are supported directly on
2574 // stack arguments, and any real arguments object use causes a bailout. 2584 // stack arguments, and any real arguments object use causes a bailout.
2575 // So this value is never used. 2585 // So this value is never used.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2684 2694
2685 2695
2686 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2696 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2687 LInstruction* pop = NULL; 2697 LInstruction* pop = NULL;
2688 2698
2689 HEnvironment* env = current_block_->last_environment(); 2699 HEnvironment* env = current_block_->last_environment();
2690 2700
2691 if (env->entry()->arguments_pushed()) { 2701 if (env->entry()->arguments_pushed()) {
2692 int argument_count = env->arguments_environment()->parameter_count(); 2702 int argument_count = env->arguments_environment()->parameter_count();
2693 pop = new(zone()) LDrop(argument_count); 2703 pop = new(zone()) LDrop(argument_count);
2694 argument_count_ -= argument_count; 2704 ASSERT(instr->argument_delta() == -argument_count);
2695 } 2705 }
2696 2706
2697 HEnvironment* outer = current_block_->last_environment()-> 2707 HEnvironment* outer = current_block_->last_environment()->
2698 DiscardInlined(false); 2708 DiscardInlined(false);
2699 current_block_->UpdateEnvironment(outer); 2709 current_block_->UpdateEnvironment(outer);
2700 return pop; 2710 return pop;
2701 } 2711 }
2702 2712
2703 2713
2704 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { 2714 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
(...skipping 21 matching lines...) Expand all
2726 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2736 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2727 LOperand* object = UseRegister(instr->object()); 2737 LOperand* object = UseRegister(instr->object());
2728 LOperand* index = UseTempRegister(instr->index()); 2738 LOperand* index = UseTempRegister(instr->index());
2729 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2739 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2730 } 2740 }
2731 2741
2732 2742
2733 } } // namespace v8::internal 2743 } } // namespace v8::internal
2734 2744
2735 #endif // V8_TARGET_ARCH_IA32 2745 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698