| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index a61bfcd997ed76870789c06425de12eaab221ef8..ed1b04b9248d774ecf2dd8c4ebe63cb63ea89c29 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -1875,11 +1875,17 @@ void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(Register type,
|
| b(ne, failure);
|
| }
|
|
|
| +static const int kRegisterPassedArguments = 4;
|
|
|
| void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
|
| int frame_alignment = ActivationFrameAlignment();
|
| +
|
| + // Reserve space for Isolate address which is always passed as last parameter
|
| + num_arguments += 1;
|
| +
|
| // Up to four simple arguments are passed in registers r0..r3.
|
| - int stack_passed_arguments = (num_arguments <= 4) ? 0 : num_arguments - 4;
|
| + int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ?
|
| + 0 : num_arguments - kRegisterPassedArguments;
|
| if (frame_alignment > kPointerSize) {
|
| // Make stack end at alignment and make room for num_arguments - 4 words
|
| // and the original value of sp.
|
| @@ -1896,12 +1902,37 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
|
|
|
| void MacroAssembler::CallCFunction(ExternalReference function,
|
| int num_arguments) {
|
| - mov(ip, Operand(function));
|
| - CallCFunction(ip, num_arguments);
|
| + CallCFunctionHelper(no_reg, function, ip, num_arguments);
|
| +}
|
| +
|
| +void MacroAssembler::CallCFunction(Register function,
|
| + Register scratch,
|
| + int num_arguments) {
|
| + CallCFunctionHelper(function,
|
| + ExternalReference::the_hole_value_location(),
|
| + scratch,
|
| + num_arguments);
|
| +
|
| }
|
|
|
|
|
| -void MacroAssembler::CallCFunction(Register function, int num_arguments) {
|
| +void MacroAssembler::CallCFunctionHelper(Register function,
|
| + ExternalReference function_reference,
|
| + Register scratch,
|
| + int num_arguments) {
|
| + // Push Isolate address as the last argument.
|
| + if (num_arguments < kRegisterPassedArguments) {
|
| + Register arg_to_reg[] = {r0, r1, r2, r3};
|
| + Register r = arg_to_reg[num_arguments];
|
| + mov(r, Operand(ExternalReference::isolate_address()));
|
| + } else {
|
| + int stack_passed_arguments = num_arguments - kRegisterPassedArguments;
|
| + // Push Isolate address on the stack after the arguments.
|
| + mov(scratch, Operand(ExternalReference::isolate_address()));
|
| + str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
|
| + }
|
| + num_arguments += 1;
|
| +
|
| // Make sure that the stack is aligned before calling a C function unless
|
| // running in the simulator. The simulator has its own alignment check which
|
| // provides more information.
|
| @@ -1925,8 +1956,13 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments) {
|
| // Just call directly. The function called cannot cause a GC, or
|
| // allow preemption, so the return address in the link register
|
| // stays correct.
|
| + if (function.is(no_reg)) {
|
| + mov(scratch, Operand(function_reference));
|
| + function = scratch;
|
| + }
|
| Call(function);
|
| - int stack_passed_arguments = (num_arguments <= 4) ? 0 : num_arguments - 4;
|
| + int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ?
|
| + 0 : num_arguments - kRegisterPassedArguments;
|
| if (OS::ActivationFrameAlignment() > kPointerSize) {
|
| ldr(sp, MemOperand(sp, stack_passed_arguments * kPointerSize));
|
| } else {
|
|
|