Fix code generation for fast smi loops to support parameters as well.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 22 Mar 2010 11:55:12 +0000 (11:55 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 22 Mar 2010 11:55:12 +0000 (11:55 +0000)
This change fixes an assert we hit when we recognized a fast smi loop
with a parameter as the loop variable.

BUG=650

Review URL: http://codereview.chromium.org/1138003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4202 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/virtual-frame-arm.h
src/ia32/codegen-ia32.cc
src/ia32/codegen-ia32.h
src/ia32/virtual-frame-ia32.h
src/virtual-frame-inl.h
src/x64/virtual-frame-x64.h
test/mjsunit/compiler/loopcount.js

index 7375b31833575baf57a0266afa01523fb4b0a234..9ac7a0548005408a68b346c17b6fa2e0607c01ff 100644 (file)
@@ -365,6 +365,7 @@ class VirtualFrame : public ZoneObject {
   inline void Nip(int num_dropped);
 
   inline void SetTypeForLocalAt(int index, NumberInfo info);
+  inline void SetTypeForParamAt(int index, NumberInfo info);
 
  private:
   static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
index 6c2cbb777861b36f6bc768522cf54c17a56771be..67c9cc1302d9f0e3e43010655bdabea56dd8a6c4 100644 (file)
@@ -3652,6 +3652,26 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
 }
 
 
+void CodeGenerator::SetTypeForStackSlot(Slot* slot, NumberInfo info) {
+  ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
+  if (slot->type() == Slot::LOCAL) {
+    frame_->SetTypeForLocalAt(slot->index(), info);
+  } else {
+    frame_->SetTypeForParamAt(slot->index(), info);
+  }
+  if (FLAG_debug_code && info.IsSmi()) {
+    if (slot->type() == Slot::LOCAL) {
+      frame_->PushLocalAt(slot->index());
+    } else {
+      frame_->PushParameterAt(slot->index());
+    }
+    Result var = frame_->Pop();
+    var.ToRegister();
+    __ AbortIfNotSmi(var.reg());
+  }
+}
+
+
 void CodeGenerator::VisitForStatement(ForStatement* node) {
   ASSERT(!in_spilled_code());
   Comment cmnt(masm_, "[ ForStatement");
@@ -3752,15 +3772,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
   // the bottom check of the loop condition.
   if (node->is_fast_smi_loop()) {
     // Set number type of the loop variable to smi.
-    Slot* slot = node->loop_variable()->slot();
-    ASSERT(slot->type() == Slot::LOCAL);
-    frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi());
-    if (FLAG_debug_code) {
-      frame_->PushLocalAt(slot->index());
-      Result var = frame_->Pop();
-      var.ToRegister();
-      __ AbortIfNotSmi(var.reg());
-    }
+    SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
   }
 
   Visit(node->body());
@@ -3786,15 +3798,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
   // expression if we are in a fast smi loop condition.
   if (node->is_fast_smi_loop() && has_valid_frame()) {
     // Set number type of the loop variable to smi.
-    Slot* slot = node->loop_variable()->slot();
-    ASSERT(slot->type() == Slot::LOCAL);
-    frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi());
-    if (FLAG_debug_code) {
-      frame_->PushLocalAt(slot->index());
-      Result var = frame_->Pop();
-      var.ToRegister();
-      __ AbortIfNotSmi(var.reg());
-    }
+    SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
   }
 
   // Based on the condition analysis, compile the backward jump as
index 386dcc05b0aa2e222116d18085dc2e10c1824ba5..c7ff2e87531a22fc81b1b8574bf97f4642986ad1 100644 (file)
@@ -652,6 +652,8 @@ class CodeGenerator: public AstVisitor {
   void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
   void CodeForSourcePosition(int pos);
 
+  void SetTypeForStackSlot(Slot* slot, NumberInfo info);
+
 #ifdef DEBUG
   // True if the registers are valid for entry to a block.  There should
   // be no frame-external references to (non-reserved) registers.
index 69c3e47d2d5e3bb927d5edf576bfef56fae1a2fa..e622cdfe0ab384726a345b0ada38d0f35fb6f5a7 100644 (file)
@@ -446,8 +446,9 @@ class VirtualFrame: public ZoneObject {
     return true;
   }
 
-  // Update the type information of a local variable frame element directly.
+  // Update the type information of a variable frame element directly.
   inline void SetTypeForLocalAt(int index, NumberInfo info);
+  inline void SetTypeForParamAt(int index, NumberInfo info);
 
  private:
   static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
index ff599d08d25cec85668f08d4cc41fbd2deaa4d44..4050d715b6bf66b88af3f3d17fc6d588926dfe88 100644 (file)
@@ -125,6 +125,11 @@ void VirtualFrame::SetTypeForLocalAt(int index, NumberInfo info) {
 }
 
 
+void VirtualFrame::SetTypeForParamAt(int index, NumberInfo info) {
+  elements_[param0_index() + index].set_number_info(info);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_VIRTUAL_FRAME_INL_H_
index e93140eae7e6e31ea8886ad0069500599dfa97a4..3e9f6dd65132a9c3c864aae5676fdd147b673b3a 100644 (file)
@@ -417,6 +417,7 @@ class VirtualFrame : public ZoneObject {
   inline void Nip(int num_dropped);
 
   inline void SetTypeForLocalAt(int index, NumberInfo info);
+  inline void SetTypeForParamAt(int index, NumberInfo info);
 
  private:
   static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
index da9bc6b7f0685351d0720c81b8f264839d4bb373..6d6918f2f51def18a8f81b23dd8485b945e0ea08 100644 (file)
@@ -84,3 +84,9 @@ function f9() {
   }
 }
 assertEquals(42, f9());
+
+
+function f10(x) {
+  for (x = 0; x < 4; x++) {}
+}
+f10(42);