| 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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 value()->PrintTo(stream); | 405 value()->PrintTo(stream); |
| 406 } | 406 } |
| 407 | 407 |
| 408 | 408 |
| 409 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { | 409 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { |
| 410 object()->PrintTo(stream); | 410 object()->PrintTo(stream); |
| 411 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); | 411 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); |
| 412 } | 412 } |
| 413 | 413 |
| 414 | 414 |
| 415 int LPlatformChunk::GetNextSpillIndex(bool is_double) { | 415 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) { |
| 416 // Skip a slot if for a double-width slot. | 416 // Skip a slot if for a double-width slot. |
| 417 if (is_double) spill_slot_count_++; | 417 if (kind == DOUBLE_REGISTERS) spill_slot_count_++; |
| 418 return spill_slot_count_++; | 418 return spill_slot_count_++; |
| 419 } | 419 } |
| 420 | 420 |
| 421 | 421 |
| 422 LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) { | 422 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 423 int index = GetNextSpillIndex(is_double); | 423 int index = GetNextSpillIndex(kind); |
| 424 if (is_double) { | 424 if (kind == DOUBLE_REGISTERS) { |
| 425 return LDoubleStackSlot::Create(index, zone()); | 425 return LDoubleStackSlot::Create(index, zone()); |
| 426 } else { | 426 } else { |
| 427 ASSERT(kind == GENERAL_REGISTERS); |
| 427 return LStackSlot::Create(index, zone()); | 428 return LStackSlot::Create(index, zone()); |
| 428 } | 429 } |
| 429 } | 430 } |
| 430 | 431 |
| 431 | 432 |
| 432 LPlatformChunk* LChunkBuilder::Build() { | 433 LPlatformChunk* LChunkBuilder::Build() { |
| 433 ASSERT(is_unused()); | 434 ASSERT(is_unused()); |
| 434 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 435 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
| 435 LPhase phase("L_Building chunk", chunk_); | 436 LPhase phase("L_Building chunk", chunk_); |
| 436 status_ = BUILDING; | 437 status_ = BUILDING; |
| 437 | 438 |
| 438 // If compiling for OSR, reserve space for the unoptimized frame, | 439 // If compiling for OSR, reserve space for the unoptimized frame, |
| 439 // which will be subsumed into this frame. | 440 // which will be subsumed into this frame. |
| 440 if (graph()->has_osr()) { | 441 if (graph()->has_osr()) { |
| 441 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 442 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 442 chunk_->GetNextSpillIndex(false); | 443 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 443 } | 444 } |
| 444 } | 445 } |
| 445 | 446 |
| 446 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); | 447 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); |
| 447 for (int i = 0; i < blocks->length(); i++) { | 448 for (int i = 0; i < blocks->length(); i++) { |
| 448 HBasicBlock* next = NULL; | 449 HBasicBlock* next = NULL; |
| 449 if (i < blocks->length() - 1) next = blocks->at(i + 1); | 450 if (i < blocks->length() - 1) next = blocks->at(i + 1); |
| 450 DoBasicBlock(blocks->at(i), next); | 451 DoBasicBlock(blocks->at(i), next); |
| 451 if (is_aborted()) return NULL; | 452 if (is_aborted()) return NULL; |
| 452 } | 453 } |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 block->set_argument_count(argument_count_); | 853 block->set_argument_count(argument_count_); |
| 853 next_block_ = NULL; | 854 next_block_ = NULL; |
| 854 current_block_ = NULL; | 855 current_block_ = NULL; |
| 855 } | 856 } |
| 856 | 857 |
| 857 | 858 |
| 858 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 859 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 859 HInstruction* old_current = current_instruction_; | 860 HInstruction* old_current = current_instruction_; |
| 860 current_instruction_ = current; | 861 current_instruction_ = current; |
| 861 if (current->has_position()) position_ = current->position(); | 862 if (current->has_position()) position_ = current->position(); |
| 862 LInstruction* instr = current->CompileToLithium(this); | 863 |
| 864 LInstruction* instr = NULL; |
| 865 if (current->CanReplaceWithDummyUses()) { |
| 866 HValue* first_operand = current->OperandCount() == 0 |
| 867 ? graph()->GetConstant1() |
| 868 : current->OperandAt(0); |
| 869 instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); |
| 870 for (int i = 1; i < current->OperandCount(); ++i) { |
| 871 LInstruction* dummy = |
| 872 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 873 dummy->set_hydrogen_value(current); |
| 874 chunk_->AddInstruction(dummy, current_block_); |
| 875 } |
| 876 } else { |
| 877 instr = current->CompileToLithium(this); |
| 878 } |
| 879 |
| 880 argument_count_ += current->argument_delta(); |
| 881 ASSERT(argument_count_ >= 0); |
| 863 | 882 |
| 864 if (instr != NULL) { | 883 if (instr != NULL) { |
| 884 // Associate the hydrogen instruction first, since we may need it for |
| 885 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. |
| 886 instr->set_hydrogen_value(current); |
| 887 |
| 865 #if DEBUG | 888 #if DEBUG |
| 866 // Make sure that the lithium instruction has either no fixed register | 889 // Make sure that the lithium instruction has either no fixed register |
| 867 // 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 |
| 868 // 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 |
| 869 // 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 |
| 870 // already allocated register needing to be used for the instruction's fixed | 893 // already allocated register needing to be used for the instruction's fixed |
| 871 // register constraint. In this case, The register allocator won't see an | 894 // register constraint. In this case, The register allocator won't see an |
| 872 // interference between the split child and the use-at-start (it would if | 895 // interference between the split child and the use-at-start (it would if |
| 873 // the it was just a plain use), so it is free to move the split child into | 896 // the it was just a plain use), so it is free to move the split child into |
| 874 // the same register that is used for the use-at-start. | 897 // the same register that is used for the use-at-start. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 891 } | 914 } |
| 892 #endif | 915 #endif |
| 893 | 916 |
| 894 instr->set_position(position_); | 917 instr->set_position(position_); |
| 895 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 918 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 896 instr = AssignPointerMap(instr); | 919 instr = AssignPointerMap(instr); |
| 897 } | 920 } |
| 898 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 921 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 899 instr = AssignEnvironment(instr); | 922 instr = AssignEnvironment(instr); |
| 900 } | 923 } |
| 901 instr->set_hydrogen_value(current); | |
| 902 chunk_->AddInstruction(instr, current_block_); | 924 chunk_->AddInstruction(instr, current_block_); |
| 903 } | 925 } |
| 904 current_instruction_ = old_current; | 926 current_instruction_ = old_current; |
| 905 } | 927 } |
| 906 | 928 |
| 907 | 929 |
| 908 LEnvironment* LChunkBuilder::CreateEnvironment( | 930 LEnvironment* LChunkBuilder::CreateEnvironment( |
| 909 HEnvironment* hydrogen_env, | 931 HEnvironment* hydrogen_env, |
| 910 int* argument_index_accumulator, | 932 int* argument_index_accumulator, |
| 911 ZoneList<HValue*>* objects_to_materialize) { | 933 ZoneList<HValue*>* objects_to_materialize) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 | 1005 |
| 984 if (hydrogen_env->frame_type() == JS_FUNCTION) { | 1006 if (hydrogen_env->frame_type() == JS_FUNCTION) { |
| 985 *argument_index_accumulator = argument_index; | 1007 *argument_index_accumulator = argument_index; |
| 986 } | 1008 } |
| 987 | 1009 |
| 988 return result; | 1010 return result; |
| 989 } | 1011 } |
| 990 | 1012 |
| 991 | 1013 |
| 992 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1014 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 993 return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); | 1015 return new(zone()) LGoto(instr->FirstSuccessor()); |
| 994 } | 1016 } |
| 995 | 1017 |
| 996 | 1018 |
| 997 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1019 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 1020 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 1021 if (goto_instr != NULL) return goto_instr; |
| 1022 |
| 998 HValue* value = instr->value(); | 1023 HValue* value = instr->value(); |
| 999 if (value->EmitAtUses()) { | |
| 1000 HBasicBlock* successor = HConstant::cast(value)->BooleanValue() | |
| 1001 ? instr->FirstSuccessor() | |
| 1002 : instr->SecondSuccessor(); | |
| 1003 return new(zone()) LGoto(successor->block_id()); | |
| 1004 } | |
| 1005 | |
| 1006 LBranch* result = new(zone()) LBranch(UseRegister(value)); | 1024 LBranch* result = new(zone()) LBranch(UseRegister(value)); |
| 1007 // Tagged values that are not known smis or booleans require a | 1025 // Tagged values that are not known smis or booleans require a |
| 1008 // deoptimization environment. If the instruction is generic no | 1026 // deoptimization environment. If the instruction is generic no |
| 1009 // environment is needed since all cases are handled. | 1027 // environment is needed since all cases are handled. |
| 1010 Representation rep = value->representation(); | 1028 Representation rep = value->representation(); |
| 1011 HType type = value->type(); | 1029 HType type = value->type(); |
| 1012 ToBooleanStub::Types expected = instr->expected_input_types(); | 1030 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 1013 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && | 1031 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && |
| 1014 !expected.IsGeneric()) { | 1032 !expected.IsGeneric()) { |
| 1015 return AssignEnvironment(result); | 1033 return AssignEnvironment(result); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 LOperand* elements = UseFixed(instr->elements(), r3); | 1103 LOperand* elements = UseFixed(instr->elements(), r3); |
| 1086 LApplyArguments* result = new(zone()) LApplyArguments(function, | 1104 LApplyArguments* result = new(zone()) LApplyArguments(function, |
| 1087 receiver, | 1105 receiver, |
| 1088 length, | 1106 length, |
| 1089 elements); | 1107 elements); |
| 1090 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); | 1108 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1091 } | 1109 } |
| 1092 | 1110 |
| 1093 | 1111 |
| 1094 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1112 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1095 ++argument_count_; | |
| 1096 LOperand* argument = Use(instr->argument()); | 1113 LOperand* argument = Use(instr->argument()); |
| 1097 return new(zone()) LPushArgument(argument); | 1114 return new(zone()) LPushArgument(argument); |
| 1098 } | 1115 } |
| 1099 | 1116 |
| 1100 | 1117 |
| 1101 LInstruction* LChunkBuilder::DoStoreCodeEntry( | 1118 LInstruction* LChunkBuilder::DoStoreCodeEntry( |
| 1102 HStoreCodeEntry* store_code_entry) { | 1119 HStoreCodeEntry* store_code_entry) { |
| 1103 LOperand* function = UseRegister(store_code_entry->function()); | 1120 LOperand* function = UseRegister(store_code_entry->function()); |
| 1104 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); | 1121 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); |
| 1105 return new(zone()) LStoreCodeEntry(function, code_object); | 1122 return new(zone()) LStoreCodeEntry(function, code_object); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 | 1169 |
| 1153 | 1170 |
| 1154 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1171 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1155 LOperand* global_object = UseRegisterAtStart(instr->value()); | 1172 LOperand* global_object = UseRegisterAtStart(instr->value()); |
| 1156 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | 1173 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); |
| 1157 } | 1174 } |
| 1158 | 1175 |
| 1159 | 1176 |
| 1160 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1177 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1161 HCallConstantFunction* instr) { | 1178 HCallConstantFunction* instr) { |
| 1162 argument_count_ -= instr->argument_count(); | |
| 1163 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, r0), instr); | 1179 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, r0), instr); |
| 1164 } | 1180 } |
| 1165 | 1181 |
| 1166 | 1182 |
| 1167 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { | 1183 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
| 1168 LOperand* context = UseFixed(instr->context(), cp); | 1184 LOperand* context = UseFixed(instr->context(), cp); |
| 1169 LOperand* function = UseFixed(instr->function(), r1); | 1185 LOperand* function = UseFixed(instr->function(), r1); |
| 1170 argument_count_ -= instr->argument_count(); | |
| 1171 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); | 1186 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); |
| 1172 return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1187 return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
| 1173 } | 1188 } |
| 1174 | 1189 |
| 1175 | 1190 |
| 1176 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1191 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1177 switch (instr->op()) { | 1192 switch (instr->op()) { |
| 1178 case kMathFloor: return DoMathFloor(instr); | 1193 case kMathFloor: return DoMathFloor(instr); |
| 1179 case kMathRound: return DoMathRound(instr); | 1194 case kMathRound: return DoMathRound(instr); |
| 1180 case kMathAbs: return DoMathAbs(instr); | 1195 case kMathAbs: return DoMathAbs(instr); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 LOperand* input = UseFixedDouble(instr->value(), d2); | 1284 LOperand* input = UseFixedDouble(instr->value(), d2); |
| 1270 LOperand* temp = FixedTemp(d3); | 1285 LOperand* temp = FixedTemp(d3); |
| 1271 LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp); | 1286 LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp); |
| 1272 return DefineFixedDouble(result, d2); | 1287 return DefineFixedDouble(result, d2); |
| 1273 } | 1288 } |
| 1274 | 1289 |
| 1275 | 1290 |
| 1276 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1291 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1277 ASSERT(instr->key()->representation().IsTagged()); | 1292 ASSERT(instr->key()->representation().IsTagged()); |
| 1278 LOperand* context = UseFixed(instr->context(), cp); | 1293 LOperand* context = UseFixed(instr->context(), cp); |
| 1279 argument_count_ -= instr->argument_count(); | |
| 1280 LOperand* key = UseFixed(instr->key(), r2); | 1294 LOperand* key = UseFixed(instr->key(), r2); |
| 1281 return MarkAsCall( | 1295 return MarkAsCall( |
| 1282 DefineFixed(new(zone()) LCallKeyed(context, key), r0), instr); | 1296 DefineFixed(new(zone()) LCallKeyed(context, key), r0), instr); |
| 1283 } | 1297 } |
| 1284 | 1298 |
| 1285 | 1299 |
| 1286 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1300 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1287 LOperand* context = UseFixed(instr->context(), cp); | 1301 LOperand* context = UseFixed(instr->context(), cp); |
| 1288 argument_count_ -= instr->argument_count(); | |
| 1289 return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), r0), instr); | 1302 return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), r0), instr); |
| 1290 } | 1303 } |
| 1291 | 1304 |
| 1292 | 1305 |
| 1293 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1306 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| 1294 LOperand* context = UseFixed(instr->context(), cp); | 1307 LOperand* context = UseFixed(instr->context(), cp); |
| 1295 argument_count_ -= instr->argument_count(); | |
| 1296 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal(context), r0), instr); | 1308 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal(context), r0), instr); |
| 1297 } | 1309 } |
| 1298 | 1310 |
| 1299 | 1311 |
| 1300 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1312 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1301 argument_count_ -= instr->argument_count(); | |
| 1302 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, r0), instr); | 1313 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, r0), instr); |
| 1303 } | 1314 } |
| 1304 | 1315 |
| 1305 | 1316 |
| 1306 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1317 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1307 LOperand* context = UseFixed(instr->context(), cp); | 1318 LOperand* context = UseFixed(instr->context(), cp); |
| 1308 LOperand* constructor = UseFixed(instr->constructor(), r1); | 1319 LOperand* constructor = UseFixed(instr->constructor(), r1); |
| 1309 argument_count_ -= instr->argument_count(); | |
| 1310 LCallNew* result = new(zone()) LCallNew(context, constructor); | 1320 LCallNew* result = new(zone()) LCallNew(context, constructor); |
| 1311 return MarkAsCall(DefineFixed(result, r0), instr); | 1321 return MarkAsCall(DefineFixed(result, r0), instr); |
| 1312 } | 1322 } |
| 1313 | 1323 |
| 1314 | 1324 |
| 1315 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { | 1325 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
| 1316 LOperand* context = UseFixed(instr->context(), cp); | 1326 LOperand* context = UseFixed(instr->context(), cp); |
| 1317 LOperand* constructor = UseFixed(instr->constructor(), r1); | 1327 LOperand* constructor = UseFixed(instr->constructor(), r1); |
| 1318 argument_count_ -= instr->argument_count(); | |
| 1319 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); | 1328 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
| 1320 return MarkAsCall(DefineFixed(result, r0), instr); | 1329 return MarkAsCall(DefineFixed(result, r0), instr); |
| 1321 } | 1330 } |
| 1322 | 1331 |
| 1323 | 1332 |
| 1324 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1333 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1325 LOperand* context = UseFixed(instr->context(), cp); | 1334 LOperand* context = UseFixed(instr->context(), cp); |
| 1326 LOperand* function = UseFixed(instr->function(), r1); | 1335 LOperand* function = UseFixed(instr->function(), r1); |
| 1327 argument_count_ -= instr->argument_count(); | |
| 1328 return MarkAsCall( | 1336 return MarkAsCall( |
| 1329 DefineFixed(new(zone()) LCallFunction(context, function), r0), instr); | 1337 DefineFixed(new(zone()) LCallFunction(context, function), r0), instr); |
| 1330 } | 1338 } |
| 1331 | 1339 |
| 1332 | 1340 |
| 1333 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1341 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1334 argument_count_ -= instr->argument_count(); | |
| 1335 LOperand* context = UseFixed(instr->context(), cp); | 1342 LOperand* context = UseFixed(instr->context(), cp); |
| 1336 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr); | 1343 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr); |
| 1337 } | 1344 } |
| 1338 | 1345 |
| 1339 | 1346 |
| 1340 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1347 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
| 1341 return DoShift(Token::ROR, instr); | 1348 return DoShift(Token::ROR, instr); |
| 1342 } | 1349 } |
| 1343 | 1350 |
| 1344 | 1351 |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 ASSERT(instr->right()->representation().IsDouble()); | 1766 ASSERT(instr->right()->representation().IsDouble()); |
| 1760 LOperand* left = UseRegisterAtStart(instr->left()); | 1767 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1761 LOperand* right = UseRegisterAtStart(instr->right()); | 1768 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1762 return new(zone()) LCompareNumericAndBranch(left, right); | 1769 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1763 } | 1770 } |
| 1764 } | 1771 } |
| 1765 | 1772 |
| 1766 | 1773 |
| 1767 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1774 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1768 HCompareObjectEqAndBranch* instr) { | 1775 HCompareObjectEqAndBranch* instr) { |
| 1776 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 1777 if (goto_instr != NULL) return goto_instr; |
| 1769 LOperand* left = UseRegisterAtStart(instr->left()); | 1778 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1770 LOperand* right = UseRegisterAtStart(instr->right()); | 1779 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1771 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1780 return new(zone()) LCmpObjectEqAndBranch(left, right); |
| 1772 } | 1781 } |
| 1773 | 1782 |
| 1774 | 1783 |
| 1775 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1784 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
| 1776 HCompareHoleAndBranch* instr) { | 1785 HCompareHoleAndBranch* instr) { |
| 1777 LOperand* value = UseRegisterAtStart(instr->value()); | 1786 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1778 return new(zone()) LCmpHoleAndBranch(value); | 1787 return new(zone()) LCmpHoleAndBranch(value); |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2218 | 2227 |
| 2219 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2228 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2220 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 2229 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
| 2221 ElementsKind elements_kind = instr->elements_kind(); | 2230 ElementsKind elements_kind = instr->elements_kind(); |
| 2222 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2231 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2223 LLoadKeyed* result = NULL; | 2232 LLoadKeyed* result = NULL; |
| 2224 | 2233 |
| 2225 if (!instr->is_external()) { | 2234 if (!instr->is_external()) { |
| 2226 LOperand* obj = NULL; | 2235 LOperand* obj = NULL; |
| 2227 if (instr->representation().IsDouble()) { | 2236 if (instr->representation().IsDouble()) { |
| 2228 obj = UseTempRegister(instr->elements()); | 2237 obj = UseRegister(instr->elements()); |
| 2229 } else { | 2238 } else { |
| 2230 ASSERT(instr->representation().IsSmiOrTagged()); | 2239 ASSERT(instr->representation().IsSmiOrTagged()); |
| 2231 obj = UseRegisterAtStart(instr->elements()); | 2240 obj = UseRegisterAtStart(instr->elements()); |
| 2232 } | 2241 } |
| 2233 result = new(zone()) LLoadKeyed(obj, key); | 2242 result = new(zone()) LLoadKeyed(obj, key); |
| 2234 } else { | 2243 } else { |
| 2235 ASSERT( | 2244 ASSERT( |
| 2236 (instr->representation().IsInteger32() && | 2245 (instr->representation().IsInteger32() && |
| 2237 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 2246 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && |
| 2238 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || | 2247 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 Abort(kTooManySpillSlotsNeededForOSR); | 2502 Abort(kTooManySpillSlotsNeededForOSR); |
| 2494 spill_index = 0; | 2503 spill_index = 0; |
| 2495 } | 2504 } |
| 2496 } | 2505 } |
| 2497 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2506 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
| 2498 } | 2507 } |
| 2499 | 2508 |
| 2500 | 2509 |
| 2501 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2510 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 2502 LOperand* context = UseFixed(instr->context(), cp); | 2511 LOperand* context = UseFixed(instr->context(), cp); |
| 2503 argument_count_ -= instr->argument_count(); | |
| 2504 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr); | 2512 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr); |
| 2505 } | 2513 } |
| 2506 | 2514 |
| 2507 | 2515 |
| 2508 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2516 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 2509 // There are no real uses of the arguments object. | 2517 // There are no real uses of the arguments object. |
| 2510 // arguments.length and element access are supported directly on | 2518 // arguments.length and element access are supported directly on |
| 2511 // stack arguments, and any real arguments object use causes a bailout. | 2519 // stack arguments, and any real arguments object use causes a bailout. |
| 2512 // So this value is never used. | 2520 // So this value is never used. |
| 2513 return NULL; | 2521 return NULL; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2618 | 2626 |
| 2619 | 2627 |
| 2620 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2628 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2621 LInstruction* pop = NULL; | 2629 LInstruction* pop = NULL; |
| 2622 | 2630 |
| 2623 HEnvironment* env = current_block_->last_environment(); | 2631 HEnvironment* env = current_block_->last_environment(); |
| 2624 | 2632 |
| 2625 if (env->entry()->arguments_pushed()) { | 2633 if (env->entry()->arguments_pushed()) { |
| 2626 int argument_count = env->arguments_environment()->parameter_count(); | 2634 int argument_count = env->arguments_environment()->parameter_count(); |
| 2627 pop = new(zone()) LDrop(argument_count); | 2635 pop = new(zone()) LDrop(argument_count); |
| 2628 argument_count_ -= argument_count; | 2636 ASSERT(instr->argument_delta() == -argument_count); |
| 2629 } | 2637 } |
| 2630 | 2638 |
| 2631 HEnvironment* outer = current_block_->last_environment()-> | 2639 HEnvironment* outer = current_block_->last_environment()-> |
| 2632 DiscardInlined(false); | 2640 DiscardInlined(false); |
| 2633 current_block_->UpdateEnvironment(outer); | 2641 current_block_->UpdateEnvironment(outer); |
| 2634 | 2642 |
| 2635 return pop; | 2643 return pop; |
| 2636 } | 2644 } |
| 2637 | 2645 |
| 2638 | 2646 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2658 | 2666 |
| 2659 | 2667 |
| 2660 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2668 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2661 LOperand* object = UseRegister(instr->object()); | 2669 LOperand* object = UseRegister(instr->object()); |
| 2662 LOperand* index = UseRegister(instr->index()); | 2670 LOperand* index = UseRegister(instr->index()); |
| 2663 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2671 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
| 2664 } | 2672 } |
| 2665 | 2673 |
| 2666 | 2674 |
| 2667 } } // namespace v8::internal | 2675 } } // namespace v8::internal |
| OLD | NEW |