DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (d8847129d134)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "jsapi-tests/tests.h"

using namespace JS;

static void
ScriptCallback(JSRuntime* rt, void* data, JSScript* script)
{
    unsigned& count = *static_cast<unsigned*>(data);
    if (script->hasIonScript())
        ++count;
}

BEGIN_TEST(test_PreserveJitCode)
{
    CHECK(testPreserveJitCode(false, 0));
    CHECK(testPreserveJitCode(true, 1));
    return true;
}

unsigned
countIonScripts(JSObject* global)
{
    unsigned count = 0;
    js::IterateScripts(rt, global->compartment(), &count, ScriptCallback);
    return count;
}

bool
testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts)
{
    rt->options().setBaseline(true);
    rt->options().setIon(true);
    rt->setOffthreadIonCompilationEnabled(false);

    RootedObject global(cx, createTestGlobal(preserveJitCode));
    CHECK(global);
    JSAutoCompartment ac(cx, global);

    CHECK_EQUAL(countIonScripts(global), 0u);

    const char* source =
        "var i = 0;\n"
        "var sum = 0;\n"
        "while (i < 10) {\n"
        "    sum += i;\n"
        "    ++i;\n"
        "}\n"
        "return sum;\n";
    unsigned length = strlen(source);

    JS::RootedFunction fun(cx);
    JS::CompileOptions options(cx);
    options.setFileAndLine(__FILE__, 1);
    JS::AutoObjectVector emptyScopeChain(cx);
    CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "f", 0, nullptr,
			      source, length, &fun));

    RootedValue value(cx);
    for (unsigned i = 0; i < 1500; ++i)
        CHECK(JS_CallFunction(cx, global, fun, JS::HandleValueArray::empty(), &value));
    CHECK_EQUAL(value.toInt32(), 45);
    CHECK_EQUAL(countIonScripts(global), 1u);

    GCForReason(rt, GC_NORMAL, gcreason::API);
    CHECK_EQUAL(countIonScripts(global), remainingIonScripts);

    GCForReason(rt, GC_SHRINK, gcreason::API);
    CHECK_EQUAL(countIonScripts(global), 0u);

    return true;
}

JSObject*
createTestGlobal(bool preserveJitCode)
{
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    options.setPreserveJitCode(preserveJitCode);
    return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}
END_TEST(test_PreserveJitCode)