Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: src/ia32/stub-cache-ia32.cc

Issue 4456002: Direct call API functions. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/stub-cache-ia32.cc
===================================================================
--- src/ia32/stub-cache-ia32.cc (revision 5789)
+++ src/ia32/stub-cache-ia32.cc (working copy)
@@ -413,6 +413,10 @@
}
+// Amount of pointers to be reserved on stack for v8::Arguments::implicit_args_.
antonm 2010/11/09 13:56:19 I am not a native speaker, but I would rather say
antonm 2010/11/09 13:56:19 'v8::Arguments::implicit_args_': should either be
+static const int kFastApiCallArguments = 3;
+
+
// Reserves space for the extra arguments to FastHandleApiCall in the
// caller's frame.
//
@@ -423,10 +427,9 @@
// -- 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 @@
// 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 @@
arguments_(arguments),
name_(name) {}
- void Compile(MacroAssembler* masm,
+ bool Compile(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
String* name,
@@ -524,7 +533,8 @@
Register scratch1,
Register scratch2,
Register scratch3,
- Label* miss) {
+ Label* miss,
+ Failure** failure) {
ASSERT(holder->HasNamedInterceptor());
ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
@@ -535,17 +545,18 @@
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 @@
name,
holder,
miss);
+ return true;
}
}
private:
- void CompileCacheable(MacroAssembler* masm,
+ bool CompileCacheable(MacroAssembler* masm,
JSObject* object,
Register receiver,
Register scratch1,
@@ -570,7 +582,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());
@@ -632,7 +645,11 @@
// 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 @@
if (can_do_fast_api_call) {
FreeSpaceForFastApiCall(masm, scratch1);
}
+
+ return true;
}
void CompileRegular(MacroAssembler* masm,
@@ -1046,8 +1065,7 @@
__ 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 @@
__ 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);
@@ -2208,7 +2225,11 @@
}
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 @@
__ 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));
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698