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 Abort("unsupported constant of type double"); | |
William Hesse
2011/01/14 10:08:26
Why does this say "of type double"?
Rico
2011/01/14 10:20:15
Changed to UNREACHABLE() - and changed on ia32 and
| |
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 |