[arm] Port native routines to use UseScratchRegisterScope
Make use of UseScratchRegisterScope instead of using the ip register directly in code stubs, builtin and the deoptimizer. In a lot of cases, we can simply use a different register rather than using the new scope. Bug: v8:6553 Change-Id: Ibc8a9a78bb88f3850c6e8b45871cc3a5b3971b3b Reviewed-on: https://chromium-review.googlesource.com/544837 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#46429}
This commit is contained in:
parent
6cb999b97b
commit
f6aed61992
@ -1006,9 +1006,16 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
|||||||
__ mov(r5, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
|
__ mov(r5, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
|
||||||
isolate())));
|
isolate())));
|
||||||
__ ldr(r5, MemOperand(r5));
|
__ ldr(r5, MemOperand(r5));
|
||||||
__ mov(ip, Operand(-1)); // Push a bad frame pointer to fail if it is used.
|
{
|
||||||
__ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() |
|
UseScratchRegisterScope temps(masm);
|
||||||
ip.bit());
|
Register scratch = temps.Acquire();
|
||||||
|
|
||||||
|
// Push a bad frame pointer to fail if it is used.
|
||||||
|
__ mov(scratch, Operand(-1));
|
||||||
|
__ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | scratch.bit());
|
||||||
|
}
|
||||||
|
|
||||||
|
Register scratch = r6;
|
||||||
|
|
||||||
// Set up frame pointer for the frame to be pushed.
|
// Set up frame pointer for the frame to be pushed.
|
||||||
__ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
|
__ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
|
||||||
@ -1017,17 +1024,17 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
|||||||
Label non_outermost_js;
|
Label non_outermost_js;
|
||||||
ExternalReference js_entry_sp(IsolateAddressId::kJSEntrySPAddress, isolate());
|
ExternalReference js_entry_sp(IsolateAddressId::kJSEntrySPAddress, isolate());
|
||||||
__ mov(r5, Operand(ExternalReference(js_entry_sp)));
|
__ mov(r5, Operand(ExternalReference(js_entry_sp)));
|
||||||
__ ldr(r6, MemOperand(r5));
|
__ ldr(scratch, MemOperand(r5));
|
||||||
__ cmp(r6, Operand::Zero());
|
__ cmp(scratch, Operand::Zero());
|
||||||
__ b(ne, &non_outermost_js);
|
__ b(ne, &non_outermost_js);
|
||||||
__ str(fp, MemOperand(r5));
|
__ str(fp, MemOperand(r5));
|
||||||
__ mov(ip, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
|
__ mov(scratch, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
|
||||||
Label cont;
|
Label cont;
|
||||||
__ b(&cont);
|
__ b(&cont);
|
||||||
__ bind(&non_outermost_js);
|
__ bind(&non_outermost_js);
|
||||||
__ mov(ip, Operand(StackFrame::INNER_JSENTRY_FRAME));
|
__ mov(scratch, Operand(StackFrame::INNER_JSENTRY_FRAME));
|
||||||
__ bind(&cont);
|
__ bind(&cont);
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
|
|
||||||
// Jump to a faked try block that does the invoke, with a faked catch
|
// Jump to a faked try block that does the invoke, with a faked catch
|
||||||
// block that sets the pending exception.
|
// block that sets the pending exception.
|
||||||
@ -1044,10 +1051,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
|||||||
// field in the JSEnv and return a failure sentinel. Coming in here the
|
// field in the JSEnv and return a failure sentinel. Coming in here the
|
||||||
// fp will be invalid because the PushStackHandler below sets it to 0 to
|
// fp will be invalid because the PushStackHandler below sets it to 0 to
|
||||||
// signal the existence of the JSEntry frame.
|
// signal the existence of the JSEntry frame.
|
||||||
__ mov(ip, Operand(ExternalReference(
|
__ mov(scratch,
|
||||||
IsolateAddressId::kPendingExceptionAddress, isolate())));
|
Operand(ExternalReference(IsolateAddressId::kPendingExceptionAddress,
|
||||||
|
isolate())));
|
||||||
}
|
}
|
||||||
__ str(r0, MemOperand(ip));
|
__ str(r0, MemOperand(scratch));
|
||||||
__ LoadRoot(r0, Heap::kExceptionRootIndex);
|
__ LoadRoot(r0, Heap::kExceptionRootIndex);
|
||||||
__ b(&exit);
|
__ b(&exit);
|
||||||
|
|
||||||
@ -1073,16 +1081,16 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
|||||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||||
isolate());
|
isolate());
|
||||||
__ mov(ip, Operand(construct_entry));
|
__ mov(scratch, Operand(construct_entry));
|
||||||
} else {
|
} else {
|
||||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||||
__ mov(ip, Operand(entry));
|
__ mov(scratch, Operand(entry));
|
||||||
}
|
}
|
||||||
__ ldr(ip, MemOperand(ip)); // deref address
|
__ ldr(scratch, MemOperand(scratch)); // deref address
|
||||||
__ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
__ add(scratch, scratch, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||||
|
|
||||||
// Branch and link to JSEntryTrampoline.
|
// Branch and link to JSEntryTrampoline.
|
||||||
__ Call(ip);
|
__ Call(scratch);
|
||||||
|
|
||||||
// Unlink this frame from the handler chain.
|
// Unlink this frame from the handler chain.
|
||||||
__ PopStackHandler();
|
__ PopStackHandler();
|
||||||
@ -1100,9 +1108,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Restore the top frame descriptors from the stack.
|
// Restore the top frame descriptors from the stack.
|
||||||
__ pop(r3);
|
__ pop(r3);
|
||||||
__ mov(ip, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
|
__ mov(scratch, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
|
||||||
isolate())));
|
isolate())));
|
||||||
__ str(r3, MemOperand(ip));
|
__ str(r3, MemOperand(scratch));
|
||||||
|
|
||||||
// Reset the stack to the callee saved registers.
|
// Reset the stack to the callee saved registers.
|
||||||
__ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
|
__ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
|
||||||
@ -1203,8 +1211,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
|||||||
// write-barrier is needed.
|
// write-barrier is needed.
|
||||||
__ bind(&megamorphic);
|
__ bind(&megamorphic);
|
||||||
__ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
|
__ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
|
||||||
__ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
|
__ LoadRoot(r4, Heap::kmegamorphic_symbolRootIndex);
|
||||||
__ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
|
__ str(r4, FieldMemOperand(r5, FixedArray::kHeaderSize));
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
|
|
||||||
// An uninitialized cache is patched with the function
|
// An uninitialized cache is patched with the function
|
||||||
@ -1296,8 +1304,8 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
|
|||||||
__ bind(&got_smi_index_);
|
__ bind(&got_smi_index_);
|
||||||
|
|
||||||
// Check for index out of range.
|
// Check for index out of range.
|
||||||
__ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
|
__ ldr(result_, FieldMemOperand(object_, String::kLengthOffset));
|
||||||
__ cmp(ip, Operand(index_));
|
__ cmp(result_, Operand(index_));
|
||||||
__ b(ls, index_out_of_range_);
|
__ b(ls, index_out_of_range_);
|
||||||
|
|
||||||
__ SmiUntag(index_);
|
__ SmiUntag(index_);
|
||||||
@ -1796,22 +1804,22 @@ void CompareICStub::GenerateKnownReceivers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
|
|
||||||
void CompareICStub::GenerateMiss(MacroAssembler* masm) {
|
void CompareICStub::GenerateMiss(MacroAssembler* masm) {
|
||||||
|
Register scratch = r2;
|
||||||
{
|
{
|
||||||
// Call the runtime system in a fresh internal frame.
|
// Call the runtime system in a fresh internal frame.
|
||||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||||
__ Push(r1, r0);
|
__ Push(r1, r0);
|
||||||
__ Push(lr, r1, r0);
|
__ Push(lr, r1, r0);
|
||||||
__ mov(ip, Operand(Smi::FromInt(op())));
|
__ mov(scratch, Operand(Smi::FromInt(op())));
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
__ CallRuntime(Runtime::kCompareIC_Miss);
|
__ CallRuntime(Runtime::kCompareIC_Miss);
|
||||||
// Compute the entry point of the rewritten stub.
|
// Compute the entry point of the rewritten stub.
|
||||||
__ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
|
__ add(scratch, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||||
// Restore registers.
|
// Restore registers.
|
||||||
__ pop(lr);
|
__ pop(lr);
|
||||||
__ Pop(r1, r0);
|
__ Pop(r1, r0);
|
||||||
}
|
}
|
||||||
|
__ Jump(scratch);
|
||||||
__ Jump(r2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2245,22 +2253,27 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
|
|||||||
__ and_(sp, sp, Operand(-frame_alignment));
|
__ and_(sp, sp, Operand(-frame_alignment));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if V8_HOST_ARCH_ARM
|
{
|
||||||
int32_t entry_hook =
|
UseScratchRegisterScope temps(masm);
|
||||||
reinterpret_cast<int32_t>(isolate()->function_entry_hook());
|
Register scratch = temps.Acquire();
|
||||||
__ mov(ip, Operand(entry_hook));
|
|
||||||
#else
|
|
||||||
// Under the simulator we need to indirect the entry hook through a
|
|
||||||
// trampoline function at a known address.
|
|
||||||
// It additionally takes an isolate as a third parameter
|
|
||||||
__ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
|
|
||||||
|
|
||||||
ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
|
#if V8_HOST_ARCH_ARM
|
||||||
__ mov(ip, Operand(ExternalReference(&dispatcher,
|
int32_t entry_hook =
|
||||||
ExternalReference::BUILTIN_CALL,
|
reinterpret_cast<int32_t>(isolate()->function_entry_hook());
|
||||||
isolate())));
|
__ mov(scratch, Operand(entry_hook));
|
||||||
|
#else
|
||||||
|
// Under the simulator we need to indirect the entry hook through a
|
||||||
|
// trampoline function at a known address.
|
||||||
|
// It additionally takes an isolate as a third parameter
|
||||||
|
__ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
|
||||||
|
|
||||||
|
ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
|
||||||
|
__ mov(scratch,
|
||||||
|
Operand(ExternalReference(
|
||||||
|
&dispatcher, ExternalReference::BUILTIN_CALL, isolate())));
|
||||||
#endif
|
#endif
|
||||||
__ Call(ip);
|
__ Call(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
// Restore the stack pointer if needed.
|
// Restore the stack pointer if needed.
|
||||||
if (frame_alignment > kPointerSize) {
|
if (frame_alignment > kPointerSize) {
|
||||||
@ -2648,8 +2661,8 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
__ sub(r6, r6, Operand(1));
|
__ sub(r6, r6, Operand(1));
|
||||||
__ str(r6, MemOperand(r9, kLevelOffset));
|
__ str(r6, MemOperand(r9, kLevelOffset));
|
||||||
__ ldr(ip, MemOperand(r9, kLimitOffset));
|
__ ldr(r6, MemOperand(r9, kLimitOffset));
|
||||||
__ cmp(r5, ip);
|
__ cmp(r5, r6);
|
||||||
__ b(ne, &delete_allocated_handles);
|
__ b(ne, &delete_allocated_handles);
|
||||||
|
|
||||||
// Leave the API exit frame.
|
// Leave the API exit frame.
|
||||||
@ -2668,8 +2681,8 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
|||||||
|
|
||||||
// Check if the function scheduled an exception.
|
// Check if the function scheduled an exception.
|
||||||
__ LoadRoot(r4, Heap::kTheHoleValueRootIndex);
|
__ LoadRoot(r4, Heap::kTheHoleValueRootIndex);
|
||||||
__ mov(ip, Operand(ExternalReference::scheduled_exception_address(isolate)));
|
__ mov(r6, Operand(ExternalReference::scheduled_exception_address(isolate)));
|
||||||
__ ldr(r5, MemOperand(ip));
|
__ ldr(r5, MemOperand(r6));
|
||||||
__ cmp(r4, r5);
|
__ cmp(r4, r5);
|
||||||
__ b(ne, &promote_scheduled_exception);
|
__ b(ne, &promote_scheduled_exception);
|
||||||
|
|
||||||
@ -2739,20 +2752,22 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
|||||||
// call data
|
// call data
|
||||||
__ push(call_data);
|
__ push(call_data);
|
||||||
|
|
||||||
Register scratch = call_data;
|
Register scratch0 = call_data;
|
||||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
Register scratch1 = r5;
|
||||||
|
__ LoadRoot(scratch0, Heap::kUndefinedValueRootIndex);
|
||||||
// return value
|
// return value
|
||||||
__ push(scratch);
|
__ push(scratch0);
|
||||||
// return value default
|
// return value default
|
||||||
__ push(scratch);
|
__ push(scratch0);
|
||||||
// isolate
|
// isolate
|
||||||
__ mov(scratch, Operand(ExternalReference::isolate_address(masm->isolate())));
|
__ mov(scratch1,
|
||||||
__ push(scratch);
|
Operand(ExternalReference::isolate_address(masm->isolate())));
|
||||||
|
__ push(scratch1);
|
||||||
// holder
|
// holder
|
||||||
__ push(holder);
|
__ push(holder);
|
||||||
|
|
||||||
// Prepare arguments.
|
// Prepare arguments.
|
||||||
__ mov(scratch, sp);
|
__ mov(scratch0, sp);
|
||||||
|
|
||||||
// Allocate the v8::Arguments structure in the arguments' space since
|
// Allocate the v8::Arguments structure in the arguments' space since
|
||||||
// it's not controlled by GC.
|
// it's not controlled by GC.
|
||||||
@ -2761,18 +2776,19 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
|||||||
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
||||||
__ EnterExitFrame(false, kApiStackSpace);
|
__ EnterExitFrame(false, kApiStackSpace);
|
||||||
|
|
||||||
DCHECK(!api_function_address.is(r0) && !scratch.is(r0));
|
DCHECK(!api_function_address.is(r0) && !scratch0.is(r0));
|
||||||
// r0 = FunctionCallbackInfo&
|
// r0 = FunctionCallbackInfo&
|
||||||
// Arguments is after the return address.
|
// Arguments is after the return address.
|
||||||
__ add(r0, sp, Operand(1 * kPointerSize));
|
__ add(r0, sp, Operand(1 * kPointerSize));
|
||||||
// FunctionCallbackInfo::implicit_args_
|
// FunctionCallbackInfo::implicit_args_
|
||||||
__ str(scratch, MemOperand(r0, 0 * kPointerSize));
|
__ str(scratch0, MemOperand(r0, 0 * kPointerSize));
|
||||||
// FunctionCallbackInfo::values_
|
// FunctionCallbackInfo::values_
|
||||||
__ add(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
__ add(scratch1, scratch0,
|
||||||
__ str(ip, MemOperand(r0, 1 * kPointerSize));
|
Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||||
|
__ str(scratch1, MemOperand(r0, 1 * kPointerSize));
|
||||||
// FunctionCallbackInfo::length_ = argc
|
// FunctionCallbackInfo::length_ = argc
|
||||||
__ mov(ip, Operand(argc()));
|
__ mov(scratch0, Operand(argc()));
|
||||||
__ str(ip, MemOperand(r0, 2 * kPointerSize));
|
__ str(scratch0, MemOperand(r0, 2 * kPointerSize));
|
||||||
|
|
||||||
ExternalReference thunk_ref =
|
ExternalReference thunk_ref =
|
||||||
ExternalReference::invoke_function_callback(masm->isolate());
|
ExternalReference::invoke_function_callback(masm->isolate());
|
||||||
|
@ -143,7 +143,8 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
|
|||||||
__ ldr(temp1, MemOperand(src, 4, PostIndex));
|
__ ldr(temp1, MemOperand(src, 4, PostIndex));
|
||||||
__ str(temp1, MemOperand(dest, 4, PostIndex));
|
__ str(temp1, MemOperand(dest, 4, PostIndex));
|
||||||
} else {
|
} else {
|
||||||
Register temp2 = ip;
|
UseScratchRegisterScope temps(&masm);
|
||||||
|
Register temp2 = temps.Acquire();
|
||||||
Label loop;
|
Label loop;
|
||||||
|
|
||||||
__ bic(temp2, chars, Operand(0x3), SetCC);
|
__ bic(temp2, chars, Operand(0x3), SetCC);
|
||||||
@ -219,8 +220,10 @@ MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
|
|||||||
__ vst1(Neon16, NeonListOperand(d0, 2), NeonMemOperand(dest));
|
__ vst1(Neon16, NeonListOperand(d0, 2), NeonMemOperand(dest));
|
||||||
__ Ret();
|
__ Ret();
|
||||||
} else {
|
} else {
|
||||||
|
UseScratchRegisterScope temps(&masm);
|
||||||
|
|
||||||
Register temp1 = r3;
|
Register temp1 = r3;
|
||||||
Register temp2 = ip;
|
Register temp2 = temps.Acquire();
|
||||||
Register temp3 = lr;
|
Register temp3 = lr;
|
||||||
Register temp4 = r4;
|
Register temp4 = r4;
|
||||||
Label loop;
|
Label loop;
|
||||||
|
@ -111,9 +111,11 @@ void Deoptimizer::TableEntryGenerator::Generate() {
|
|||||||
// We use a run-time check for VFP32DREGS.
|
// We use a run-time check for VFP32DREGS.
|
||||||
CpuFeatureScope scope(masm(), VFP32DREGS,
|
CpuFeatureScope scope(masm(), VFP32DREGS,
|
||||||
CpuFeatureScope::kDontCheckSupported);
|
CpuFeatureScope::kDontCheckSupported);
|
||||||
|
UseScratchRegisterScope temps(masm());
|
||||||
|
Register scratch = temps.Acquire();
|
||||||
|
|
||||||
// Check CPU flags for number of registers, setting the Z condition flag.
|
// Check CPU flags for number of registers, setting the Z condition flag.
|
||||||
__ CheckFor32DRegs(ip);
|
__ CheckFor32DRegs(scratch);
|
||||||
|
|
||||||
// Push registers d0-d15, and possibly d16-d31, on the stack.
|
// Push registers d0-d15, and possibly d16-d31, on the stack.
|
||||||
// If d16-d31 are not pushed, decrease the stack pointer instead.
|
// If d16-d31 are not pushed, decrease the stack pointer instead.
|
||||||
@ -130,9 +132,13 @@ void Deoptimizer::TableEntryGenerator::Generate() {
|
|||||||
// handle this a bit differently.
|
// handle this a bit differently.
|
||||||
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
|
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
|
||||||
|
|
||||||
__ mov(ip, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
|
{
|
||||||
isolate())));
|
UseScratchRegisterScope temps(masm());
|
||||||
__ str(fp, MemOperand(ip));
|
Register scratch = temps.Acquire();
|
||||||
|
__ mov(scratch, Operand(ExternalReference(
|
||||||
|
IsolateAddressId::kCEntryFPAddress, isolate())));
|
||||||
|
__ str(fp, MemOperand(scratch));
|
||||||
|
}
|
||||||
|
|
||||||
const int kSavedRegistersAreaSize =
|
const int kSavedRegistersAreaSize =
|
||||||
(kNumberOfRegisters * kPointerSize) + kDoubleRegsSize + kFloatRegsSize;
|
(kNumberOfRegisters * kPointerSize) + kDoubleRegsSize + kFloatRegsSize;
|
||||||
@ -294,15 +300,18 @@ void Deoptimizer::TableEntryGenerator::Generate() {
|
|||||||
|
|
||||||
// Restore the registers from the stack.
|
// Restore the registers from the stack.
|
||||||
__ ldm(ia_w, sp, restored_regs); // all but pc registers.
|
__ ldm(ia_w, sp, restored_regs); // all but pc registers.
|
||||||
__ pop(ip); // remove sp
|
|
||||||
__ pop(ip); // remove lr
|
|
||||||
|
|
||||||
__ InitializeRootRegister();
|
__ InitializeRootRegister();
|
||||||
|
|
||||||
__ pop(ip); // remove pc
|
// Remove sp, lr and pc.
|
||||||
__ pop(ip); // get continuation, leave pc on stack
|
__ Drop(3);
|
||||||
__ pop(lr);
|
{
|
||||||
__ Jump(ip);
|
UseScratchRegisterScope temps(masm());
|
||||||
|
Register scratch = temps.Acquire();
|
||||||
|
__ pop(scratch); // get continuation, leave pc on stack
|
||||||
|
__ pop(lr);
|
||||||
|
__ Jump(scratch);
|
||||||
|
}
|
||||||
__ stop("Unreachable.");
|
__ stop("Unreachable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,13 +324,15 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
|
|||||||
// ARMv7, we can use movw (with a maximum immediate of 0xffff). On ARMv6, we
|
// ARMv7, we can use movw (with a maximum immediate of 0xffff). On ARMv6, we
|
||||||
// need two instructions.
|
// need two instructions.
|
||||||
STATIC_ASSERT((kMaxNumberOfEntries - 1) <= 0xffff);
|
STATIC_ASSERT((kMaxNumberOfEntries - 1) <= 0xffff);
|
||||||
|
UseScratchRegisterScope temps(masm());
|
||||||
|
Register scratch = temps.Acquire();
|
||||||
if (CpuFeatures::IsSupported(ARMv7)) {
|
if (CpuFeatures::IsSupported(ARMv7)) {
|
||||||
CpuFeatureScope scope(masm(), ARMv7);
|
CpuFeatureScope scope(masm(), ARMv7);
|
||||||
Label done;
|
Label done;
|
||||||
for (int i = 0; i < count(); i++) {
|
for (int i = 0; i < count(); i++) {
|
||||||
int start = masm()->pc_offset();
|
int start = masm()->pc_offset();
|
||||||
USE(start);
|
USE(start);
|
||||||
__ movw(ip, i);
|
__ movw(scratch, i);
|
||||||
__ b(&done);
|
__ b(&done);
|
||||||
DCHECK_EQ(table_entry_size_, masm()->pc_offset() - start);
|
DCHECK_EQ(table_entry_size_, masm()->pc_offset() - start);
|
||||||
}
|
}
|
||||||
@ -337,14 +348,14 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
|
|||||||
for (int i = 0; i < count(); i++) {
|
for (int i = 0; i < count(); i++) {
|
||||||
int start = masm()->pc_offset();
|
int start = masm()->pc_offset();
|
||||||
USE(start);
|
USE(start);
|
||||||
__ mov(ip, Operand(i & 0xff)); // Set the low byte.
|
__ mov(scratch, Operand(i & 0xff)); // Set the low byte.
|
||||||
__ b(&high_fixes[i >> 8]); // Jump to the secondary table.
|
__ b(&high_fixes[i >> 8]); // Jump to the secondary table.
|
||||||
DCHECK_EQ(table_entry_size_, masm()->pc_offset() - start);
|
DCHECK_EQ(table_entry_size_, masm()->pc_offset() - start);
|
||||||
}
|
}
|
||||||
// Generate the secondary table, to set the high byte.
|
// Generate the secondary table, to set the high byte.
|
||||||
for (int high = 1; high <= high_fix_max; high++) {
|
for (int high = 1; high <= high_fix_max; high++) {
|
||||||
__ bind(&high_fixes[high]);
|
__ bind(&high_fixes[high]);
|
||||||
__ orr(ip, ip, Operand(high << 8));
|
__ orr(scratch, scratch, Operand(high << 8));
|
||||||
// If this isn't the last entry, emit a branch to the end of the table.
|
// If this isn't the last entry, emit a branch to the end of the table.
|
||||||
// The last entry can just fall through.
|
// The last entry can just fall through.
|
||||||
if (high < high_fix_max) __ b(&high_fixes[0]);
|
if (high < high_fix_max) __ b(&high_fixes[0]);
|
||||||
@ -354,7 +365,7 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
|
|||||||
// through with no additional branch.
|
// through with no additional branch.
|
||||||
__ bind(&high_fixes[0]);
|
__ bind(&high_fixes[0]);
|
||||||
}
|
}
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -439,6 +439,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
|
|||||||
// -- sp[...]: constructor arguments
|
// -- sp[...]: constructor arguments
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
|
Register scratch = r2;
|
||||||
|
|
||||||
// Enter a construct frame.
|
// Enter a construct frame.
|
||||||
{
|
{
|
||||||
FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
|
FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
|
||||||
@ -469,8 +471,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
__ b(&entry);
|
__ b(&entry);
|
||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ ldr(ip, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
__ ldr(scratch, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
__ bind(&entry);
|
__ bind(&entry);
|
||||||
__ sub(r5, r5, Operand(1), SetCC);
|
__ sub(r5, r5, Operand(1), SetCC);
|
||||||
__ b(ge, &loop);
|
__ b(ge, &loop);
|
||||||
@ -486,13 +488,13 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
|
|||||||
// Restore context from the frame.
|
// Restore context from the frame.
|
||||||
__ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
|
__ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
|
||||||
// Restore smi-tagged arguments count from the frame.
|
// Restore smi-tagged arguments count from the frame.
|
||||||
__ ldr(r1, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
|
__ ldr(scratch, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
|
||||||
// Leave construct frame.
|
// Leave construct frame.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove caller arguments from the stack and return.
|
// Remove caller arguments from the stack and return.
|
||||||
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
||||||
__ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
|
__ add(sp, sp, Operand(scratch, LSL, kPointerSizeLog2 - kSmiTagSize));
|
||||||
__ add(sp, sp, Operand(kPointerSize));
|
__ add(sp, sp, Operand(kPointerSize));
|
||||||
__ Jump(lr);
|
__ Jump(lr);
|
||||||
}
|
}
|
||||||
@ -592,9 +594,10 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
|
|||||||
// -- sp[4*kPointerSize]: context
|
// -- sp[4*kPointerSize]: context
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
__ b(&entry);
|
__ b(&entry);
|
||||||
|
|
||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ ldr(ip, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
__ ldr(r6, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
||||||
__ push(ip);
|
__ push(r6);
|
||||||
__ bind(&entry);
|
__ bind(&entry);
|
||||||
__ sub(r5, r5, Operand(1), SetCC);
|
__ sub(r5, r5, Operand(1), SetCC);
|
||||||
__ b(ge, &loop);
|
__ b(ge, &loop);
|
||||||
@ -731,28 +734,31 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
|
__ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
|
||||||
__ ldr(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
|
__ ldr(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
|
||||||
|
|
||||||
// Flood function if we are stepping.
|
|
||||||
Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
|
Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
|
||||||
Label stepping_prepared;
|
Label stepping_prepared;
|
||||||
|
Register scratch = r5;
|
||||||
|
|
||||||
|
// Flood function if we are stepping.
|
||||||
ExternalReference debug_hook =
|
ExternalReference debug_hook =
|
||||||
ExternalReference::debug_hook_on_function_call_address(masm->isolate());
|
ExternalReference::debug_hook_on_function_call_address(masm->isolate());
|
||||||
__ mov(ip, Operand(debug_hook));
|
__ mov(scratch, Operand(debug_hook));
|
||||||
__ ldrsb(ip, MemOperand(ip));
|
__ ldrsb(scratch, MemOperand(scratch));
|
||||||
__ cmp(ip, Operand(0));
|
__ cmp(scratch, Operand(0));
|
||||||
__ b(ne, &prepare_step_in_if_stepping);
|
__ b(ne, &prepare_step_in_if_stepping);
|
||||||
|
|
||||||
// Flood function if we need to continue stepping in the suspended generator.
|
// Flood function if we need to continue stepping in the suspended
|
||||||
|
// generator.
|
||||||
ExternalReference debug_suspended_generator =
|
ExternalReference debug_suspended_generator =
|
||||||
ExternalReference::debug_suspended_generator_address(masm->isolate());
|
ExternalReference::debug_suspended_generator_address(masm->isolate());
|
||||||
__ mov(ip, Operand(debug_suspended_generator));
|
__ mov(scratch, Operand(debug_suspended_generator));
|
||||||
__ ldr(ip, MemOperand(ip));
|
__ ldr(scratch, MemOperand(scratch));
|
||||||
__ cmp(ip, Operand(r1));
|
__ cmp(scratch, Operand(r1));
|
||||||
__ b(eq, &prepare_step_in_suspended_generator);
|
__ b(eq, &prepare_step_in_suspended_generator);
|
||||||
__ bind(&stepping_prepared);
|
__ bind(&stepping_prepared);
|
||||||
|
|
||||||
// Push receiver.
|
// Push receiver.
|
||||||
__ ldr(ip, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset));
|
__ ldr(scratch, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset));
|
||||||
__ Push(ip);
|
__ Push(scratch);
|
||||||
|
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r1 : the JSGeneratorObject to resume
|
// -- r1 : the JSGeneratorObject to resume
|
||||||
@ -798,8 +804,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
// undefined because generator functions are non-constructable.
|
// undefined because generator functions are non-constructable.
|
||||||
__ Move(r3, r1);
|
__ Move(r3, r1);
|
||||||
__ Move(r1, r4);
|
__ Move(r1, r4);
|
||||||
__ ldr(r5, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
__ ldr(scratch, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
||||||
__ Jump(r5);
|
__ Jump(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
__ bind(&prepare_step_in_if_stepping);
|
__ bind(&prepare_step_in_if_stepping);
|
||||||
@ -1056,14 +1062,13 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
|
|||||||
Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)));
|
Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)));
|
||||||
__ Assert(eq, kExpectedOptimizationSentinel);
|
__ Assert(eq, kExpectedOptimizationSentinel);
|
||||||
}
|
}
|
||||||
|
// Checking whether the queued function is ready for install is
|
||||||
// Checking whether the queued function is ready for install is optional,
|
// optional, since we come across interrupts and stack checks elsewhere.
|
||||||
// since we come across interrupts and stack checks elsewhere. However,
|
// However, not checking may delay installing ready functions, and
|
||||||
// not checking may delay installing ready functions, and always checking
|
// always checking would be quite expensive. A good compromise is to
|
||||||
// would be quite expensive. A good compromise is to first check against
|
// first check against stack limit as a cue for an interrupt signal.
|
||||||
// stack limit as a cue for an interrupt signal.
|
__ LoadRoot(scratch2, Heap::kStackLimitRootIndex);
|
||||||
__ LoadRoot(ip, Heap::kStackLimitRootIndex);
|
__ cmp(sp, Operand(scratch2));
|
||||||
__ cmp(sp, Operand(ip));
|
|
||||||
__ b(hs, &fallthrough);
|
__ b(hs, &fallthrough);
|
||||||
GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
|
GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
|
||||||
}
|
}
|
||||||
@ -1229,9 +1234,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
// Dispatch to the first bytecode handler for the function.
|
// Dispatch to the first bytecode handler for the function.
|
||||||
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
|
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
|
||||||
kInterpreterBytecodeOffsetRegister));
|
kInterpreterBytecodeOffsetRegister));
|
||||||
__ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
|
__ ldr(r4, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
|
||||||
kPointerSizeLog2));
|
kPointerSizeLog2));
|
||||||
__ Call(ip);
|
__ Call(r4);
|
||||||
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
|
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
|
||||||
|
|
||||||
// The return value is in r0.
|
// The return value is in r0.
|
||||||
@ -1361,8 +1366,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver to be constructed.
|
// Push a slot for the receiver to be constructed.
|
||||||
__ mov(ip, Operand::Zero());
|
__ mov(r5, Operand::Zero());
|
||||||
__ push(ip);
|
__ push(r5);
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
||||||
|
|
||||||
@ -1415,8 +1420,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver to be constructed.
|
// Push a slot for the receiver to be constructed.
|
||||||
__ mov(ip, Operand::Zero());
|
__ mov(r5, Operand::Zero());
|
||||||
__ push(ip);
|
__ push(r5);
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
||||||
|
|
||||||
@ -1473,9 +1478,11 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
|||||||
// Dispatch to the target bytecode.
|
// Dispatch to the target bytecode.
|
||||||
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
|
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
|
||||||
kInterpreterBytecodeOffsetRegister));
|
kInterpreterBytecodeOffsetRegister));
|
||||||
__ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
|
UseScratchRegisterScope temps(masm);
|
||||||
kPointerSizeLog2));
|
Register scratch = temps.Acquire();
|
||||||
__ mov(pc, ip);
|
__ ldr(scratch, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
|
||||||
|
kPointerSizeLog2));
|
||||||
|
__ Jump(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
|
void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
|
||||||
@ -1741,11 +1748,14 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
__ ldr(fp, MemOperand(
|
__ ldr(fp, MemOperand(
|
||||||
sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
||||||
__ Pop(ip);
|
|
||||||
|
UseScratchRegisterScope temps(masm);
|
||||||
|
Register scratch = temps.Acquire();
|
||||||
|
__ Pop(scratch);
|
||||||
__ add(sp, sp,
|
__ add(sp, sp,
|
||||||
Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp));
|
||||||
__ Pop(lr);
|
__ Pop(lr);
|
||||||
__ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
__ add(pc, scratch, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -1949,13 +1959,14 @@ void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
|
|||||||
// r0: actual number of arguments
|
// r0: actual number of arguments
|
||||||
// r1: callable
|
// r1: callable
|
||||||
{
|
{
|
||||||
|
Register scratch = r3;
|
||||||
Label loop;
|
Label loop;
|
||||||
// Calculate the copy start address (destination). Copy end address is sp.
|
// Calculate the copy start address (destination). Copy end address is sp.
|
||||||
__ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
|
__ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
|
||||||
|
|
||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ ldr(ip, MemOperand(r2, -kPointerSize));
|
__ ldr(scratch, MemOperand(r2, -kPointerSize));
|
||||||
__ str(ip, MemOperand(r2));
|
__ str(scratch, MemOperand(r2));
|
||||||
__ sub(r2, r2, Operand(kPointerSize));
|
__ sub(r2, r2, Operand(kPointerSize));
|
||||||
__ cmp(r2, sp);
|
__ cmp(r2, sp);
|
||||||
__ b(ne, &loop);
|
__ b(ne, &loop);
|
||||||
@ -2092,17 +2103,19 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
__ AssertFixedArray(r2);
|
__ AssertFixedArray(r2);
|
||||||
|
|
||||||
|
Register scratch = r8;
|
||||||
|
|
||||||
// Check for stack overflow.
|
// Check for stack overflow.
|
||||||
{
|
{
|
||||||
// Check the stack for overflow. We are not trying to catch interruptions
|
// Check the stack for overflow. We are not trying to catch interruptions
|
||||||
// (i.e. debug break and preemption) here, so check the "real stack limit".
|
// (i.e. debug break and preemption) here, so check the "real stack limit".
|
||||||
Label done;
|
Label done;
|
||||||
__ LoadRoot(ip, Heap::kRealStackLimitRootIndex);
|
__ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
|
||||||
// Make ip the space we have left. The stack might already be overflowed
|
// The stack might already be overflowed here which will cause 'scratch' to
|
||||||
// here which will cause ip to become negative.
|
// become negative.
|
||||||
__ sub(ip, sp, ip);
|
__ sub(scratch, sp, scratch);
|
||||||
// Check if the arguments will overflow the stack.
|
// Check if the arguments will overflow the stack.
|
||||||
__ cmp(ip, Operand(r4, LSL, kPointerSizeLog2));
|
__ cmp(scratch, Operand(r4, LSL, kPointerSizeLog2));
|
||||||
__ b(gt, &done); // Signed comparison.
|
__ b(gt, &done); // Signed comparison.
|
||||||
__ TailCallRuntime(Runtime::kThrowStackOverflow);
|
__ TailCallRuntime(Runtime::kThrowStackOverflow);
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -2116,11 +2129,11 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
|||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ cmp(r6, r4);
|
__ cmp(r6, r4);
|
||||||
__ b(eq, &done);
|
__ b(eq, &done);
|
||||||
__ add(ip, r2, Operand(r6, LSL, kPointerSizeLog2));
|
__ add(scratch, r2, Operand(r6, LSL, kPointerSizeLog2));
|
||||||
__ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize));
|
__ ldr(scratch, FieldMemOperand(scratch, FixedArray::kHeaderSize));
|
||||||
__ cmp(ip, r5);
|
__ cmp(scratch, r5);
|
||||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex, eq);
|
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex, eq);
|
||||||
__ Push(ip);
|
__ Push(scratch);
|
||||||
__ add(r6, r6, Operand(1));
|
__ add(r6, r6, Operand(1));
|
||||||
__ b(&loop);
|
__ b(&loop);
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -2141,11 +2154,15 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
|||||||
// -- r2 : start index (to support rest parameters)
|
// -- r2 : start index (to support rest parameters)
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
|
Register scratch = r6;
|
||||||
|
|
||||||
// Check if we have an arguments adaptor frame below the function frame.
|
// Check if we have an arguments adaptor frame below the function frame.
|
||||||
Label arguments_adaptor, arguments_done;
|
Label arguments_adaptor, arguments_done;
|
||||||
__ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
__ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||||
__ ldr(ip, MemOperand(r4, CommonFrameConstants::kContextOrFrameTypeOffset));
|
__ ldr(scratch,
|
||||||
__ cmp(ip, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
MemOperand(r4, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||||
|
__ cmp(scratch,
|
||||||
|
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||||
__ b(eq, &arguments_adaptor);
|
__ b(eq, &arguments_adaptor);
|
||||||
{
|
{
|
||||||
__ ldr(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
__ ldr(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||||
@ -2177,8 +2194,8 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
|||||||
__ add(r0, r0, r5);
|
__ add(r0, r0, r5);
|
||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
{
|
{
|
||||||
__ ldr(ip, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
__ ldr(scratch, MemOperand(r4, r5, LSL, kPointerSizeLog2));
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
__ sub(r5, r5, Operand(1), SetCC);
|
__ sub(r5, r5, Operand(1), SetCC);
|
||||||
__ b(ne, &loop);
|
__ b(ne, &loop);
|
||||||
}
|
}
|
||||||
@ -2438,6 +2455,8 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
|
|||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Register scratch = r6;
|
||||||
|
|
||||||
// Relocate arguments down the stack.
|
// Relocate arguments down the stack.
|
||||||
{
|
{
|
||||||
Label loop, done_loop;
|
Label loop, done_loop;
|
||||||
@ -2445,8 +2464,8 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
|
|||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ cmp(r5, r0);
|
__ cmp(r5, r0);
|
||||||
__ b(gt, &done_loop);
|
__ b(gt, &done_loop);
|
||||||
__ ldr(ip, MemOperand(sp, r4, LSL, kPointerSizeLog2));
|
__ ldr(scratch, MemOperand(sp, r4, LSL, kPointerSizeLog2));
|
||||||
__ str(ip, MemOperand(sp, r5, LSL, kPointerSizeLog2));
|
__ str(scratch, MemOperand(sp, r5, LSL, kPointerSizeLog2));
|
||||||
__ add(r4, r4, Operand(1));
|
__ add(r4, r4, Operand(1));
|
||||||
__ add(r5, r5, Operand(1));
|
__ add(r5, r5, Operand(1));
|
||||||
__ b(&loop);
|
__ b(&loop);
|
||||||
@ -2461,8 +2480,8 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
|
|||||||
__ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
__ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
||||||
__ bind(&loop);
|
__ bind(&loop);
|
||||||
__ sub(r4, r4, Operand(1), SetCC);
|
__ sub(r4, r4, Operand(1), SetCC);
|
||||||
__ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2));
|
__ ldr(scratch, MemOperand(r2, r4, LSL, kPointerSizeLog2));
|
||||||
__ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
|
__ str(scratch, MemOperand(sp, r0, LSL, kPointerSizeLog2));
|
||||||
__ add(r0, r0, Operand(1));
|
__ add(r0, r0, Operand(1));
|
||||||
__ b(gt, &loop);
|
__ b(gt, &loop);
|
||||||
}
|
}
|
||||||
@ -2486,18 +2505,19 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Patch the receiver to [[BoundThis]].
|
// Patch the receiver to [[BoundThis]].
|
||||||
__ ldr(ip, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset));
|
__ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset));
|
||||||
__ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
|
__ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
|
||||||
|
|
||||||
// Push the [[BoundArguments]] onto the stack.
|
// Push the [[BoundArguments]] onto the stack.
|
||||||
Generate_PushBoundArguments(masm);
|
Generate_PushBoundArguments(masm);
|
||||||
|
|
||||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||||
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||||
__ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
|
||||||
|
__ mov(r3, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||||
masm->isolate())));
|
masm->isolate())));
|
||||||
__ ldr(ip, MemOperand(ip));
|
__ ldr(r3, MemOperand(r3));
|
||||||
__ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
__ add(pc, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -2599,9 +2619,10 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||||
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||||
__ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
|
||||||
__ ldr(ip, MemOperand(ip));
|
__ mov(r2, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||||
__ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
__ ldr(r2, MemOperand(r2));
|
||||||
|
__ add(pc, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -2726,10 +2747,12 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
__ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
__ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
||||||
__ b(eq, &dont_adapt_arguments);
|
__ b(eq, &dont_adapt_arguments);
|
||||||
|
|
||||||
|
Register scratch = r5;
|
||||||
|
|
||||||
{ // Enough parameters: actual >= expected
|
{ // Enough parameters: actual >= expected
|
||||||
__ bind(&enough);
|
__ bind(&enough);
|
||||||
EnterArgumentsAdaptorFrame(masm);
|
EnterArgumentsAdaptorFrame(masm);
|
||||||
Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
|
Generate_StackOverflowCheck(masm, r2, scratch, &stack_overflow);
|
||||||
|
|
||||||
// Calculate copy start address into r0 and copy end address into r4.
|
// Calculate copy start address into r0 and copy end address into r4.
|
||||||
// r0: actual number of arguments as a smi
|
// r0: actual number of arguments as a smi
|
||||||
@ -2750,8 +2773,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
|
|
||||||
Label copy;
|
Label copy;
|
||||||
__ bind(©);
|
__ bind(©);
|
||||||
__ ldr(ip, MemOperand(r0, 0));
|
__ ldr(scratch, MemOperand(r0, 0));
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
__ cmp(r0, r4); // Compare before moving to next argument.
|
__ cmp(r0, r4); // Compare before moving to next argument.
|
||||||
__ sub(r0, r0, Operand(kPointerSize));
|
__ sub(r0, r0, Operand(kPointerSize));
|
||||||
__ b(ne, ©);
|
__ b(ne, ©);
|
||||||
@ -2762,7 +2785,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
{ // Too few parameters: Actual < expected
|
{ // Too few parameters: Actual < expected
|
||||||
__ bind(&too_few);
|
__ bind(&too_few);
|
||||||
EnterArgumentsAdaptorFrame(masm);
|
EnterArgumentsAdaptorFrame(masm);
|
||||||
Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
|
Generate_StackOverflowCheck(masm, r2, scratch, &stack_overflow);
|
||||||
|
|
||||||
// Calculate copy start address into r0 and copy end address is fp.
|
// Calculate copy start address into r0 and copy end address is fp.
|
||||||
// r0: actual number of arguments as a smi
|
// r0: actual number of arguments as a smi
|
||||||
@ -2778,9 +2801,11 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
// r3: new target (passed through to callee)
|
// r3: new target (passed through to callee)
|
||||||
Label copy;
|
Label copy;
|
||||||
__ bind(©);
|
__ bind(©);
|
||||||
|
|
||||||
// Adjust load for return address and receiver.
|
// Adjust load for return address and receiver.
|
||||||
__ ldr(ip, MemOperand(r0, 2 * kPointerSize));
|
__ ldr(scratch, MemOperand(r0, 2 * kPointerSize));
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
|
|
||||||
__ cmp(r0, fp); // Compare before moving to next argument.
|
__ cmp(r0, fp); // Compare before moving to next argument.
|
||||||
__ sub(r0, r0, Operand(kPointerSize));
|
__ sub(r0, r0, Operand(kPointerSize));
|
||||||
__ b(ne, ©);
|
__ b(ne, ©);
|
||||||
@ -2789,7 +2814,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
// r1: function
|
// r1: function
|
||||||
// r2: expected number of arguments
|
// r2: expected number of arguments
|
||||||
// r3: new target (passed through to callee)
|
// r3: new target (passed through to callee)
|
||||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||||
__ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
|
__ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
|
||||||
// Adjust for frame.
|
// Adjust for frame.
|
||||||
__ sub(r4, r4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
|
__ sub(r4, r4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
|
||||||
@ -2797,7 +2822,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
|||||||
|
|
||||||
Label fill;
|
Label fill;
|
||||||
__ bind(&fill);
|
__ bind(&fill);
|
||||||
__ push(ip);
|
__ push(scratch);
|
||||||
__ cmp(sp, r4);
|
__ cmp(sp, r4);
|
||||||
__ b(ne, &fill);
|
__ b(ne, &fill);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user