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
This commit is contained in:
parent
011ca83783
commit
d3ad5be781
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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<Code> 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<Code> 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<Code> ic = is_classic_mode()
|
||||
? isolate()->builtins()->KeyedStoreIC_Initialize()
|
||||
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user