Author: [email protected]
Date: Tue Jan 6 05:41:47 2009
New Revision: 1029
Modified:
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/codegen.cc
branches/experimental/toiger/src/virtual-frame-ia32.cc
branches/experimental/toiger/src/virtual-frame-ia32.h
branches/experimental/toiger/test/mjsunit/switch.js
Log:
Experimental: begin using the register allocator for switch statements
but not fast-case ones.
Review URL: http://codereview.chromium.org/16513
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Tue Jan 6 05:41:47
2009
@@ -1675,12 +1675,12 @@
// Verify that the result of the runtime call and the esi register are
// the same in debug mode.
__ cmp(context.reg(), Operand(esi));
- verified_true.Branch(equal, &context);
+ context.Unuse();
+ verified_true.Branch(equal);
frame_->SpillAll();
__ int3();
- verified_true.Bind(&context);
+ verified_true.Bind();
}
- context.Unuse();
// Update context local.
frame_->SaveContextRegister();
@@ -1724,6 +1724,7 @@
// placeholders, and fill in the addresses after the labels have been
// bound.
+ VirtualFrame::SpilledScope spilled_scope(this);
frame_->EmitPop(eax); // supposed Smi
// check range of value, if outside [0..length-1] jump to default/end
label.
ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
@@ -1738,8 +1739,8 @@
__ cmp(ebx, HEAP_NUMBER_TYPE);
fail_label->Branch(not_equal);
// eax points to a heap number.
- __ push(eax);
- __ CallRuntime(Runtime::kNumberToSmi, 1);
+ frame_->EmitPush(eax);
+ frame_->CallRuntime(Runtime::kNumberToSmi, 1);
is_smi.Bind();
if (min_index != 0) {
@@ -1777,13 +1778,12 @@
void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
ASSERT(!in_spilled_code());
- VirtualFrame::SpilledScope spilled_scope(this);
Comment cmnt(masm_, "[ SwitchStatement");
CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
node->break_target()->set_code_generator(this);
- LoadAndSpill(node->tag());
+ Load(node->tag());
if (TryGenerateFastCaseSwitchStatement(node)) {
return;
@@ -1805,34 +1805,42 @@
continue;
}
+ // Compile each non-default clause.
Comment cmnt(masm_, "[ Case clause");
- // Compile the test.
- next_test.Bind();
- next_test.Unuse();
- // Duplicate TOS.
- __ mov(eax, frame_->Top());
- frame_->EmitPush(eax);
- LoadAndSpill(clause->label());
+ // Label and compile the test.
+ if (next_test.is_linked()) {
+ // Recycle the same label for each test.
+ next_test.Bind();
+ next_test.Unuse();
+ }
+ // Duplicate the switch value.
+ frame_->Dup();
+ Load(clause->label());
Comparison(equal, true);
Branch(false, &next_test);
- // Before entering the body from the test, remove the switch value from
- // the stack.
+ // Before entering the body from the test remove the switch value from
+ // the frame.
frame_->Drop();
// Label the body so that fall through is enabled.
if (i > 0 && cases->at(i - 1)->is_default()) {
+ // The previous case was the default. This will be the target of a
+ // possible backward edge.
default_exit.Bind();
- } else {
+ } else if (fall_through.is_linked()) {
+ // Recycle the same label for each fall through except for the
default
+ // case.
fall_through.Bind();
fall_through.Unuse();
}
- VisitStatementsAndSpill(clause->statements());
+ VisitStatements(clause->statements());
- // If control flow can fall through from the body, jump to the next
body
+ // If control flow can fall through from the body jump to the next body
// or the end of the statement.
if (has_valid_frame()) {
if (i < length - 1 && cases->at(i + 1)->is_default()) {
+ // The next case is the default.
default_entry.Jump();
} else {
fall_through.Jump();
@@ -1840,15 +1848,15 @@
}
}
- // The final "test" removes the switch value.
+ // The block at the final "test" label removes the switch value.
next_test.Bind();
frame_->Drop();
- // If there is a default clause, compile it.
+ // If there is a default clause, compile it now.
if (default_clause != NULL) {
Comment cmnt(masm_, "[ Default clause");
default_entry.Bind();
- VisitStatementsAndSpill(default_clause->statements());
+ VisitStatements(default_clause->statements());
// If control flow can fall out of the default and there is a case
after
// it, jump to that case's body.
if (has_valid_frame() && default_exit.is_bound()) {
Modified: branches/experimental/toiger/src/codegen.cc
==============================================================================
--- branches/experimental/toiger/src/codegen.cc (original)
+++ branches/experimental/toiger/src/codegen.cc Tue Jan 6 05:41:47 2009
@@ -442,9 +442,10 @@
CaseClause* clause = cases->at(i);
if (clause->is_default()) {
if (default_index >= 0) {
- return false; // More than one default label:
- // Defer to normal case for error.
- }
+ // There is more than one default label. Defer to the normal case
+ // for error.
+ return false;
+ }
default_index = i;
} else {
Expression* label = clause->label();
@@ -456,9 +457,9 @@
if (!value->IsSmi()) {
return false;
}
- int smi = Smi::cast(value)->value();
- if (smi < min_index) { min_index = smi; }
- if (smi > max_index) { max_index = smi; }
+ int int_value = Smi::cast(value)->value();
+ min_index = Min(int_value, min_index);
+ max_index = Max(int_value, max_index);
}
}
Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc Tue Jan 6
05:41:47 2009
@@ -727,15 +727,14 @@
ASSERT(temp.is_valid());
FrameElement new_element
= FrameElement::RegisterElement(temp.reg(),
- FrameElement::NOT_SYNCED);
+ FrameElement::SYNCED);
Use(temp.reg());
elements_[index] = new_element;
+ __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
+
Use(temp.reg());
+ new_element.clear_sync();
elements_.Add(new_element);
-
- // Finally, move the element at the index into its new location.
- elements_[index].set_sync();
- __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
} else {
// For constants and registers, add an (unsynced) copy of the element
to
// the top of the frame.
@@ -896,9 +895,6 @@
}
}
}
-
-
-void VirtualFrame::Drop() { Drop(1); }
Result VirtualFrame::Pop() {
Modified: branches/experimental/toiger/src/virtual-frame-ia32.h
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.h (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.h Tue Jan 6
05:41:47 2009
@@ -351,7 +351,10 @@
void Drop(int count);
// Drop one element.
- void Drop();
+ void Drop() { Drop(1); }
+
+ // Duplicate the top element of the frame.
+ void Dup() { LoadFrameSlotAt(elements_.length() - 1); }
// Pop an element from the top of the expression stack.
// Returns a Result, which may be a constant or a register.
Modified: branches/experimental/toiger/test/mjsunit/switch.js
==============================================================================
--- branches/experimental/toiger/test/mjsunit/switch.js (original)
+++ branches/experimental/toiger/test/mjsunit/switch.js Tue Jan 6 05:41:47
2009
@@ -222,8 +222,8 @@
assertEquals(190, f6(20), "largeSwitch.20");
assertEquals(2016, f6(64), "largeSwitch.64");
assertEquals(4032, f6(128), "largeSwitch.128");
-assertEquals(4222, f6(148), "largeSwitch.148");
-
+assertEquals(4222, f6(148), "largeSwitch.148");
+
function f7(value) {
switch (value) {
@@ -252,7 +252,7 @@
case 11:
case 12:
case 13:
- case 14:
+ case 14:
case 15: // Dummy fillers
}
return "default";
@@ -270,7 +270,7 @@
function makeVeryLong(length) {
var res = "function() {\n" +
- " var res = 0;\n" +
+ " var res = 0;\n" +
" for (var i = 0; i <= " + length + "; i++) {\n" +
" switch(i) {\n";
for (var i = 0; i < length; i++) {
@@ -286,4 +286,4 @@
var verylong_size = 1000;
var verylong = makeVeryLong(verylong_size);
-assertEquals(verylong_size * 2 + 1, verylong());
\ No newline at end of file
+assertEquals(verylong_size * 2 + 1, verylong());
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---