diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 330679921ce..e600f9130df 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -721,19 +721,8 @@ static const char js_werror_option_str[] = JS_OPTIONS_DOT_STR "werror"; static const char js_zeal_option_str[] = JS_OPTIONS_DOT_STR "gczeal"; static const char js_zeal_frequency_str[] = JS_OPTIONS_DOT_STR "gczeal.frequency"; #endif -static const char js_typeinfer_content_str[] = JS_OPTIONS_DOT_STR "typeinference.content"; -static const char js_typeinfer_chrome_str[] = JS_OPTIONS_DOT_STR "typeinference.chrome"; static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log"; static const char js_memnotify_option_str[] = JS_OPTIONS_DOT_STR "mem.notify"; -static const char js_asmjs_content_str[] = JS_OPTIONS_DOT_STR "asmjs"; -static const char js_baselinejit_content_str[] = JS_OPTIONS_DOT_STR "baselinejit.content"; -static const char js_baselinejit_chrome_str[] = JS_OPTIONS_DOT_STR "baselinejit.chrome"; -static const char js_baselinejit_eager_str[] = JS_OPTIONS_DOT_STR "baselinejit.unsafe_eager_compilation"; -static const char js_ion_content_str[] = JS_OPTIONS_DOT_STR "ion.content"; -static const char js_ion_chrome_str[] = JS_OPTIONS_DOT_STR "ion.chrome"; -static const char js_ion_eager_str[] = JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation"; -static const char js_parallel_parsing_str[] = JS_OPTIONS_DOT_STR "parallel_parsing"; -static const char js_ion_parallel_compilation_str[] = JS_OPTIONS_DOT_STR "ion.parallel_compilation"; void nsJSContext::JSOptionChangedCallback(const char *pref, void *data) @@ -756,39 +745,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) nsCOMPtr contentWindow(do_QueryInterface(global)); nsCOMPtr chromeWindow(do_QueryInterface(global)); - bool useTypeInference = Preferences::GetBool((chromeWindow || !contentWindow) ? - js_typeinfer_chrome_str : - js_typeinfer_content_str); - bool useBaselineJIT = Preferences::GetBool((chromeWindow || !contentWindow) ? - js_baselinejit_chrome_str : - js_baselinejit_content_str); - bool useBaselineJITEager = Preferences::GetBool(js_baselinejit_eager_str); - bool useIon = Preferences::GetBool((chromeWindow || !contentWindow) ? - js_ion_chrome_str : - js_ion_content_str); - bool useIonEager = Preferences::GetBool(js_ion_eager_str); - bool useAsmJS = Preferences::GetBool(js_asmjs_content_str); - bool parallelParsing = Preferences::GetBool(js_parallel_parsing_str); - bool parallelIonCompilation = Preferences::GetBool(js_ion_parallel_compilation_str); - nsCOMPtr xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID); - if (xr) { - bool safeMode = false; - xr->GetInSafeMode(&safeMode); - if (safeMode) { - useTypeInference = false; - useBaselineJIT = false; - useBaselineJITEager = false; - useIon = false; - useIonEager = false; - useAsmJS = false; - } - } - - JS::ContextOptionsRef(cx).setTypeInference(useTypeInference) - .setBaseline(useBaselineJIT) - .setIon(useIon) - .setAsmJS(useAsmJS); - #ifdef DEBUG // In debug builds, warnings are enabled in chrome context if // javascript.options.strict.debug is true @@ -800,15 +756,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) JS::ContextOptionsRef(cx).setWerror(Preferences::GetBool(js_werror_option_str)); - ::JS_SetParallelParsingEnabled(context->mContext, parallelParsing); - ::JS_SetParallelIonCompilationEnabled(context->mContext, parallelIonCompilation); - - ::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER, - (useBaselineJITEager ? 0 : -1)); - - ::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_ION_USECOUNT_TRIGGER, - (useIonEager ? 0 : -1)); - #ifdef JS_GC_ZEAL int32_t zeal = Preferences::GetInt(js_zeal_option_str, -1); int32_t frequency = Preferences::GetInt(js_zeal_frequency_str, JS_DEFAULT_ZEAL_FREQ); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 7e2bbd575c5..b996a872cf2 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -148,7 +148,7 @@ namespace { const uint32_t kNoIndex = uint32_t(-1); -const JS::ContextOptions kRequiredJSContextOptions = +const JS::ContextOptions kRequiredContextOptions = JS::ContextOptions().setDontReportUncaught(true) .setNoScriptRval(true); @@ -300,7 +300,7 @@ GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName, } void -LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) +LoadRuntimeAndContextOptions(const char* aPrefName, void* /* aClosure */) { AssertIsOnMainThread(); @@ -330,51 +330,47 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) } #endif + // Runtime options. + JS::RuntimeOptions runtimeOptions; + if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) { + runtimeOptions.setAsmJS(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference"))) { + runtimeOptions.setTypeInference(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit"))) { + runtimeOptions.setBaseline(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("ion"))) { + runtimeOptions.setIon(true); + } + // Common options. - JS::ContextOptions commonOptions = kRequiredJSContextOptions; + JS::ContextOptions commonContextOptions = kRequiredContextOptions; if (GetWorkerPref(NS_LITERAL_CSTRING("strict"))) { - commonOptions.setExtraWarnings(true); + commonContextOptions.setExtraWarnings(true); } if (GetWorkerPref(NS_LITERAL_CSTRING("werror"))) { - commonOptions.setWerror(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) { - commonOptions.setAsmJS(true); + commonContextOptions.setWerror(true); } // Content options. - JS::ContextOptions contentOptions = commonOptions; - if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit.content"))) { - contentOptions.setBaseline(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("ion.content"))) { - contentOptions.setIon(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.content"))) { - contentOptions.setTypeInference(true); - } + JS::ContextOptions contentContextOptions = commonContextOptions; // Chrome options. - JS::ContextOptions chromeOptions = commonOptions; - if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit.chrome"))) { - chromeOptions.setBaseline(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("ion.chrome"))) { - chromeOptions.setIon(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.chrome"))) { - chromeOptions.setTypeInference(true); - } + JS::ContextOptions chromeContextOptions = commonContextOptions; #ifdef DEBUG if (GetWorkerPref(NS_LITERAL_CSTRING("strict.debug"))) { - chromeOptions.setExtraWarnings(true); + chromeContextOptions.setExtraWarnings(true); } #endif - RuntimeService::SetDefaultJSContextOptions(contentOptions, chromeOptions); + RuntimeService::SetDefaultRuntimeAndContextOptions(runtimeOptions, + contentContextOptions, + chromeContextOptions); if (rts) { - rts->UpdateAllWorkerJSContextOptions(); + rts->UpdateAllWorkerRuntimeAndContextOptions(); } } @@ -771,6 +767,8 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) JSSettings settings; aWorkerPrivate->CopyJSSettings(settings); + JS::RuntimeOptionsRef(aRuntime) = settings.runtimeOptions; + JSSettings::JSGCSettingsArray& gcSettings = settings.gcSettings; // This is the real place where we set the max memory for the runtime. @@ -1614,10 +1612,11 @@ RuntimeService::Init() // Initialize JSSettings. if (!sDefaultJSSettings.gcSettings[0].IsSet()) { - sDefaultJSSettings.chrome.contextOptions = kRequiredJSContextOptions; + sDefaultJSSettings.runtimeOptions = JS::RuntimeOptions(); + sDefaultJSSettings.chrome.contextOptions = kRequiredContextOptions; sDefaultJSSettings.chrome.maxScriptRuntime = -1; sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST); - sDefaultJSSettings.content.contextOptions = kRequiredJSContextOptions; + sDefaultJSSettings.content.contextOptions = kRequiredContextOptions; sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC; #ifdef JS_GC_ZEAL sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ; @@ -1692,13 +1691,13 @@ RuntimeService::Init() PREF_DOM_WINDOW_DUMP_ENABLED, reinterpret_cast(WORKERPREF_DUMP))) || #endif - NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions, + NS_FAILED(Preferences::RegisterCallback(LoadRuntimeAndContextOptions, PREF_JS_OPTIONS_PREFIX, nullptr)) || NS_FAILED(Preferences::RegisterCallbackAndCall( - LoadJSContextOptions, - PREF_WORKERS_OPTIONS_PREFIX, - nullptr)) || + LoadRuntimeAndContextOptions, + PREF_WORKERS_OPTIONS_PREFIX, + nullptr)) || NS_FAILED(Preferences::RegisterCallbackAndCall( JSVersionChanged, PREF_WORKERS_LATEST_JS_VERSION, @@ -1845,10 +1844,10 @@ RuntimeService::Cleanup() if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged, PREF_WORKERS_LATEST_JS_VERSION, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions, + NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions, PREF_JS_OPTIONS_PREFIX, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions, + NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions, PREF_WORKERS_OPTIONS_PREFIX, nullptr)) || #if DUMP_CONTROLLED_BY_PREF @@ -2230,9 +2229,10 @@ RuntimeService::NoteIdleThread(WorkerThread* aThread) } void -RuntimeService::UpdateAllWorkerJSContextOptions() +RuntimeService::UpdateAllWorkerRuntimeAndContextOptions() { - BROADCAST_ALL_WORKERS(UpdateJSContextOptions, + BROADCAST_ALL_WORKERS(UpdateRuntimeAndContextOptions, + sDefaultJSSettings.runtimeOptions, sDefaultJSSettings.content.contextOptions, sDefaultJSSettings.chrome.contextOptions); } diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h index b209bc90abb..9f81fd3fa07 100644 --- a/dom/workers/RuntimeService.h +++ b/dom/workers/RuntimeService.h @@ -174,16 +174,19 @@ public: } static void - SetDefaultJSContextOptions(const JS::ContextOptions& aContentOptions, - const JS::ContextOptions& aChromeOptions) + SetDefaultRuntimeAndContextOptions( + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions) { AssertIsOnMainThread(); - sDefaultJSSettings.content.contextOptions = aContentOptions; - sDefaultJSSettings.chrome.contextOptions = aChromeOptions; + sDefaultJSSettings.runtimeOptions = aRuntimeOptions; + sDefaultJSSettings.content.contextOptions = aContentCxOptions; + sDefaultJSSettings.chrome.contextOptions = aChromeCxOptions; } void - UpdateAllWorkerJSContextOptions(); + UpdateAllWorkerRuntimeAndContextOptions(); void UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 9eac3b4bb8f..7691764bb58 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1516,25 +1516,32 @@ private: } }; -class UpdateJSContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable +class UpdateRuntimeAndContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable { - JS::ContextOptions mContentOptions; - JS::ContextOptions mChromeOptions; + JS::RuntimeOptions mRuntimeOptions; + JS::ContextOptions mContentCxOptions; + JS::ContextOptions mChromeCxOptions; public: - UpdateJSContextOptionsRunnable(WorkerPrivate* aWorkerPrivate, - const JS::ContextOptions& aContentOptions, - const JS::ContextOptions& aChromeOptions) + UpdateRuntimeAndContextOptionsRunnable( + WorkerPrivate* aWorkerPrivate, + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions) : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount), - mContentOptions(aContentOptions), mChromeOptions(aChromeOptions) + mRuntimeOptions(aRuntimeOptions), + mContentCxOptions(aContentCxOptions), + mChromeCxOptions(aChromeCxOptions) { } private: virtual bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE { - aWorkerPrivate->UpdateJSContextOptionsInternal(aCx, mContentOptions, - mChromeOptions); + aWorkerPrivate->UpdateRuntimeAndContextOptionsInternal(aCx, + mRuntimeOptions, + mContentCxOptions, + mChromeCxOptions); return true; } }; @@ -2838,22 +2845,26 @@ WorkerPrivateParent::GetInnerWindowId() template void -WorkerPrivateParent::UpdateJSContextOptions( - JSContext* aCx, - const JS::ContextOptions& aContentOptions, - const JS::ContextOptions& aChromeOptions) +WorkerPrivateParent::UpdateRuntimeAndContextOptions( + JSContext* aCx, + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions) { AssertIsOnParentThread(); { MutexAutoLock lock(mMutex); - mJSSettings.content.contextOptions = aContentOptions; - mJSSettings.chrome.contextOptions = aChromeOptions; + mJSSettings.runtimeOptions = aRuntimeOptions; + mJSSettings.content.contextOptions = aContentCxOptions; + mJSSettings.chrome.contextOptions = aChromeCxOptions; } - nsRefPtr runnable = - new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aContentOptions, - aChromeOptions); + nsRefPtr runnable = + new UpdateRuntimeAndContextOptionsRunnable(ParentAsWorkerPrivate(), + aRuntimeOptions, + aContentCxOptions, + aChromeCxOptions); if (!runnable->Dispatch(aCx)) { NS_WARNING("Failed to update worker context options!"); JS_ClearPendingException(aCx); @@ -5491,17 +5502,21 @@ WorkerPrivate::RescheduleTimeoutTimer(JSContext* aCx) } void -WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx, - const JS::ContextOptions& aContentOptions, - const JS::ContextOptions& aChromeOptions) +WorkerPrivate::UpdateRuntimeAndContextOptionsInternal( + JSContext* aCx, + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions) { AssertIsOnWorkerThread(); - JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeOptions : aContentOptions; + JS::RuntimeOptionsRef(aCx) = aRuntimeOptions; + JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeCxOptions : aContentCxOptions; for (uint32_t index = 0; index < mChildWorkers.Length(); index++) { - mChildWorkers[index]->UpdateJSContextOptions(aCx, aContentOptions, - aChromeOptions); + mChildWorkers[index]->UpdateRuntimeAndContextOptions(aCx, aRuntimeOptions, + aContentCxOptions, + aChromeCxOptions); } } diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index ce66719b3cc..72189f115a7 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -389,8 +389,10 @@ public: GetInnerWindowId(); void - UpdateJSContextOptions(JSContext* aCx, const JS::ContextOptions& aChromeOptions, - const JS::ContextOptions& aContentOptions); + UpdateRuntimeAndContextOptions(JSContext* aCx, + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions); void UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue); @@ -906,8 +908,11 @@ public: } void - UpdateJSContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContentOptions, - const JS::ContextOptions& aChromeOptions); + UpdateRuntimeAndContextOptionsInternal( + JSContext* aCx, + const JS::RuntimeOptions& aRuntimeOptions, + const JS::ContextOptions& aContentCxOptions, + const JS::ContextOptions& aChromeCxOptions); void UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue); diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index c86c23bccbc..2a57df013c4 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -107,6 +107,7 @@ struct JSSettings JSContentChromeSettings chrome; JSContentChromeSettings content; JSGCSettingsArray gcSettings; + JS::RuntimeOptions runtimeOptions; #ifdef JS_GC_ZEAL uint8_t gcZeal; diff --git a/js/jsd/jsd_xpc.cpp b/js/jsd/jsd_xpc.cpp index ca1c299b1b0..0f869a7ae13 100644 --- a/js/jsd/jsd_xpc.cpp +++ b/js/jsd/jsd_xpc.cpp @@ -1655,11 +1655,7 @@ jsdContext::GetJSContext(JSContext **_rval) #define JSOPTION_DONT_REPORT_UNCAUGHT JS_BIT(8) #define JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT JS_BIT(11) #define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) -#define JSOPTION_BASELINE JS_BIT(14) -#define JSOPTION_TYPE_INFERENCE JS_BIT(16) #define JSOPTION_STRICT_MODE JS_BIT(17) -#define JSOPTION_ION JS_BIT(18) -#define JSOPTION_ASMJS JS_BIT(19) #define JSOPTION_MASK JS_BITMASK(20) NS_IMETHODIMP @@ -1673,11 +1669,7 @@ jsdContext::GetOptions(uint32_t *_rval) | (JS::ContextOptionsRef(mJSCx).dontReportUncaught() ? JSOPTION_DONT_REPORT_UNCAUGHT : 0) | (JS::ContextOptionsRef(mJSCx).noDefaultCompartmentObject() ? JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT : 0) | (JS::ContextOptionsRef(mJSCx).noScriptRval() ? JSOPTION_NO_SCRIPT_RVAL : 0) - | (JS::ContextOptionsRef(mJSCx).strictMode() ? JSOPTION_STRICT_MODE : 0) - | (JS::ContextOptionsRef(mJSCx).baseline() ? JSOPTION_BASELINE : 0) - | (JS::ContextOptionsRef(mJSCx).typeInference() ? JSOPTION_TYPE_INFERENCE : 0) - | (JS::ContextOptionsRef(mJSCx).ion() ? JSOPTION_ION : 0) - | (JS::ContextOptionsRef(mJSCx).asmJS() ? JSOPTION_ASMJS : 0); + | (JS::ContextOptionsRef(mJSCx).strictMode() ? JSOPTION_STRICT_MODE : 0); return NS_OK; } @@ -1698,11 +1690,7 @@ jsdContext::SetOptions(uint32_t options) .setDontReportUncaught(options & JSOPTION_DONT_REPORT_UNCAUGHT) .setNoDefaultCompartmentObject(options & JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT) .setNoScriptRval(options & JSOPTION_NO_SCRIPT_RVAL) - .setStrictMode(options & JSOPTION_STRICT_MODE) - .setBaseline(options & JSOPTION_BASELINE) - .setTypeInference(options & JSOPTION_TYPE_INFERENCE) - .setIon(options & JSOPTION_ION) - .setAsmJS(options & JSOPTION_ASMJS); + .setStrictMode(options & JSOPTION_STRICT_MODE); return NS_OK; } diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 6087d77cd27..0c07d4fc2cb 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1160,7 +1160,7 @@ SetJitCompilerOption(JSContext *cx, unsigned argc, jsval *vp) if (number < 0) number = -1; - JS_SetGlobalJitCompilerOption(cx, opt, uint32_t(number)); + JS_SetGlobalJitCompilerOption(cx->runtime(), opt, uint32_t(number)); args.rval().setUndefined(); return true; @@ -1175,10 +1175,10 @@ GetJitCompilerOptions(JSContext *cx, unsigned argc, jsval *vp) RootedValue value(cx); -#define JIT_COMPILER_MATCH(key, string) \ - opt = JSJITCOMPILER_ ## key; \ - value.setInt32(JS_GetGlobalJitCompilerOption(cx, opt)); \ - if (!JS_SetProperty(cx, info, string, value)) \ +#define JIT_COMPILER_MATCH(key, string) \ + opt = JSJITCOMPILER_ ## key; \ + value.setInt32(JS_GetGlobalJitCompilerOption(cx->runtime(), opt)); \ + if (!JS_SetProperty(cx, info, string, value)) \ return false; JSJitCompilerOption opt = JSJITCOMPILER_NOT_AN_OPTION; diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 85c318ef14d..7c4b810f1fc 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -6952,7 +6952,7 @@ js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp) cx->signalHandlersInstalled() && cx->gcSystemPageSize() == AsmJSPageSize && !cx->compartment()->debugMode() && - cx->compartment()->options().asmJS(cx); + cx->runtime()->options().asmJS(); args.rval().set(BooleanValue(available)); return true; diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 7bfed2c1919..3edf4715e31 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -312,7 +312,7 @@ struct BaselineScript inline bool IsBaselineEnabled(JSContext *cx) { - return cx->compartment()->options().baseline(cx); + return cx->runtime()->options().baseline(); } MethodStatus diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index bdf0f9bb954..9a58a81fb92 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -159,8 +159,8 @@ void StopAllOffThreadCompilations(JSCompartment *comp); static inline bool IsIonEnabled(JSContext *cx) { - return cx->compartment()->options().ion(cx) && - cx->compartment()->options().baseline(cx) && + return cx->runtime()->options().ion() && + cx->runtime()->options().baseline() && cx->typeInferenceEnabled(); } diff --git a/js/src/jsapi-tests/testFuncCallback.cpp b/js/src/jsapi-tests/testFuncCallback.cpp index 4fc83d838c6..fa70966e521 100644 --- a/js/src/jsapi-tests/testFuncCallback.cpp +++ b/js/src/jsapi-tests/testFuncCallback.cpp @@ -133,7 +133,7 @@ JSContext *createContext() JSContext *cx = JSAPITest::createContext(); if (!cx) return nullptr; - JS::ContextOptionsRef(cx).setBaseline(true) + JS::RuntimeOptionsRef(cx).setBaseline(true) .setIon(true); return cx; } diff --git a/js/src/jsapi-tests/testProfileStrings.cpp b/js/src/jsapi-tests/testProfileStrings.cpp index 3f51b5ebc79..786322573b2 100644 --- a/js/src/jsapi-tests/testProfileStrings.cpp +++ b/js/src/jsapi-tests/testProfileStrings.cpp @@ -141,7 +141,7 @@ END_TEST(testProfileStrings_isCalledWithInterpreter) BEGIN_TEST(testProfileStrings_isCalledWithJIT) { CHECK(initialize(cx)); - JS::ContextOptionsRef(cx).setBaseline(true) + JS::RuntimeOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function g() { var p = new Prof(); p.test_fn(); }"); @@ -190,7 +190,7 @@ END_TEST(testProfileStrings_isCalledWithJIT) BEGIN_TEST(testProfileStrings_isCalledWhenError) { CHECK(initialize(cx)); - JS::ContextOptionsRef(cx).setBaseline(true) + JS::RuntimeOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function check2() { throw 'a'; }"); @@ -214,7 +214,7 @@ END_TEST(testProfileStrings_isCalledWhenError) BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly) { CHECK(initialize(cx)); - JS::ContextOptionsRef(cx).setBaseline(true) + JS::RuntimeOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function b(p) { p.test_fn(); }"); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index c5594700827..f06d86872b5 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -882,6 +882,18 @@ JS_StringToVersion(const char *string) return JSVERSION_UNKNOWN; } +JS_PUBLIC_API(JS::RuntimeOptions &) +JS::RuntimeOptionsRef(JSRuntime *rt) +{ + return rt->options(); +} + +JS_PUBLIC_API(JS::RuntimeOptions &) +JS::RuntimeOptionsRef(JSContext *cx) +{ + return cx->runtime()->options(); +} + JS_PUBLIC_API(JS::ContextOptions &) JS::ContextOptionsRef(JSContext *cx) { @@ -2453,36 +2465,6 @@ class AutoHoldZone } /* anonymous namespace */ -bool -JS::CompartmentOptions::baseline(JSContext *cx) const -{ - return baselineOverride_.get(cx->options().baseline()); -} - -bool -JS::CompartmentOptions::typeInference(const ExclusiveContext *cx) const -{ - /* Unlike the other options that can be overriden on a per compartment - * basis, the default value for the typeInference option is stored on the - * compartment's type zone, rather than the current JSContext. Type zones - * copy this default value over from the current JSContext when they are - * created. - */ - return typeInferenceOverride_.get(cx->compartment()->zone()->types.inferenceEnabled); -} - -bool -JS::CompartmentOptions::ion(JSContext *cx) const -{ - return ionOverride_.get(cx->options().ion()); -} - -bool -JS::CompartmentOptions::asmJS(JSContext *cx) const -{ - return asmJSOverride_.get(cx->options().asmJS()); -} - bool JS::CompartmentOptions::cloneSingletons(JSContext *cx) const { @@ -4440,7 +4422,7 @@ JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version) strictOption = cx->options().strictMode(); extraWarningsOption = cx->options().extraWarnings(); werrorOption = cx->options().werror(); - asmJSOption = cx->options().asmJS(); + asmJSOption = cx->runtime()->options().asmJS(); } bool @@ -5982,23 +5964,23 @@ JS_ScheduleGC(JSContext *cx, uint32_t count) #endif JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSContext *cx, bool enabled) +JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled) { #ifdef JS_ION - cx->runtime()->setParallelParsingEnabled(enabled); + rt->setParallelParsingEnabled(enabled); #endif } JS_PUBLIC_API(void) -JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled) +JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled) { #ifdef JS_ION - cx->runtime()->setParallelIonCompilationEnabled(enabled); + rt->setParallelIonCompilationEnabled(enabled); #endif } JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value) +JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value) { #ifdef JS_ION @@ -6021,19 +6003,19 @@ JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t v break; case JSJITCOMPILER_ION_ENABLE: if (value == 1) { - JS::ContextOptionsRef(cx).setIon(true); + JS::RuntimeOptionsRef(rt).setIon(true); IonSpew(js::jit::IonSpew_Scripts, "Enable ion"); } else if (value == 0) { - JS::ContextOptionsRef(cx).setIon(false); + JS::RuntimeOptionsRef(rt).setIon(false); IonSpew(js::jit::IonSpew_Scripts, "Disable ion"); } break; case JSJITCOMPILER_BASELINE_ENABLE: if (value == 1) { - JS::ContextOptionsRef(cx).setBaseline(true); + JS::RuntimeOptionsRef(rt).setBaseline(true); IonSpew(js::jit::IonSpew_BaselineScripts, "Enable baseline"); } else if (value == 0) { - JS::ContextOptionsRef(cx).setBaseline(false); + JS::RuntimeOptionsRef(rt).setBaseline(false); IonSpew(js::jit::IonSpew_BaselineScripts, "Disable baseline"); } break; @@ -6044,7 +6026,7 @@ JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t v } JS_PUBLIC_API(int) -JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt) +JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt) { #ifdef JS_ION switch (opt) { @@ -6053,9 +6035,9 @@ JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt) case JSJITCOMPILER_ION_USECOUNT_TRIGGER: return jit::js_JitOptions.forcedDefaultIonUsesBeforeCompile; case JSJITCOMPILER_ION_ENABLE: - return JS::ContextOptionsRef(cx).ion(); + return JS::RuntimeOptionsRef(rt).ion(); case JSJITCOMPILER_BASELINE_ENABLE: - return JS::ContextOptionsRef(cx).baseline(); + return JS::RuntimeOptionsRef(rt).baseline(); default: break; } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 508af04a8a3..88a98fe26e6 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1438,6 +1438,69 @@ JS_StringToVersion(const char *string); namespace JS { +class JS_PUBLIC_API(RuntimeOptions) { + public: + RuntimeOptions() + : baseline_(false), + typeInference_(false), + ion_(false), + asmJS_(false) + { + } + + bool baseline() const { return baseline_; } + RuntimeOptions &setBaseline(bool flag) { + baseline_ = flag; + return *this; + } + RuntimeOptions &toggleBaseline() { + baseline_ = !baseline_; + return *this; + } + + bool typeInference() const { return typeInference_; } + RuntimeOptions &setTypeInference(bool flag) { + typeInference_ = flag; + return *this; + } + RuntimeOptions &toggleTypeInference() { + typeInference_ = !typeInference_; + return *this; + } + + bool ion() const { return ion_; } + RuntimeOptions &setIon(bool flag) { + ion_ = flag; + return *this; + } + RuntimeOptions &toggleIon() { + ion_ = !ion_; + return *this; + } + + bool asmJS() const { return asmJS_; } + RuntimeOptions &setAsmJS(bool flag) { + asmJS_ = flag; + return *this; + } + RuntimeOptions &toggleAsmJS() { + asmJS_ = !asmJS_; + return *this; + } + + private: + bool baseline_ : 1; + bool typeInference_ : 1; + bool ion_ : 1; + bool asmJS_ : 1; +}; + +JS_PUBLIC_API(RuntimeOptions &) +RuntimeOptionsRef(JSRuntime *rt); + +JS_PUBLIC_API(RuntimeOptions &) +RuntimeOptionsRef(JSContext *cx); + class JS_PUBLIC_API(ContextOptions) { public: ContextOptions() @@ -1449,10 +1512,6 @@ class JS_PUBLIC_API(ContextOptions) { noDefaultCompartmentObject_(false), noScriptRval_(false), strictMode_(false), - baseline_(false), - typeInference_(false), - ion_(false), - asmJS_(false), cloneSingletons_(false) { } @@ -1537,46 +1596,6 @@ class JS_PUBLIC_API(ContextOptions) { return *this; } - bool baseline() const { return baseline_; } - ContextOptions &setBaseline(bool flag) { - baseline_ = flag; - return *this; - } - ContextOptions &toggleBaseline() { - baseline_ = !baseline_; - return *this; - } - - bool typeInference() const { return typeInference_; } - ContextOptions &setTypeInference(bool flag) { - typeInference_ = flag; - return *this; - } - ContextOptions &toggleTypeInference() { - typeInference_ = !typeInference_; - return *this; - } - - bool ion() const { return ion_; } - ContextOptions &setIon(bool flag) { - ion_ = flag; - return *this; - } - ContextOptions &toggleIon() { - ion_ = !ion_; - return *this; - } - - bool asmJS() const { return asmJS_; } - ContextOptions &setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - ContextOptions &toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - bool cloneSingletons() const { return cloneSingletons_; } ContextOptions &setCloneSingletons(bool flag) { cloneSingletons_ = flag; @@ -1596,10 +1615,6 @@ class JS_PUBLIC_API(ContextOptions) { bool noDefaultCompartmentObject_ : 1; bool noScriptRval_ : 1; bool strictMode_ : 1; - bool baseline_ : 1; - bool typeInference_ : 1; - bool ion_ : 1; - bool asmJS_ : 1; bool cloneSingletons_ : 1; }; @@ -2646,18 +2661,6 @@ class JS_PUBLIC_API(CompartmentOptions) return *this; } - bool baseline(JSContext *cx) const; - Override &baselineOverride() { return baselineOverride_; } - - bool typeInference(const js::ExclusiveContext *cx) const; - Override &typeInferenceOverride() { return typeInferenceOverride_; } - - bool ion(JSContext *cx) const; - Override &ionOverride() { return ionOverride_; } - - bool asmJS(JSContext *cx) const; - Override &asmJSOverride() { return asmJSOverride_; } - bool cloneSingletons(JSContext *cx) const; Override &cloneSingletonsOverride() { return cloneSingletonsOverride_; } @@ -2680,10 +2683,6 @@ class JS_PUBLIC_API(CompartmentOptions) JSVersion version_; bool invisibleToDebugger_; bool mergeable_; - Override baselineOverride_; - Override typeInferenceOverride_; - Override ionOverride_; - Override asmJSOverride_; Override cloneSingletonsOverride_; union { ZoneSpecifier spec; @@ -4658,10 +4657,10 @@ JS_ScheduleGC(JSContext *cx, uint32_t count); #endif extern JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSContext *cx, bool enabled); +JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled); extern JS_PUBLIC_API(void) -JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled); +JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled); #define JIT_COMPILER_OPTIONS(Register) \ Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \ @@ -4680,9 +4679,9 @@ typedef enum JSJitCompilerOption { } JSJitCompilerOption; extern JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value); +JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value); extern JS_PUBLIC_API(int) -JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt); +JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt); /* * Convert a uint32_t index into a jsid. diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 74b49d6037c..ba570e6915e 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -521,7 +521,7 @@ namespace js { inline bool ExclusiveContext::typeInferenceEnabled() const { - return compartment_->options().typeInference(this); + return zone()->types.inferenceEnabled; } inline js::Handle diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index a3450af894d..f82dc49abdf 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1831,7 +1831,7 @@ void TypeZone::init(JSContext *cx) { if (!cx || - !cx->options().typeInference() || + !cx->runtime()->options().typeInference() || !cx->runtime()->jitSupportsFloatingPoint) { return; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index a8f2295e534..02d00922e4c 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -118,11 +118,7 @@ static double gTimeoutInterval = -1.0; static volatile bool gTimedOut = false; static JS::Value gTimeoutFunc; -static bool enableTypeInference = true; static bool enableDisassemblyDumps = false; -static bool enableIon = true; -static bool enableBaseline = true; -static bool enableAsmJS = true; static bool printTiming = false; static const char *jsCacheDir = nullptr; @@ -653,7 +649,8 @@ Options(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); - JS::ContextOptions oldOptions = JS::ContextOptionsRef(cx); + JS::RuntimeOptions oldRuntimeOptions = JS::RuntimeOptionsRef(cx); + JS::ContextOptions oldContextOptions = JS::ContextOptionsRef(cx); for (unsigned i = 0; i < args.length(); i++) { JSString *str = JS::ToString(cx, args[i]); if (!str) @@ -667,7 +664,7 @@ Options(JSContext *cx, unsigned argc, jsval *vp) if (strcmp(opt.ptr(), "strict") == 0) JS::ContextOptionsRef(cx).toggleExtraWarnings(); else if (strcmp(opt.ptr(), "typeinfer") == 0) - JS::ContextOptionsRef(cx).toggleTypeInference(); + JS::RuntimeOptionsRef(cx).toggleTypeInference(); else if (strcmp(opt.ptr(), "werror") == 0) JS::ContextOptionsRef(cx).toggleWerror(); else if (strcmp(opt.ptr(), "strict_mode") == 0) @@ -691,19 +688,19 @@ Options(JSContext *cx, unsigned argc, jsval *vp) char *names = strdup(""); bool found = false; - if (!names && oldOptions.extraWarnings()) { + if (!names && oldContextOptions.extraWarnings()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict"); found = true; } - if (!names && oldOptions.typeInference()) { + if (!names && oldRuntimeOptions.typeInference()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "typeinfer"); found = true; } - if (!names && oldOptions.werror()) { + if (!names && oldContextOptions.werror()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "werror"); found = true; } - if (!names && oldOptions.strictMode()) { + if (!names && oldContextOptions.strictMode()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict_mode"); found = true; } @@ -5603,14 +5600,6 @@ NewContext(JSRuntime *rt) JS_SetContextPrivate(cx, data); JS_SetErrorReporter(cx, my_ErrorReporter); - if (enableTypeInference) - JS::ContextOptionsRef(cx).toggleTypeInference(); - if (enableIon) - JS::ContextOptionsRef(cx).toggleIon(); - if (enableBaseline) - JS::ContextOptionsRef(cx).toggleBaseline(); - if (enableAsmJS) - JS::ContextOptionsRef(cx).toggleAsmJS(); return cx; } @@ -5712,11 +5701,11 @@ BindScriptArgs(JSContext *cx, JSObject *obj_, OptionParser *op) // so we're guarding the function definition with an #ifdef, too, to avoid // build warning for unused function in non-ion-enabled builds: #if defined(JS_ION) -static int +static bool OptionFailure(const char *option, const char *str) { fprintf(stderr, "Unrecognized option for %s: %s\n", option, str); - return EXIT_FAILURE; + return false; } #endif /* JS_ION */ @@ -5725,14 +5714,6 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) { RootedObject obj(cx, obj_); - if (op->getBoolOption('c')) - compileOnly = true; - - if (op->getBoolOption('w')) - reportWarnings = true; - else if (op->getBoolOption('W')) - reportWarnings = false; - if (op->getBoolOption('s')) JS::ContextOptionsRef(cx).toggleExtraWarnings(); @@ -5741,163 +5722,6 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) JS_SetDebugMode(cx, true); } - jsCacheDir = op->getStringOption("js-cache"); - if (jsCacheDir) { - if (op->getBoolOption("js-cache-per-process")) - jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, (unsigned)getpid()); - jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir); - } - - if (op->getBoolOption('b')) - printTiming = true; - - if (op->getBoolOption('D')) { - cx->runtime()->profilingScripts = true; - enableDisassemblyDumps = true; - } - -#ifdef JS_THREADSAFE - int32_t threadCount = op->getIntOption("thread-count"); - if (threadCount >= 0) - SetFakeCPUCount(threadCount); -#endif /* JS_THREADSAFE */ - -#if defined(JS_ION) - if (op->getBoolOption("no-ion")) { - enableIon = false; - JS::ContextOptionsRef(cx).toggleIon(); - } - if (op->getBoolOption("no-asmjs")) { - enableAsmJS = false; - JS::ContextOptionsRef(cx).toggleAsmJS(); - } - - if (op->getBoolOption("no-baseline")) { - enableBaseline = false; - JS::ContextOptionsRef(cx).toggleBaseline(); - } - - if (const char *str = op->getStringOption("ion-gvn")) { - if (strcmp(str, "off") == 0) { - jit::js_JitOptions.disableGvn = true; - } else if (strcmp(str, "pessimistic") == 0) { - jit::js_JitOptions.forceGvnKind = true; - jit::js_JitOptions.forcedGvnKind = jit::GVN_Pessimistic; - } else if (strcmp(str, "optimistic") == 0) { - jit::js_JitOptions.forceGvnKind = true; - jit::js_JitOptions.forcedGvnKind = jit::GVN_Optimistic; - } else { - return OptionFailure("ion-gvn", str); - } - } - - if (const char *str = op->getStringOption("ion-licm")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableLicm = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableLicm = true; - else - return OptionFailure("ion-licm", str); - } - - if (const char *str = op->getStringOption("ion-edgecase-analysis")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableEdgeCaseAnalysis = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableEdgeCaseAnalysis = true; - else - return OptionFailure("ion-edgecase-analysis", str); - } - - if (const char *str = op->getStringOption("ion-range-analysis")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableRangeAnalysis = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableRangeAnalysis = true; - else - return OptionFailure("ion-range-analysis", str); - } - - if (op->getBoolOption("ion-check-range-analysis")) - jit::js_JitOptions.checkRangeAnalysis = true; - - if (const char *str = op->getStringOption("ion-inlining")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableInlining = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableInlining = true; - else - return OptionFailure("ion-inlining", str); - } - - if (const char *str = op->getStringOption("ion-osr")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.osr = true; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.osr = false; - else - return OptionFailure("ion-osr", str); - } - - if (const char *str = op->getStringOption("ion-limit-script-size")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.limitScriptSize = true; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.limitScriptSize = false; - else - return OptionFailure("ion-limit-script-size", str); - } - - int32_t useCount = op->getIntOption("ion-uses-before-compile"); - if (useCount >= 0) - jit::js_JitOptions.setUsesBeforeCompile(useCount); - - useCount = op->getIntOption("baseline-uses-before-compile"); - if (useCount >= 0) - jit::js_JitOptions.baselineUsesBeforeCompile = useCount; - - if (op->getBoolOption("baseline-eager")) - jit::js_JitOptions.baselineUsesBeforeCompile = 0; - - if (const char *str = op->getStringOption("ion-regalloc")) { - if (strcmp(str, "lsra") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_LSRA; - } else if (strcmp(str, "backtracking") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Backtracking; - } else if (strcmp(str, "stupid") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Stupid; - } else { - return OptionFailure("ion-regalloc", str); - } - } - - if (op->getBoolOption("ion-eager")) - jit::js_JitOptions.setEagerCompilation(); - - if (op->getBoolOption("ion-compile-try-catch")) - jit::js_JitOptions.compileTryCatch = true; - - bool parallelCompilation = true; - if (const char *str = op->getStringOption("ion-parallel-compile")) { - if (strcmp(str, "off") == 0) - parallelCompilation = false; - else if (strcmp(str, "on") != 0) - return OptionFailure("ion-parallel-compile", str); - } -#ifdef JS_THREADSAFE - cx->runtime()->setParallelIonCompilationEnabled(parallelCompilation); -#endif - -#endif /* JS_ION */ - -#ifdef DEBUG - if (op->getBoolOption("dump-entrained-variables")) - dumpEntrainedVariables = true; -#endif - /* |scriptArgs| gets bound on the global before any code is run. */ if (!BindScriptArgs(cx, obj, op)) return EXIT_FAILURE; @@ -5941,20 +5765,191 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) return gExitCode ? gExitCode : EXIT_SUCCESS; } +static bool +SetRuntimeOptions(JSRuntime *rt, const OptionParser &op) +{ +#if defined(JS_ION) + bool enableBaseline = !op.getBoolOption("no-baseline"); + bool enableIon = !op.getBoolOption("no-ion"); + bool enableTypeInference = !op.getBoolOption("no-ti"); + bool enableAsmJS = !op.getBoolOption("no-asmjs"); + + JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline) + .setIon(enableIon) + .setTypeInference(enableTypeInference) + .setAsmJS(enableAsmJS); + + if (const char *str = op.getStringOption("ion-gvn")) { + if (strcmp(str, "off") == 0) { + jit::js_JitOptions.disableGvn = true; + } else if (strcmp(str, "pessimistic") == 0) { + jit::js_JitOptions.forceGvnKind = true; + jit::js_JitOptions.forcedGvnKind = jit::GVN_Pessimistic; + } else if (strcmp(str, "optimistic") == 0) { + jit::js_JitOptions.forceGvnKind = true; + jit::js_JitOptions.forcedGvnKind = jit::GVN_Optimistic; + } else { + return OptionFailure("ion-gvn", str); + } + } + + if (const char *str = op.getStringOption("ion-licm")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableLicm = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableLicm = true; + else + return OptionFailure("ion-licm", str); + } + + if (const char *str = op.getStringOption("ion-edgecase-analysis")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableEdgeCaseAnalysis = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableEdgeCaseAnalysis = true; + else + return OptionFailure("ion-edgecase-analysis", str); + } + + if (const char *str = op.getStringOption("ion-range-analysis")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableRangeAnalysis = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableRangeAnalysis = true; + else + return OptionFailure("ion-range-analysis", str); + } + + if (op.getBoolOption("ion-check-range-analysis")) + jit::js_JitOptions.checkRangeAnalysis = true; + + if (const char *str = op.getStringOption("ion-inlining")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableInlining = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableInlining = true; + else + return OptionFailure("ion-inlining", str); + } + + if (const char *str = op.getStringOption("ion-osr")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.osr = true; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.osr = false; + else + return OptionFailure("ion-osr", str); + } + + if (const char *str = op.getStringOption("ion-limit-script-size")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.limitScriptSize = true; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.limitScriptSize = false; + else + return OptionFailure("ion-limit-script-size", str); + } + + int32_t useCount = op.getIntOption("ion-uses-before-compile"); + if (useCount >= 0) + jit::js_JitOptions.setUsesBeforeCompile(useCount); + + useCount = op.getIntOption("baseline-uses-before-compile"); + if (useCount >= 0) + jit::js_JitOptions.baselineUsesBeforeCompile = useCount; + + if (op.getBoolOption("baseline-eager")) + jit::js_JitOptions.baselineUsesBeforeCompile = 0; + + if (const char *str = op.getStringOption("ion-regalloc")) { + if (strcmp(str, "lsra") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_LSRA; + } else if (strcmp(str, "backtracking") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Backtracking; + } else if (strcmp(str, "stupid") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Stupid; + } else { + return OptionFailure("ion-regalloc", str); + } + } + + if (op.getBoolOption("ion-eager")) + jit::js_JitOptions.setEagerCompilation(); + + if (op.getBoolOption("ion-compile-try-catch")) + jit::js_JitOptions.compileTryCatch = true; + + bool parallelCompilation = true; + if (const char *str = op.getStringOption("ion-parallel-compile")) { + if (strcmp(str, "off") == 0) + parallelCompilation = false; + else if (strcmp(str, "on") != 0) + return OptionFailure("ion-parallel-compile", str); + } +#ifdef JS_THREADSAFE + rt->setParallelIonCompilationEnabled(parallelCompilation); +#endif + +#if defined(JS_CODEGEN_X86) && defined(DEBUG) + if (op.getBoolOption("no-fpu")) + JSC::MacroAssembler::SetFloatingPointDisabled(); +#endif + +#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(DEBUG) + if (op.getBoolOption("no-sse3")) { + JSC::MacroAssembler::SetSSE3Disabled(); + PropagateFlagToNestedShells("--no-sse3"); + } + if (op.getBoolOption("no-sse4")) { + JSC::MacroAssembler::SetSSE4Disabled(); + PropagateFlagToNestedShells("--no-sse4"); + } +#endif + +#endif // JS_ION + +#ifdef JS_ARM_SIMULATOR + if (op.getBoolOption("arm-sim-icache-checks")) + jit::Simulator::ICacheCheckingEnabled = true; + + int32_t stopAt = op.getIntOption("arm-sim-stop-at"); + if (stopAt >= 0) + jit::Simulator::StopSimAt = stopAt; +#endif + + reportWarnings = op.getBoolOption('w'); + compileOnly = op.getBoolOption('c'); + printTiming = op.getBoolOption('b'); + rt->profilingScripts = enableDisassemblyDumps = op.getBoolOption('D'); + + jsCacheDir = op.getStringOption("js-cache"); + if (jsCacheDir) { + if (op.getBoolOption("js-cache-per-process")) + jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, (unsigned)getpid()); + jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir); + } + +#ifdef JS_THREADSAFE + int32_t threadCount = op.getIntOption("thread-count"); + if (threadCount >= 0) + SetFakeCPUCount(threadCount); +#endif /* JS_THREADSAFE */ + +#ifdef DEBUG + dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables"); +#endif + + return true; +} + static int Shell(JSContext *cx, OptionParser *op, char **envp) { JSAutoRequest ar(cx); - /* - * First check to see if type inference is enabled. These flags - * must be set on the compartment when it is constructed. - */ - if (op->getBoolOption("no-ti")) { - enableTypeInference = false; - JS::ContextOptionsRef(cx).toggleTypeInference(); - } - if (op->getBoolOption("fuzzing-safe")) fuzzingSafe = true; else @@ -6170,33 +6165,7 @@ main(int argc, char **argv, char **envp) * Process OOM options as early as possible so that we can observe as many * allocations as possible. */ - if (op.getBoolOption('O')) - OOM_printAllocationCount = true; - -#if defined(JS_CODEGEN_X86) && defined(JS_ION) - if (op.getBoolOption("no-fpu")) - JSC::MacroAssembler::SetFloatingPointDisabled(); -#endif - -#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(JS_ION) - if (op.getBoolOption("no-sse3")) { - JSC::MacroAssembler::SetSSE3Disabled(); - PropagateFlagToNestedShells("--no-sse3"); - } - if (op.getBoolOption("no-sse4")) { - JSC::MacroAssembler::SetSSE4Disabled(); - PropagateFlagToNestedShells("--no-sse4"); - } -#endif -#endif - -#ifdef JS_ARM_SIMULATOR - if (op.getBoolOption("arm-sim-icache-checks")) - jit::Simulator::ICacheCheckingEnabled = true; - - int32_t stopAt = op.getIntOption("arm-sim-stop-at"); - if (stopAt >= 0) - jit::Simulator::StopSimAt = stopAt; + OOM_printAllocationCount = op.getBoolOption('O'); #endif // Start the engine. @@ -6207,6 +6176,10 @@ main(int argc, char **argv, char **envp) rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS); if (!rt) return 1; + + if (!SetRuntimeOptions(rt, op)) + return 1; + gTimeoutFunc = NullValue(); if (!JS_AddNamedValueRootRT(rt, &gTimeoutFunc, "gTimeoutFunc")) return 1; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index db27e203e63..aba9c3b9cf5 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1683,6 +1683,7 @@ struct JSRuntime : public JS::shadow::Runtime, void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *runtime); private: + JS::RuntimeOptions options_; JSUseHelperThreads useHelperThreads_; @@ -1730,6 +1731,13 @@ struct JSRuntime : public JS::shadow::Runtime, return isWorkerRuntime_; } + const JS::RuntimeOptions &options() const { + return options_; + } + JS::RuntimeOptions &options() { + return options_; + } + #ifdef DEBUG public: js::AutoEnterPolicy *enteredPolicy; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index d4a0368860c..375ef2f0c46 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3245,26 +3245,41 @@ nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope, return NS_DispatchToMainThread(run); } -#define GENERATE_JSOPTION_GETTER_SETTER(_attr, _getter, _setter) \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ - { \ - *aValue = ContextOptionsRef(cx)._getter(); \ - return NS_OK; \ - } \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ - { \ - ContextOptionsRef(cx)._setter(aValue); \ - return NS_OK; \ +#define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ + { \ + *aValue = ContextOptionsRef(cx)._getter(); \ + return NS_OK; \ + } \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ + { \ + ContextOptionsRef(cx)._setter(aValue); \ + return NS_OK; \ } -GENERATE_JSOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings) -GENERATE_JSOPTION_GETTER_SETTER(Werror, werror, setWerror) -GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) -GENERATE_JSOPTION_GETTER_SETTER(Ion, ion, setIon) +#define GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(_attr, _getter, _setter) \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ + { \ + *aValue = RuntimeOptionsRef(cx)._getter(); \ + return NS_OK; \ + } \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ + { \ + RuntimeOptionsRef(cx)._setter(aValue); \ + return NS_OK; \ + } -#undef GENERATE_JSOPTION_GETTER_SETTER +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings) +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Werror, werror, setWerror) +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) +GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(Ion, ion, setIon) + +#undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER +#undef GENERATE_JSRUNTIMEOPTION_GETTER_SETTER NS_IMETHODIMP nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx) diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 92337ec48b2..5ff0fcbfa94 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -46,6 +46,7 @@ #include "nsAboutProtocolUtils.h" #include "GeckoProfiler.h" +#include "nsIXULRuntime.h" #include "nsJSPrincipals.h" #ifdef MOZ_CRASHREPORTER @@ -1498,6 +1499,45 @@ void XPCJSRuntime::SystemIsBeingShutDown() Enumerate(DetachedWrappedNativeProtoShutdownMarker, nullptr); } +#define JS_OPTIONS_DOT_STR "javascript.options." + +static void +ReloadPrefsCallback(const char *pref, void *data) +{ + XPCJSRuntime *runtime = reinterpret_cast(data); + JSRuntime *rt = runtime->Runtime(); + + bool safeMode = false; + nsCOMPtr xr = do_GetService("@mozilla.org/xre/runtime;1"); + if (xr) { + xr->GetInSafeMode(&safeMode); + } + + bool useBaseline = Preferences::GetBool(JS_OPTIONS_DOT_STR "baselinejit") && !safeMode; + bool useTypeInference = Preferences::GetBool(JS_OPTIONS_DOT_STR "typeinference") && !safeMode; + bool useIon = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion") && !safeMode; + bool useAsmJS = Preferences::GetBool(JS_OPTIONS_DOT_STR "asmjs") && !safeMode; + + bool parallelParsing = Preferences::GetBool(JS_OPTIONS_DOT_STR "parallel_parsing"); + bool parallelIonCompilation = Preferences::GetBool(JS_OPTIONS_DOT_STR + "ion.parallel_compilation"); + bool useBaselineEager = Preferences::GetBool(JS_OPTIONS_DOT_STR + "baselinejit.unsafe_eager_compilation"); + bool useIonEager = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation"); + + JS::RuntimeOptionsRef(rt).setBaseline(useBaseline) + .setTypeInference(useTypeInference) + .setIon(useIon) + . setAsmJS(useAsmJS); + + JS_SetParallelParsingEnabled(rt, parallelParsing); + JS_SetParallelIonCompilationEnabled(rt, parallelIonCompilation); + JS_SetGlobalJitCompilerOption(rt, JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER, + useBaselineEager ? 0 : -1); + JS_SetGlobalJitCompilerOption(rt, JSJITCOMPILER_ION_USECOUNT_TRIGGER, + useIonEager ? 0 : -1); +} + XPCJSRuntime::~XPCJSRuntime() { // This destructor runs before ~CycleCollectedJSRuntime, which does the @@ -1583,6 +1623,8 @@ XPCJSRuntime::~XPCJSRuntime() MOZ_ASSERT(mScratchStrings[i].empty(), "Short lived string still in use"); } #endif + + Preferences::UnregisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this); } static void @@ -3161,6 +3203,10 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) if (!JS_GetGlobalDebugHooks(runtime)->debuggerHandler) xpc_InstallJSDebuggerKeywordHandler(runtime); #endif + + // Watch for the JS boolean options. + ReloadPrefsCallback(nullptr, this); + Preferences::RegisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this); } // static diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 8cb8c842561..95fd1163f1c 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -1039,11 +1039,11 @@ ProcessArgsForCompartment(JSContext *cx, char **argv, int argc) ContextOptionsRef(cx).toggleExtraWarnings(); break; case 'I': - ContextOptionsRef(cx).toggleIon() + RuntimeOptionsRef(cx).toggleIon() .toggleAsmJS(); break; case 'n': - ContextOptionsRef(cx).toggleTypeInference(); + RuntimeOptionsRef(cx).toggleTypeInference(); break; } } @@ -1487,9 +1487,6 @@ XRE_XPCShellMain(int argc, char **argv, char **envp) return 1; } - // Ion not enabled yet here because of bug 931861. - JS::ContextOptionsRef(cx).setBaseline(true); - argc--; argv++; ProcessArgsForCompartment(cx, argv, argc); diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index c672cbabc32..eb8d4b8a0c1 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -361,56 +361,12 @@ TraceXPCGlobal(JSTracer *trc, JSObject *obj) mozilla::dom::TraceProtoAndIfaceCache(trc, obj); } -#ifdef DEBUG -#include "mozilla/Preferences.h" -#include "nsIXULRuntime.h" -static void -CheckTypeInference(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal) -{ - // Check that the global class isn't whitelisted. - if (strcmp(clasp->name, "Sandbox") || - strcmp(clasp->name, "nsXBLPrototypeScript compilation scope") || - strcmp(clasp->name, "nsXULPrototypeScript compilation scope")) - return; - - // Check that the pref is on. - if (!mozilla::Preferences::GetBool("javascript.options.typeinference")) - return; - - // Check that we're not chrome. - bool isSystem; - nsIScriptSecurityManager* ssm; - ssm = XPCWrapper::GetSecurityManager(); - if (NS_FAILED(ssm->IsSystemPrincipal(principal, &isSystem)) || !isSystem) - return; - - // Check that safe mode isn't on. - bool safeMode; - nsCOMPtr xr = do_GetService("@mozilla.org/xre/runtime;1"); - if (!xr) { - NS_WARNING("Couldn't get XUL runtime!"); - return; - } - if (NS_FAILED(xr->GetInSafeMode(&safeMode)) || safeMode) - return; - - // Finally, do the damn assert. - MOZ_ASSERT(ContextOptionsRef(cx).typeInference()); -} -#else -#define CheckTypeInference(cx, clasp, principal) {} -#endif - namespace xpc { JSObject* CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, JS::CompartmentOptions& aOptions) { - // Make sure that Type Inference is enabled for everything non-chrome. - // Sandboxes and compilation scopes are exceptions. See bug 744034. - CheckTypeInference(cx, clasp, principal); - MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); MOZ_ASSERT(principal); @@ -420,6 +376,7 @@ CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, if (!global) return nullptr; JSAutoCompartment ac(cx, global); + // The constructor automatically attaches the scope to the compartment private // of |global|. (void) new XPCWrappedNativeScope(cx, global); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 41b4aba0c90..289cb1e7e99 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -740,15 +740,12 @@ pref("javascript.options.strict", false); #ifdef DEBUG pref("javascript.options.strict.debug", true); #endif -pref("javascript.options.baselinejit.content", true); -pref("javascript.options.baselinejit.chrome", true); -pref("javascript.options.ion.content", true); -pref("javascript.options.ion.chrome", true); +pref("javascript.options.baselinejit", true); +pref("javascript.options.ion", true); pref("javascript.options.asmjs", true); pref("javascript.options.parallel_parsing", true); pref("javascript.options.ion.parallel_compilation", true); -pref("javascript.options.typeinference.content", true); -pref("javascript.options.typeinference.chrome", true); +pref("javascript.options.typeinference", true); // This preference limits the memory usage of javascript. // If you want to change these values for your device, // please find Bug 417052 comment 17 and Bug 456721