Commit 1f113071 authored by Jan de Mooij's avatar Jan de Mooij
Browse files

Bug 1363054 part 3 - Pass StackTypeSet* to addMonitorStubForValue. r=tcampbell

parent 2c06db87
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -783,6 +783,8 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_

    RootedScript script(cx, frame->script());
    jsbytecode* pc = stub->icEntry()->pc(frame->script());
    StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);

    JSOp op = JSOp(*pc);
    FallbackICSpew(cx, stub, "GetElem(%s)", CodeName[op]);

@@ -797,7 +799,7 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_
        if (!GetElemOptimizedArguments(cx, frame, &lhsCopy, rhs, res, &isOptimizedArgs))
            return false;
        if (isOptimizedArgs)
            TypeScript::Monitor(cx, frame->script(), pc, res);
            TypeScript::Monitor(cx, script, pc, types, res);
    }

    bool attached = false;
@@ -828,7 +830,7 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_
    if (!isOptimizedArgs) {
        if (!GetElementOperation(cx, op, lhsCopy, rhs, res))
            return false;
        TypeScript::Monitor(cx, frame->script(), pc, res);
        TypeScript::Monitor(cx, script, pc, types, res);
    }

    // Check if debug mode toggling made the stub invalid.
@@ -836,7 +838,7 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_
        return true;

    // Add a type monitor stub for the resulting value.
    if (!stub->addMonitorStubForValue(cx, frame, res))
    if (!stub->addMonitorStubForValue(cx, frame, types, res))
        return false;

    if (attached)
@@ -1372,14 +1374,15 @@ DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_
            return false;
    }

    TypeScript::Monitor(cx, script, pc, res);
    StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);
    TypeScript::Monitor(cx, script, pc, types, res);

    // Check if debug mode toggling made the stub invalid.
    if (stub.invalid())
        return true;

    // Add a type monitor stub for the resulting value.
    if (!stub->addMonitorStubForValue(cx, frame, res))
    if (!stub->addMonitorStubForValue(cx, frame, types, res))
        return false;

    if (!attached)
@@ -2450,14 +2453,15 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint
        res.set(callArgs.rval());
    }

    TypeScript::Monitor(cx, script, pc, res);
    StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);
    TypeScript::Monitor(cx, script, pc, types, res);

    // Check if debug mode toggling made the stub invalid.
    if (stub.invalid())
        return true;

    // Add a type monitor stub for the resulting value.
    if (!stub->addMonitorStubForValue(cx, frame, res))
    if (!stub->addMonitorStubForValue(cx, frame, types, res))
        return false;

    // If 'callee' is a potential Call_StringSplit, try to attach an
@@ -2509,7 +2513,8 @@ DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_
        return true;

    // Add a type monitor stub for the resulting value.
    if (!stub->addMonitorStubForValue(cx, frame, res))
    StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);
    if (!stub->addMonitorStubForValue(cx, frame, types, res))
        return false;

    if (!handled)
+36 −24
Original line number Diff line number Diff line
@@ -456,9 +456,9 @@ ICMonitoredFallbackStub::initMonitoringChain(JSContext* cx, ICStubSpace* space)

bool
ICMonitoredFallbackStub::addMonitorStubForValue(JSContext* cx, BaselineFrame* frame,
                                                HandleValue val)
                                                StackTypeSet* types, HandleValue val)
{
    return fallbackMonitorStub_->addMonitorStubForValue(cx, frame, val);
    return fallbackMonitorStub_->addMonitorStubForValue(cx, frame, types, val);
}

bool
@@ -2059,14 +2059,15 @@ DoGetPropFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_
    if (!ComputeGetPropResult(cx, frame, op, name, val, res))
        return false;

    TypeScript::Monitor(cx, script, pc, res);
    StackTypeSet* types = TypeScript::BytecodeTypes(script, pc);
    TypeScript::Monitor(cx, script, pc, types, res);

    // Check if debug mode toggling made the stub invalid.
    if (stub.invalid())
        return true;

    // Add a type monitor stub for the resulting value.
    if (!stub->addMonitorStubForValue(cx, frame, res))
    if (!stub->addMonitorStubForValue(cx, frame, types, res))
        return false;

    if (attached)
@@ -2173,8 +2174,11 @@ BaselineScript::noteAccessedGetter(uint32_t pcOffset)
//

