diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-11-11 22:42:06 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-11-11 22:42:06 -0800 |
commit | 564a48643bd3edc6da845e458277a54c8068d0e2 (patch) | |
tree | ea483922ae95ef2f1c206aaab2238bf58fd860df /deps/v8/src/ia32/stub-cache-ia32.cc | |
parent | d4af8a6b6ac0045620ad6da94e97a71e6e6fad52 (diff) | |
download | node-new-564a48643bd3edc6da845e458277a54c8068d0e2.tar.gz |
Upgrade V8 to 2.5.6
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, 102 insertions, 76 deletions
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index e387088359..f59928fe2b 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -413,6 +413,10 @@ 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. // @@ -423,10 +427,9 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { // -- esp[4] : last argument in the internal frame of the caller // ----------------------------------- __ pop(scratch); - __ push(Immediate(Smi::FromInt(0))); - __ push(Immediate(Smi::FromInt(0))); - __ push(Immediate(Smi::FromInt(0))); - __ push(Immediate(Smi::FromInt(0))); + for (int i = 0; i < kFastApiCallArguments; i++) { + __ push(Immediate(Smi::FromInt(0))); + } __ push(scratch); } @@ -434,75 +437,81 @@ 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[16] : first fast api call extra argument - // -- esp[20] : last argument in the internal frame + // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument. + // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal + // frame. // ----------------------------------- __ pop(scratch); - __ add(Operand(esp), Immediate(kPointerSize * 4)); + __ add(Operand(esp), Immediate(kPointerSize * kFastApiCallArguments)); __ push(scratch); } // Generates call to FastHandleApiCall builtin. -static void GenerateFastApiCall(MacroAssembler* masm, +static bool GenerateFastApiCall(MacroAssembler* masm, const CallOptimization& optimization, - int argc) { + int argc, + Failure** failure) { // ----------- 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 call data - // -- esp[12] : api callback - // -- esp[16] : api function + // -- esp[8] : api function // (first fast api call extra argument) - // -- esp[20] : last argument + // -- esp[12] : api call data + // -- esp[16] : last argument // -- ... - // -- esp[(argc + 5) * 4] : first argument - // -- esp[(argc + 6) * 4] : receiver + // -- esp[(argc + 3) * 4] : first argument + // -- esp[(argc + 4) * 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, 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))); - } + __ mov(Operand(esp, 2 * kPointerSize), edi); Object* call_data = optimization.api_call_info()->data(); + Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); if (Heap::InNewSpace(call_data)) { - if (!info_loaded) { - __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info())); - } + __ mov(ecx, api_call_info_handle); __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); - __ mov(Operand(esp, 2 * kPointerSize), ebx); + __ mov(Operand(esp, 3 * kPointerSize), ebx); } else { - __ mov(Operand(esp, 2 * kPointerSize), + __ mov(Operand(esp, 3 * kPointerSize), Immediate(Handle<Object>(call_data))); } - // Set the number of arguments. - __ mov(eax, Immediate(argc + 4)); + // Prepare arguments for ApiCallEntryStub. + __ lea(eax, Operand(esp, 3 * kPointerSize)); + __ lea(ebx, Operand(esp, (argc + 3) * kPointerSize)); + __ Set(edx, Immediate(argc)); - // 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); + 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(); + + // 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; } @@ -515,7 +524,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { arguments_(arguments), name_(name) {} - void Compile(MacroAssembler* masm, + bool Compile(MacroAssembler* masm, JSObject* object, JSObject* holder, String* name, @@ -524,7 +533,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { Register scratch1, Register scratch2, Register scratch3, - Label* miss) { + Label* miss, + Failure** failure) { ASSERT(holder->HasNamedInterceptor()); ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); @@ -535,17 +545,18 @@ class CallInterceptorCompiler BASE_EMBEDDED { CallOptimization optimization(lookup); if (optimization.is_constant_call()) { - CompileCacheable(masm, - object, - receiver, - scratch1, - scratch2, - scratch3, - holder, - lookup, - name, - optimization, - miss); + return CompileCacheable(masm, + object, + receiver, + scratch1, + scratch2, + scratch3, + holder, + lookup, + name, + optimization, + miss, + failure); } else { CompileRegular(masm, object, @@ -556,11 +567,12 @@ class CallInterceptorCompiler BASE_EMBEDDED { name, holder, miss); + return true; } } private: - void CompileCacheable(MacroAssembler* masm, + bool CompileCacheable(MacroAssembler* masm, JSObject* object, Register receiver, Register scratch1, @@ -570,7 +582,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { LookupResult* lookup, String* name, const CallOptimization& optimization, - Label* miss_label) { + Label* miss_label, + Failure** failure) { ASSERT(optimization.is_constant_call()); ASSERT(!lookup->holder()->IsGlobalObject()); @@ -632,7 +645,11 @@ class CallInterceptorCompiler BASE_EMBEDDED { // Invoke function. if (can_do_fast_api_call) { - GenerateFastApiCall(masm, optimization, arguments_.immediate()); + bool success = GenerateFastApiCall(masm, optimization, + arguments_.immediate(), failure); + if (!success) { + return false; + } } else { __ InvokeFunction(optimization.constant_function(), arguments_, JUMP_FUNCTION); @@ -650,6 +667,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { if (can_do_fast_api_call) { FreeSpaceForFastApiCall(masm, scratch1); } + + return true; } void CompileRegular(MacroAssembler* masm, @@ -905,7 +924,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(lookup_result)); + set_failure(Failure::cast(maybe_lookup_result)); return reg; } name = String::cast(lookup_result); @@ -1046,8 +1065,7 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, __ EnterInternalFrame(); // Push the stack address where the list of arguments ends. - __ mov(scratch2, esp); - __ sub(Operand(scratch2), Immediate(2 * kPointerSize)); + __ lea(scratch2, Operand(esp, -2 * kPointerSize)); __ push(scratch2); __ push(receiver); // receiver __ push(reg); // holder @@ -1061,12 +1079,11 @@ 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. - __ mov(eax, esp); - __ add(Operand(eax), Immediate(4 * kPointerSize)); + STATIC_ASSERT(ApiGetterEntryStub::kStackSpace == 5); + __ lea(eax, Operand(esp, 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); @@ -1077,7 +1094,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(result); + *failure = Failure::cast(try_call_result); return false; } } @@ -2208,7 +2225,11 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, } if (depth != kInvalidProtoDepth) { - GenerateFastApiCall(masm(), optimization, argc); + Failure* failure; + bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); + if (!success) { + return failure; + } } else { __ InvokeFunction(function, arguments(), JUMP_FUNCTION); } @@ -2253,16 +2274,21 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); CallInterceptorCompiler compiler(this, arguments(), ecx); - compiler.Compile(masm(), - object, - holder, - name, - &lookup, - edx, - ebx, - edi, - eax, - &miss); + Failure* failure; + bool success = compiler.Compile(masm(), + object, + holder, + name, + &lookup, + edx, + ebx, + edi, + eax, + &miss, + &failure); + if (!success) { + return false; + } // Restore receiver. __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |