Reviewers: fschneider,

Description:
Detect overflow of contant pool in virtual frame compiler.

Gracefully fallback to a different code pattern when that happens.

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

Please review this at http://codereview.chromium.org/6599002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/frame-element.h
  M src/ia32/codegen-ia32.cc
  M src/ia32/virtual-frame-ia32.h
  M src/ia32/virtual-frame-ia32.cc
  M src/virtual-frame-heavy-inl.h
  M src/x64/codegen-x64.cc
  M src/x64/virtual-frame-x64.h


Index: src/frame-element.h
diff --git a/src/frame-element.h b/src/frame-element.h
index 3b91b9d34ac99f9056e866ebf8c014de62cb616e..ae5d6a1bf2f1859f0e8aff7d58d5dfc4937dc35b 100644
--- a/src/frame-element.h
+++ b/src/frame-element.h
@@ -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: src/ia32/codegen-ia32.cc
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index ae544dc63b211ac43ea618e7d1ecde9178e2daaa..538361fa51c05a5da31eca949a385c434948103c 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -5360,10 +5360,21 @@ 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 (node->handle()->IsSmi()) {
+      __ Set(temp.reg(), Immediate(Smi::cast(*node->handle())));
+    } else {
+      __ mov(temp.reg(), 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: src/ia32/virtual-frame-ia32.cc
diff --git a/src/ia32/virtual-frame-ia32.cc b/src/ia32/virtual-frame-ia32.cc
index 1cc91a9fea2b19e16ff26a7c246dc422737d7b71..515a9fe97ad8da53ceafdb081447ba5481facb4f 100644
--- a/src/ia32/virtual-frame-ia32.cc
+++ b/src/ia32/virtual-frame-ia32.cc
@@ -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: src/ia32/virtual-frame-ia32.h
diff --git a/src/ia32/virtual-frame-ia32.h b/src/ia32/virtual-frame-ia32.h
index 729469fdccd5f79f73f0c76abaaf5200f284dc09..93362b42714262aa9edbd9709279af59b3914d30 100644
--- a/src/ia32/virtual-frame-ia32.h
+++ b/src/ia32/virtual-frame-ia32.h
@@ -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: src/virtual-frame-heavy-inl.h
diff --git a/src/virtual-frame-heavy-inl.h b/src/virtual-frame-heavy-inl.h
index 2755eee648d37e1b4e9bef13bcffbb4f1fecf169..ac844b44c7aa2e681059c6ec0a421a2b169962cb 100644
--- a/src/virtual-frame-heavy-inl.h
+++ b/src/virtual-frame-heavy-inl.h
@@ -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: src/x64/codegen-x64.cc
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index f47ba18473216cf0356f0ee4e7b974230470c7fd..783484e66331cc5cf6a80dcebb0587f10d18d668 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -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: src/x64/virtual-frame-x64.h
diff --git a/src/x64/virtual-frame-x64.h b/src/x64/virtual-frame-x64.h
index 4a9c72034e0ab25c7040a4501aefbd2d82ec7bba..58619e5d13593ddfe263e8e858d863461140720a 100644
--- a/src/x64/virtual-frame-x64.h
+++ b/src/x64/virtual-frame-x64.h
@@ -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);


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to