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

Unified Diff: src/virtual-frame-ia32.cc

Issue 15079: Experimental: this is a substantial change to allow the virtual frame... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years 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 side-by-side diff with in-line comments
Download patch
« src/register-allocator-ia32.cc ('K') | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/virtual-frame-ia32.cc
===================================================================
--- src/virtual-frame-ia32.cc (revision 1012)
+++ src/virtual-frame-ia32.cc (working copy)
@@ -131,7 +131,16 @@
}
-// Spill any register if possible, making its reference count zero.
+void VirtualFrame::Spill(Register target) {
+ for (int i = 0; i < elements_.length(); i++) {
+ if (elements_[i].is_register() && elements_[i].reg().is(target)) {
+ SpillElementAt(i);
+ }
+ }
+}
+
+
+// Spill any register if possible, making its external reference count zero.
Register VirtualFrame::SpillAnyRegister() {
// Find the leftmost (ordered by register code), least
// internally-referenced register whose internal reference count matches
@@ -148,26 +157,11 @@
}
}
- if (best_register_code != no_reg.code_) {
- // Spill all occurrences of the register. There are min_count
- // occurrences, stop when we have spilled them all to avoid syncing
- // elements unnecessarily.
- int i = 0;
- while (min_count > 0) {
- ASSERT(i < elements_.length());
- if (elements_[i].is_register() &&
- elements_[i].reg().code() == best_register_code) {
- // Found an instance of the best_register being used in the frame.
- // Spill it.
- SpillElementAt(i);
- min_count--;
- }
- i++;
- }
- }
-
- ASSERT(cgen_->allocator()->count(best_register_code) == 0);
Register result = { best_register_code };
+ if (result.is_valid()) {
+ Spill(result);
+ ASSERT(!cgen_->allocator()->is_used(result));
+ }
return result;
}
@@ -277,29 +271,6 @@
}
-bool VirtualFrame::IsMergable() {
- // We cannot merge to a frame that has constants as elements, because an
- // arbitrary frame may not have the same constants at those locations. We
- // cannot merge to a frame that has registers that are mulitply referenced
- // in the frame, because an arbitrary frame might not exhibit the same
- // sharing. Thus, a frame is mergable if all elements are in memory or a
- // register and no register is multiply referenced.
- for (int i = 0; i < RegisterFile::kNumRegisters; i++) {
- if (frame_registers_.count(i) > 1) {
- return false;
- }
- }
-
- for (int i = 0; i < elements_.length(); i++) {
- if (!elements_[i].is_memory() && !elements_[i].is_register()) {
- return false;
- }
- }
-
- return true;
-}
-
-
bool VirtualFrame::RequiresMergeCode() {
// A frame requires merge code to be generated in the event that
// there are duplicated non-synched registers or else elements not
@@ -331,13 +302,21 @@
void VirtualFrame::MakeMergable() {
Comment cmnt(masm_, "[ Make frame mergable");
+ // We can call MakeMergable on a frame that is not the code generator's
+ // current frame, which will leave the global register counts out of sync
+ // with the frame. We simply save the current frame and restore it at the
+ // end of this function. We should find a better way to deal with this.
+ VirtualFrame* original_frame = cgen_->frame();
+ ASSERT(cgen_->HasValidEntryRegisters());
+ cgen_->SetFrame(this);
+ ASSERT(cgen_->HasValidEntryRegisters());
+
// Remove constants from the frame and ensure that no registers are
- // multiply referenced within the frame. Allocate elements to their
- // new locations from the top down so that the topmost elements have
- // a chance to be in registers, then fill them into memory from the
- // bottom up. (NB: Currently when spilling registers that are
- // multiply referenced, it is the lowermost occurrence that gets to
- // stay in the register.)
+ // multiply referenced within the frame. Allocate elements to their new
+ // locations from the top down so that the topmost elements have a chance
+ // to be in registers, then fill them into memory from the bottom up.
+ // (NB: Currently when spilling registers that are multiply referenced, it
+ // is the lowermost occurrence that gets to stay in the register.)
// The elements of new_elements are initially invalid.
FrameElement* new_elements = new FrameElement[elements_.length()];
@@ -346,7 +325,7 @@
FrameElement element = elements_[i];
if (element.is_constant() ||
(element.is_register() &&
- frame_registers_.count(element.reg().code()) > 1)) {
+ frame_registers_.count(element.reg()) > 1)) {
// A simple strategy is to locate these elements in memory if they are
// synced (avoiding a spill right now) and otherwise to prefer a
// register for them.
@@ -402,11 +381,18 @@
}
delete[] new_elements;
+ ASSERT(cgen_->HasValidEntryRegisters());
+ cgen_->SetFrame(original_frame);
+ ASSERT(cgen_->HasValidEntryRegisters());
}
void VirtualFrame::MergeTo(VirtualFrame* expected) {
Comment cmnt(masm_, "[ Merge frame");
+ // We should always be merging the code generator's current frame to an
+ // expected frame.
+ ASSERT(cgen_->frame() == this);
+
ASSERT(cgen_ == expected->cgen_);
ASSERT(masm_ == expected->masm_);
ASSERT(elements_.length() == expected->elements_.length());
@@ -481,7 +467,7 @@
elements_[i] = target;
} else {
// We need to move source to target.
- if (frame_registers_.is_used(target.reg().code())) {
+ if (frame_registers_.is_used(target.reg())) {
// The move is blocked because the target contains valid data.
// If we are stuck with only cycles remaining, then we spill source.
// Otherwise, we just need more iterations.
@@ -733,6 +719,7 @@
void VirtualFrame::PushTryHandler(HandlerType type) {
+ ASSERT(cgen_->HasValidEntryRegisters());
// Grow the expression stack by handler size less two (the return address
// is already pushed by a call instruction, and PushTryHandler from the
// macro assembler will leave the top of stack in the eax register to be
@@ -745,18 +732,34 @@
void VirtualFrame::CallStub(CodeStub* stub, int frame_arg_count) {
+ ASSERT(cgen_->HasValidEntryRegisters());
PrepareForCall(frame_arg_count);
__ CallStub(stub);
}
+Result VirtualFrame::CallStub(CodeStub* stub,
+ Result* arg0,
+ Result* arg1,
+ int frame_arg_count) {
+ arg0->Unuse();
+ arg1->Unuse();
+ CallStub(stub, frame_arg_count);
+ Result result = cgen_->allocator()->Allocate(eax);
+ ASSERT(result.is_valid());
+ return result;
+}
+
+
void VirtualFrame::CallRuntime(Runtime::Function* f, int frame_arg_count) {
+ ASSERT(cgen_->HasValidEntryRegisters());
PrepareForCall(frame_arg_count);
__ CallRuntime(f, frame_arg_count);
}
void VirtualFrame::CallRuntime(Runtime::FunctionId id, int frame_arg_count) {
+ ASSERT(cgen_->HasValidEntryRegisters());
PrepareForCall(frame_arg_count);
__ CallRuntime(id, frame_arg_count);
}
@@ -765,6 +768,7 @@
void VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
int frame_arg_count) {
+ ASSERT(cgen_->HasValidEntryRegisters());
PrepareForCall(frame_arg_count);
__ InvokeBuiltin(id, flag);
}
@@ -773,6 +777,7 @@
void VirtualFrame::CallCodeObject(Handle<Code> code,
RelocInfo::Mode rmode,
int frame_arg_count) {
+ ASSERT(cgen_->HasValidEntryRegisters());
PrepareForCall(frame_arg_count);
__ call(code, rmode);
}
@@ -802,17 +807,6 @@
void VirtualFrame::Drop() { Drop(1); }
-/*
-We need comparison with literal to work.
-It will get Result, is register or constant.
-Pop gives it this, from register, constant, memory, or
-reference to slot.
-
-In comparison to literal, we need register case to work.
-We need non-smi stub to exit and return with a non-spilled frame.
-*/
-
-
Result VirtualFrame::Pop() {
FrameElement popped = elements_.RemoveLast();
bool pop_needed = (stack_pointer_ == elements_.length());
@@ -841,6 +835,7 @@
}
}
+
void VirtualFrame::EmitPop(Register reg) {
ASSERT(stack_pointer_ == elements_.length() - 1);
stack_pointer_--;
« src/register-allocator-ia32.cc ('K') | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698