From 69d8678baf1bba763216f34bbdf46f095101e714 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Tue, 4 Feb 2014 00:06:44 +0000 Subject: [PATCH] MIPS: Unroll push loop in r19040 and other push optimizations. BUG= R=plind44@gmail.com Review URL: https://codereview.chromium.org/145973015 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19042 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/builtins-mips.cc | 12 ++++-------- src/mips/code-stubs-mips.cc | 7 +++++-- src/mips/full-codegen-mips.cc | 17 ++++++----------- src/mips/lithium-codegen-mips.cc | 6 ++---- src/mips/stub-cache-mips.cc | 12 ++++++------ 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc index 2d345a4..7a097a3 100644 --- a/src/mips/builtins-mips.cc +++ b/src/mips/builtins-mips.cc @@ -585,8 +585,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // Receiver for constructor call allocated. // t4: JSObject __ bind(&allocated); - __ push(t4); - __ push(t4); + __ Push(t4, t4); // Reload the number of arguments from the stack. // sp[0]: receiver @@ -1092,9 +1091,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { { FrameScope scope(masm, StackFrame::INTERNAL); __ sll(a0, a0, kSmiTagSize); // Smi tagged. - __ push(a0); - - __ push(a2); + __ Push(a0, a2); __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); __ mov(a2, v0); @@ -1244,9 +1241,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Push current limit and index. __ bind(&okay); - __ push(v0); // Limit. - __ mov(a1, zero_reg); // Initial index. - __ push(a1); + __ mov(a1, zero_reg); + __ Push(v0, a1); // Limit and initial index. // Get the receiver. __ lw(a0, MemOperand(fp, kRecvOffset)); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 68cab0c..05ddf87 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -483,9 +483,12 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { FrameScope scope(masm, StackFrame::INTERNAL); ASSERT(descriptor->register_param_count_ == 0 || a0.is(descriptor->register_params_[param_count - 1])); - // Push arguments + // Push arguments, adjust sp. + __ Subu(sp, sp, Operand(param_count * kPointerSize)); for (int i = 0; i < param_count; ++i) { - __ push(descriptor->register_params_[i]); + // Store argument to stack. + __ sw(descriptor->register_params_[i], + MemOperand(sp, (param_count-1-i) * kPointerSize)); } ExternalReference miss = descriptor->miss_handler(); __ CallExternalReference(miss, descriptor->register_param_count_); diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 8ce586e..4a7e504 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1159,10 +1159,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ lw(a2, FieldMemOperand(a2, DescriptorArray::kEnumCacheBridgeCacheOffset)); // Set up the four remaining stack slots. - __ push(v0); // Map. __ li(a0, Operand(Smi::FromInt(0))); - // Push enumeration cache, enumeration cache length (as smi) and zero. - __ Push(a2, a1, a0); + // Push map, enumeration cache, enumeration cache length (as smi) and zero. + __ Push(v0, a2, a1, a0); __ jmp(&loop); __ bind(&no_descriptors); @@ -1227,8 +1226,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Convert the entry to a string or (smi) 0 if it isn't a property // any more. If the property has been removed while iterating, we // just skip it. - __ push(a1); // Enumerable. - __ push(a3); // Current entry. + __ Push(a1, a3); // Enumerable and current entry. __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); __ mov(a3, result_register()); __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); @@ -2506,19 +2504,17 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, // able to drill a hole to that function context, even from inside a // 'with' context. We thus bypass the normal static scope lookup for // var->IsContextSlot(). - __ push(v0); __ li(a0, Operand(var->name())); - __ Push(cp, a0); // Context and name. + __ Push(v0, cp, a0); // Context and name. __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); } } else if (var->mode() == LET && op != Token::INIT_LET) { // Non-initializing assignment to let variable needs a write barrier. if (var->IsLookupSlot()) { - __ push(v0); // Value. __ li(a1, Operand(var->name())); __ li(a0, Operand(Smi::FromInt(language_mode()))); - __ Push(cp, a1, a0); // Context, name, strict mode. + __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. __ CallRuntime(Runtime::kStoreContextSlot, 4); } else { ASSERT(var->IsStackAllocated() || var->IsContextSlot()); @@ -2563,10 +2559,9 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, } } else { ASSERT(var->IsLookupSlot()); - __ push(v0); // Value. __ li(a1, Operand(var->name())); __ li(a0, Operand(Smi::FromInt(language_mode()))); - __ Push(cp, a1, a0); // Context, name, strict mode. + __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. __ CallRuntime(Runtime::kStoreContextSlot, 4); } } diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index eef5405..a2df23f 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -179,8 +179,7 @@ bool LCodeGen::GeneratePrologue() { if (slots > 0) { if (FLAG_debug_code) { __ Subu(sp, sp, Operand(slots * kPointerSize)); - __ push(a0); - __ push(a1); + __ Push(a0, a1); __ Addu(a0, sp, Operand(slots * kPointerSize)); __ li(a1, Operand(kSlotsZapValue)); Label loop; @@ -188,8 +187,7 @@ bool LCodeGen::GeneratePrologue() { __ Subu(a0, a0, Operand(kPointerSize)); __ sw(a1, MemOperand(a0, 2 * kPointerSize)); __ Branch(&loop, ne, a0, Operand(sp)); - __ pop(a1); - __ pop(a0); + __ Pop(a0, a1); } else { __ Subu(sp, sp, Operand(slots * kPointerSize)); } diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 189db80..10813eb 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -778,13 +778,15 @@ static void GenerateFastApiCall(MacroAssembler* masm, int argc, Register* values) { ASSERT(!receiver.is(scratch_in)); - __ push(receiver); + // Preparing to push, adjust sp. + __ Subu(sp, sp, Operand((argc + 1) * kPointerSize)); + __ sw(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver. // Write the arguments to stack frame. for (int i = 0; i < argc; i++) { Register arg = values[argc-1-i]; ASSERT(!receiver.is(arg)); ASSERT(!scratch_in.is(arg)); - __ push(arg); + __ sw(arg, MemOperand(sp, (argc-1-i) * kPointerSize)); // Push arg. } ASSERT(optimization.is_simple_api_call()); @@ -1228,8 +1230,7 @@ Handle StoreStubCompiler::CompileStoreCallback( // checks. ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); - __ push(receiver()); // Receiver. - __ push(holder_reg); + __ Push(receiver(), holder_reg); // Receiver. __ li(at, Operand(callback)); // Callback info. __ push(at); __ li(at, Operand(name)); @@ -1284,8 +1285,7 @@ void StoreStubCompiler::GenerateStoreViaSetter( if (!setter.is_null()) { // Call the JavaScript setter with receiver and value on the stack. - __ push(a1); - __ push(a0); + __ Push(a1, a0); ParameterCount actual(1); ParameterCount expected(setter); __ InvokeFunction(setter, expected, actual, -- 2.7.4