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
86
87
88
89
90
91
92
93
94
95
96
97
|
/* 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/. */
// For js::jit::IsIonEnabled().
#include "jit/Ion.h"
#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(cx, global->compartment(), &count, ScriptCallback);
return count;
}
bool
testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts)
{
cx->options().setBaseline(true);
cx->options().setIon(true);
cx->setOffthreadIonCompilationEnabled(false);
RootedObject global(cx, createTestGlobal(preserveJitCode));
CHECK(global);
JSAutoCompartment ac(cx, global);
#ifdef JS_CODEGEN_ARM64
// The ARM64 Ion JIT is not yet enabled, so this test will fail with
// countIonScripts(global) == 0. Once Ion is enabled for ARM64, this test
// should be passing again, and this code can be deleted.
// Bug 1208526 - ARM64: Reenable jsapi-tests/testPreserveJitCode once Ion is enabled
if (!js::jit::IsIonEnabled(cx))
knownFail = true;
#endif
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(cx, GC_NORMAL, gcreason::API);
CHECK_EQUAL(countIonScripts(global), remainingIonScripts);
GCForReason(cx, GC_SHRINK, gcreason::API);
CHECK_EQUAL(countIonScripts(global), 0u);
return true;
}
JSObject*
createTestGlobal(bool preserveJitCode)
{
JS::CompartmentOptions options;
options.creationOptions().setPreserveJitCode(preserveJitCode);
options.behaviors().setVersion(JSVERSION_LATEST);
return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}
END_TEST(test_PreserveJitCode)
|