Author: [email protected]
Date: Wed Mar 11 03:25:48 2009
New Revision: 1486
Modified:
branches/bleeding_edge/src/codegen-arm.cc
branches/bleeding_edge/src/codegen-arm.h
branches/bleeding_edge/src/codegen-ia32.cc
branches/bleeding_edge/src/codegen-ia32.h
branches/bleeding_edge/src/codegen.cc
branches/bleeding_edge/src/codegen.h
Log:
Fix issue 268 by explicitly calling Unuse (to deallocate all contained
virtual frames) on zone-allocated jump targets. These include jump
targets in AST nodes and the entry and exit targets of deferred code.
See http://code.google.com/p/v8/issues/detail?id=268
Review URL: http://codereview.chromium.org/42067
Modified: branches/bleeding_edge/src/codegen-arm.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.cc (original)
+++ branches/bleeding_edge/src/codegen-arm.cc Wed Mar 11 03:25:48 2009
@@ -284,7 +284,11 @@
DeleteFrame();
// Process any deferred code using the register allocator.
- ProcessDeferred();
+ if (HasStackOverflow()) {
+ ClearDeferred();
+ } else {
+ ProcessDeferred();
+ }
allocator_ = NULL;
scope_ = NULL;
@@ -1133,6 +1137,7 @@
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
@@ -1594,6 +1599,7 @@
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
@@ -1781,6 +1787,8 @@
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
@@ -1971,6 +1979,8 @@
// Exit.
exit.Bind();
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
ASSERT(frame_->height() == original_height);
}
Modified: branches/bleeding_edge/src/codegen-arm.h
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.h (original)
+++ branches/bleeding_edge/src/codegen-arm.h Wed Mar 11 03:25:48 2009
@@ -195,6 +195,8 @@
// Accessors
Scope* scope() const { return scope_; }
+ // Clearing and generating deferred code.
+ void ClearDeferred();
void ProcessDeferred();
bool is_eval() { return is_eval_; }
Modified: branches/bleeding_edge/src/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.cc (original)
+++ branches/bleeding_edge/src/codegen-ia32.cc Wed Mar 11 03:25:48 2009
@@ -307,7 +307,11 @@
DeleteFrame();
// Process any deferred code using the register allocator.
- ProcessDeferred();
+ if (HasStackOverflow()) {
+ ClearDeferred();
+ } else {
+ ProcessDeferred();
+ }
// There is no need to delete the register allocator, it is a
// stack-allocated local.
@@ -1567,6 +1571,7 @@
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
}
@@ -2094,37 +2099,39 @@
// There are two ways to reach the body: from the corresponding
// test or as the fall through of the previous body.
- if (!clause->body_target()->is_linked() && !has_valid_frame()) {
- // If we have neither, skip this body.
- continue;
- } else if (clause->body_target()->is_linked() && has_valid_frame()) {
- // If we have both, put a jump on the fall through path to avoid
- // the dropping of the switch value on the test path. The
- // exception is the default which has already had the switch
- // value dropped.
- if (clause->is_default()) {
- clause->body_target()->Bind();
+ if (clause->body_target()->is_linked() || has_valid_frame()) {
+ if (clause->body_target()->is_linked()) {
+ if (has_valid_frame()) {
+ // If we have both a jump to the test and a fall through, put
+ // a jump on the fall through path to avoid the dropping of
+ // the switch value on the test path. The exception is the
+ // default which has already had the switch value dropped.
+ if (clause->is_default()) {
+ clause->body_target()->Bind();
+ } else {
+ JumpTarget body(this);
+ body.Jump();
+ clause->body_target()->Bind();
+ frame_->Drop();
+ body.Bind();
+ }
+ } else {
+ // No fall through to worry about.
+ clause->body_target()->Bind();
+ if (!clause->is_default()) {
+ frame_->Drop();
+ }
+ }
} else {
- JumpTarget body(this);
- body.Jump();
- clause->body_target()->Bind();
- frame_->Drop();
- body.Bind();
- }
- } else if (clause->body_target()->is_linked()) {
- // No fall through to worry about.
- clause->body_target()->Bind();
- if (!clause->is_default()) {
- frame_->Drop();
+ // Otherwise, we have only fall through.
+ ASSERT(has_valid_frame());
}
- } else {
- // Otherwise, we have only fall through.
- ASSERT(has_valid_frame());
- }
- // We are now prepared to compile the body.
- Comment cmnt(masm_, "[ Case body");
- VisitStatements(clause->statements());
+ // We are now prepared to compile the body.
+ Comment cmnt(masm_, "[ Case body");
+ VisitStatements(clause->statements());
+ }
+ clause->body_target()->Unuse();
}
// We may not have a valid frame here so bind the break target only
@@ -2132,6 +2139,7 @@
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
}
@@ -2452,6 +2460,8 @@
}
DecrementLoopNesting();
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
}
@@ -2636,6 +2646,9 @@
// Exit.
exit.Bind();
+
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
}
Modified: branches/bleeding_edge/src/codegen-ia32.h
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.h (original)
+++ branches/bleeding_edge/src/codegen-ia32.h Wed Mar 11 03:25:48 2009
@@ -340,6 +340,8 @@
// Accessors
Scope* scope() const { return scope_; }
+ // Clearing and generating deferred code.
+ void ClearDeferred();
void ProcessDeferred();
bool is_eval() { return is_eval_; }
Modified: branches/bleeding_edge/src/codegen.cc
==============================================================================
--- branches/bleeding_edge/src/codegen.cc (original)
+++ branches/bleeding_edge/src/codegen.cc Wed Mar 11 03:25:48 2009
@@ -53,6 +53,13 @@
}
+void CodeGenerator::ClearDeferred() {
+ for (int i = 0; i < deferred_.length(); i++) {
+ deferred_[i]->Clear();
+ }
+}
+
+
void CodeGenerator::ProcessDeferred() {
while (!deferred_.is_empty()) {
DeferredCode* code = deferred_.RemoveLast();
@@ -66,6 +73,7 @@
Comment cmnt(masm, code->comment());
code->Generate();
ASSERT(code->enter()->is_bound());
+ code->Clear();
}
}
Modified: branches/bleeding_edge/src/codegen.h
==============================================================================
--- branches/bleeding_edge/src/codegen.h (original)
+++ branches/bleeding_edge/src/codegen.h Wed Mar 11 03:25:48 2009
@@ -52,6 +52,7 @@
// CodeGenerator::CodeGenerator
// CodeGenerator::~CodeGenerator
// CodeGenerator::ProcessDeferred
+// CodeGenerator::ClearDeferred
// CodeGenerator::GenCode
// CodeGenerator::BuildBoilerplate
// CodeGenerator::ComputeCallInitialize
@@ -91,6 +92,14 @@
virtual ~DeferredCode() { }
virtual void Generate() = 0;
+
+ // Unuse the entry and exit targets, deallocating all virtual frames
+ // held by them. It will be impossible to emit a (correct) jump
+ // into or out of the deferred code after clearing.
+ void Clear() {
+ enter_.Unuse();
+ exit_.Unuse();
+ }
MacroAssembler* masm() const { return masm_; }
CodeGenerator* generator() const { return generator_; }
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---