bool
ICTypeMonitor_Fallback::addMonitorStubForValue(JSContext* cx, BaselineFrame* frame, HandleValue val)
ICTypeMonitor_Fallback::addMonitorStubForValue(JSContext* cx, BaselineFrame* frame,
                                               StackTypeSet* types, HandleValue val)
{
    MOZ_ASSERT(types);

    bool wasDetachedMonitorChain = lastMonitorStubPtrAddr_ == nullptr;
    MOZ_ASSERT_IF(wasDetachedMonitorChain, numOptimizedMonitorStubs_ == 0);

@@ -2298,7 +2302,10 @@ DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame, ICTypeMonitor_Fallbac
    jsbytecode* pc = stub->icEntry()->pc(script);
    TypeFallbackICSpew(cx, stub, "TypeMonitor");

    if (value.isMagic()) {
    // Copy input value to res.
    res.set(value);

    if (MOZ_UNLIKELY(value.isMagic())) {
        // It's possible that we arrived here from bailing out of Ion, and that
        // Ion proved that the value is dead and optimized out. In such cases,
        // do nothing. However, it's also possible that we have an uninitialized
@@ -2306,7 +2313,6 @@ DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame, ICTypeMonitor_Fallbac

        if (value.whyMagic() == JS_OPTIMIZED_OUT) {
            MOZ_ASSERT(!stub->monitorsThis());
            res.set(value);
            return true;
        }

@@ -2317,32 +2323,38 @@ DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame, ICTypeMonitor_Fallbac
        MOZ_ASSERT(stub->monitorsThis() ||
                   *GetNextPc(pc) == JSOP_CHECKTHIS ||
                   *GetNextPc(pc) == JSOP_CHECKRETURN);
        if (stub->monitorsThis())
            TypeScript::SetThis(cx, script, TypeSet::UnknownType());
        else
            TypeScript::Monitor(cx, script, pc, TypeSet::UnknownType());
        return true;
    }

    // Note: ideally we would merge this if-else statement with the one below,
    // but that triggers an MSVC 2015 compiler bug. See bug 1363054.
    StackTypeSet* types;
    uint32_t argument;
    if (stub->monitorsThis()) {
        MOZ_ASSERT(pc == script->code());
        if (value.isMagic(JS_UNINITIALIZED_LEXICAL))
            TypeScript::SetThis(cx, script, TypeSet::UnknownType());
    if (stub->monitorsArgument(&argument))
        types = TypeScript::ArgTypes(script, argument);
    else if (stub->monitorsThis())
        types = TypeScript::ThisTypes(script);
    else
            TypeScript::SetThis(cx, script, value);
    } else if (stub->monitorsArgument(&argument)) {
        types = TypeScript::BytecodeTypes(script, pc);

    if (stub->monitorsArgument(&argument)) {
        MOZ_ASSERT(pc == script->code());
        MOZ_ASSERT(!value.isMagic(JS_UNINITIALIZED_LEXICAL));
        TypeScript::SetArgument(cx, script, argument, value);
    } else if (stub->monitorsThis()) {
        MOZ_ASSERT(pc == script->code());
        TypeScript::SetThis(cx, script, value);
    } else {
        if (value.isMagic(JS_UNINITIALIZED_LEXICAL))
            TypeScript::Monitor(cx, script, pc, TypeSet::UnknownType());
        else
            TypeScript::Monitor(cx, script, pc, value);
        TypeScript::Monitor(cx, script, pc, types, value);
    }

    if (!stub->invalid() && !stub->addMonitorStubForValue(cx, frame, value))
        return false;

    // Copy input value to res.
    res.set(value);
    if (MOZ_UNLIKELY(stub->invalid()))
        return true;

    return stub->addMonitorStubForValue(cx, frame, types, value);
}

typedef bool (*DoTypeMonitorFallbackFn)(JSContext*, BaselineFrame*, ICTypeMonitor_Fallback*,
+4 −2
Original line number Diff line number Diff line
@@ -1208,7 +1208,8 @@ class ICMonitoredFallbackStub : public ICFallbackStub

  public:
    MOZ_MUST_USE bool initMonitoringChain(JSContext* cx, ICStubSpace* space);
    MOZ_MUST_USE bool addMonitorStubForValue(JSContext* cx, BaselineFrame* frame, HandleValue val);
    MOZ_MUST_USE bool addMonitorStubForValue(JSContext* cx, BaselineFrame* frame,
                                             StackTypeSet* types, HandleValue val);

    inline ICTypeMonitor_Fallback* fallbackMonitorStub() const {
        return fallbackMonitorStub_;
@@ -1468,7 +1469,8 @@ class ICTypeMonitor_Fallback : public ICStub

    // Create a new monitor stub for the type of the given value, and
    // add it to this chain.
    MOZ_MUST_USE bool addMonitorStubForValue(JSContext* cx, BaselineFrame* frame, HandleValue val);
    MOZ_MUST_USE bool addMonitorStubForValue(JSContext* cx, BaselineFrame* frame,
                                             StackTypeSet* types, HandleValue val);

    void resetMonitorStubChain(Zone* zone);

+11 −0
Original line number Diff line number Diff line
@@ -489,6 +489,8 @@ MarkObjectStateChange(JSContext* cx, JSObject* obj)

/* Interface helpers for JSScript*. */
extern void TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, TypeSet::Type type);
extern void TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, StackTypeSet* types,
                              TypeSet::Type type);
extern void TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, const Value& rval);

/////////////////////////////////////////////////////////////////////
@@ -589,6 +591,15 @@ TypeScript::Monitor(JSContext* cx, const js::Value& rval)
    Monitor(cx, script, pc, rval);
}

/* static */ inline void
TypeScript::Monitor(JSContext* cx, JSScript* script, jsbytecode* pc, StackTypeSet* types,
                    const js::Value& rval)
{
    TypeSet::Type type = TypeSet::GetValueType(rval);
    if (!types->hasType(type))
        TypeMonitorResult(cx, script, pc, types, type);
}

/* static */ inline void
TypeScript::MonitorAssign(JSContext* cx, HandleObject obj, jsid id)
{
+16 −0
Original line number Diff line number Diff line
@@ -3341,6 +3341,22 @@ js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, TypeSet::
    types->addType(cx, type);
}

void
js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, StackTypeSet* types,
                      TypeSet::Type type)
{
    assertSameCompartment(cx, script, type);

    AutoEnterAnalysis enter(cx);

    MOZ_ASSERT(types == TypeScript::BytecodeTypes(script, pc));
    MOZ_ASSERT(!types->hasType(type));

    InferSpew(ISpewOps, "bytecodeType: %p %05" PRIuSIZE ": %s",
              script, script->pcToOffset(pc), TypeSet::TypeString(type));
    types->addType(cx, type);
}

void
js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, const js::Value& rval)
{
Loading