From 4a12504f89eb7ded69623c5aff04432bfc85d24c Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Thu, 14 May 2009 16:06:04 +0000 Subject: [PATCH] Improve algorithm for detaching and attaching a virtual frame to the code generator. Inline copying of a register file. Review URL: http://codereview.chromium.org/113402 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1954 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/virtual-frame-arm.h | 20 ++++++++++++++++++-- src/ia32/virtual-frame-ia32.h | 20 ++++++++++++++++++-- src/register-allocator.cc | 10 ---------- src/register-allocator.h | 6 +++++- src/virtual-frame.cc | 24 ------------------------ src/x64/virtual-frame-x64.h | 21 ++++++++++++++++++--- 6 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/arm/virtual-frame-arm.h b/src/arm/virtual-frame-arm.h index b6233e4b27..8d7b8bd30a 100644 --- a/src/arm/virtual-frame-arm.h +++ b/src/arm/virtual-frame-arm.h @@ -127,13 +127,29 @@ class VirtualFrame : public ZoneObject { // tells the register allocator that it is free to use frame-internal // registers. Used when the code generator's frame is switched from this // one to NULL by an unconditional jump. - void DetachFromCodeGenerator(); + void DetachFromCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Unuse(temp); + } + } + } // (Re)attach a frame to its code generator. This informs the register // allocator that the frame-internal register references are active again. // Used when a code generator's frame is switched from NULL to this one by // binding a label. - void AttachToCodeGenerator(); + void AttachToCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Use(temp); + } + } + } // Emit code for the physical JS entry and exit frame sequences. After // calling Enter, the virtual frame is ready for use; and after calling diff --git a/src/ia32/virtual-frame-ia32.h b/src/ia32/virtual-frame-ia32.h index 7878bfd2ab..37fd2e9aaf 100644 --- a/src/ia32/virtual-frame-ia32.h +++ b/src/ia32/virtual-frame-ia32.h @@ -130,13 +130,29 @@ class VirtualFrame : public ZoneObject { // tells the register allocator that it is free to use frame-internal // registers. Used when the code generator's frame is switched from this // one to NULL by an unconditional jump. - void DetachFromCodeGenerator(); + void DetachFromCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Unuse(temp); + } + } + } // (Re)attach a frame to its code generator. This informs the register // allocator that the frame-internal register references are active again. // Used when a code generator's frame is switched from NULL to this one by // binding a label. - void AttachToCodeGenerator(); + void AttachToCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Use(temp); + } + } + } // Emit code for the physical JS entry and exit frame sequences. After // calling Enter, the virtual frame is ready for use; and after calling diff --git a/src/register-allocator.cc b/src/register-allocator.cc index 94e031fa0b..1da7e6b5d3 100644 --- a/src/register-allocator.cc +++ b/src/register-allocator.cc @@ -71,16 +71,6 @@ void Result::CopyTo(Result* destination) const { } -// ------------------------------------------------------------------------- -// RegisterFile implementation. - -void RegisterFile::CopyTo(RegisterFile* other) { - for (int i = 0; i < kNumRegisters; i++) { - other->ref_counts_[i] = ref_counts_[i]; - } -} - - // ------------------------------------------------------------------------- // RegisterAllocator implementation. diff --git a/src/register-allocator.h b/src/register-allocator.h index dfe1b55820..19dde9616c 100644 --- a/src/register-allocator.h +++ b/src/register-allocator.h @@ -243,7 +243,11 @@ class RegisterFile BASE_EMBEDDED { } // Copy the reference counts from this register file to the other. - void CopyTo(RegisterFile* other); + void CopyTo(RegisterFile* other) { + for (int i = 0; i < kNumRegisters; i++) { + other->ref_counts_[i] = ref_counts_[i]; + } + } private: int ref_counts_[kNumRegisters]; diff --git a/src/virtual-frame.cc b/src/virtual-frame.cc index db6b50d794..f5da5fcea2 100644 --- a/src/virtual-frame.cc +++ b/src/virtual-frame.cc @@ -304,30 +304,6 @@ void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) { } -void VirtualFrame::DetachFromCodeGenerator() { - // Tell the global register allocator that it is free to reallocate all - // register references contained in this frame. The frame elements remain - // register references, so the frame-internal reference count is not - // decremented. - for (int i = 0; i < elements_.length(); i++) { - if (elements_[i].is_register()) { - cgen_->allocator()->Unuse(elements_[i].reg()); - } - } -} - - -void VirtualFrame::AttachToCodeGenerator() { - // Tell the global register allocator that the frame-internal register - // references are live again. - for (int i = 0; i < elements_.length(); i++) { - if (elements_[i].is_register()) { - cgen_->allocator()->Use(elements_[i].reg()); - } - } -} - - void VirtualFrame::PrepareForReturn() { // Spill all locals. This is necessary to make sure all locals have // the right value when breaking at the return site in the debugger. diff --git a/src/x64/virtual-frame-x64.h b/src/x64/virtual-frame-x64.h index f71766d033..818a46efbf 100644 --- a/src/x64/virtual-frame-x64.h +++ b/src/x64/virtual-frame-x64.h @@ -130,13 +130,28 @@ class VirtualFrame : public Malloced { // tells the register allocator that it is free to use frame-internal // registers. Used when the code generator's frame is switched from this // one to NULL by an unconditional jump. - void DetachFromCodeGenerator(); - + void DetachFromCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Unuse(temp); + } + } + } // (Re)attach a frame to its code generator. This informs the register // allocator that the frame-internal register references are active again. // Used when a code generator's frame is switched from NULL to this one by // binding a label. - void AttachToCodeGenerator(); + void AttachToCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen_->allocator(); + for (int i = 0; i < kNumRegisters; i++) { + if (is_used(i)) { + Register temp = { i }; + cgen_allocator->Use(temp); + } + } + } // Emit code for the physical JS entry and exit frame sequences. After // calling Enter, the virtual frame is ready for use; and after calling