OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 } | 731 } |
732 | 732 |
733 | 733 |
734 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 734 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
735 HArithmeticBinaryOperation* instr) { | 735 HArithmeticBinaryOperation* instr) { |
736 Abort("Unimplemented: %s", "DoArithmeticT"); | 736 Abort("Unimplemented: %s", "DoArithmeticT"); |
737 return NULL; | 737 return NULL; |
738 } | 738 } |
739 | 739 |
740 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 740 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
741 Abort("Unimplemented: %s", "DoBasicBlock"); | 741 ASSERT(is_building()); |
| 742 current_block_ = block; |
| 743 next_block_ = next_block; |
| 744 if (block->IsStartBlock()) { |
| 745 block->UpdateEnvironment(graph_->start_environment()); |
| 746 argument_count_ = 0; |
| 747 } else if (block->predecessors()->length() == 1) { |
| 748 // We have a single predecessor => copy environment and outgoing |
| 749 // argument count from the predecessor. |
| 750 ASSERT(block->phis()->length() == 0); |
| 751 HBasicBlock* pred = block->predecessors()->at(0); |
| 752 HEnvironment* last_environment = pred->last_environment(); |
| 753 ASSERT(last_environment != NULL); |
| 754 // Only copy the environment, if it is later used again. |
| 755 if (pred->end()->SecondSuccessor() == NULL) { |
| 756 ASSERT(pred->end()->FirstSuccessor() == block); |
| 757 } else { |
| 758 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
| 759 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
| 760 last_environment = last_environment->Copy(); |
| 761 } |
| 762 } |
| 763 block->UpdateEnvironment(last_environment); |
| 764 ASSERT(pred->argument_count() >= 0); |
| 765 argument_count_ = pred->argument_count(); |
| 766 } else { |
| 767 // We are at a state join => process phis. |
| 768 HBasicBlock* pred = block->predecessors()->at(0); |
| 769 // No need to copy the environment, it cannot be used later. |
| 770 HEnvironment* last_environment = pred->last_environment(); |
| 771 for (int i = 0; i < block->phis()->length(); ++i) { |
| 772 HPhi* phi = block->phis()->at(i); |
| 773 last_environment->SetValueAt(phi->merged_index(), phi); |
| 774 } |
| 775 for (int i = 0; i < block->deleted_phis()->length(); ++i) { |
| 776 last_environment->SetValueAt(block->deleted_phis()->at(i), |
| 777 graph_->GetConstantUndefined()); |
| 778 } |
| 779 block->UpdateEnvironment(last_environment); |
| 780 // Pick up the outgoing argument count of one of the predecessors. |
| 781 argument_count_ = pred->argument_count(); |
| 782 } |
| 783 HInstruction* current = block->first(); |
| 784 int start = chunk_->instructions()->length(); |
| 785 while (current != NULL && !is_aborted()) { |
| 786 // Code for constants in registers is generated lazily. |
| 787 if (!current->EmitAtUses()) { |
| 788 VisitInstruction(current); |
| 789 } |
| 790 current = current->next(); |
| 791 } |
| 792 int end = chunk_->instructions()->length() - 1; |
| 793 if (end >= start) { |
| 794 block->set_first_instruction_index(start); |
| 795 block->set_last_instruction_index(end); |
| 796 } |
| 797 block->set_argument_count(argument_count_); |
| 798 next_block_ = NULL; |
| 799 current_block_ = NULL; |
742 } | 800 } |
743 | 801 |
744 | 802 |
745 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 803 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
746 HInstruction* old_current = current_instruction_; | 804 HInstruction* old_current = current_instruction_; |
747 current_instruction_ = current; | 805 current_instruction_ = current; |
748 allocator_->BeginInstruction(); | 806 allocator_->BeginInstruction(); |
749 if (current->has_position()) position_ = current->position(); | 807 if (current->has_position()) position_ = current->position(); |
750 LInstruction* instr = current->CompileToLithium(this); | 808 LInstruction* instr = current->CompileToLithium(this); |
751 | 809 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 } | 859 } |
802 } | 860 } |
803 result->AddValue(op, value->representation()); | 861 result->AddValue(op, value->representation()); |
804 } | 862 } |
805 | 863 |
806 return result; | 864 return result; |
807 } | 865 } |
808 | 866 |
809 | 867 |
810 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 868 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
811 Abort("Unimplemented: %s", "DoGoto"); | 869 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
812 return NULL; | 870 instr->include_stack_check()); |
| 871 return (instr->include_stack_check()) |
| 872 ? AssignPointerMap(result) |
| 873 : result; |
813 } | 874 } |
814 | 875 |
815 | 876 |
816 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 877 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
817 Abort("Unimplemented: %s", "DoBranch"); | 878 Abort("Unimplemented: %s", "DoBranch"); |
818 return NULL; | 879 return NULL; |
819 } | 880 } |
820 | 881 |
821 | 882 |
822 LInstruction* LChunkBuilder::DoCompareMapAndBranch( | 883 LInstruction* LChunkBuilder::DoCompareMapAndBranch( |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 } | 1185 } |
1125 | 1186 |
1126 | 1187 |
1127 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1188 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
1128 Abort("Unimplemented: %s", "DoCheckMap"); | 1189 Abort("Unimplemented: %s", "DoCheckMap"); |
1129 return NULL; | 1190 return NULL; |
1130 } | 1191 } |
1131 | 1192 |
1132 | 1193 |
1133 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1194 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
1134 Abort("Unimplemented: %s", "DoReturn"); | 1195 return new LReturn(UseFixed(instr->value(), rax)); |
1135 return NULL; | |
1136 } | 1196 } |
1137 | 1197 |
1138 | 1198 |
1139 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1199 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1140 Abort("Unimplemented: %s", "DoConstant"); | 1200 Representation r = instr->representation(); |
1141 return NULL; | 1201 if (r.IsInteger32()) { |
| 1202 int32_t value = instr->Integer32Value(); |
| 1203 return DefineAsRegister(new LConstantI(value)); |
| 1204 } else if (r.IsDouble()) { |
| 1205 double value = instr->DoubleValue(); |
| 1206 return DefineAsRegister(new LConstantD(value)); |
| 1207 } else if (r.IsTagged()) { |
| 1208 return DefineAsRegister(new LConstantT(instr->handle())); |
| 1209 } else { |
| 1210 UNREACHABLE(); |
| 1211 return NULL; |
| 1212 } |
1142 } | 1213 } |
1143 | 1214 |
1144 | 1215 |
1145 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1216 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
1146 Abort("Unimplemented: %s", "DoLoadGlobal"); | 1217 Abort("Unimplemented: %s", "DoLoadGlobal"); |
1147 return NULL; | 1218 return NULL; |
1148 } | 1219 } |
1149 | 1220 |
1150 | 1221 |
1151 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1222 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 } | 1318 } |
1248 | 1319 |
1249 | 1320 |
1250 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1321 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
1251 Abort("Unimplemented: %s", "DoOsrEntry"); | 1322 Abort("Unimplemented: %s", "DoOsrEntry"); |
1252 return NULL; | 1323 return NULL; |
1253 } | 1324 } |
1254 | 1325 |
1255 | 1326 |
1256 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1327 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
1257 Abort("Unimplemented: %s", "DoParameter"); | 1328 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
1258 return NULL; | 1329 return DefineAsSpilled(new LParameter, spill_index); |
1259 } | 1330 } |
1260 | 1331 |
1261 | 1332 |
1262 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1333 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
1263 Abort("Unimplemented: %s", "DoUnknownOSRValue"); | 1334 Abort("Unimplemented: %s", "DoUnknownOSRValue"); |
1264 return NULL; | 1335 return NULL; |
1265 } | 1336 } |
1266 | 1337 |
1267 | 1338 |
1268 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1339 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
(...skipping 19 matching lines...) Expand all Loading... |
1288 return NULL; | 1359 return NULL; |
1289 } | 1360 } |
1290 | 1361 |
1291 | 1362 |
1292 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1363 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
1293 Abort("Unimplemented: %s", "DoTypeofIs"); | 1364 Abort("Unimplemented: %s", "DoTypeofIs"); |
1294 return NULL; | 1365 return NULL; |
1295 } | 1366 } |
1296 | 1367 |
1297 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1368 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
1298 Abort("Unimplemented: %s", "DoSimulate"); | 1369 HEnvironment* env = current_block_->last_environment(); |
| 1370 ASSERT(env != NULL); |
| 1371 |
| 1372 env->set_ast_id(instr->ast_id()); |
| 1373 |
| 1374 env->Drop(instr->pop_count()); |
| 1375 for (int i = 0; i < instr->values()->length(); ++i) { |
| 1376 HValue* value = instr->values()->at(i); |
| 1377 if (instr->HasAssignedIndexAt(i)) { |
| 1378 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 1379 } else { |
| 1380 env->Push(value); |
| 1381 } |
| 1382 } |
| 1383 ASSERT(env->length() == instr->environment_length()); |
| 1384 |
| 1385 // If there is an instruction pending deoptimization environment create a |
| 1386 // lazy bailout instruction to capture the environment. |
| 1387 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 1388 LLazyBailout* lazy_bailout = new LLazyBailout; |
| 1389 LInstruction* result = AssignEnvironment(lazy_bailout); |
| 1390 instructions_pending_deoptimization_environment_-> |
| 1391 set_deoptimization_environment(result->environment()); |
| 1392 ClearInstructionPendingDeoptimizationEnvironment(); |
| 1393 return result; |
| 1394 } |
| 1395 |
1299 return NULL; | 1396 return NULL; |
1300 } | 1397 } |
1301 | 1398 |
1302 | 1399 |
1303 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 1400 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
1304 Abort("Unimplemented: %s", "DoStackCheck"); | 1401 return MarkAsCall(new LStackCheck, instr); |
1305 return NULL; | |
1306 } | 1402 } |
1307 | 1403 |
1308 | 1404 |
1309 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 1405 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
1310 Abort("Unimplemented: %s", "DoEnterInlined"); | 1406 Abort("Unimplemented: %s", "DoEnterInlined"); |
1311 return NULL; | 1407 return NULL; |
1312 } | 1408 } |
1313 | 1409 |
1314 | 1410 |
1315 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1411 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
1316 Abort("Unimplemented: %s", "DoLeaveInlined"); | 1412 Abort("Unimplemented: %s", "DoLeaveInlined"); |
1317 return NULL; | 1413 return NULL; |
1318 } | 1414 } |
1319 | 1415 |
1320 } } // namespace v8::internal | 1416 } } // namespace v8::internal |
1321 | 1417 |
1322 #endif // V8_TARGET_ARCH_X64 | 1418 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |