From bdef78eda03364b42c61ae01d4cb9c320dfb9257 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Mon, 28 Feb 2011 12:09:53 +0000 Subject: [PATCH] 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 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 | 4 ++++ src/ia32/codegen-ia32.cc | 16 +++++++++++++--- src/ia32/virtual-frame-ia32.cc | 1 + src/ia32/virtual-frame-ia32.h | 2 ++ src/virtual-frame-heavy-inl.h | 6 ++++++ src/x64/codegen-x64.cc | 13 ++++++++++++- src/x64/virtual-frame-x64.h | 2 ++ 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/frame-element.h b/src/frame-element.h index 3b91b9d..ae5d6a1 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(); diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index ae544dc..770ec0b 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -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()); + } } } diff --git a/src/ia32/virtual-frame-ia32.cc b/src/ia32/virtual-frame-ia32.cc index 1cc91a9..515a9fe 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 value) { + ASSERT(!ConstantPoolOverflowed()); elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED)); elements_[element_count() - 1].set_untagged_int32(true); } diff --git a/src/ia32/virtual-frame-ia32.h b/src/ia32/virtual-frame-ia32.h index 729469f..93362b4 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 value); diff --git a/src/virtual-frame-heavy-inl.h b/src/virtual-frame-heavy-inl.h index 2755eee..ac844b4 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 value) { + ASSERT(!ConstantPoolOverflowed()); FrameElement element = FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); elements_.Add(element); diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index d713b75..dfee36e 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()); + } } diff --git a/src/x64/virtual-frame-x64.h b/src/x64/virtual-frame-x64.h index 4029c58..824743d 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 value); + inline bool ConstantPoolOverflowed(); + // Push an element on the virtual frame. inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown()); inline void Push(Handle value); -- 2.7.4