summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/stub-cache-ia32.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-11-11 22:42:06 -0800
committerRyan Dahl <ry@tinyclouds.org>2010-11-11 22:42:06 -0800
commit564a48643bd3edc6da845e458277a54c8068d0e2 (patch)
treeea483922ae95ef2f1c206aaab2238bf58fd860df /deps/v8/src/ia32/stub-cache-ia32.cc
parentd4af8a6b6ac0045620ad6da94e97a71e6e6fad52 (diff)
downloadnode-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.cc178
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));