From d3ad5be781eb528b5b9f0753b5910d4cd484c3b5 Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Tue, 5 Nov 2013 09:00:00 +0000 Subject: [PATCH] Try to use STMDB/LDMIA instead of LDR/STR sequences whenever possible. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/44313002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17466 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/builtins-arm.cc | 16 +++----- src/arm/code-stubs-arm.cc | 14 ++----- src/arm/full-codegen-arm.cc | 73 ++++++++++++++++--------------------- src/arm/ic-arm.cc | 4 +- 4 files changed, 44 insertions(+), 63 deletions(-) diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc index 60f5290030..ae50d7965b 100644 --- a/src/arm/builtins-arm.cc +++ b/src/arm/builtins-arm.cc @@ -294,10 +294,8 @@ static void CallRuntimePassFunction(MacroAssembler* masm, FrameScope scope(masm, StackFrame::INTERNAL); // Push a copy of the function onto the stack. __ push(r1); - // Push call kind information. - __ push(r5); - // Function is also the parameter to the runtime call. - __ push(r1); + // Push call kind information and function as parameter to the runtime call. + __ Push(r5, r1); __ CallRuntime(function_id, 1); // Restore call kind information. @@ -406,9 +404,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ strb(r4, constructor_count); __ b(ne, &allocate); - __ Push(r1, r2); + __ push(r1); - __ push(r1); // constructor + __ Push(r2, r1); // r1 = constructor // The call will replace the stub, so the countdown is only done once. __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); @@ -1208,8 +1206,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Out of stack space. __ ldr(r1, MemOperand(fp, kFunctionOffset)); - __ push(r1); - __ push(r0); + __ Push(r1, r0); __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); // End of stack check. @@ -1291,8 +1288,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // r0: current argument index __ bind(&loop); __ ldr(r1, MemOperand(fp, kArgsOffset)); - __ push(r1); - __ push(r0); + __ Push(r1, r0); // Call the runtime to access the property in the arguments array. __ CallRuntime(Runtime::kGetProperty, 2); diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 9330eb1411..19993b09a5 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -3344,16 +3344,12 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { // Arguments register must be smi-tagged to call out. __ SmiTag(r0); - __ push(r0); - __ push(r1); - __ push(r2); + __ Push(r2, r1, r0); CreateAllocationSiteStub create_stub; __ CallStub(&create_stub); - __ pop(r2); - __ pop(r1); - __ pop(r0); + __ Pop(r2, r1, r0); __ SmiUntag(r0); } __ b(&done); @@ -5021,8 +5017,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) { FrameScope scope(masm, StackFrame::INTERNAL); __ Push(r1, r0); - __ push(lr); - __ Push(r1, r0); + __ Push(lr, r1, r0); __ mov(ip, Operand(Smi::FromInt(op_))); __ push(ip); __ CallExternalReference(miss, 3); @@ -5030,8 +5025,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) { __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); // Restore registers. __ pop(lr); - __ pop(r0); - __ pop(r1); + __ Pop(r1, r0); } __ Jump(r2); diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 02d1933300..4b9658c54d 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -624,12 +624,11 @@ void FullCodeGenerator::StackValueContext::Plug( Label done; __ bind(materialize_true); __ LoadRoot(ip, Heap::kTrueValueRootIndex); - __ push(ip); __ jmp(&done); __ bind(materialize_false); __ LoadRoot(ip, Heap::kFalseValueRootIndex); - __ push(ip); __ bind(&done); + __ push(ip); } @@ -1608,9 +1607,8 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { __ jmp(&allocated); __ bind(&runtime_allocate); - __ push(r5); __ mov(r0, Operand(Smi::FromInt(size))); - __ push(r0); + __ Push(r5, r0); __ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ pop(r5); @@ -2047,8 +2045,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter - __ push(r3); // iter - __ push(r0); // exception + __ Push(r3, r0); // iter, exception __ jmp(&l_call); // try { received = %yield result } @@ -2084,8 +2081,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ bind(&l_next); __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter - __ push(r3); // iter - __ push(r0); // received + __ Push(r3, r0); // iter, received // result = receiver[f](arg); __ bind(&l_call); @@ -2161,11 +2157,13 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, __ bl(&resume_frame); __ jmp(&done); __ bind(&resume_frame); - __ push(lr); // Return address. - __ push(fp); // Caller's frame pointer. - __ mov(fp, sp); - __ push(cp); // Callee's context. - __ push(r4); // Callee's JS Function. + // lr = return address. + // fp = caller's frame pointer. + // cp = callee's context, + // r4 = callee's JS function. + __ Push(lr, fp, cp, r4); + // Adjust FP to point to saved FP. + __ add(fp, sp, Operand(2 * kPointerSize)); // Load the operand stack size. __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset)); @@ -2197,8 +2195,8 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, __ push(r2); __ b(&push_operand_holes); __ bind(&call_resume); - __ push(r1); - __ push(result_register()); + ASSERT(!result_register().is(r1)); + __ Push(r1, result_register()); __ Push(Smi::FromInt(resume_mode)); __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); // Not reached: the runtime call returns elsewhere. @@ -2420,8 +2418,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); __ mov(r1, r0); - __ pop(r2); - __ pop(r0); // Restore value. + __ Pop(r0, r2); // r0 = restored value. Handle ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); @@ -2555,8 +2552,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { // Record source code position before IC call. SetSourcePosition(expr->position()); - __ pop(r1); // Key. - __ pop(r2); + __ Pop(r2, r1); // r1 = key. Handle ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() @@ -2685,27 +2681,25 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { - // Push copy of the first argument or undefined if it doesn't exist. + // r4: copy of the first argument or undefined if it doesn't exist. if (arg_count > 0) { - __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); + __ ldr(r4, MemOperand(sp, arg_count * kPointerSize)); } else { - __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); + __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); } - __ push(r1); - // Push the receiver of the enclosing function. + // r3: the receiver of the enclosing function. int receiver_offset = 2 + info_->scope()->num_parameters(); - __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize)); - __ push(r1); - // Push the language mode. - __ mov(r1, Operand(Smi::FromInt(language_mode()))); - __ push(r1); + __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); - // Push the start position of the scope the calls resides in. + // r2: the language mode. + __ mov(r2, Operand(Smi::FromInt(language_mode()))); + + // r1: the start position of the scope the calls resides in. __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); - __ push(r1); // Do the runtime call. + __ Push(r4, r3, r2, r1); __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); } @@ -2779,9 +2773,9 @@ void FullCodeGenerator::VisitCall(Call* expr) { __ bind(&slow); // Call the runtime to find the function to call (returned in r0) // and the object holding it (returned in edx). - __ push(context_register()); + ASSERT(!context_register().is(r2)); __ mov(r2, Operand(proxy->name())); - __ push(r2); + __ Push(context_register(), r2); __ CallRuntime(Runtime::kLoadContextSlot, 2); __ Push(r0, r1); // Function, receiver. @@ -3498,8 +3492,7 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { VisitForStackValue(args->at(1)); // index VisitForStackValue(args->at(2)); // value - __ pop(value); - __ pop(index); + __ Pop(index, value); VisitForAccumulatorValue(args->at(0)); // string if (FLAG_debug_code) { @@ -3526,8 +3519,7 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { VisitForStackValue(args->at(1)); // index VisitForStackValue(args->at(2)); // value - __ pop(value); - __ pop(index); + __ Pop(index, value); VisitForAccumulatorValue(args->at(0)); // string if (FLAG_debug_code) { @@ -4271,9 +4263,9 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { } else { // Non-global variable. Call the runtime to try to delete from the // context where the variable was introduced. - __ push(context_register()); + ASSERT(!context_register().is(r2)); __ mov(r2, Operand(var->name())); - __ push(r2); + __ Push(context_register(), r2); __ CallRuntime(Runtime::kDeleteContextSlot, 2); context()->Plug(r0); } @@ -4503,8 +4495,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { break; } case KEYED_PROPERTY: { - __ pop(r1); // Key. - __ pop(r2); // Receiver. + __ Pop(r2, r1); // r1 = key. r2 = receiver. Handle ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index aded4c1dd8..4019461677 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -577,8 +577,8 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3); { FrameScope scope(masm, StackFrame::INTERNAL); - __ push(r2); // save the key - __ Push(r1, r2); // pass the receiver and the key + __ Push(r2, r1); // save the key and the receiver + __ push(r2); // pass the receiver and the key __ CallRuntime(Runtime::kKeyedGetProperty, 2); __ pop(r2); // restore the key }