Chromium Code Reviews| Index: src/codegen.cc |
| =================================================================== |
| --- src/codegen.cc (revision 969) |
| +++ src/codegen.cc (working copy) |
| @@ -40,7 +40,7 @@ |
| DeferredCode::DeferredCode(CodeGenerator* generator) |
| : masm_(generator->masm()), |
| generator_(generator), |
| - enter_(generator), |
| + frame_(NULL), |
| exit_(generator), |
| statement_position_(masm_->last_statement_position()), |
| position_(masm_->last_position()) { |
| @@ -51,6 +51,39 @@ |
| } |
| +void DeferredCode::BranchTo(Condition cc) { |
| + // Set the register file and frame based on the first branch to the |
| + // deferred code. |
| + if (frame_ == NULL) { |
| + generator()->allocator()->SaveTo(®isters_); |
| + frame_ = new VirtualFrame(generator()->frame()); |
| + } else { |
| + // The frame and register file must match the existing ones. |
| + ASSERT(generator()->allocator()->Matches(®isters_)); |
| + ASSERT(generator()->frame()->Equals(frame_)); |
| + } |
| + |
| + // Emit the branch. |
| + masm_->j(cc, &enter_, not_taken); |
| +} |
| + |
| + |
| +void DeferredCode::BindExit() { |
| + exit_.Bind(); |
| +} |
| + |
| +void DeferredCode::ExitIfBound() { |
| + if (exit_.is_bound()) { |
| + // This backward jump will emit code to merge the code generator's |
| + // current frame to the exit frame and then delete the current frame. |
| + exit_.Jump(); |
| + } else { |
| + // Don't leak the code generator's current frame. |
| + generator()->DeleteFrame(); |
| + } |
| +} |
| + |
| + |
| void CodeGenerator::ProcessDeferred() { |
| while (!deferred_.is_empty()) { |
| DeferredCode* code = deferred_.RemoveLast(); |
| @@ -63,13 +96,17 @@ |
| masm->RecordPosition(code->position()); |
| } |
| // Bind labels and generate the code. |
| - code->enter()->Bind(); |
| + masm->bind(code->enter()); |
| + allocator()->RestoreFrom(code->registers()); |
| + // Transfer ownership of the deferred code's expected frame to the code |
| + // generator. |
| + SetFrame(code->frame()); |
| + code->clear_frame(); |
| + // For now, we spill before entering any deferred code. |
| frame_->SpillAll(); |
| Comment cmnt(masm, code->comment()); |
| code->Generate(); |
| - if (code->exit()->is_bound()) { |
| - code->exit()->Jump(); |
| - } |
| + code->ExitIfBound(); |
|
William Hesse
2008/12/16 09:10:54
Do we have any deferred code objects that don't re
|
| } |
| } |