Bug 983462 - Implement own property native getter cacheing at JSOP_GETPROP sites in BC. (r=djvj)
authorEric Faust <efaustbmo@gmail.com>
Mon, 24 Mar 2014 14:55:25 -0700
changeset 175111 f0b24db4d53820333bef36b3c525fd97dc6fb4ed
parent 175110 e05b578dcd6d1fdbfc3df0b278256e4b3969fd78
child 175112 3d94ebde9018619354dcaeff8a48c60b62ee29ca
push id26481
push usercbook@mozilla.com
push dateTue, 25 Mar 2014 12:11:08 +0000
treeherdermozilla-central@ed1b7cda3ffa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs983462
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 983462 - Implement own property native getter cacheing at JSOP_GETPROP sites in BC. (r=djvj)
js/src/jit/BaselineIC.cpp
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -3377,20 +3377,16 @@ IsCacheableGetPropReadSlot(JSObject *obj
 }
 
 static bool
 IsCacheableGetPropCall(JSContext *cx, JSObject *obj, JSObject *holder, Shape *shape, bool *isScripted,
                        bool isDOMProxy=false)
 {
     JS_ASSERT(isScripted);
 
-    // Currently we only optimize getter calls for getters bound on prototypes.
-    if (obj == holder)
-        return false;
-
     if (!shape || !IsCacheableProtoChain(obj, holder, isDOMProxy))
         return false;
 
     if (shape->hasSlot() || shape->hasDefaultGetter())
         return false;
 
     if (!shape->hasGetterValue())
         return false;
@@ -3778,16 +3774,20 @@ static bool TryAttachNativeGetElemStub(J
 
 #if JS_HAS_NO_SUCH_METHOD
         // It's unlikely that a getter function will be used in callelem locations.
         // Just don't attach stubs in that case to avoid issues with __noSuchMethod__ handling.
         if (isCallElem)
             return true;
 #endif
 
+        // For now, we do not handle own property getters
+        if (obj == holder)
+            return true;
+
         // If a suitable stub already exists, nothing else to do.
         if (GetElemNativeStubExists(stub, obj, holder, propName, needsAtomize))
             return true;
 
         // Remove any existing stubs that may interfere with the new stub being added.
         RemoveExistingGetElemNativeStubs(cx, stub, obj, holder, propName, needsAtomize);
 
         ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
@@ -5643,19 +5643,18 @@ TryAttachGlobalNameStub(JSContext *cx, H
         ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
         if (!newStub)
             return false;
 
         stub->addNewStub(newStub);
         return true;
     }
 
-    if (shape->hasGetterValue() && shape->getterValue().isObject() &&
-        shape->getterObject()->is<JSFunction>() &&
-        shape->getterObject()->as<JSFunction>().isNative())
+    bool isScripted;
+    if (IsCacheableGetPropCall(cx, global, global, shape, &isScripted) && !isScripted)
     {
 #ifdef JS_HAS_NO_SUCH_METHOD
         if (JSOp(*pc) == JSOP_CALLGNAME)
             return true;
 #endif
         ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
         IonSpew(IonSpew_BaselineIC, "  Generating GetName(GlobalName/NativeGetter) stub");
         RootedFunction getter(cx, &shape->getterObject()->as<JSFunction>());
@@ -6167,16 +6166,20 @@ TryAttachNativeGetPropStub(JSContext *cx
 #if JS_HAS_NO_SUCH_METHOD
         // It's hard to keep the original object alive through a call, and it's unlikely
         // that a getter will be used to generate functions for calling in CALLPROP locations.
         // Just don't attach stubs in that case.
         if (isCallProp)
             return true;
 #endif
 
+        // Don't handle scripted own property getters
+        if (obj == holder)
+            return true;
+
         RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
         JS_ASSERT(obj != holder);
         JS_ASSERT(callee->hasScript());
 
         IonSpew(IonSpew_BaselineIC, "  Generating GetProp(NativeObj/ScriptedGetter %s:%d) stub",
                     callee->nonLazyScript()->filename(), callee->nonLazyScript()->lineno());
 
         ICGetProp_CallScripted::Compiler compiler(cx, monitorStub, obj, holder, callee,
@@ -6196,40 +6199,44 @@ TryAttachNativeGetPropStub(JSContext *cx
         // It's unlikely that a getter function will be used to generate functions for calling
         // in CALLPROP locations.  Just don't attach stubs in that case to avoid issues with
         // __noSuchMethod__ handling.
         if (isCallProp)
             return true;
 #endif
 
         RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
-        JS_ASSERT(obj != holder);
         JS_ASSERT(callee->isNative());
 
         IonSpew(IonSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
                 isDOMProxy ? "DOMProxyObj" : "NativeObj",
                 isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
                 callee->native());
 
         ICStub *newStub = nullptr;
         if (isDOMProxy) {
+            JS_ASSERT(obj != holder);
             ICStub::Kind kind;
             if (domProxyHasGeneration) {
                 if (UpdateExistingGenerationalDOMProxyStub(stub, obj)) {
                     *attached = true;
                     return true;
                 }
                 kind = ICStub::GetProp_CallDOMProxyWithGenerationNative;
             } else {
                 kind = ICStub::GetProp_CallDOMProxyNative;
             }
             Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
             ICGetPropCallDOMProxyNativeCompiler
                 compiler(cx, kind, monitorStub, proxy, holder, callee, script->pcToOffset(pc));
             newStub = compiler.getStub(compiler.getStubSpace(script));
+        } else if (obj == holder) {
+            ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, callee,
+                                                    script->pcToOffset(pc));
+            newStub = compiler.getStub(compiler.getStubSpace(script));
         } else {
             ICGetProp_CallNativePrototype::Compiler compiler(cx, monitorStub, obj, holder, callee,
                                                              script->pcToOffset(pc));
             newStub = compiler.getStub(compiler.getStubSpace(script));
         }
         if (!newStub)
             return false;
         stub->addNewStub(newStub);