Don't inline monitored calls or calls with type barriers (bug 728221, r=dvander)
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 18 Feb 2012 11:23:28 +0100
changeset 88145 24951fdc836f9ef18d874ac4d7ab1b0c2647874c
parent 88144 0e427c752e4830d2e31158c1b773eca0c24a881a
child 88146 5f5174a78b682c3b491060dd38e3fbcb5cd9bf6c
push id619
push userjandemooij@gmail.com
push dateSat, 18 Feb 2012 10:24:03 +0000
reviewersdvander
bugs728221
milestone13.0a1
Don't inline monitored calls or calls with type barriers (bug 728221, r=dvander)
js/src/ion/IonBuilder.cpp
js/src/ion/TypeOracle.cpp
js/src/ion/TypeOracle.h
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -2329,16 +2329,21 @@ IonBuilder::makeInliningDecision(uint32 
 {
     JS_ASSERT(data->shouldInline == false);
 
     if (script->getUseCount() < js_IonOptions.usesBeforeInlining) {
         IonSpew(IonSpew_Inlining, "Not inlining, caller is not hot");
         return true;
     }
 
+    if (!oracle->canInlineCall(script, pc)) {
+        IonSpew(IonSpew_Inlining, "Cannot inline due to uninlineable call site");
+        return true;
+    }
+
     JSFunction *inlineFunc = NULL;
     if (!getInliningTarget(argc, pc, &inlineFunc))
         return false;
 
     if (!inlineFunc) {
         IonSpew(IonSpew_Inlining, "Decided not to inline");
         return true;
     }
--- a/js/src/ion/TypeOracle.cpp
+++ b/js/src/ion/TypeOracle.cpp
@@ -337,16 +337,27 @@ TypeInferenceOracle::getCallArg(JSScript
 
 TypeSet *
 TypeInferenceOracle::getCallReturn(JSScript *script, jsbytecode *pc)
 {
     return script->analysis()->pushedTypes(pc, 0);
 }
 
 bool
+TypeInferenceOracle::canInlineCall(JSScript *caller, jsbytecode *pc)
+{
+    JS_ASSERT(JSOp(*pc) == JSOP_CALL);
+
+    Bytecode *code = caller->analysis()->maybeCode(pc);
+    if (code->monitoredTypes || code->monitoredTypesReturn || caller->analysis()->typeBarriers(cx, pc))
+        return false;
+    return true;
+}
+
+bool
 TypeInferenceOracle::canEnterInlinedScript(JSScript *inlineScript)
 {
     return inlineScript->hasAnalysis() && inlineScript->analysis()->ranInference() &&
         inlineScript->analysis()->inlineable() && !inlineScript->analysis()->usesScopeChain();
 }
 
 TypeSet *
 TypeInferenceOracle::globalPropertyWrite(JSScript *script, jsbytecode *pc, jsid id,
--- a/js/src/ion/TypeOracle.h
+++ b/js/src/ion/TypeOracle.h
@@ -157,17 +157,19 @@ class TypeOracle
         return NULL;
     }
     virtual types::TypeSet *getCallArg(JSScript *script, uint32 argc, uint32 arg, jsbytecode *pc) {
         return NULL;
     }
     virtual types::TypeSet *getCallReturn(JSScript *script, jsbytecode *pc) {
         return NULL;
     }
-
+    virtual bool canInlineCall(JSScript *caller, jsbytecode *pc) {
+        return false;
+    }
     virtual bool canEnterInlinedScript(JSScript *callee) {
         return false;
     }
 };
 
 class DummyOracle : public TypeOracle
 {
   public:
@@ -231,16 +233,17 @@ class TypeInferenceOracle : public TypeO
     bool elementWriteIsDense(JSScript *script, jsbytecode *pc);
     bool elementWriteIsPacked(JSScript *script, jsbytecode *pc);
     bool setElementHasWrittenHoles(JSScript *script, jsbytecode *pc);
     bool propertyWriteCanSpecialize(JSScript *script, jsbytecode *pc);
     bool propertyWriteNeedsBarrier(JSScript *script, jsbytecode *pc, jsid id);
     MIRType elementWrite(JSScript *script, jsbytecode *pc);
     bool arrayPrototypeHasIndexedProperty();
     bool canInlineCalls();
+    bool canInlineCall(JSScript *caller, jsbytecode *pc);
     bool canEnterInlinedScript(JSScript *inlineScript);
 };
 
 static inline MIRType
 MIRTypeFromValueType(JSValueType type)
 {
     switch (type) {
       case JSVAL_TYPE_DOUBLE: