Chromium Code Reviews| Index: src/arm/stub-cache-arm.cc |
| =================================================================== |
| --- src/arm/stub-cache-arm.cc (revision 6213) |
| +++ src/arm/stub-cache-arm.cc (working copy) |
| @@ -571,6 +571,11 @@ |
| __ CallStub(&stub); |
| } |
| +#ifdef USE_SIMULATOR |
| +static const int kFastApiCallArguments = 4; |
| +#else |
| +static const int kFastApiCallArguments = 3; |
| +#endif |
| // Reserves space for the extra arguments to FastHandleApiCall in the |
| // caller's frame. |
| @@ -579,16 +584,15 @@ |
| static void ReserveSpaceForFastApiCall(MacroAssembler* masm, |
| Register scratch) { |
| __ mov(scratch, Operand(Smi::FromInt(0))); |
| - __ push(scratch); |
| - __ push(scratch); |
| - __ push(scratch); |
| - __ push(scratch); |
| + for (int i = 0; i < kFastApiCallArguments; i++) { |
| + __ push(scratch); |
| + } |
| } |
| // Undoes the effects of ReserveSpaceForFastApiCall. |
| static void FreeSpaceForFastApiCall(MacroAssembler* masm) { |
| - __ Drop(4); |
| + __ Drop(kFastApiCallArguments); |
| } |
| @@ -636,7 +640,65 @@ |
| RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
| } |
| +#ifndef USE_SIMULATOR |
| +static bool GenerateFastApiDirectCall(MacroAssembler* masm, |
| + const CallOptimization& optimization, |
|
antonm
2011/01/11 14:11:33
nit: indentation is slightly off
Zaheer
2011/01/11 15:44:35
Done
|
| + int argc, |
| + Failure** failure) { |
|
antonm
2011/01/11 14:11:33
may you add a stack map like in ia32 version?
Zaheer
2011/01/11 15:44:35
Done
|
| + // Get the function and setup the context. |
| + JSFunction* function = optimization.constant_function(); |
| + __ mov(r5, Operand(Handle<JSFunction>(function))); |
| + __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); |
| + // Pass the additional arguments FastHandleApiCall expects. |
| + Object* call_data = optimization.api_call_info()->data(); |
| + Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); |
| + if (Heap::InNewSpace(call_data)) { |
| + __ Move(r0, api_call_info_handle); |
| + __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); |
| + } else { |
| + __ Move(r6, Handle<Object>(call_data)); |
| + } |
| + __ stm(ib, sp, r5.bit() | r6.bit()); |
|
antonm
2011/01/11 14:11:33
please, add a comment what are you doing here.
|
| + __ add(r2, sp, Operand(2 * kPointerSize)); // r2 = data |
| + |
| + Object* callback = optimization.api_call_info()->callback(); |
| + Address api_function_address = v8::ToCData<Address>(callback); |
| + ApiFunction fun(api_function_address); |
| + |
| + const int kApiStackSpace = 4; |
| + __ PrepareCallApiFunction(kApiStackSpace, |
| + argc + kFastApiCallArguments + 1, |
| + r4); |
| + // v8::Arguments::implicit_args = data |
| + __ str(r2, MemOperand(sp)); |
|
antonm
2011/01/11 14:11:33
I don't know if it'd be faster, but maybe you can
Zaheer
2011/01/11 15:44:35
will check
|
| + __ add(ip, r2, Operand(argc * kPointerSize)); |
| + // v8::Arguments::values = last argument |
| + __ str(ip, MemOperand(sp, 1 * kPointerSize)); |
| + __ mov(ip, Operand(argc)); |
| + // v8::Arguments::length_ = argc |
|
antonm
2011/01/11 14:11:33
for me comments are one line below they should be:
Zaheer
2011/01/11 15:44:35
Mistake! fixed
|
| + __ str(ip, MemOperand(sp, 2 * kPointerSize)); |
| + __ mov(ip, Operand(0)); |
| + // v8::Arguments::is_construct_call = 0 |
| + __ str(ip, MemOperand(sp, 3 * kPointerSize)); |
| + // r0 = v8::Arguments& |
| + __ mov(r0, sp); |
| + |
| + // Emitting a stub call may try to allocate (if the code is not |
| + // already generated). Do not allow the assembler to perform a |
| + // garbage collection but instead return the allocation failure |
| + // object. |
| + MaybeObject* result = |
| + masm->TryCallApiFunctionAndReturn(&fun); |
| + if (result->IsFailure()) { |
| + *failure = Failure::cast(result); |
| + return false; |
| + } |
| + return true; |
| +} |
| +#endif |
| + |
| + |
| class CallInterceptorCompiler BASE_EMBEDDED { |
| public: |
| CallInterceptorCompiler(StubCompiler* stub_compiler, |
| @@ -646,7 +708,7 @@ |
| arguments_(arguments), |
| name_(name) {} |
| - void Compile(MacroAssembler* masm, |
| + bool Compile(MacroAssembler* masm, |
| JSObject* object, |
| JSObject* holder, |
| String* name, |
| @@ -655,7 +717,8 @@ |
| Register scratch1, |
| Register scratch2, |
| Register scratch3, |
| - Label* miss) { |
| + Label* miss, |
| + Failure **failure) { |
| ASSERT(holder->HasNamedInterceptor()); |
| ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| @@ -665,7 +728,7 @@ |
| CallOptimization optimization(lookup); |
| if (optimization.is_constant_call()) { |
| - CompileCacheable(masm, |
| + return CompileCacheable(masm, |
| object, |
| receiver, |
| scratch1, |
| @@ -675,7 +738,8 @@ |
| lookup, |
| name, |
| optimization, |
| - miss); |
| + miss, |
| + failure); |
| } else { |
| CompileRegular(masm, |
| object, |
| @@ -686,11 +750,12 @@ |
| name, |
| holder, |
| miss); |
| + return true; |
| } |
| } |
| private: |
| - void CompileCacheable(MacroAssembler* masm, |
| + bool CompileCacheable(MacroAssembler* masm, |
| JSObject* object, |
| Register receiver, |
| Register scratch1, |
| @@ -700,7 +765,8 @@ |
| LookupResult* lookup, |
| String* name, |
| const CallOptimization& optimization, |
| - Label* miss_label) { |
| + Label* miss_label, |
| + Failure **failure) { |
| ASSERT(optimization.is_constant_call()); |
| ASSERT(!lookup->holder()->IsGlobalObject()); |
| @@ -764,7 +830,17 @@ |
| // Invoke function. |
| if (can_do_fast_api_call) { |
| +#ifdef USE_SIMULATOR |
| GenerateFastApiCall(masm, optimization, arguments_.immediate()); |
| +#else |
| + bool success = GenerateFastApiDirectCall(masm, |
| + optimization, |
| + arguments_.immediate(), |
| + failure); |
| + if (!success) { |
| + return false; |
| + } |
| +#endif |
| } else { |
| __ InvokeFunction(optimization.constant_function(), arguments_, |
| JUMP_FUNCTION); |
| @@ -782,6 +858,8 @@ |
| if (can_do_fast_api_call) { |
| FreeSpaceForFastApiCall(masm); |
| } |
| + |
| + return true; |
| } |
| void CompileRegular(MacroAssembler* masm, |
| @@ -2238,7 +2316,18 @@ |
| } |
| if (depth != kInvalidProtoDepth) { |
| +#ifdef USE_SIMULATOR |
|
antonm
2011/01/11 14:11:33
do we need a special case for simulator?
Zaheer
2011/01/11 15:44:35
currently the simulator interface to the native ap
antonm
2011/01/11 19:27:40
I see, let's ask Erik, maybe he can suggest someth
|
| GenerateFastApiCall(masm(), optimization, argc); |
| +#else |
| + Failure* failure; |
| + bool success = GenerateFastApiDirectCall(masm(), |
| + optimization, |
| + argc, |
| + &failure); |
| + if (!success) { |
| + return failure; |
| + } |
| +#endif |
| } else { |
| __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
| } |
| @@ -2282,7 +2371,8 @@ |
| __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| CallInterceptorCompiler compiler(this, arguments(), r2); |
| - compiler.Compile(masm(), |
| + Failure *failure; |
| + bool success = compiler.Compile(masm(), |
| object, |
| holder, |
| name, |
| @@ -2291,7 +2381,11 @@ |
| r3, |
| r4, |
| r0, |
| - &miss); |
| + &miss, |
| + &failure); |
| + if (!success) { |
| + return false; |
| + } |
| // Move returned value, the function to call, to r1. |
| __ mov(r1, r0); |