Index: src/ia32/stub-cache-ia32.cc |
=================================================================== |
--- src/ia32/stub-cache-ia32.cc (revision 5791) |
+++ src/ia32/stub-cache-ia32.cc (working copy) |
@@ -495,22 +495,35 @@ |
Address api_function_address = v8::ToCData<Address>(callback); |
ApiFunction fun(api_function_address); |
- ApiCallEntryStub stub(api_call_info_handle, &fun); |
+ const int kApiArgc = 1; // API function gets reference to the v8::Arguments. |
- __ EnterInternalFrame(); |
+ // Allocate the v8::Arguments structure in the arguments' space since |
+ // it's not controlled by GC. |
+ const int kApiStackSpace = 4; |
+ __ PrepareCallApiFunction(argc + kFastApiCallArguments + 1, |
antonm
2010/11/10 14:53:54
not sure if it's worth it, but maybe unify exit fr
SeRya
2010/11/11 15:50:39
Please, explain what do you mean by that?
antonm
2010/11/12 18:35:55
Sure and sorry for not making it clear.
Take a lo
SeRya
2010/11/13 09:19:49
Apparently push is shorter than mov and may be it
|
+ kApiArgc + kApiStackSpace); |
+ |
+ __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. |
+ __ mov(ApiParameterOperand(2), ebx); // v8::Arguments::values_. |
+ __ mov(ApiParameterOperand(3), edx); // v8::Arguments::length_. |
antonm
2010/11/10 14:53:54
cannot we fuse those moves and moves above (ln. 49
SeRya
2010/11/11 15:50:39
Sure. I just forgot to do it.
antonm
2010/11/12 18:35:55
Is it the only opportunity? For example we could
SeRya
2010/11/13 09:19:49
Done.
|
+ // v8::Arguments::is_construct_call_. |
+ __ mov(ApiParameterOperand(4), Immediate(0)); |
+ |
+ // v8::InvocationCallback's argument. |
+ __ lea(eax, ApiParameterOperand(1)); |
+ __ mov(ApiParameterOperand(0), eax); |
+ |
// 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); |
+ MaybeObject* result = masm->TryCallApiFunctionAndReturn(&fun, kApiArgc + |
antonm
2010/11/10 14:53:54
that might be just me, but I am slightly uneasy wi
SeRya
2010/11/11 15:50:39
Done.
|
+ kApiStackSpace); |
if (result->IsFailure()) { |
*failure = Failure::cast(result); |
return false; |
} |
- |
- __ LeaveInternalFrame(); |
- __ ret((argc + 4) * kPointerSize); |
return true; |
} |
@@ -1063,44 +1076,55 @@ |
Handle<AccessorInfo> callback_handle(callback); |
- __ EnterInternalFrame(); |
- // Push the stack address where the list of arguments ends. |
- __ lea(scratch2, Operand(esp, -2 * kPointerSize)); |
- __ push(scratch2); |
+ // Insert additional parameters into the stack frame above return address. |
antonm
2010/11/10 14:53:54
are we sure it is always safe to piggy back on out
SeRya
2010/11/11 15:50:39
Technically this is not outer frame, it's our own.
|
+ ASSERT(!scratch3.is(reg)); |
antonm
2010/11/10 14:53:54
shouldn't you check as well that !scratch{2,3}.is(
SeRya
2010/11/11 15:50:39
Caller code must give 5 different registers. If th
antonm
2010/11/12 18:35:55
I personally find this check somewhat misleading.
SeRya
2010/11/13 09:19:49
This asserts what we are not trying to use a regis
|
+ __ pop(scratch3); // Get return address to place it below. |
+ |
__ push(receiver); // receiver |
+ __ mov(scratch2, Operand(esp)); |
+ ASSERT(!scratch2.is(reg)); |
__ push(reg); // holder |
// Push data from AccessorInfo. |
if (Heap::InNewSpace(callback_handle->data())) { |
- __ mov(scratch2, Immediate(callback_handle)); |
- __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); |
+ __ mov(scratch1, Immediate(callback_handle)); |
+ __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); |
} else { |
__ push(Immediate(Handle<Object>(callback_handle->data()))); |
} |
+ // Push the stack address where the list of arguments ends. |
+ __ push(scratch2); |
+ |
__ 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(ebx, esp); |
+ __ push(scratch3); // Restore return addresss. |
+ |
// Do call through the api. |
Address getter_address = v8::ToCData<Address>(callback->getter()); |
ApiFunction fun(getter_address); |
- ApiGetterEntryStub stub(callback_handle, &fun); |
+ |
+ // 3 elements array for v8::Agruments::values_, handler for name and pointer |
+ // to the values (it considered as smi in GC). |
antonm
2010/11/10 14:53:54
are you talking about ApiParameters below? if yes
SeRya
2010/11/11 15:50:39
stake space (the first parameter of PrepareCallApi
|
+ const int kStackSpace = 5; |
+ const int kApiArgc = 2; |
+ |
+ __ PrepareCallApiFunction(kStackSpace, kApiArgc); |
antonm
2010/11/10 14:53:54
again, couldn't we merge pushing and exit frame se
|
+ __ lea(eax, Operand(ebx, 1 * kPointerSize)); |
+ __ mov(ApiParameterOperand(0), ebx); // name. |
+ __ mov(ApiParameterOperand(1), eax); // arguments pointer. |
antonm
2010/11/10 14:53:54
I won't be surprised if __mov(APO(0), ebx); __ add
SeRya
2010/11/11 15:50:39
Done.
|
+ |
// 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. |
- 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); |
- return false; |
- } |
+ MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kApiArgc); |
+ if (result->IsFailure()) { |
+ *failure = Failure::cast(result); |
+ return false; |
} |
- __ LeaveInternalFrame(); |
- __ ret(0); |
return true; |
} |