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