Revision: 2659 Author: [email protected] Date: Tue Aug 11 04:46:27 2009 Log: Remove much of the register allocation overhead from ARM. When registers are required for calls, explicitly construct a Result with the needed register rather than allocating it. For returns from calls, let the return value in r0 be implicit rather than explicitly allocated.
Review URL: http://codereview.chromium.org/164316 http://code.google.com/p/v8/source/detail?r=2659 Modified: /branches/bleeding_edge/src/arm/codegen-arm.cc /branches/bleeding_edge/src/arm/virtual-frame-arm.cc /branches/bleeding_edge/src/arm/virtual-frame-arm.h ======================================= --- /branches/bleeding_edge/src/arm/codegen-arm.cc Fri Aug 7 01:18:31 2009 +++ /branches/bleeding_edge/src/arm/codegen-arm.cc Tue Aug 11 04:46:27 2009 @@ -1036,11 +1036,7 @@ // We call with 0 args because there are 0 on the stack. CompareStub stub(cc, strict); frame_->CallStub(&stub, 0); - - Result result = allocator_->Allocate(r0); - ASSERT(result.is_valid()); - __ cmp(result.reg(), Operand(0)); - result.Unuse(); + __ cmp(r0, Operand(0)); exit.Jump(); // Do smi comparisons by pointer comparison. @@ -1749,9 +1745,8 @@ primitive.Bind(); frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(0)); + Result arg_count(r0); + __ mov(r0, Operand(0)); frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1); jsobject.Bind(); @@ -1832,15 +1827,10 @@ __ ldr(r0, frame_->ElementAt(4)); // push enumerable frame_->EmitPush(r0); frame_->EmitPush(r3); // push entry - Result arg_count_register = allocator_->Allocate(r0); - ASSERT(arg_count_register.is_valid()); - __ mov(arg_count_register.reg(), Operand(1)); - Result result = frame_->InvokeBuiltin(Builtins::FILTER_KEY, - CALL_JS, - &arg_count_register, - 2); - __ mov(r3, Operand(result.reg())); - result.Unuse(); + Result arg_count_reg(r0); + __ mov(r0, Operand(1)); + frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, &arg_count_reg, 2); + __ mov(r3, Operand(r0)); // If the property has been removed while iterating, we just skip it. __ cmp(r3, Operand(Factory::null_value())); @@ -2433,9 +2423,8 @@ // Load the global object. LoadGlobal(); // Setup the name register. - Result name = allocator_->Allocate(r2); - ASSERT(name.is_valid()); // We are in spilled code. - __ mov(name.reg(), Operand(slot->var()->name())); + Result name(r2); + __ mov(r2, Operand(slot->var()->name())); // Call IC stub. if (typeof_state == INSIDE_TYPEOF) { frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &name, 0); @@ -2775,9 +2764,8 @@ Comment cmnt(masm_, "[ CatchExtensionObject"); LoadAndSpill(node->key()); LoadAndSpill(node->value()); - Result result = - frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); - frame_->EmitPush(result.reg()); + frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); + frame_->EmitPush(r0); ASSERT(frame_->height() == original_height + 1); } @@ -3117,24 +3105,22 @@ } // r0: the number of arguments. - Result num_args = allocator_->Allocate(r0); - ASSERT(num_args.is_valid()); - __ mov(num_args.reg(), Operand(arg_count)); + Result num_args(r0); + __ mov(r0, Operand(arg_count)); // Load the function into r1 as per calling convention. - Result function = allocator_->Allocate(r1); - ASSERT(function.is_valid()); - __ ldr(function.reg(), frame_->ElementAt(arg_count + 1)); + Result function(r1); + __ ldr(r1, frame_->ElementAt(arg_count + 1)); // Call the construct call builtin that handles allocation and // constructor invocation. CodeForSourcePosition(node->position()); Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); - Result result = frame_->CallCodeObject(ic, - RelocInfo::CONSTRUCT_CALL, - &num_args, - &function, - arg_count + 1); + frame_->CallCodeObject(ic, + RelocInfo::CONSTRUCT_CALL, + &num_args, + &function, + arg_count + 1); // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). __ str(r0, frame_->Top()); @@ -3477,9 +3463,8 @@ if (property != NULL) { LoadAndSpill(property->obj()); LoadAndSpill(property->key()); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(1)); // not counting receiver + Result arg_count(r0); + __ mov(r0, Operand(1)); // not counting receiver frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); } else if (variable != NULL) { @@ -3488,9 +3473,8 @@ LoadGlobal(); __ mov(r0, Operand(variable->name())); frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(1)); // not counting receiver + Result arg_count(r0); + __ mov(r0, Operand(1)); // not counting receiver frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); } else if (slot != NULL && slot->type() == Slot::LOOKUP) { @@ -3503,9 +3487,8 @@ frame_->EmitPush(r0); __ mov(r0, Operand(variable->name())); frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(1)); // not counting receiver + Result arg_count(r0); + __ mov(r0, Operand(1)); // not counting receiver frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); } else { @@ -3556,9 +3539,8 @@ smi_label.Branch(eq); frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(0)); // not counting receiver + Result arg_count(r0); + __ mov(r0, Operand(0)); // not counting receiver frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1); continue_label.Jump(); @@ -3581,9 +3563,8 @@ __ tst(r0, Operand(kSmiTagMask)); continue_label.Branch(eq); frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(0)); // not counting receiver + Result arg_count(r0); + __ mov(r0, Operand(0)); // not counting receiver frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); continue_label.Bind(); break; @@ -3669,9 +3650,8 @@ { // Convert the operand to a number. frame_->EmitPush(r0); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(0)); + Result arg_count(r0); + __ mov(r0, Operand(0)); frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); } if (is_postfix) { @@ -4048,14 +4028,10 @@ case Token::IN: { LoadAndSpill(left); LoadAndSpill(right); - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(1)); // not counting receiver - Result result = frame_->InvokeBuiltin(Builtins::IN, - CALL_JS, - &arg_count, - 2); - frame_->EmitPush(result.reg()); + Result arg_count(r0); + __ mov(r0, Operand(1)); // not counting receiver + frame_->InvokeBuiltin(Builtins::IN, CALL_JS, &arg_count, 2); + frame_->EmitPush(r0); break; } @@ -4063,9 +4039,9 @@ LoadAndSpill(left); LoadAndSpill(right); InstanceofStub stub; - Result result = frame_->CallStub(&stub, 2); + frame_->CallStub(&stub, 2); // At this point if instanceof succeeded then r0 == 0. - __ tst(result.reg(), Operand(result.reg())); + __ tst(r0, Operand(r0)); cc_reg_ = eq; break; } @@ -4135,15 +4111,14 @@ Variable* var = expression_->AsVariableProxy()->AsVariable(); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); // Setup the name register. - Result name_reg = cgen_->allocator()->Allocate(r2); - ASSERT(name_reg.is_valid()); - __ mov(name_reg.reg(), Operand(name)); + Result name_reg(r2); + __ mov(r2, Operand(name)); ASSERT(var == NULL || var->is_global()); RelocInfo::Mode rmode = (var == NULL) ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT; - Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0); - frame->EmitPush(answer.reg()); + frame->CallCodeObject(ic, rmode, &name_reg, 0); + frame->EmitPush(r0); break; } @@ -4162,8 +4137,8 @@ RelocInfo::Mode rmode = (var == NULL) ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT; - Result answer = frame->CallCodeObject(ic, rmode, 0); - frame->EmitPush(answer.reg()); + frame->CallCodeObject(ic, rmode, 0); + frame->EmitPush(r0); break; } @@ -4272,20 +4247,18 @@ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<String> name(GetName()); - Result value = cgen_->allocator()->Allocate(r0); - ASSERT(value.is_valid()); - frame->EmitPop(value.reg()); + Result value(r0); + frame->EmitPop(r0); // Setup the name register. - Result property_name = cgen_->allocator()->Allocate(r2); - ASSERT(property_name.is_valid()); - __ mov(property_name.reg(), Operand(name)); - Result answer = frame->CallCodeObject(ic, - RelocInfo::CODE_TARGET, - &value, - &property_name, - 0); - frame->EmitPush(answer.reg()); + Result property_name(r2); + __ mov(r2, Operand(name)); + frame->CallCodeObject(ic, + RelocInfo::CODE_TARGET, + &value, + &property_name, + 0); + frame->EmitPush(r0); break; } @@ -4298,12 +4271,10 @@ // Call IC code. Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); // TODO(1222589): Make the IC grab the values from the stack. - Result value = cgen_->allocator()->Allocate(r0); - ASSERT(value.is_valid()); - frame->EmitPop(value.reg()); // value - Result result = - frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0); - frame->EmitPush(result.reg()); + Result value(r0); + frame->EmitPop(r0); // value + frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0); + frame->EmitPush(r0); break; } ======================================= --- /branches/bleeding_edge/src/arm/virtual-frame-arm.cc Mon Aug 10 04:13:34 2009 +++ /branches/bleeding_edge/src/arm/virtual-frame-arm.cc Tue Aug 11 04:46:27 2009 @@ -186,76 +186,62 @@ } -Result VirtualFrame::RawCallStub(CodeStub* stub) { +void VirtualFrame::RawCallStub(CodeStub* stub) { ASSERT(cgen()->HasValidEntryRegisters()); __ CallStub(stub); - Result result = cgen()->allocator()->Allocate(r0); - ASSERT(result.is_valid()); - return result; } -Result VirtualFrame::CallStub(CodeStub* stub, Result* arg) { +void VirtualFrame::CallStub(CodeStub* stub, Result* arg) { PrepareForCall(0, 0); arg->Unuse(); - return RawCallStub(stub); + RawCallStub(stub); } -Result VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) { +void VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) { PrepareForCall(0, 0); arg0->Unuse(); arg1->Unuse(); - return RawCallStub(stub); + RawCallStub(stub); } -Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { +void VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { PrepareForCall(arg_count, arg_count); ASSERT(cgen()->HasValidEntryRegisters()); __ CallRuntime(f, arg_count); - Result result = cgen()->allocator()->Allocate(r0); - ASSERT(result.is_valid()); - return result; } -Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { +void VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { PrepareForCall(arg_count, arg_count); ASSERT(cgen()->HasValidEntryRegisters()); __ CallRuntime(id, arg_count); - Result result = cgen()->allocator()->Allocate(r0); - ASSERT(result.is_valid()); - return result; } -Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, - InvokeJSFlags flags, - Result* arg_count_register, - int arg_count) { +void VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, + InvokeJSFlags flags, + Result* arg_count_register, + int arg_count) { ASSERT(arg_count_register->reg().is(r0)); PrepareForCall(arg_count, arg_count); arg_count_register->Unuse(); __ InvokeBuiltin(id, flags); - Result result = cgen()->allocator()->Allocate(r0); - return result; } -Result VirtualFrame::RawCallCodeObject(Handle<Code> code, +void VirtualFrame::RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode) { ASSERT(cgen()->HasValidEntryRegisters()); __ Call(code, rmode); - Result result = cgen()->allocator()->Allocate(r0); - ASSERT(result.is_valid()); - return result; } -Result VirtualFrame::CallCodeObject(Handle<Code> code, - RelocInfo::Mode rmode, - int dropped_args) { +void VirtualFrame::CallCodeObject(Handle<Code> code, + RelocInfo::Mode rmode, + int dropped_args) { int spilled_args = 0; switch (code->kind()) { case Code::CALL_IC: @@ -276,14 +262,14 @@ break; } PrepareForCall(spilled_args, dropped_args); - return RawCallCodeObject(code, rmode); + RawCallCodeObject(code, rmode); } -Result VirtualFrame::CallCodeObject(Handle<Code> code, - RelocInfo::Mode rmode, - Result* arg, - int dropped_args) { +void VirtualFrame::CallCodeObject(Handle<Code> code, + RelocInfo::Mode rmode, + Result* arg, + int dropped_args) { int spilled_args = 0; switch (code->kind()) { case Code::LOAD_IC: @@ -304,15 +290,15 @@ } PrepareForCall(spilled_args, dropped_args); arg->Unuse(); - return RawCallCodeObject(code, rmode); + RawCallCodeObject(code, rmode); } -Result VirtualFrame::CallCodeObject(Handle<Code> code, - RelocInfo::Mode rmode, - Result* arg0, - Result* arg1, - int dropped_args) { +void VirtualFrame::CallCodeObject(Handle<Code> code, + RelocInfo::Mode rmode, + Result* arg0, + Result* arg1, + int dropped_args) { int spilled_args = 1; switch (code->kind()) { case Code::STORE_IC: @@ -336,7 +322,7 @@ PrepareForCall(spilled_args, dropped_args); arg0->Unuse(); arg1->Unuse(); - return RawCallCodeObject(code, rmode); + RawCallCodeObject(code, rmode); } ======================================= --- /branches/bleeding_edge/src/arm/virtual-frame-arm.h Mon Aug 10 04:13:34 2009 +++ /branches/bleeding_edge/src/arm/virtual-frame-arm.h Tue Aug 11 04:46:27 2009 @@ -283,46 +283,46 @@ // Call stub given the number of arguments it expects on (and // removes from) the stack. - Result CallStub(CodeStub* stub, int arg_count) { + void CallStub(CodeStub* stub, int arg_count) { PrepareForCall(arg_count, arg_count); - return RawCallStub(stub); + RawCallStub(stub); } // Call stub that expects its argument in r0. The argument is given // as a result which must be the register r0. - Result CallStub(CodeStub* stub, Result* arg); + void CallStub(CodeStub* stub, Result* arg); // Call stub that expects its arguments in r1 and r0. The arguments // are given as results which must be the appropriate registers. - Result CallStub(CodeStub* stub, Result* arg0, Result* arg1); + void CallStub(CodeStub* stub, Result* arg0, Result* arg1); // Call runtime given the number of arguments expected on (and // removed from) the stack. - Result CallRuntime(Runtime::Function* f, int arg_count); - Result CallRuntime(Runtime::FunctionId id, int arg_count); + void CallRuntime(Runtime::Function* f, int arg_count); + void CallRuntime(Runtime::FunctionId id, int arg_count); // Invoke builtin given the number of arguments it expects on (and // removes from) the stack. - Result InvokeBuiltin(Builtins::JavaScript id, - InvokeJSFlags flag, - Result* arg_count_register, - int arg_count); + void InvokeBuiltin(Builtins::JavaScript id, + InvokeJSFlags flag, + Result* arg_count_register, + int arg_count); // Call into an IC stub given the number of arguments it removes // from the stack. Register arguments are passed as results and // consumed by the call. - Result CallCodeObject(Handle<Code> ic, - RelocInfo::Mode rmode, - int dropped_args); - Result CallCodeObject(Handle<Code> ic, - RelocInfo::Mode rmode, - Result* arg, - int dropped_args); - Result CallCodeObject(Handle<Code> ic, - RelocInfo::Mode rmode, - Result* arg0, - Result* arg1, - int dropped_args); + void CallCodeObject(Handle<Code> ic, + RelocInfo::Mode rmode, + int dropped_args); + void CallCodeObject(Handle<Code> ic, + RelocInfo::Mode rmode, + Result* arg, + int dropped_args); + void CallCodeObject(Handle<Code> ic, + RelocInfo::Mode rmode, + Result* arg0, + Result* arg1, + int dropped_args); // Drop a number of elements from the top of the expression stack. May // emit code to affect the physical frame. Does not clobber any registers @@ -506,11 +506,11 @@ // Call a code stub that has already been prepared for calling (via // PrepareForCall). - Result RawCallStub(CodeStub* stub); + void RawCallStub(CodeStub* stub); // Calls a code object which has already been prepared for calling // (via PrepareForCall). - Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); + void RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); bool Equals(VirtualFrame* other); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
