diff options
Diffstat (limited to 'deps/v8/src/ia32/stub-cache-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/stub-cache-ia32.cc | 178 |
1 files changed, 76 insertions, 102 deletions
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index f59928fe2..e38708835 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -413,10 +413,6 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, } -// Number of pointers to be reserved on stack for fast API call. -static const int kFastApiCallArguments = 3; - - // Reserves space for the extra arguments to FastHandleApiCall in the // caller's frame. // @@ -427,9 +423,10 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { // -- esp[4] : last argument in the internal frame of the caller // ----------------------------------- __ pop(scratch); - for (int i = 0; i < kFastApiCallArguments; i++) { - __ push(Immediate(Smi::FromInt(0))); - } + __ push(Immediate(Smi::FromInt(0))); + __ push(Immediate(Smi::FromInt(0))); + __ push(Immediate(Smi::FromInt(0))); + __ push(Immediate(Smi::FromInt(0))); __ push(scratch); } @@ -437,81 +434,75 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { // Undoes the effects of ReserveSpaceForFastApiCall. static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { // ----------- S t a t e ------------- - // -- esp[0] : return address. - // -- esp[4] : last fast api call extra argument. + // -- esp[0] : return address + // -- esp[4] : last fast api call extra argument // -- ... - // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument. - // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal - // frame. + // -- esp[16] : first fast api call extra argument + // -- esp[20] : last argument in the internal frame // ----------------------------------- __ pop(scratch); - __ add(Operand(esp), Immediate(kPointerSize * kFastApiCallArguments)); + __ add(Operand(esp), Immediate(kPointerSize * 4)); __ push(scratch); } // Generates call to FastHandleApiCall builtin. -static bool GenerateFastApiCall(MacroAssembler* masm, +static void GenerateFastApiCall(MacroAssembler* masm, const CallOptimization& optimization, - int argc, - Failure** failure) { + int argc) { // ----------- S t a t e ------------- // -- esp[0] : return address // -- esp[4] : object passing the type check // (last fast api call extra argument, // set by CheckPrototypes) - // -- esp[8] : api function + // -- esp[8] : api call data + // -- esp[12] : api callback + // -- esp[16] : api function // (first fast api call extra argument) - // -- esp[12] : api call data - // -- esp[16] : last argument + // -- esp[20] : last argument // -- ... - // -- esp[(argc + 3) * 4] : first argument - // -- esp[(argc + 4) * 4] : receiver + // -- esp[(argc + 5) * 4] : first argument + // -- esp[(argc + 6) * 4] : receiver // ----------------------------------- + // Get the function and setup the context. JSFunction* function = optimization.constant_function(); __ mov(edi, Immediate(Handle<JSFunction>(function))); __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); // Pass the additional arguments FastHandleApiCall expects. - __ mov(Operand(esp, 2 * kPointerSize), edi); + __ mov(Operand(esp, 4 * kPointerSize), edi); + bool info_loaded = false; + Object* callback = optimization.api_call_info()->callback(); + if (Heap::InNewSpace(callback)) { + info_loaded = true; + __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info())); + __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kCallbackOffset)); + __ mov(Operand(esp, 3 * kPointerSize), ebx); + } else { + __ mov(Operand(esp, 3 * kPointerSize), Immediate(Handle<Object>(callback))); + } Object* call_data = optimization.api_call_info()->data(); - Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); if (Heap::InNewSpace(call_data)) { - __ mov(ecx, api_call_info_handle); + if (!info_loaded) { + __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info())); + } __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); - __ mov(Operand(esp, 3 * kPointerSize), ebx); + __ mov(Operand(esp, 2 * kPointerSize), ebx); } else { - __ mov(Operand(esp, 3 * kPointerSize), + __ mov(Operand(esp, 2 * kPointerSize), Immediate(Handle<Object>(call_data))); } - // Prepare arguments for ApiCallEntryStub. - __ lea(eax, Operand(esp, 3 * kPointerSize)); - __ lea(ebx, Operand(esp, (argc + 3) * kPointerSize)); - __ Set(edx, Immediate(argc)); - - Object* callback = optimization.api_call_info()->callback(); - Address api_function_address = v8::ToCData<Address>(callback); - ApiFunction fun(api_function_address); - - ApiCallEntryStub stub(api_call_info_handle, &fun); - - __ EnterInternalFrame(); + // Set the number of arguments. + __ mov(eax, Immediate(argc + 4)); - // 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->TryCallStub(&stub); - if (result->IsFailure()) { - *failure = Failure::cast(result); - return false; - } - - __ LeaveInternalFrame(); - __ ret((argc + 4) * kPointerSize); - return true; + // Jump to the fast api call builtin (tail call). + Handle<Code> code = Handle<Code>( + Builtins::builtin(Builtins::FastHandleApiCall)); + ParameterCount expected(0); + __ InvokeCode(code, expected, expected, + RelocInfo::CODE_TARGET, JUMP_FUNCTION); } @@ -524,7 +515,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { arguments_(arguments), name_(name) {} - bool Compile(MacroAssembler* masm, + void Compile(MacroAssembler* masm, JSObject* object, JSObject* holder, String* name, @@ -533,8 +524,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { Register scratch1, Register scratch2, Register scratch3, - Label* miss, - Failure** failure) { + Label* miss) { ASSERT(holder->HasNamedInterceptor()); ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); @@ -545,18 +535,17 @@ class CallInterceptorCompiler BASE_EMBEDDED { CallOptimization optimization(lookup); if (optimization.is_constant_call()) { - return CompileCacheable(masm, - object, - receiver, - scratch1, - scratch2, - scratch3, - holder, - lookup, - name, - optimization, - miss, - failure); + CompileCacheable(masm, + object, + receiver, + scratch1, + scratch2, + scratch3, + holder, + lookup, + name, + optimization, + miss); } else { CompileRegular(masm, object, @@ -567,12 +556,11 @@ class CallInterceptorCompiler BASE_EMBEDDED { name, holder, miss); - return true; } } private: - bool CompileCacheable(MacroAssembler* masm, + void CompileCacheable(MacroAssembler* masm, JSObject* object, Register receiver, Register scratch1, @@ -582,8 +570,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { LookupResult* lookup, String* name, const CallOptimization& optimization, - Label* miss_label, - Failure** failure) { + Label* miss_label) { ASSERT(optimization.is_constant_call()); ASSERT(!lookup->holder()->IsGlobalObject()); @@ -645,11 +632,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { // Invoke function. if (can_do_fast_api_call) { - bool success = GenerateFastApiCall(masm, optimization, - arguments_.immediate(), failure); - if (!success) { - return false; - } + GenerateFastApiCall(masm, optimization, arguments_.immediate()); } else { __ InvokeFunction(optimization.constant_function(), arguments_, JUMP_FUNCTION); @@ -667,8 +650,6 @@ class CallInterceptorCompiler BASE_EMBEDDED { if (can_do_fast_api_call) { FreeSpaceForFastApiCall(masm, scratch1); } - - return true; } void CompileRegular(MacroAssembler* masm, @@ -924,7 +905,7 @@ Register StubCompiler::CheckPrototypes(JSObject* object, MaybeObject* maybe_lookup_result = Heap::LookupSymbol(name); Object* lookup_result = NULL; // Initialization to please compiler. if (!maybe_lookup_result->ToObject(&lookup_result)) { - set_failure(Failure::cast(maybe_lookup_result)); + set_failure(Failure::cast(lookup_result)); return reg; } name = String::cast(lookup_result); @@ -1065,7 +1046,8 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, __ EnterInternalFrame(); // Push the stack address where the list of arguments ends. - __ lea(scratch2, Operand(esp, -2 * kPointerSize)); + __ mov(scratch2, esp); + __ sub(Operand(scratch2), Immediate(2 * kPointerSize)); __ push(scratch2); __ push(receiver); // receiver __ push(reg); // holder @@ -1079,11 +1061,12 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, __ push(name_reg); // name // Save a pointer to where we pushed the arguments pointer. // This will be passed as the const AccessorInfo& to the C++ callback. - STATIC_ASSERT(ApiGetterEntryStub::kStackSpace == 5); - __ lea(eax, Operand(esp, 4 * kPointerSize)); + __ mov(eax, esp); + __ add(Operand(eax), Immediate(4 * kPointerSize)); __ mov(ebx, esp); // Do call through the api. + ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace); Address getter_address = v8::ToCData<Address>(callback->getter()); ApiFunction fun(getter_address); ApiGetterEntryStub stub(callback_handle, &fun); @@ -1094,7 +1077,7 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, Object* result = NULL; // Initialization to please compiler. { MaybeObject* try_call_result = masm()->TryCallStub(&stub); if (!try_call_result->ToObject(&result)) { - *failure = Failure::cast(try_call_result); + *failure = Failure::cast(result); return false; } } @@ -2225,11 +2208,7 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, } if (depth != kInvalidProtoDepth) { - Failure* failure; - bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); - if (!success) { - return failure; - } + GenerateFastApiCall(masm(), optimization, argc); } else { __ InvokeFunction(function, arguments(), JUMP_FUNCTION); } @@ -2274,21 +2253,16 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); CallInterceptorCompiler compiler(this, arguments(), ecx); - Failure* failure; - bool success = compiler.Compile(masm(), - object, - holder, - name, - &lookup, - edx, - ebx, - edi, - eax, - &miss, - &failure); - if (!success) { - return false; - } + compiler.Compile(masm(), + object, + holder, + name, + &lookup, + edx, + ebx, + edi, + eax, + &miss); // Restore receiver. __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |