From 6ed860b7d6e7e507c914c3707c49c0e537e53ace Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Fri, 12 Jun 2009 14:43:27 +0000 Subject: [PATCH] Remove branching and binding with two arguments from the JumpTarget class. Manually manage off-frame results at the two sites where they were used. Review URL: http://codereview.chromium.org/125048 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2157 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/codegen-ia32.cc | 77 ++++++++++++++++++++++++++++++------------------ src/jump-target.cc | 30 ------------------- src/jump-target.h | 2 -- 3 files changed, 49 insertions(+), 60 deletions(-) diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 638e4e7..b941493 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1871,13 +1871,19 @@ void CodeGenerator::Comparison(Condition cc, // Implement comparison against a constant Smi, inlining the case // where both sides are Smis. left_side.ToRegister(); - ASSERT(left_side.is_valid()); + + // Here we split control flow to the stub call and inlined cases + // before finally splitting it to the control destination. We use + // a jump target and branching to duplicate the virtual frame at + // the first split. We manually handle the off-frame references + // by reconstituting them on the non-fall-through path. JumpTarget is_smi; + Register left_reg = left_side.reg(); + Handle right_val = right_side.handle(); __ test(left_side.reg(), Immediate(kSmiTagMask)); - is_smi.Branch(zero, &left_side, &right_side, taken); + is_smi.Branch(zero, taken); - // Setup and call the compare stub, which expects its arguments - // in registers. + // Setup and call the compare stub. CompareStub stub(cc, strict); Result result = frame_->CallStub(&stub, &left_side, &right_side); result.ToRegister(); @@ -1886,12 +1892,12 @@ void CodeGenerator::Comparison(Condition cc, dest->true_target()->Branch(cc); dest->false_target()->Jump(); - is_smi.Bind(&left_side, &right_side); - left_side.ToRegister(); + is_smi.Bind(); + left_side = Result(left_reg); + right_side = Result(right_val); // Test smi equality and comparison by signed int comparison. if (IsUnsafeSmi(right_side.handle())) { right_side.ToRegister(); - ASSERT(right_side.is_valid()); __ cmp(left_side.reg(), Operand(right_side.reg())); } else { __ cmp(Operand(left_side.reg()), Immediate(right_side.handle())); @@ -1943,35 +1949,50 @@ void CodeGenerator::Comparison(Condition cc, (right_side.is_constant() && !right_side.handle()->IsSmi()); left_side.ToRegister(); right_side.ToRegister(); - JumpTarget is_smi; - if (!known_non_smi) { - // Check for the smi case. + + if (known_non_smi) { + // When non-smi, call out to the compare stub. + CompareStub stub(cc, strict); + Result answer = frame_->CallStub(&stub, &left_side, &right_side); + if (cc == equal) { + __ test(answer.reg(), Operand(answer.reg())); + } else { + __ cmp(answer.reg(), 0); + } + answer.Unuse(); + dest->Split(cc); + } else { + // Here we split control flow to the stub call and inlined cases + // before finally splitting it to the control destination. We use + // a jump target and branching to duplicate the virtual frame at + // the first split. We manually handle the off-frame references + // by reconstituting them on the non-fall-through path. + JumpTarget is_smi; + Register left_reg = left_side.reg(); + Register right_reg = right_side.reg(); + Result temp = allocator_->Allocate(); ASSERT(temp.is_valid()); __ mov(temp.reg(), left_side.reg()); __ or_(temp.reg(), Operand(right_side.reg())); __ test(temp.reg(), Immediate(kSmiTagMask)); temp.Unuse(); - is_smi.Branch(zero, &left_side, &right_side, taken); - } - // When non-smi, call out to the compare stub, which expects its - // arguments in registers. - CompareStub stub(cc, strict); - Result answer = frame_->CallStub(&stub, &left_side, &right_side); - if (cc == equal) { - __ test(answer.reg(), Operand(answer.reg())); - } else { - __ cmp(answer.reg(), 0); - } - answer.Unuse(); - if (known_non_smi) { - dest->Split(cc); - } else { + is_smi.Branch(zero, taken); + // When non-smi, call out to the compare stub. + CompareStub stub(cc, strict); + Result answer = frame_->CallStub(&stub, &left_side, &right_side); + if (cc == equal) { + __ test(answer.reg(), Operand(answer.reg())); + } else { + __ cmp(answer.reg(), 0); + } + answer.Unuse(); dest->true_target()->Branch(cc); dest->false_target()->Jump(); - is_smi.Bind(&left_side, &right_side); - left_side.ToRegister(); - right_side.ToRegister(); + + is_smi.Bind(); + left_side = Result(left_reg); + right_side = Result(right_reg); __ cmp(left_side.reg(), Operand(right_side.reg())); right_side.Unuse(); left_side.Unuse(); diff --git a/src/jump-target.cc b/src/jump-target.cc index 0ae3843..a9d7770 100644 --- a/src/jump-target.cc +++ b/src/jump-target.cc @@ -268,25 +268,6 @@ void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { } -void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint hint) { - ASSERT(cgen()->frame() != NULL); - - // We want to check that non-frame registers at the call site stay in - // the same registers on the fall-through branch. - DECLARE_ARGCHECK_VARS(arg0); - DECLARE_ARGCHECK_VARS(arg1); - - cgen()->frame()->Push(arg0); - cgen()->frame()->Push(arg1); - DoBranch(cc, hint); - *arg1 = cgen()->frame()->Pop(); - *arg0 = cgen()->frame()->Pop(); - - ASSERT_ARGCHECK(arg0); - ASSERT_ARGCHECK(arg1); -} - - void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { ASSERT(cgen()->has_valid_frame()); @@ -328,17 +309,6 @@ void JumpTarget::Bind(Result* arg) { } -void JumpTarget::Bind(Result* arg0, Result* arg1) { - if (cgen()->has_valid_frame()) { - cgen()->frame()->Push(arg0); - cgen()->frame()->Push(arg1); - } - DoBind(); - *arg1 = cgen()->frame()->Pop(); - *arg0 = cgen()->frame()->Pop(); -} - - void JumpTarget::AddReachingFrame(VirtualFrame* frame) { ASSERT(reaching_frames_.length() == merge_labels_.length()); ASSERT(entry_frame_ == NULL); diff --git a/src/jump-target.h b/src/jump-target.h index 1a49c6e..0c42f1b 100644 --- a/src/jump-target.h +++ b/src/jump-target.h @@ -113,14 +113,12 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated. // code after the branch. virtual void Branch(Condition cc, Hint hint = no_hint); virtual void Branch(Condition cc, Result* arg, Hint hint = no_hint); - void Branch(Condition cc, Result* arg0, Result* arg1, Hint hint = no_hint); // Bind a jump target. If there is no current frame at the binding // site, there must be at least one frame reaching via a forward // jump. virtual void Bind(); virtual void Bind(Result* arg); - void Bind(Result* arg0, Result* arg1); // Emit a call to a jump target. There must be a current frame at // the call. The frame at the target is the same as the current -- 2.7.4