Revision: 19033
Author: [email protected]
Date: Mon Feb 3 15:19:38 2014 UTC
Log: let load and store api callbacks use global proxy as receiver
[email protected]
BUG=
Review URL: https://codereview.chromium.org/151063003
http://code.google.com/p/v8/source/detail?r=19033
Modified:
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Jan 31 16:52:17
2014 UTC
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon Feb 3 15:19:38
2014 UTC
@@ -782,11 +782,23 @@
}
-static void GenerateFastApiCallBody(MacroAssembler* masm,
- const CallOptimization& optimization,
- int argc,
- Register holder_in,
- bool restore_context) {
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+ const CallOptimization& optimization,
+ Handle<Map> receiver_map,
+ Register receiver,
+ Register scratch_in,
+ int argc,
+ Register* values) {
+ ASSERT(!receiver.is(scratch_in));
+ __ push(receiver);
+ // Write the arguments to stack frame.
+ for (int i = 0; i < argc; i++) {
+ Register arg = values[argc-1-i];
+ ASSERT(!receiver.is(arg));
+ ASSERT(!scratch_in.is(arg));
+ __ push(arg);
+ }
ASSERT(optimization.is_simple_api_call());
// Abi for CallApiFunctionStub.
@@ -796,7 +808,21 @@
Register api_function_address = r1;
// Put holder in place.
- __ Move(holder, holder_in);
+ CallOptimization::HolderLookup holder_lookup;
+ Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
+ receiver_map,
+ &holder_lookup);
+ switch (holder_lookup) {
+ case CallOptimization::kHolderIsReceiver:
+ __ Move(holder, receiver);
+ break;
+ case CallOptimization::kHolderFound:
+ __ Move(holder, api_holder);
+ break;
+ case CallOptimization::kHolderNotFound:
+ UNREACHABLE();
+ break;
+ }
Isolate* isolate = masm->isolate();
Handle<JSFunction> function = optimization.constant_function();
@@ -828,34 +854,9 @@
__ mov(api_function_address, Operand(ref));
// Jump to stub.
- CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
+ CallApiFunctionStub stub(true, call_data_undefined, argc);
__ TailCallStub(&stub);
}
-
-
-// Generate call to api function.
-static void GenerateFastApiCall(MacroAssembler* masm,
- const CallOptimization& optimization,
- Register receiver,
- Register scratch,
- int argc,
- Register* values) {
- ASSERT(!receiver.is(scratch));
- __ push(receiver);
- // Write the arguments to stack frame.
- for (int i = 0; i < argc; i++) {
- Register arg = values[argc-1-i];
- ASSERT(!receiver.is(arg));
- ASSERT(!scratch.is(arg));
- __ push(arg);
- }
- // Stack now matches JSFunction abi.
- GenerateFastApiCallBody(masm,
- optimization,
- argc,
- receiver,
- true);
-}
void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code>
code) {
@@ -1075,9 +1076,11 @@
void LoadStubCompiler::GenerateLoadCallback(
- const CallOptimization& call_optimization) {
+ const CallOptimization& call_optimization,
+ Handle<Map> receiver_map) {
GenerateFastApiCall(
- masm(), call_optimization, receiver(), scratch3(), 0, NULL);
+ masm(), call_optimization, receiver_map,
+ receiver(), scratch3(), 0, NULL);
}
@@ -1267,7 +1270,8 @@
Register values[] = { value() };
GenerateFastApiCall(
- masm(), call_optimization, receiver(), scratch3(), 1, values);
+ masm(), call_optimization, handle(object->map()),
+ receiver(), scratch3(), 1, values);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri Jan 31 16:52:17
2014 UTC
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon Feb 3 15:19:38
2014 UTC
@@ -418,11 +418,30 @@
}
-static void GenerateFastApiCallBody(MacroAssembler* masm,
- const CallOptimization& optimization,
- int argc,
- Register holder_in,
- bool restore_context) {
+// Generate call to api function.
+// This function uses push() to generate smaller, faster code than
+// the version above. It is an optimization that should will be removed
+// when api call ICs are generated in hydrogen.
+static void GenerateFastApiCall(MacroAssembler* masm,
+ const CallOptimization& optimization,
+ Handle<Map> receiver_map,
+ Register receiver,
+ Register scratch_in,
+ int argc,
+ Register* values) {
+ // Copy return value.
+ __ pop(scratch_in);
+ // receiver
+ __ push(receiver);
+ // Write the arguments to stack frame.
+ for (int i = 0; i < argc; i++) {
+ Register arg = values[argc-1-i];
+ ASSERT(!receiver.is(arg));
+ ASSERT(!scratch_in.is(arg));
+ __ push(arg);
+ }
+ __ push(scratch_in);
+ // Stack now matches JSFunction abi.
ASSERT(optimization.is_simple_api_call());
// Abi for CallApiFunctionStub.
@@ -430,11 +449,24 @@
Register call_data = ebx;
Register holder = ecx;
Register api_function_address = edx;
+ Register scratch = edi; // scratch_in is no longer valid.
// Put holder in place.
- __ Move(holder, holder_in);
-
- Register scratch = edi;
+ CallOptimization::HolderLookup holder_lookup;
+ Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
+ receiver_map,
+ &holder_lookup);
+ switch (holder_lookup) {
+ case CallOptimization::kHolderIsReceiver:
+ __ Move(holder, receiver);
+ break;
+ case CallOptimization::kHolderFound:
+ __ LoadHeapObject(holder, api_holder);
+ break;
+ case CallOptimization::kHolderNotFound:
+ UNREACHABLE();
+ break;
+ }
Isolate* isolate = masm->isolate();
Handle<JSFunction> function = optimization.constant_function();
@@ -461,40 +493,9 @@
__ mov(api_function_address, Immediate(function_address));
// Jump to stub.
- CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
+ CallApiFunctionStub stub(true, call_data_undefined, argc);
__ TailCallStub(&stub);
}
-
-
-// Generate call to api function.
-// This function uses push() to generate smaller, faster code than
-// the version above. It is an optimization that should will be removed
-// when api call ICs are generated in hydrogen.
-static void GenerateFastApiCall(MacroAssembler* masm,
- const CallOptimization& optimization,
- Register receiver,
- Register scratch1,
- int argc,
- Register* values) {
- // Copy return value.
- __ pop(scratch1);
- // receiver
- __ push(receiver);
- // Write the arguments to stack frame.
- for (int i = 0; i < argc; i++) {
- Register arg = values[argc-1-i];
- ASSERT(!receiver.is(arg));
- ASSERT(!scratch1.is(arg));
- __ push(arg);
- }
- __ push(scratch1);
- // Stack now matches JSFunction abi.
- GenerateFastApiCallBody(masm,
- optimization,
- argc,
- receiver,
- true);
-}
void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
@@ -1065,10 +1066,11 @@
void LoadStubCompiler::GenerateLoadCallback(
- const CallOptimization& call_optimization) {
+ const CallOptimization& call_optimization,
+ Handle<Map> receiver_map) {
GenerateFastApiCall(
- masm(), call_optimization, receiver(),
- scratch1(), 0, NULL);
+ masm(), call_optimization, receiver_map,
+ receiver(), scratch1(), 0, NULL);
}
@@ -1271,8 +1273,8 @@
Register values[] = { value() };
GenerateFastApiCall(
- masm(), call_optimization, receiver(),
- scratch1(), 1, values);
+ masm(), call_optimization, handle(object->map()),
+ receiver(), scratch1(), 1, values);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
=======================================
--- /branches/bleeding_edge/src/ic.cc Fri Jan 31 16:52:17 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Mon Feb 3 15:19:38 2014 UTC
@@ -938,7 +938,7 @@
}
CallOptimization call_optimization(function);
if (call_optimization.is_simple_api_call() &&
- call_optimization.IsCompatibleReceiver(*object)) {
+ call_optimization.IsCompatibleReceiver(object, holder)) {
return compiler.CompileLoadCallback(
type, holder, name, call_optimization);
}
@@ -1364,7 +1364,7 @@
Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
CallOptimization call_optimization(function);
if (call_optimization.is_simple_api_call() &&
- call_optimization.IsCompatibleReceiver(*receiver)) {
+ call_optimization.IsCompatibleReceiver(receiver, holder)) {
return compiler.CompileStoreCallback(
receiver, holder, name, call_optimization);
}
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Fri Jan 31 16:52:17 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Mon Feb 3 15:19:38 2014 UTC
@@ -951,7 +951,7 @@
ASSERT(call_optimization.is_simple_api_call());
Handle<JSFunction> callback = call_optimization.constant_function();
CallbackHandlerFrontend(type, receiver(), holder, name, callback);
- GenerateLoadCallback(call_optimization);
+ GenerateLoadCallback(call_optimization, IC::TypeToMap(*type, isolate()));
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
@@ -1357,7 +1357,6 @@
Handle<Map> object_map,
HolderLookup* holder_lookup) const {
ASSERT(is_simple_api_call());
- ASSERT_EQ(kHolderNotFound, *holder_lookup);
if (!object_map->IsJSObjectMap()) {
*holder_lookup = kHolderNotFound;
return Handle<JSObject>::null();
@@ -1380,6 +1379,38 @@
*holder_lookup = kHolderNotFound;
return Handle<JSObject>::null();
}
+
+
+bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
+ Handle<JSObject> holder) const
{
+ ASSERT(is_simple_api_call());
+ if (!receiver->IsJSObject()) return false;
+ Handle<Map> map(JSObject::cast(*receiver)->map());
+ HolderLookup holder_lookup;
+ Handle<JSObject> api_holder =
+ LookupHolderOfExpectedType(map, &holder_lookup);
+ switch (holder_lookup) {
+ case kHolderNotFound:
+ return false;
+ case kHolderIsReceiver:
+ return true;
+ case kHolderFound:
+ if (api_holder.is_identical_to(holder)) return true;
+ // Check if holder is in prototype chain of api_holder.
+ {
+ JSObject* object = *api_holder;
+ while (true) {
+ Object* prototype = object->map()->prototype();
+ if (!prototype->IsJSObject()) return false;
+ if (prototype == *holder) return true;
+ object = JSObject::cast(prototype);
+ }
+ }
+ break;
+ }
+ UNREACHABLE();
+ return false;
+}
void CallOptimization::Initialize(Handle<JSFunction> function) {
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Fri Jan 31 16:52:17 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.h Mon Feb 3 15:19:38 2014 UTC
@@ -611,7 +611,8 @@
void GenerateLoadConstant(Handle<Object> value);
void GenerateLoadCallback(Register reg,
Handle<ExecutableAccessorInfo> callback);
- void GenerateLoadCallback(const CallOptimization& call_optimization);
+ void GenerateLoadCallback(const CallOptimization& call_optimization,
+ Handle<Map> receiver_map);
void GenerateLoadInterceptor(Register holder_reg,
Handle<Object> object,
Handle<JSObject> holder,
@@ -827,11 +828,9 @@
Handle<Map> receiver_map,
HolderLookup* holder_lookup) const;
- bool IsCompatibleReceiver(Object* receiver) {
- ASSERT(is_simple_api_call());
- if (expected_receiver_type_.is_null()) return true;
- return expected_receiver_type_->IsTemplateFor(receiver);
- }
+ // Check if the api holder is between the receiver and the holder.
+ bool IsCompatibleReceiver(Handle<Object> receiver,
+ Handle<JSObject> holder) const;
private:
void Initialize(Handle<JSFunction> function);
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Fri Jan 31 16:52:17
2014 UTC
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon Feb 3 15:19:38
2014 UTC
@@ -392,23 +392,52 @@
}
-static void GenerateFastApiCallBody(MacroAssembler* masm,
- const CallOptimization& optimization,
- int argc,
- Register holder_in,
- bool restore_context) {
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+ const CallOptimization& optimization,
+ Handle<Map> receiver_map,
+ Register receiver,
+ Register scratch_in,
+ int argc,
+ Register* values) {
ASSERT(optimization.is_simple_api_call());
+ __ PopReturnAddressTo(scratch_in);
+ // receiver
+ __ push(receiver);
+ // Write the arguments to stack frame.
+ for (int i = 0; i < argc; i++) {
+ Register arg = values[argc-1-i];
+ ASSERT(!receiver.is(arg));
+ ASSERT(!scratch_in.is(arg));
+ __ push(arg);
+ }
+ __ PushReturnAddressFrom(scratch_in);
+ // Stack now matches JSFunction abi.
+
// Abi for CallApiFunctionStub.
Register callee = rax;
Register call_data = rbx;
Register holder = rcx;
Register api_function_address = rdx;
+ Register scratch = rdi; // scratch_in is no longer valid.
// Put holder in place.
- __ Move(holder, holder_in);
-
- Register scratch = rdi;
+ CallOptimization::HolderLookup holder_lookup;
+ Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
+ receiver_map,
+ &holder_lookup);
+ switch (holder_lookup) {
+ case CallOptimization::kHolderIsReceiver:
+ __ Move(holder, receiver);
+ break;
+ case CallOptimization::kHolderFound:
+ __ Move(holder, api_holder);
+ break;
+ case CallOptimization::kHolderNotFound:
+ UNREACHABLE();
+ break;
+ }
Isolate* isolate = masm->isolate();
Handle<JSFunction> function = optimization.constant_function();
@@ -436,36 +465,9 @@
api_function_address, function_address,
RelocInfo::EXTERNAL_REFERENCE);
// Jump to stub.
- CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
+ CallApiFunctionStub stub(true, call_data_undefined, argc);
__ TailCallStub(&stub);
}
-
-
-// Generate call to api function.
-static void GenerateFastApiCall(MacroAssembler* masm,
- const CallOptimization& optimization,
- Register receiver,
- Register scratch1,
- int argc,
- Register* values) {
- __ PopReturnAddressTo(scratch1);
- // receiver
- __ push(receiver);
- // Write the arguments to stack frame.
- for (int i = 0; i < argc; i++) {
- Register arg = values[argc-1-i];
- ASSERT(!receiver.is(arg));
- ASSERT(!scratch1.is(arg));
- __ push(arg);
- }
- __ PushReturnAddressFrom(scratch1);
- // Stack now matches JSFunction abi.
- GenerateFastApiCallBody(masm,
- optimization,
- argc,
- receiver,
- true);
-}
void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
@@ -968,10 +970,11 @@
void LoadStubCompiler::GenerateLoadCallback(
- const CallOptimization& call_optimization) {
+ const CallOptimization& call_optimization,
+ Handle<Map> receiver_map) {
GenerateFastApiCall(
- masm(), call_optimization, receiver(),
- scratch1(), 0, NULL);
+ masm(), call_optimization, receiver_map,
+ receiver(), scratch1(), 0, NULL);
}
@@ -1165,8 +1168,8 @@
Register values[] = { value() };
GenerateFastApiCall(
- masm(), call_optimization, receiver(),
- scratch1(), 1, values);
+ masm(), call_optimization, handle(object->map()),
+ receiver(), scratch1(), 1, values);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.