Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 // not use registers. | 413 // not use registers. |
| 414 for (int i = 0; i < elements_.length(); i++) { | 414 for (int i = 0; i < elements_.length(); i++) { |
| 415 FrameElement source = elements_[i]; | 415 FrameElement source = elements_[i]; |
| 416 FrameElement target = expected->elements_[i]; | 416 FrameElement target = expected->elements_[i]; |
| 417 if (target.is_memory() && !source.is_memory()) { | 417 if (target.is_memory() && !source.is_memory()) { |
| 418 ASSERT(source.is_register() || source.is_constant()); | 418 ASSERT(source.is_register() || source.is_constant()); |
| 419 SpillElementAt(i); | 419 SpillElementAt(i); |
| 420 } | 420 } |
| 421 } | 421 } |
| 422 | 422 |
| 423 // Then register-to-register moves, not yet implemented. | 423 MergeMoveRegistersToRegisters(expected); |
| 424 for (int i = 0; i < elements_.length(); i++) { | |
| 425 FrameElement source = elements_[i]; | |
| 426 FrameElement target = expected->elements_[i]; | |
| 427 ASSERT(!source.is_register() || !target.is_register()); | |
| 428 } | |
| 429 | 424 |
| 430 // Finally, constant-to-register and memory-to-register. We do these from | 425 // Finally, constant-to-register and memory-to-register. We do these from |
| 431 // the top down so we can use pop for memory-to-register moves above the | 426 // the top down so we can use pop for memory-to-register moves above the |
| 432 // expected stack pointer. | 427 // expected stack pointer. |
| 433 for (int i = elements_.length() - 1; i >= 0; i--) { | 428 for (int i = elements_.length() - 1; i >= 0; i--) { |
| 434 FrameElement source = elements_[i]; | 429 FrameElement source = elements_[i]; |
| 435 FrameElement target = expected->elements_[i]; | 430 FrameElement target = expected->elements_[i]; |
| 436 if (target.is_register() && !source.is_register()) { | 431 if (target.is_register() && !source.is_register()) { |
| 437 ASSERT(source.is_constant() || source.is_memory()); | 432 ASSERT(source.is_constant() || source.is_memory()); |
| 438 if (source.is_memory()) { | 433 if (source.is_memory()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 ASSERT(elements_[i].is_constant()); | 479 ASSERT(elements_[i].is_constant()); |
| 485 ASSERT(elements_[i].handle().location() == | 480 ASSERT(elements_[i].handle().location() == |
| 486 expect.handle().location()); | 481 expect.handle().location()); |
| 487 ASSERT(elements_[i].is_synced() == expect.is_synced()); | 482 ASSERT(elements_[i].is_synced() == expect.is_synced()); |
| 488 } | 483 } |
| 489 } | 484 } |
| 490 #endif | 485 #endif |
| 491 } | 486 } |
| 492 | 487 |
| 493 | 488 |
| 489 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame *expected) { | |
| 490 int start = 0; | |
| 491 int end = elements_.length() - 1; | |
| 492 bool any_moves_blocked; // Did we fail to make some moves this iteration? | |
| 493 bool should_break_cycles = false; | |
| 494 bool any_moves_made; // Did we make any progress this iteration? | |
| 495 do { | |
| 496 any_moves_blocked = false; | |
| 497 any_moves_made = false; | |
| 498 int first_move_blocked = kIllegalIndex; | |
| 499 int last_move_blocked = kIllegalIndex; | |
| 500 for (int i = start; i <= end; i++) { | |
| 501 FrameElement source = elements_[i]; | |
| 502 FrameElement target = expected->elements_[i]; | |
| 503 if (source.is_register() && target.is_register && | |
| 504 !target.reg().is(source.reg())) { | |
|
Kevin Millikin (Chromium)
2008/12/14 13:05:04
As we discussed, the source and targets could be t
William Hesse
2008/12/15 13:43:59
Done.
| |
| 505 // We need to move source to target. | |
| 506 if (frame_registers_.is_used(target.reg().code())) { | |
| 507 // The move is blocked because the target contains valid data. | |
| 508 // If we are stuck with only cycles remaining, then we spill source. | |
| 509 // Otherwise, we just need more iterations. | |
| 510 if (should_break_cycles) { | |
| 511 SpillElementAt(i); | |
| 512 should_break_cycles = false; | |
| 513 } else { // Record a blocked move. | |
| 514 if (!any_moves_blocked) { | |
| 515 first_move_blocked = i; | |
| 516 } | |
| 517 last_move_blocked = i; | |
| 518 any_moves_blocked = true; | |
| 519 } | |
| 520 } else { | |
| 521 // The move is not blocked. This frame element can be moved from | |
| 522 // its source register to its target register. | |
| 523 Use(target.reg()); | |
| 524 Unuse(source.reg()); | |
| 525 if (target.is_synced() && !source.is_synced()) { | |
| 526 SyncElementAt(i); | |
|
Kevin Millikin (Chromium)
2008/12/14 13:05:04
It seems better to call sync (which will work on t
William Hesse
2008/12/15 13:43:59
Done.
| |
| 527 } | |
| 528 elements_[i] = target; | |
| 529 __ mov(target.reg(), source.reg()); | |
| 530 any_moves_made = true; | |
| 531 } | |
| 532 } | |
| 533 } | |
| 534 // Update control flags for next iteration. | |
| 535 should_break_cycles = (any_moves_blocked && !any_moves_made); | |
| 536 if (any_moves_blocked) { | |
| 537 start = first_move_blocked; | |
| 538 end = last_move_blocked; | |
|
iposva
2008/12/12 18:13:03
This is potentially a premature optimization. Thes
William Hesse
2008/12/15 13:43:59
You are right. But should we actually remove it?
| |
| 539 } | |
| 540 } while (any_moves_blocked); | |
| 541 } | |
| 542 | |
| 543 | |
| 494 void VirtualFrame::DetachFromCodeGenerator() { | 544 void VirtualFrame::DetachFromCodeGenerator() { |
| 495 // Tell the global register allocator that it is free to reallocate all | 545 // Tell the global register allocator that it is free to reallocate all |
| 496 // register references contained in this frame. The frame elements remain | 546 // register references contained in this frame. The frame elements remain |
| 497 // register references, so the frame-internal reference count is not | 547 // register references, so the frame-internal reference count is not |
| 498 // decremented. | 548 // decremented. |
| 499 for (int i = 0; i < elements_.length(); i++) { | 549 for (int i = 0; i < elements_.length(); i++) { |
| 500 if (elements_[i].is_register()) { | 550 if (elements_[i].is_register()) { |
| 501 cgen_->allocator()->Unuse(elements_[i].reg()); | 551 cgen_->allocator()->Unuse(elements_[i].reg()); |
| 502 } | 552 } |
| 503 } | 553 } |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 return false; | 839 return false; |
| 790 } | 840 } |
| 791 } | 841 } |
| 792 return true; | 842 return true; |
| 793 } | 843 } |
| 794 #endif | 844 #endif |
| 795 | 845 |
| 796 #undef __ | 846 #undef __ |
| 797 | 847 |
| 798 } } // namespace v8::internal | 848 } } // namespace v8::internal |
| OLD | NEW |