Added IC support for native setters on the prototype chain.

Review URL: https://chromiumcodereview.appspot.com/10873057

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12402 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f9d48562
......@@ -2673,9 +2673,10 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<AccessorInfo> callback,
Handle<String> name) {
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
......@@ -2683,19 +2684,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- lr : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(r1, &miss);
CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
// Check that the map of the object hasn't changed.
__ CheckMap(r1, r3, Handle<Map>(object->map()), &miss,
DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(r1, r3, &miss);
}
// Stub never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Stub never generated for non-global objects that require access checks.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ push(r1); // receiver
__ mov(ip, Operand(callback)); // callback info
......
......@@ -2601,9 +2601,10 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<AccessorInfo> callback,
Handle<String> name) {
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : name
......@@ -2611,19 +2612,14 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- esp[0] : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed, preserving the value register.
__ push(eax);
__ JumpIfSmi(edx, &miss);
CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss);
__ pop(eax); // restore value
// Check that the map of the object hasn't changed.
__ CheckMap(edx, Handle<Map>(object->map()),
&miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(edx, ebx, &miss);
}
// Stub never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Stub never generated for non-global objects that require access checks.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ pop(ebx); // remove the return address
__ push(edx); // receiver
......@@ -2639,6 +2635,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// Handle store cache miss.
__ bind(&miss);
__ pop(eax);
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
......
......@@ -1331,7 +1331,7 @@ static bool LookupForWrite(Handle<JSObject> receiver,
return false;
}
Handle<Object> callback(lookup->GetCallbackObject());
return callback->IsAccessorPair() && StoreICableLookup(lookup);
return StoreICableLookup(lookup);
}
if (lookup->IsInterceptor() &&
......@@ -1491,13 +1491,12 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject());
if (callback->IsAccessorInfo()) {
ASSERT(*holder == *receiver); // LookupForWrite checks this.
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->setter()) == 0) return;
if (!holder->HasFastProperties()) return;
ASSERT(info->IsCompatibleReceiver(*receiver));
if (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeStoreCallback(
name, receiver, info, strict_mode);
name, receiver, holder, info, strict_mode);
} else if (callback->IsAccessorPair()) {
Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
if (!setter->IsJSFunction()) return;
......
......@@ -2676,9 +2676,10 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<AccessorInfo> callback,
Handle<String> name) {
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
......@@ -2686,19 +2687,13 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- ra : return address
// -----------------------------------
Label miss;
// Check that the map of the object hasn't changed.
__ CheckMap(a1, a3, Handle<Map>(object->map()), &miss,
DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(a1, a3, &miss);
}
// Check that the maps haven't changed.
__ JumpIfSmi(a1, &miss, a3);
CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
// Stub never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ push(a1); // Receiver.
__ li(a3, Operand(callback)); // Callback info.
......
......@@ -504,6 +504,7 @@ Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback,
StrictModeFlag strict_mode) {
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
......@@ -513,7 +514,8 @@ Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
if (probe->IsCode()) return Handle<Code>::cast(probe);
StoreStubCompiler compiler(isolate_, strict_mode);
Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
Handle<Code> code =
compiler.CompileStoreCallback(name, receiver, holder, callback);
PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
JSObject::UpdateMapCodeCache(receiver, name, code);
......
......@@ -159,6 +159,7 @@ class StubCache {
Handle<Code> ComputeStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback,
StrictModeFlag strict_mode);
......@@ -704,9 +705,10 @@ class StoreStubCompiler: public StubCompiler {
Handle<Map> transition,
Handle<String> name);
Handle<Code> CompileStoreCallback(Handle<JSObject> object,
Handle<AccessorInfo> callback,
Handle<String> name);
Handle<Code> CompileStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
static void GenerateStoreViaSetter(MacroAssembler* masm,
Handle<JSFunction> setter);
......
......@@ -2429,9 +2429,10 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<AccessorInfo> callback,
Handle<String> name) {
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- rax : value
// -- rcx : name
......@@ -2439,19 +2440,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -- rsp[0] : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(rdx, &miss);
CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
// Check that the map of the object hasn't changed.
__ CheckMap(rdx, Handle<Map>(object->map()), &miss,
DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(rdx, rbx, &miss);
}
// Stub never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Stub never generated for non-global objects that require access checks.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
__ pop(rbx); // remove the return address
__ push(rdx); // receiver
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment