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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/lithium-allocator.h ('k') | src/liveedit.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (use_pos->HasOperand()) { 471 if (use_pos->HasOperand()) {
472 ASSERT(op->IsRegister() || op->IsDoubleRegister() || 472 ASSERT(op->IsRegister() || op->IsDoubleRegister() ||
473 !use_pos->RequiresRegister()); 473 !use_pos->RequiresRegister());
474 use_pos->operand()->ConvertTo(op->kind(), op->index()); 474 use_pos->operand()->ConvertTo(op->kind(), op->index());
475 } 475 }
476 use_pos = use_pos->next(); 476 use_pos = use_pos->next();
477 } 477 }
478 } 478 }
479 479
480 480
481 UsePosition* LiveRange::AddUsePosition(LifetimePosition pos) {
482 return AddUsePosition(pos, CreateAssignedOperand());
483 }
484
485
486 bool LiveRange::CanCover(LifetimePosition position) const { 481 bool LiveRange::CanCover(LifetimePosition position) const {
487 if (IsEmpty()) return false; 482 if (IsEmpty()) return false;
488 return Start().Value() <= position.Value() && 483 return Start().Value() <= position.Value() &&
489 position.Value() < End().Value(); 484 position.Value() < End().Value();
490 } 485 }
491 486
492 487
493 bool LiveRange::Covers(LifetimePosition position) { 488 bool LiveRange::Covers(LifetimePosition position) {
494 if (!CanCover(position)) return false; 489 if (!CanCover(position)) return false;
495 UseInterval* start_search = FirstSearchIntervalForPosition(position); 490 UseInterval* start_search = FirstSearchIntervalForPosition(position);
(...skipping 27 matching lines...) Expand all
523 if (a == NULL || a->start().Value() > other->End().Value()) break; 518 if (a == NULL || a->start().Value() > other->End().Value()) break;
524 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); 519 AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
525 } else { 520 } else {
526 b = b->next(); 521 b = b->next();
527 } 522 }
528 } 523 }
529 return LifetimePosition::Invalid(); 524 return LifetimePosition::Invalid();
530 } 525 }
531 526
532 527
528 LAllocator::LAllocator(int num_values, HGraph* graph)
529 : chunk_(NULL),
530 live_in_sets_(graph->blocks()->length()),
531 live_ranges_(num_values * 2),
532 fixed_live_ranges_(NULL),
533 fixed_double_live_ranges_(NULL),
534 unhandled_live_ranges_(num_values * 2),
535 active_live_ranges_(8),
536 inactive_live_ranges_(8),
537 reusable_slots_(8),
538 next_virtual_register_(num_values),
539 first_artificial_register_(num_values),
540 mode_(NONE),
541 num_registers_(-1),
542 graph_(graph),
543 has_osr_entry_(false) {}
544
545
533 void LAllocator::InitializeLivenessAnalysis() { 546 void LAllocator::InitializeLivenessAnalysis() {
534 // Initialize the live_in sets for each block to NULL. 547 // Initialize the live_in sets for each block to NULL.
535 int block_count = graph_->blocks()->length(); 548 int block_count = graph_->blocks()->length();
536 live_in_sets_.Initialize(block_count); 549 live_in_sets_.Initialize(block_count);
537 live_in_sets_.AddBlock(NULL, block_count); 550 live_in_sets_.AddBlock(NULL, block_count);
538 } 551 }
539 552
540 553
541 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { 554 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) {
542 // Compute live out for the given block, except not including backward 555 // Compute live out for the given block, except not including backward
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 LInstruction* instr = InstructionAt(pos); 629 LInstruction* instr = InstructionAt(pos);
617 if (instr->HasPointerMap()) { 630 if (instr->HasPointerMap()) {
618 instr->pointer_map()->RecordPointer(operand); 631 instr->pointer_map()->RecordPointer(operand);
619 } 632 }
620 } 633 }
621 return operand; 634 return operand;
622 } 635 }
623 636
624 637
625 LiveRange* LAllocator::FixedLiveRangeFor(int index) { 638 LiveRange* LAllocator::FixedLiveRangeFor(int index) {
626 if (index >= fixed_live_ranges_.length()) { 639 ASSERT(index < Register::kNumAllocatableRegisters);
627 fixed_live_ranges_.AddBlock(NULL,
628 index - fixed_live_ranges_.length() + 1);
629 }
630
631 LiveRange* result = fixed_live_ranges_[index]; 640 LiveRange* result = fixed_live_ranges_[index];
632 if (result == NULL) { 641 if (result == NULL) {
633 result = new LiveRange(FixedLiveRangeID(index)); 642 result = new LiveRange(FixedLiveRangeID(index));
634 ASSERT(result->IsFixed()); 643 ASSERT(result->IsFixed());
635 result->set_assigned_register(index, GENERAL_REGISTERS); 644 result->set_assigned_register(index, GENERAL_REGISTERS);
636 fixed_live_ranges_[index] = result; 645 fixed_live_ranges_[index] = result;
637 } 646 }
638 return result; 647 return result;
639 } 648 }
640 649
641 650
642 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { 651 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) {
643 if (index >= fixed_double_live_ranges_.length()) { 652 ASSERT(index < DoubleRegister::kNumAllocatableRegisters);
644 fixed_double_live_ranges_.AddBlock(NULL,
645 index - fixed_double_live_ranges_.length() + 1);
646 }
647
648 LiveRange* result = fixed_double_live_ranges_[index]; 653 LiveRange* result = fixed_double_live_ranges_[index];
649 if (result == NULL) { 654 if (result == NULL) {
650 result = new LiveRange(FixedDoubleLiveRangeID(index)); 655 result = new LiveRange(FixedDoubleLiveRangeID(index));
651 ASSERT(result->IsFixed()); 656 ASSERT(result->IsFixed());
652 result->set_assigned_register(index, DOUBLE_REGISTERS); 657 result->set_assigned_register(index, DOUBLE_REGISTERS);
653 fixed_double_live_ranges_[index] = result; 658 fixed_double_live_ranges_[index] = result;
654 } 659 }
655 return result; 660 return result;
656 } 661 }
657 662
663
658 LiveRange* LAllocator::LiveRangeFor(int index) { 664 LiveRange* LAllocator::LiveRangeFor(int index) {
659 if (index >= live_ranges_.length()) { 665 if (index >= live_ranges_.length()) {
660 live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1); 666 live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1);
661 } 667 }
662 LiveRange* result = live_ranges_[index]; 668 LiveRange* result = live_ranges_[index];
663 if (result == NULL) { 669 if (result == NULL) {
664 result = new LiveRange(index); 670 result = new LiveRange(index);
665 live_ranges_[index] = result; 671 live_ranges_[index] = result;
666 } 672 }
667 return result; 673 return result;
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 LOperand* pred_op = pred_cover->CreateAssignedOperand(); 1098 LOperand* pred_op = pred_cover->CreateAssignedOperand();
1093 LOperand* cur_op = cur_cover->CreateAssignedOperand(); 1099 LOperand* cur_op = cur_cover->CreateAssignedOperand();
1094 if (!pred_op->Equals(cur_op)) { 1100 if (!pred_op->Equals(cur_op)) {
1095 LGap* gap = NULL; 1101 LGap* gap = NULL;
1096 if (block->predecessors()->length() == 1) { 1102 if (block->predecessors()->length() == 1) {
1097 gap = GapAt(block->first_instruction_index()); 1103 gap = GapAt(block->first_instruction_index());
1098 } else { 1104 } else {
1099 ASSERT(pred->end()->SecondSuccessor() == NULL); 1105 ASSERT(pred->end()->SecondSuccessor() == NULL);
1100 gap = GetLastGap(pred); 1106 gap = GetLastGap(pred);
1101 1107
1108 // We are going to insert a move before the branch instruction.
1109 // Some branch instructions (e.g. loops' back edges)
1110 // can potentially cause a GC so they have a pointer map.
1111 // By insterting a move we essentially create a copy of a
1112 // value which is invisible to PopulatePointerMaps(), because we store
1113 // it into a location different from the operand of a live range
1114 // covering a branch instruction.
1115 // Thus we need to manually record a pointer.
1102 if (HasTaggedValue(range->id())) { 1116 if (HasTaggedValue(range->id())) {
1103 LInstruction* branch = InstructionAt(pred->last_instruction_index()); 1117 LInstruction* branch = InstructionAt(pred->last_instruction_index());
1104 if (branch->HasPointerMap()) { 1118 if (branch->HasPointerMap()) {
1105 branch->pointer_map()->RecordPointer(cur_op); 1119 branch->pointer_map()->RecordPointer(cur_op);
1106 } 1120 }
1107 } 1121 }
1108 } 1122 }
1109 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op); 1123 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op);
1110 } 1124 }
1111 } 1125 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 } 1278 }
1265 1279
1266 #ifdef DEBUG 1280 #ifdef DEBUG
1267 if (block_id == 0) { 1281 if (block_id == 0) {
1268 BitVector::Iterator iterator(live); 1282 BitVector::Iterator iterator(live);
1269 bool found = false; 1283 bool found = false;
1270 while (!iterator.Done()) { 1284 while (!iterator.Done()) {
1271 found = true; 1285 found = true;
1272 int operand_index = iterator.Current(); 1286 int operand_index = iterator.Current();
1273 PrintF("Function: %s\n", 1287 PrintF("Function: %s\n",
1274 *graph_->info()->function()->debug_name()->ToCString()); 1288 *chunk_->info()->function()->debug_name()->ToCString());
1275 PrintF("Value %d used before first definition!\n", operand_index); 1289 PrintF("Value %d used before first definition!\n", operand_index);
1276 LiveRange* range = LiveRangeFor(operand_index); 1290 LiveRange* range = LiveRangeFor(operand_index);
1277 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); 1291 PrintF("First use is at %d\n", range->first_pos()->pos().Value());
1278 iterator.Advance(); 1292 iterator.Advance();
1279 } 1293 }
1280 ASSERT(!found); 1294 ASSERT(!found);
1281 } 1295 }
1282 #endif 1296 #endif
1283 } 1297 }
1284 } 1298 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 void LAllocator::AllocateDoubleRegisters() { 1440 void LAllocator::AllocateDoubleRegisters() {
1427 HPhase phase("Allocate double registers", this); 1441 HPhase phase("Allocate double registers", this);
1428 num_registers_ = DoubleRegister::kNumAllocatableRegisters; 1442 num_registers_ = DoubleRegister::kNumAllocatableRegisters;
1429 mode_ = DOUBLE_REGISTERS; 1443 mode_ = DOUBLE_REGISTERS;
1430 AllocateRegisters(); 1444 AllocateRegisters();
1431 } 1445 }
1432 1446
1433 1447
1434 void LAllocator::AllocateRegisters() { 1448 void LAllocator::AllocateRegisters() {
1435 ASSERT(mode_ != NONE); 1449 ASSERT(mode_ != NONE);
1436 reusable_slots_.Clear(); 1450 ASSERT(unhandled_live_ranges_.is_empty());
1437 1451
1438 for (int i = 0; i < live_ranges_.length(); ++i) { 1452 for (int i = 0; i < live_ranges_.length(); ++i) {
1439 if (live_ranges_[i] != NULL) { 1453 if (live_ranges_[i] != NULL) {
1440 if (RequiredRegisterKind(live_ranges_[i]->id()) == mode_) { 1454 if (RequiredRegisterKind(live_ranges_[i]->id()) == mode_) {
1441 AddToUnhandledUnsorted(live_ranges_[i]); 1455 AddToUnhandledUnsorted(live_ranges_[i]);
1442 } 1456 }
1443 } 1457 }
1444 } 1458 }
1445 SortUnhandled(); 1459 SortUnhandled();
1446 ASSERT(UnhandledIsSorted()); 1460 ASSERT(UnhandledIsSorted());
1447 1461
1462 ASSERT(reusable_slots_.is_empty());
1448 ASSERT(active_live_ranges_.is_empty()); 1463 ASSERT(active_live_ranges_.is_empty());
1449 ASSERT(inactive_live_ranges_.is_empty()); 1464 ASSERT(inactive_live_ranges_.is_empty());
1450 1465
1451 if (mode_ == DOUBLE_REGISTERS) { 1466 if (mode_ == DOUBLE_REGISTERS) {
1452 for (int i = 0; i < fixed_double_live_ranges_.length(); ++i) { 1467 for (int i = 0; i < fixed_double_live_ranges_.length(); ++i) {
1453 LiveRange* current = fixed_double_live_ranges_.at(i); 1468 LiveRange* current = fixed_double_live_ranges_.at(i);
1454 if (current != NULL) { 1469 if (current != NULL) {
1455 AddToInactive(current); 1470 AddToInactive(current);
1456 } 1471 }
1457 } 1472 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 bool result = TryAllocateFreeReg(current); 1537 bool result = TryAllocateFreeReg(current);
1523 if (!result) { 1538 if (!result) {
1524 AllocateBlockedReg(current); 1539 AllocateBlockedReg(current);
1525 } 1540 }
1526 1541
1527 if (current->HasRegisterAssigned()) { 1542 if (current->HasRegisterAssigned()) {
1528 AddToActive(current); 1543 AddToActive(current);
1529 } 1544 }
1530 } 1545 }
1531 1546
1532 active_live_ranges_.Clear(); 1547 reusable_slots_.Rewind(0);
1533 inactive_live_ranges_.Clear(); 1548 active_live_ranges_.Rewind(0);
1549 inactive_live_ranges_.Rewind(0);
1534 } 1550 }
1535 1551
1536 1552
1537 void LAllocator::Setup() { 1553 void LAllocator::Setup() {
1538 LConstantOperand::SetupCache(); 1554 LConstantOperand::SetupCache();
1539 LStackSlot::SetupCache(); 1555 LStackSlot::SetupCache();
1540 LDoubleStackSlot::SetupCache(); 1556 LDoubleStackSlot::SetupCache();
1541 LRegister::SetupCache(); 1557 LRegister::SetupCache();
1542 LDoubleRegister::SetupCache(); 1558 LDoubleRegister::SetupCache();
1543 } 1559 }
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 LiveRange* current = live_ranges()->at(i); 2097 LiveRange* current = live_ranges()->at(i);
2082 if (current != NULL) current->Verify(); 2098 if (current != NULL) current->Verify();
2083 } 2099 }
2084 } 2100 }
2085 2101
2086 2102
2087 #endif 2103 #endif
2088 2104
2089 2105
2090 } } // namespace v8::internal 2106 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lithium-allocator.h ('k') | src/liveedit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698