Chromium Code Reviews| 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 |