Detect overflow of contant pool in virtual frame compiler.
authorvegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 28 Feb 2011 12:09:53 +0000 (12:09 +0000)
committervegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 28 Feb 2011 12:09:53 +0000 (12:09 +0000)
Gracefully fallback to a different code pattern when that happens.

BUG=http://crbug.com/61802
TEST=none

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

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

src/frame-element.h
src/ia32/codegen-ia32.cc
src/ia32/virtual-frame-ia32.cc
src/ia32/virtual-frame-ia32.h
src/virtual-frame-heavy-inl.h
src/x64/codegen-x64.cc
src/x64/virtual-frame-x64.h

index 3b91b9d..ae5d6a1 100644 (file)
@@ -113,6 +113,10 @@ class FrameElement BASE_EMBEDDED {
 
   static ZoneObjectList* ConstantList();
 
+  static bool ConstantPoolOverflowed() {
+    return !DataField::is_valid(ConstantList()->length());
+  }
+
   // Clear the constants indirection table.
   static void ClearConstantList() {
     ConstantList()->Clear();
index ae544dc..770ec0b 100644 (file)
@@ -5360,10 +5360,20 @@ void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
 
 void CodeGenerator::VisitLiteral(Literal* node) {
   Comment cmnt(masm_, "[ Literal");
-  if (in_safe_int32_mode()) {
-    frame_->PushUntaggedElement(node->handle());
+  if (frame_->ConstantPoolOverflowed()) {
+    Result temp = allocator_->Allocate();
+    ASSERT(temp.is_valid());
+    if (in_safe_int32_mode()) {
+      temp.set_untagged_int32(true);
+    }
+    __ Set(temp.reg(), Immediate(node->handle()));
+    frame_->Push(&temp);
   } else {
-    frame_->Push(node->handle());
+    if (in_safe_int32_mode()) {
+      frame_->PushUntaggedElement(node->handle());
+    } else {
+      frame_->Push(node->handle());
+    }
   }
 }
 
index 1cc91a9..515a9fe 100644 (file)
@@ -1306,6 +1306,7 @@ void VirtualFrame::EmitPush(Immediate immediate, TypeInfo info) {
 
 
 void VirtualFrame::PushUntaggedElement(Handle<Object> value) {
+  ASSERT(!ConstantPoolOverflowed());
   elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED));
   elements_[element_count() - 1].set_untagged_int32(true);
 }
index 729469f..93362b4 100644 (file)
@@ -419,6 +419,8 @@ class VirtualFrame: public ZoneObject {
   void EmitPush(Immediate immediate,
                 TypeInfo info = TypeInfo::Unknown());
 
+  inline bool ConstantPoolOverflowed();
+
   // Push an element on the virtual frame.
   inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
   inline void Push(Handle<Object> value);
index 2755eee..ac844b4 100644 (file)
@@ -82,7 +82,13 @@ void VirtualFrame::Push(Register reg, TypeInfo info) {
 }
 
 
+bool VirtualFrame::ConstantPoolOverflowed() {
+  return FrameElement::ConstantPoolOverflowed();
+}
+
+
 void VirtualFrame::Push(Handle<Object> value) {
+  ASSERT(!ConstantPoolOverflowed());
   FrameElement element =
       FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED);
   elements_.Add(element);
index d713b75..dfee36e 100644 (file)
@@ -4694,7 +4694,18 @@ void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
 
 void CodeGenerator::VisitLiteral(Literal* node) {
   Comment cmnt(masm_, "[ Literal");
-  frame_->Push(node->handle());
+  if (frame_->ConstantPoolOverflowed()) {
+    Result temp = allocator_->Allocate();
+    ASSERT(temp.is_valid());
+    if (node->handle()->IsSmi()) {
+      __ Move(temp.reg(), Smi::cast(*node->handle()));
+    } else {
+      __ movq(temp.reg(), node->handle(), RelocInfo::EMBEDDED_OBJECT);
+    }
+    frame_->Push(&temp);
+  } else {
+    frame_->Push(node->handle());
+  }
 }
 
 
index 4029c58..824743d 100644 (file)
@@ -400,6 +400,8 @@ class VirtualFrame : public ZoneObject {
   // Uses kScratchRegister, emits appropriate relocation info.
   void EmitPush(Handle<Object> value);
 
+  inline bool ConstantPoolOverflowed();
+
   // Push an element on the virtual frame.
   inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
   inline void Push(Handle<Object> value);