Ensure deallocation of the dynamically allocated shadow targets used

for compilation of try/finally, even in the case where control cannot
reach the end of the finally block.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1490 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2009-03-11 13:14:27 +00:00
parent 1a7359fb9d
commit 3c41aab15d
2 changed files with 38 additions and 34 deletions

View File

@ -2260,31 +2260,33 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
VisitStatementsAndSpill(node->finally_block()->statements()); VisitStatementsAndSpill(node->finally_block()->statements());
if (has_valid_frame()) { if (has_valid_frame()) {
JumpTarget exit(this);
// Restore state and return value or faked TOS. // Restore state and return value or faked TOS.
frame_->EmitPop(r2); frame_->EmitPop(r2);
frame_->EmitPop(r0); frame_->EmitPop(r0);
}
// Generate code to jump to the right destination for all used // Generate code to jump to the right destination for all used
// formerly shadowing targets. Deallocate each shadow target. // formerly shadowing targets. Deallocate each shadow target.
for (int i = 0; i < shadows.length(); i++) { for (int i = 0; i < shadows.length(); i++) {
if (shadows[i]->is_bound()) { if (has_valid_frame() && shadows[i]->is_bound()) {
JumpTarget* original = shadows[i]->other_target(); JumpTarget* original = shadows[i]->other_target();
__ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); __ cmp(r2, Operand(Smi::FromInt(JUMPING + i)));
if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
JumpTarget skip(this); JumpTarget skip(this);
skip.Branch(ne); skip.Branch(ne);
frame_->PrepareForReturn(); frame_->PrepareForReturn();
original->Jump(); original->Jump();
skip.Bind(); skip.Bind();
} else { } else {
original->Branch(eq); original->Branch(eq);
}
} }
delete shadows[i];
} }
delete shadows[i];
}
if (has_valid_frame()) {
// Check if we need to rethrow the exception. // Check if we need to rethrow the exception.
JumpTarget exit(this);
__ cmp(r2, Operand(Smi::FromInt(THROWING))); __ cmp(r2, Operand(Smi::FromInt(THROWING)));
exit.Branch(ne); exit.Branch(ne);

View File

@ -2921,31 +2921,33 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
VisitStatementsAndSpill(node->finally_block()->statements()); VisitStatementsAndSpill(node->finally_block()->statements());
if (has_valid_frame()) { if (has_valid_frame()) {
JumpTarget exit(this);
// Restore state and return value or faked TOS. // Restore state and return value or faked TOS.
frame_->EmitPop(ecx); frame_->EmitPop(ecx);
frame_->EmitPop(eax); frame_->EmitPop(eax);
}
// Generate code to jump to the right destination for all used // Generate code to jump to the right destination for all used
// formerly shadowing targets. Deallocate each shadow target. // formerly shadowing targets. Deallocate each shadow target.
for (int i = 0; i < shadows.length(); i++) { for (int i = 0; i < shadows.length(); i++) {
if (shadows[i]->is_bound()) { if (has_valid_frame() && shadows[i]->is_bound()) {
JumpTarget* original = shadows[i]->other_target(); JumpTarget* original = shadows[i]->other_target();
__ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i)));
if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
JumpTarget skip(this); JumpTarget skip(this);
skip.Branch(not_equal); skip.Branch(not_equal);
frame_->PrepareForReturn(); frame_->PrepareForReturn();
original->Jump(); original->Jump();
skip.Bind(); skip.Bind();
} else { } else {
original->Branch(equal); original->Branch(equal);
}
} }
delete shadows[i];
} }
delete shadows[i];
}
if (has_valid_frame()) {
// Check if we need to rethrow the exception. // Check if we need to rethrow the exception.
JumpTarget exit(this);
__ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING)));
exit.Branch(not_equal); exit.Branch(not_equal);