tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testPreserveJitCode.cpp (3228B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
      6 
      7 #include "jit/Ion.h"                      // js::jit::IsIonEnabled
      8 #include "js/CallAndConstruct.h"          // JS::CallFunction
      9 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction
     10 #include "js/EnvironmentChain.h"          // JS::EnvironmentChain
     11 #include "js/GlobalObject.h"              // JS_NewGlobalObject
     12 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
     13 #include "jsapi-tests/tests.h"
     14 #include "util/Text.h"
     15 
     16 #include "vm/JSObject-inl.h"
     17 #include "vm/JSScript-inl.h"
     18 
     19 using namespace JS;
     20 
     21 static void ScriptCallback(JSRuntime* rt, void* data, js::BaseScript* script,
     22                           const JS::AutoRequireNoGC& nogc) {
     23  unsigned& count = *static_cast<unsigned*>(data);
     24  if (script->asJSScript()->hasIonScript()) {
     25    ++count;
     26  }
     27 }
     28 
     29 BEGIN_TEST(test_PreserveJitCode) {
     30  CHECK(testPreserveJitCode(false, 0));
     31  CHECK(testPreserveJitCode(true, 1));
     32  return true;
     33 }
     34 
     35 unsigned countIonScripts(JSObject* global) {
     36  unsigned count = 0;
     37  js::IterateScripts(cx, global->nonCCWRealm(), &count, ScriptCallback);
     38  return count;
     39 }
     40 
     41 bool testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts) {
     42  cx->runtime()->setOffthreadIonCompilationEnabled(false);
     43 
     44  RootedObject global(cx, createTestGlobal(preserveJitCode));
     45  CHECK(global);
     46  JSAutoRealm ar(cx, global);
     47 
     48  // The Ion JIT may be unavailable due to --disable-jit or lack of support
     49  // for this platform.
     50  if (!js::jit::IsIonEnabled(cx)) {
     51    knownFail = true;
     52  }
     53 
     54  CHECK_EQUAL(countIonScripts(global), 0u);
     55 
     56  static constexpr char source[] =
     57      "var i = 0;\n"
     58      "var sum = 0;\n"
     59      "while (i < 10) {\n"
     60      "    sum += i;\n"
     61      "    ++i;\n"
     62      "}\n"
     63      "return sum;\n";
     64  constexpr unsigned length = js_strlen(source);
     65 
     66  JS::SourceText<mozilla::Utf8Unit> srcBuf;
     67  CHECK(srcBuf.init(cx, source, length, JS::SourceOwnership::Borrowed));
     68 
     69  JS::CompileOptions options(cx);
     70  options.setFileAndLine(__FILE__, 1);
     71 
     72  JS::RootedFunction fun(cx);
     73  JS::EnvironmentChain emptyEnvChain(cx, JS::SupportUnscopables::No);
     74  fun =
     75      JS::CompileFunction(cx, emptyEnvChain, options, "f", 0, nullptr, srcBuf);
     76  CHECK(fun);
     77 
     78  RootedValue value(cx);
     79  for (unsigned i = 0; i < 1500; ++i) {
     80    CHECK(JS_CallFunction(cx, global, fun, JS::HandleValueArray::empty(),
     81                          &value));
     82  }
     83  CHECK_EQUAL(value.toInt32(), 45);
     84  CHECK_EQUAL(countIonScripts(global), 1u);
     85 
     86  NonIncrementalGC(cx, JS::GCOptions::Normal, GCReason::API);
     87  CHECK_EQUAL(countIonScripts(global), remainingIonScripts);
     88 
     89  NonIncrementalGC(cx, JS::GCOptions::Shrink, GCReason::API);
     90  CHECK_EQUAL(countIonScripts(global), 0u);
     91 
     92  return true;
     93 }
     94 
     95 JSObject* createTestGlobal(bool preserveJitCode) {
     96  JS::RealmOptions options;
     97  options.creationOptions().setPreserveJitCode(preserveJitCode);
     98  return JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
     99                            JS::FireOnNewGlobalHook, options);
    100 }
    101 END_TEST(test_PreserveJitCode)