Bug 1249252: SharedStubs - Add typebarrier to getprop shared stub, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Thu, 18 Feb 2016 15:17:38 -0500
changeset 284760 3f395a031f6a8c3730107b4e3e4d0f3b75a34563
parent 284759 4c296a2008eba697240840f570d919a69bf3d44f
child 284761 d9c73b9a2a960a3e7e57990574a588000ee7995a
push id72096
push userhv1989@gmail.com
push dateThu, 18 Feb 2016 20:18:57 +0000
treeherdermozilla-inbound@3f395a031f6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1249252
milestone47.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 1249252: SharedStubs - Add typebarrier to getprop shared stub, r=jandem
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -11105,17 +11105,17 @@ IonBuilder::jsop_getprop(PropertyName* n
 
     // Try to emit a polymorphic cache.
     trackOptimizationAttempt(TrackedStrategy::GetProp_InlineCache);
     if (!getPropTryCache(&emitted, obj, name, barrier, types) || emitted)
         return emitted;
 
     // Try to emit a shared stub.
     trackOptimizationAttempt(TrackedStrategy::GetProp_SharedCache);
-    if (!getPropTrySharedStub(&emitted, obj) || emitted)
+    if (!getPropTrySharedStub(&emitted, obj, types) || emitted)
         return emitted;
 
     // Emit a call.
     MCallGetProperty* call = MCallGetProperty::New(alloc(), obj, name);
     current->add(call);
     current->push(call);
     if (!resumeAfter(call))
         return false;
@@ -12045,32 +12045,41 @@ IonBuilder::getPropTryCache(bool* emitte
         return false;
 
     trackOptimizationSuccess();
     *emitted = true;
     return true;
 }
 
 bool
-IonBuilder::getPropTrySharedStub(bool* emitted, MDefinition* obj)
+IonBuilder::getPropTrySharedStub(bool* emitted, MDefinition* obj, TemporaryTypeSet* types)
 {
     MOZ_ASSERT(*emitted == false);
 
     // Try to emit a shared stub cache.
 
     if (JitOptions.disableSharedStubs)
         return true;
 
     MInstruction* stub = MUnarySharedStub::New(alloc(), obj);
     current->add(stub);
     current->push(stub);
 
     if (!resumeAfter(stub))
         return false;
 
+    // Due to inlining, it's possible the observed TypeSet is non-empty,
+    // even though we know |obj| is null/undefined and the MCallGetProperty
+    // will throw. Don't push a TypeBarrier in this case, to avoid
+    // inlining the following (unreachable) JSOP_CALL.
+    if (*pc != JSOP_CALLPROP || !IsNullOrUndefined(obj->type())) {
+        if (!pushTypeBarrier(stub, types, BarrierKind::TypeSet))
+            return false;
+    }
+
     *emitted = true;
     return true;
 }
 
 MDefinition*
 IonBuilder::tryInnerizeWindow(MDefinition* obj)
 {
     // Try to optimize accesses on outer window proxies (window.foo, for
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -452,17 +452,17 @@ class IonBuilder
     bool getPropTryComplexPropOfTypedObject(bool* emitted, MDefinition* typedObj,
                                             int32_t fieldOffset,
                                             TypedObjectPrediction fieldTypeReprs,
                                             size_t fieldIndex);
     bool getPropTryInnerize(bool* emitted, MDefinition* obj, PropertyName* name,
                             TemporaryTypeSet* types);
     bool getPropTryCache(bool* emitted, MDefinition* obj, PropertyName* name,
                          BarrierKind barrier, TemporaryTypeSet* types);
-    bool getPropTrySharedStub(bool* emitted, MDefinition* obj);
+    bool getPropTrySharedStub(bool* emitted, MDefinition* obj, TemporaryTypeSet* types);
 
     // jsop_setprop() helpers.
     bool setPropTryCommonSetter(bool* emitted, MDefinition* obj,
                                 PropertyName* name, MDefinition* value);
     bool setPropTryCommonDOMSetter(bool* emitted, MDefinition* obj,
                                    MDefinition* value, JSFunction* setter,
                                    TemporaryTypeSet* objTypes);
     bool setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,