Bug 857094. (r=sstangl)
authorShu-yu Guo <shu@rfrn.org>
Thu, 04 Apr 2013 08:13:22 -0700
changeset 127707 1aa1dc84a1a40a4616755115bdfd1e566c46cf3c
parent 127706 9cbf2e118de6437a9bbc4fcd7a1ccdc78cd57268
child 127708 273c69918d05f2a19da9dc0bc3df51c9d644ab29
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstangl
bugs857094
milestone23.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 857094. (r=sstangl)
js/src/ion/IonBuilder.cpp
js/src/ion/MCallOptimize.cpp
js/src/ion/TypeOracle.cpp
js/src/ion/TypeOracle.h
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -6053,17 +6053,16 @@ IonBuilder::jsop_setelem_dense()
 
         current->add(ins);
         current->push(value);
 
         if (!resumeAfter(ins))
             return false;
     }
 
-    // Determine whether a write barrier is required.
     if (oracle->elementWriteNeedsBarrier(script(), pc))
         store->setNeedsBarrier();
 
     if (elementType != MIRType_None && packed)
         store->setElementType(elementType);
 
     return true;
 }
--- a/js/src/ion/MCallOptimize.cpp
+++ b/js/src/ion/MCallOptimize.cpp
@@ -996,16 +996,19 @@ IonBuilder::inlineUnsafeSetDenseArrayEle
     // there were setters on the prototype, they would not be invoked.
     // But this is actually the desired behavior.
 
     MStoreElement *store = MStoreElement::New(elements, id,
                                               callInfo.getArg(elemi),
                                               /* needsHoleCheck = */ false);
     store->setRacy();
 
+    if (oracle->elementWriteNeedsBarrier(getInlineArgTypeSet(callInfo, arri)))
+        store->setNeedsBarrier();
+
     current->add(store);
 
     if (!resumeAfter(store))
         return false;
 
     return true;
 }
 
--- a/js/src/ion/TypeOracle.cpp
+++ b/js/src/ion/TypeOracle.cpp
@@ -635,18 +635,23 @@ TypeInferenceOracle::propertyWriteNeedsB
     return types->propertyNeedsBarrier(cx, id);
 }
 
 bool
 TypeInferenceOracle::elementWriteNeedsBarrier(RawScript script, jsbytecode *pc)
 {
     // Return true if SETELEM-like instructions need a write barrier before modifying
     // a property. The object is the third value popped by SETELEM.
-    StackTypeSet *types = script->analysis()->poppedTypes(pc, 2);
-    return types->propertyNeedsBarrier(cx, JSID_VOID);
+    return elementWriteNeedsBarrier(script->analysis()->poppedTypes(pc, 2));
+}
+
+bool
+TypeInferenceOracle::elementWriteNeedsBarrier(StackTypeSet *obj)
+{
+    return obj->propertyNeedsBarrier(cx, JSID_VOID);
 }
 
 StackTypeSet *
 TypeInferenceOracle::getCallTarget(RawScript caller, uint32_t argc, jsbytecode *pc)
 {
     JS_ASSERT(caller == this->script());
     JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE);
 
--- a/js/src/ion/TypeOracle.h
+++ b/js/src/ion/TypeOracle.h
@@ -136,16 +136,19 @@ class TypeOracle
         return true;
     }
     virtual bool propertyWriteNeedsBarrier(RawScript script, jsbytecode *pc, RawId id) {
         return true;
     }
     virtual bool elementWriteNeedsBarrier(RawScript script, jsbytecode *pc) {
         return true;
     }
+    virtual bool elementWriteNeedsBarrier(types::StackTypeSet *obj) {
+        return true;
+    }
     virtual MIRType elementWrite(RawScript script, jsbytecode *pc) {
         return MIRType_None;
     }
 
     /* |pc| must be a |JSOP_CALL|. */
     virtual types::StackTypeSet *getCallTarget(RawScript caller, uint32_t argc, jsbytecode *pc) {
         // Same assertion as TypeInferenceOracle::getCallTarget.
         JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE && JSOp(*pc) != JSOP_EVAL);
@@ -283,16 +286,17 @@ class TypeInferenceOracle : public TypeO
     bool elementWriteNeedsDoubleConversion(RawScript script, jsbytecode *pc);
     bool elementWriteHasExtraIndexedProperty(RawScript script, jsbytecode *pc);
     bool elementWriteIsPacked(RawScript script, jsbytecode *pc);
     bool arrayResultShouldHaveDoubleConversion(RawScript script, jsbytecode *pc);
     bool setElementHasWrittenHoles(RawScript script, jsbytecode *pc);
     bool propertyWriteCanSpecialize(RawScript script, jsbytecode *pc);
     bool propertyWriteNeedsBarrier(RawScript script, jsbytecode *pc, RawId id);
     bool elementWriteNeedsBarrier(RawScript script, jsbytecode *pc);
+    bool elementWriteNeedsBarrier(types::StackTypeSet *obj);
     MIRType elementWrite(RawScript script, jsbytecode *pc);
     bool canInlineCall(HandleScript caller, jsbytecode *pc);
     types::TypeBarrier *callArgsBarrier(HandleScript caller, jsbytecode *pc);
     bool canEnterInlinedFunction(RawFunction callee);
     bool callReturnTypeSetMatches(RawScript callerScript, jsbytecode *callerPc, RawFunction callee);
     bool callArgsTypeSetIntersects(types::StackTypeSet *thisType, Vector<types::StackTypeSet *> &argvType, RawFunction callee);
     bool callArgsTypeSetMatches(types::StackTypeSet *thisType, Vector<types::StackTypeSet *> &argvType, RawFunction callee);
     types::StackTypeSet *aliasedVarBarrier(RawScript script, jsbytecode *pc, types::StackTypeSet **barrier);
@@ -411,9 +415,8 @@ IsNullOrUndefined(MIRType type)
 {
     return type == MIRType_Null || type == MIRType_Undefined;
 }
 
 } /* ion */
 } /* js */
 
 #endif // js_ion_type_oracle_h__
-