Example #1
0
    bool invalidateBailedOutScripts() {
        RootedScript script(cx_, fun_->toFunction()->nonLazyScript());

        // Sometimes the script is collected or invalidated already,
        // for example when a full GC runs at an inconvenient time.
        if (!script->hasParallelIonScript()) {
            JS_ASSERT(hasNoPendingInvalidations());
            return true;
        }

        IonScript *ion = script->parallelIonScript();
        JS_ASSERT(pendingInvalidations.length() == ion->parallelInvalidatedScriptEntries());
        Vector<types::RecompileInfo> invalid(cx_);
        for (uint32_t i = 0; i < pendingInvalidations.length(); i++) {
            JSScript *script = pendingInvalidations[i];
            if (script && !hasScript(invalid, script)) {
                JS_ASSERT(script->hasParallelIonScript());
                if (!invalid.append(script->parallelIonScript()->recompileInfo()))
                    return false;
                ion->parallelInvalidatedScriptList()[i] = script;
            }
            pendingInvalidations[i] = NULL;
        }
        Invalidate(cx_, invalid);
        return true;
    }
Example #2
0
    MethodStatus compileForParallelExecution() {
        // The kernel should be a self-hosted function.
        if (!fun_->isFunction())
            return Method_Skipped;

        RootedFunction callee(cx_, fun_->toFunction());

        if (!callee->isInterpreted() || !callee->isSelfHostedBuiltin())
            return Method_Skipped;

        if (callee->isInterpretedLazy() && !callee->initializeLazyScript(cx_))
            return Method_Error;

        // If this function has not been run enough to enable parallel
        // execution, perform a warmup.
        RootedScript script(cx_, callee->nonLazyScript());
        if (script->getUseCount() < js_IonOptions.usesBeforeCompileParallel) {
            if (!warmupForParallelExecution())
                return Method_Error;
        }

        if (script->hasParallelIonScript() &&
            !script->parallelIonScript()->hasInvalidatedCallTarget())
        {
            Spew(SpewOps, "Already compiled");
            return Method_Compiled;
        }

        Spew(SpewOps, "Compiling all reachable functions");

        ParallelCompileContext compileContext(cx_);
        if (!compileContext.appendToWorklist(script))
            return Method_Error;

        MethodStatus status = compileContext.compileTransitively();
        if (status != Method_Compiled)
            return status;

        // it can happen that during transitive compilation, our
        // callee's parallel ion script is invalidated or GC'd. So
        // before we declare success, double check that it's still
        // compiled!
        if (!callee->nonLazyScript()->hasParallelIonScript())
            return Method_Skipped;

        return Method_Compiled;
    }
Example #3
0
    virtual bool parallel(ForkJoinSlice &slice) {
#ifndef JS_ION
        JS_NOT_REACHED("Parallel execution without ion");
        return false;
#else
        Spew(SpewOps, "Up");

        // Make a new IonContext for the slice, which is needed if we need to
        // re-enter the VM.
        IonContext icx(cx_, NULL);

        JS_ASSERT(pendingInvalidations[slice.sliceId] == NULL);

        JS_ASSERT(fun_->isFunction());
        RootedFunction callee(cx_, fun_->toFunction());
        if (!callee->nonLazyScript()->hasParallelIonScript()) {
            // Sometimes, particularly with GCZeal, the parallel ion
            // script can be collected between starting the parallel
            // op and reaching this point.  In that case, we just fail
            // and fallback.
            Spew(SpewOps, "Down (Script no longer present)");
            return false;
        }

        ParallelIonInvoke<3> fii(cx_, callee, 3);

        fii.args[0] = Int32Value(slice.sliceId);
        fii.args[1] = Int32Value(slice.numSlices);
        fii.args[2] = BooleanValue(false);

        bool ok = fii.invoke(cx_);
        JS_ASSERT(ok == !slice.abortedScript);
        if (!ok) {
            JSScript *script = slice.abortedScript;
            Spew(SpewBailouts, "Aborted script: %p (hasParallelIonScript? %d)",
                 script, script->hasParallelIonScript());
            JS_ASSERT(script->hasParallelIonScript());
            pendingInvalidations[slice.sliceId] = script;
        }

        Spew(SpewOps, "Down");

        return ok;
#endif // JS_ION
    }
Example #4
0
JSObject *
js_InitBooleanClass(JSContext *cx, HandleObject obj)
{
    JS_ASSERT(obj->isNative());

    Rooted<GlobalObject*> global(cx, &obj->asGlobal());

    RootedObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanClass));
    if (!booleanProto)
        return NULL;
    booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));

    RootedFunction ctor(cx, global->createConstructor(cx, Boolean, cx->names().Boolean, 1));
    if (!ctor)
        return NULL;

    if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
        return NULL;

    if (!DefinePropertiesAndBrand(cx, booleanProto, NULL, boolean_methods))
        return NULL;

    Handle<PropertyName*> valueOfName = cx->names().valueOf;
    RootedFunction
        valueOf(cx, js_NewFunction(cx, NullPtr(), bool_valueOf, 0, JSFunction::NATIVE_FUN,
                                   global, valueOfName));
    if (!valueOf)
        return NULL;

    RootedValue value(cx, ObjectValue(*valueOf));
    if (!JSObject::defineProperty(cx, booleanProto, valueOfName, value,
                                  JS_PropertyStub, JS_StrictPropertyStub, 0))
    {
        return NULL;
    }

    global->setBooleanValueOf(valueOf);

    if (!DefineConstructorAndPrototype(cx, global, JSProto_Boolean, ctor, booleanProto))
        return NULL;

    return booleanProto;
}
Example #5
0
JSObject *
js_InitBooleanClass(JSContext *cx, JSObject *obj)
{
    JS_ASSERT(obj->isNative());

    Rooted<GlobalObject*> global(cx, &obj->asGlobal());

    RootedObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanClass));
    if (!booleanProto)
        return NULL;
    booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));

    RootedFunction ctor(cx, global->createConstructor(cx, Boolean, CLASS_NAME(cx, Boolean), 1));
    if (!ctor)
        return NULL;

    if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
        return NULL;

    if (!DefinePropertiesAndBrand(cx, booleanProto, NULL, boolean_methods))
        return NULL;

    Rooted<PropertyName*> valueOfName(cx, cx->runtime->atomState.valueOfAtom);
    Rooted<JSFunction*> valueOf(cx,
                                js_NewFunction(cx, NULL, bool_valueOf, 0, 0, global, valueOfName));
    if (!valueOf)
        return NULL;
    if (!booleanProto->defineProperty(cx, valueOfName, ObjectValue(*valueOf),
                                      JS_PropertyStub, JS_StrictPropertyStub, 0))
    {
        return NULL;
    }

    global->setBooleanValueOf(valueOf);

    if (!DefineConstructorAndPrototype(cx, global, JSProto_Boolean, ctor, booleanProto))
        return NULL;

    return booleanProto;
}
Example #6
0
 bool append(uint32_t index, HandleValue v) {
     JS_ASSERT(!array->getOps()->getElement);
     return !!baseops::DefineElement(cx, array, index, v, JS_PropertyStub, JS_StrictPropertyStub,
                                     JSPROP_ENUMERATE);
 }