Bug 939562 part 3 - Move JIT flags from ContextOptions to RuntimeOptions. r=bent,bholley,luke
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 26 Feb 2014 10:25:36 +0100
changeset 189727 45ac7b7d7466a02176f9fa6fcaa25948a453b92a
parent 189726 03a1df22a53b94ee5165c607587237abb34cd99b
child 189728 81c5d568d949d384507a39967672e477d82dad49
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, bholley, luke
bugs939562
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 939562 part 3 - Move JIT flags from ContextOptions to RuntimeOptions. r=bent,bholley,luke
dom/base/nsJSEnvironment.cpp
dom/workers/RuntimeService.cpp
dom/workers/RuntimeService.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/Workers.h
js/jsd/jsd_xpc.cpp
js/src/builtin/TestingFunctions.cpp
js/src/jit/AsmJS.cpp
js/src/jit/BaselineJIT.h
js/src/jit/Ion.h
js/src/jsapi-tests/testFuncCallback.cpp
js/src/jsapi-tests/testProfileStrings.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscompartment.h
js/src/jsinfer.cpp
js/src/shell/js.cpp
js/src/vm/Runtime.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/nsXPConnect.cpp
modules/libpref/src/init/all.js
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -716,29 +716,18 @@ static const char js_strict_option_str[]
 #ifdef DEBUG
 static const char js_strict_debug_option_str[] = JS_OPTIONS_DOT_STR "strict.debug";
 #endif
 static const char js_werror_option_str[] = JS_OPTIONS_DOT_STR "werror";
 #ifdef JS_GC_ZEAL
 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)
 {
   nsJSContext *context = reinterpret_cast<nsJSContext *>(data);
   JSContext *cx = context->mContext;
 
   sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
@@ -751,69 +740,27 @@ nsJSContext::JSOptionChangedCallback(con
   // So ask for the member directly instead.
   nsIScriptGlobalObject *global = context->GetGlobalObjectRef();
 
   // XXX should we check for sysprin instead of a chrome window, to make
   // XXX components be covered by the chrome pref instead of the content one?
   nsCOMPtr<nsIDOMWindow> contentWindow(do_QueryInterface(global));
   nsCOMPtr<nsIDOMChromeWindow> 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<nsIXULRuntime> 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
   if (Preferences::GetBool(js_strict_debug_option_str) &&
       (chromeWindow || !contentWindow)) {
     JS::ContextOptionsRef(cx).setExtraWarnings(true);
   }
 #endif
 
   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);
   if (zeal >= 0)
     ::JS_SetGCZeal(context->mContext, (uint8_t)zeal, frequency);
 #endif
 }
 
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -143,17 +143,17 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 
 #endif
 
 #define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
 
 namespace {
 
 const uint32_t kNoIndex = uint32_t(-1);
 
-const JS::ContextOptions kRequiredJSContextOptions =
+const JS::ContextOptions kRequiredContextOptions =
   JS::ContextOptions().setDontReportUncaught(true)
                       .setNoScriptRval(true);
 
 uint32_t gMaxWorkersPerDomain = MAX_WORKERS_PER_DOMAIN;
 
 // Does not hold an owning reference.
 RuntimeService* gRuntimeService = nullptr;
 
@@ -295,17 +295,17 @@ GenerateSharedWorkerKey(const nsACString
     }
   }
 
   aKey.Append('|');
   aKey.Append(aScriptSpec);
 }
 
 void
-LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
+LoadRuntimeAndContextOptions(const char* aPrefName, void* /* aClosure */)
 {
   AssertIsOnMainThread();
 
   RuntimeService* rts = RuntimeService::GetService();
   if (!rts && !gRuntimeServiceDuringInit) {
     // May be shutting down, just bail.
     return;
   }
@@ -325,61 +325,57 @@ LoadJSContextOptions(const char* aPrefNa
 
 #ifdef JS_GC_ZEAL
   if (prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL) ||
       prefName.EqualsLiteral(PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL)) {
     return;
   }
 #endif
 
+  // Runtime options.
+  JS::RuntimeOptions runtimeOptions;
+  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs"))) {
+    runtimeOptions.setAsmJS(true);
+  }
+  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("typeinference"))) {
+    runtimeOptions.setTypeInference(true);
+  }
+  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit"))) {
+    runtimeOptions.setBaseline(true);
+  }
+  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion"))) {
+    runtimeOptions.setIon(true);
+  }
+
   // Common options.
-  JS::ContextOptions commonOptions = kRequiredJSContextOptions;
+  JS::ContextOptions commonContextOptions = kRequiredContextOptions;
   if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict"))) {
-    commonOptions.setExtraWarnings(true);
+    commonContextOptions.setExtraWarnings(true);
   }
   if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror"))) {
-    commonOptions.setWerror(true);
-  }
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs"))) {
-    commonOptions.setAsmJS(true);
+    commonContextOptions.setWerror(true);
   }
 
   // Content options.
-  JS::ContextOptions contentOptions = commonOptions;
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit.content"))) {
-    contentOptions.setBaseline(true);
-  }
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion.content"))) {
-    contentOptions.setIon(true);
-  }
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("typeinference.content"))) {
-    contentOptions.setTypeInference(true);
-  }
+  JS::ContextOptions contentContextOptions = commonContextOptions;
 
   // Chrome options.
-  JS::ContextOptions chromeOptions = commonOptions;
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit.chrome"))) {
-    chromeOptions.setBaseline(true);
-  }
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion.chrome"))) {
-    chromeOptions.setIon(true);
-  }
-  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("typeinference.chrome"))) {
-    chromeOptions.setTypeInference(true);
-  }
+  JS::ContextOptions chromeContextOptions = commonContextOptions;
 #ifdef DEBUG
   if (GetWorkerPref<bool>(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();
   }
 }
 
 #ifdef JS_GC_ZEAL
 void
 LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */)
 {
   AssertIsOnMainThread();
@@ -767,16 +763,18 @@ JSContext*
 CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
 {
   aWorkerPrivate->AssertIsOnWorkerThread();
   NS_ASSERTION(!aWorkerPrivate->GetJSContext(), "Already has a context!");
 
   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.
   for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
     const JSSettings::JSGCSetting& setting = gcSettings[index];
     if (setting.IsSet()) {
       NS_ASSERTION(setting.value, "Can't handle 0 values!");
       JS_SetGCParameter(aRuntime, setting.key, setting.value);
@@ -1610,20 +1608,21 @@ nsresult
 RuntimeService::Init()
 {
   AssertIsOnMainThread();
 
   nsLayoutStatics::AddRef();
 
   // 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;
     sDefaultJSSettings.gcZeal = 0;
 #endif
     SetDefaultJSGCSettings(JSGC_MAX_BYTES, WORKER_DEFAULT_RUNTIME_HEAPSIZE);
     SetDefaultJSGCSettings(JSGC_ALLOCATION_THRESHOLD,
                            WORKER_DEFAULT_ALLOCATION_THRESHOLD);
@@ -1688,23 +1687,23 @@ RuntimeService::Init()
                                         nullptr)) ||
 #endif
 #if DUMP_CONTROLLED_BY_PREF
       NS_FAILED(Preferences::RegisterCallbackAndCall(
                                   WorkerPrefChanged,
                                   PREF_DOM_WINDOW_DUMP_ENABLED,
                                   reinterpret_cast<void *>(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,
                                                  nullptr))) {
     NS_WARNING("Failed to register pref callbacks!");
   }
 
   NS_ASSERTION(gRuntimeServiceDuringInit == this, "Should be 'this'!");
@@ -1841,20 +1840,20 @@ RuntimeService::Cleanup()
   }
 
   NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!");
 
   if (mObserved) {
     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
         NS_FAILED(Preferences::UnregisterCallback(
                                   WorkerPrefChanged,
                                   PREF_DOM_WINDOW_DUMP_ENABLED,
                                   reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
 #endif
@@ -2226,19 +2225,20 @@ RuntimeService::NoteIdleThread(WorkerThr
   // Schedule timer.
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mIdleThreadTimer->InitWithFuncCallback(
                                                  ShutdownIdleThreads, nullptr,
                                                  IDLE_THREAD_TIMEOUT_SEC * 1000,
                                                  nsITimer::TYPE_ONE_SHOT)));
 }
 
 void
-RuntimeService::UpdateAllWorkerJSContextOptions()
+RuntimeService::UpdateAllWorkerRuntimeAndContextOptions()
 {
-  BROADCAST_ALL_WORKERS(UpdateJSContextOptions,
+  BROADCAST_ALL_WORKERS(UpdateRuntimeAndContextOptions,
+                        sDefaultJSSettings.runtimeOptions,
                         sDefaultJSSettings.content.contextOptions,
                         sDefaultJSSettings.chrome.contextOptions);
 }
 
 void
 RuntimeService::UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue)
 {
   BROADCAST_ALL_WORKERS(UpdatePreference, aPref, aValue);
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -169,26 +169,29 @@ public:
   static void
   GetDefaultPreferences(bool aPreferences[WORKERPREF_COUNT])
   {
     AssertIsOnMainThread();
     memcpy(aPreferences, sDefaultPreferences, WORKERPREF_COUNT * sizeof(bool));
   }
 
   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);
 
   static void
   SetDefaultJSGCSettings(JSGCParamKey aKey, uint32_t aValue)
   {
     AssertIsOnMainThread();
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1510,35 +1510,42 @@ private:
       mTimer->Cancel();
       mTimer = nullptr;
     }
 
     return true;
   }
 };
 
-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;
   }
 };
 
 class UpdatePreferenceRunnable MOZ_FINAL : public WorkerControlRunnable
 {
   WorkerPreference mPref;
   bool mValue;
@@ -2838,32 +2845,36 @@ WorkerPrivateParent<Derived>::GetInnerWi
   AssertIsOnMainThread();
   NS_ASSERTION(!mLoadInfo.mWindow || mLoadInfo.mWindow->IsInnerWindow(),
                "Outer window?");
   return mLoadInfo.mWindow ? mLoadInfo.mWindow->WindowID() : 0;
 }
 
 template <class Derived>
 void
-WorkerPrivateParent<Derived>::UpdateJSContextOptions(
-                                      JSContext* aCx,
-                                      const JS::ContextOptions& aContentOptions,
-                                      const JS::ContextOptions& aChromeOptions)
+WorkerPrivateParent<Derived>::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;
-  }
-
-  nsRefPtr<UpdateJSContextOptionsRunnable> runnable =
-    new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aContentOptions,
-                                       aChromeOptions);
+    mJSSettings.runtimeOptions = aRuntimeOptions;
+    mJSSettings.content.contextOptions = aContentCxOptions;
+    mJSSettings.chrome.contextOptions = aChromeCxOptions;
+  }
+
+  nsRefPtr<UpdateRuntimeAndContextOptionsRunnable> runnable =
+    new UpdateRuntimeAndContextOptionsRunnable(ParentAsWorkerPrivate(),
+                                               aRuntimeOptions,
+                                               aContentCxOptions,
+                                               aChromeCxOptions);
   if (!runnable->Dispatch(aCx)) {
     NS_WARNING("Failed to update worker context options!");
     JS_ClearPendingException(aCx);
   }
 }
 
 template <class Derived>
 void
@@ -5498,27 +5509,31 @@ WorkerPrivate::RescheduleTimeoutTimer(JS
     JS_ReportError(aCx, "Failed to start timer!");
     return false;
   }
 
   return true;
 }
 
 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);
   }
 }
 
 void
 WorkerPrivate::UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue)
 {
   AssertIsOnWorkerThread();
   MOZ_ASSERT(aPref >= 0 && aPref < WORKERPREF_COUNT);
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -384,18 +384,20 @@ public:
                                uint64_t aMessagePortSerial,
                                JSAutoStructuredCloneBuffer&& aBuffer,
                                nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
 
   uint64_t
   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);
 
   void
   UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
                                 uint32_t value);
 
@@ -901,18 +903,21 @@ public:
   void
   CloseHandlerFinished()
   {
     AssertIsOnWorkerThread();
     mCloseHandlerFinished = true;
   }
 
   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);
 
   void
   UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
 
   enum WorkerRanOrNot {
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -102,16 +102,17 @@ struct JSSettings
     JSContentChromeSettings()
     : contextOptions(), compartmentOptions(), maxScriptRuntime(0)
     { }
   };
 
   JSContentChromeSettings chrome;
   JSContentChromeSettings content;
   JSGCSettingsArray gcSettings;
+  JS::RuntimeOptions runtimeOptions;
 
 #ifdef JS_GC_ZEAL
   uint8_t gcZeal;
   uint32_t gcZealFrequency;
 #endif
 
   JSSettings()
 #ifdef JS_GC_ZEAL
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -1651,39 +1651,31 @@ jsdContext::GetJSContext(JSContext **_rv
 
 #define JSOPTION_EXTRA_WARNINGS                 JS_BIT(0)
 #define JSOPTION_WERROR                         JS_BIT(1)
 #define JSOPTION_VAROBJFIX                      JS_BIT(2)
 #define JSOPTION_PRIVATE_IS_NSISUPPORTS         JS_BIT(3)
 #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
 jsdContext::GetOptions(uint32_t *_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     *_rval = (JS::ContextOptionsRef(mJSCx).extraWarnings() ? JSOPTION_EXTRA_WARNINGS : 0)
            | (JS::ContextOptionsRef(mJSCx).werror() ? JSOPTION_WERROR : 0)
            | (JS::ContextOptionsRef(mJSCx).varObjFix() ? JSOPTION_VAROBJFIX : 0)
            | (JS::ContextOptionsRef(mJSCx).privateIsNSISupports() ? JSOPTION_PRIVATE_IS_NSISUPPORTS : 0)
            | (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;
 }
 
 NS_IMETHODIMP
 jsdContext::SetOptions(uint32_t options)
 {
     ASSERT_VALID_EPHEMERAL;
 
@@ -1694,21 +1686,17 @@ jsdContext::SetOptions(uint32_t options)
         return NS_ERROR_ILLEGAL_VALUE;
 
     JS::ContextOptionsRef(mJSCx).setExtraWarnings(options & JSOPTION_EXTRA_WARNINGS)
                                 .setWerror(options & JSOPTION_WERROR)
                                 .setVarObjFix(options & JSOPTION_VAROBJFIX)
                                 .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;
 }
 
 NS_IMETHODIMP
 jsdContext::GetPrivateData(nsISupports **_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     if (JS::ContextOptionsRef(mJSCx).privateIsNSISupports()) 
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1155,35 +1155,35 @@ SetJitCompilerOption(JSContext *cx, unsi
         ReportUsageError(cx, callee, "First argument does not name a valid option (see jsapi.h).");
         return false;
     }
 
     int32_t number = args[1].toInt32();
     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;
 }
 
 static bool
 GetJitCompilerOptions(JSContext *cx, unsigned argc, jsval *vp)
 {
     RootedObject info(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
     if (!info)
         return false;
 
     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;
     JIT_COMPILER_OPTIONS(JIT_COMPILER_MATCH);
 #undef JIT_COMPILER_MATCH
 
     *vp = ObjectValue(*info);
 
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -7023,13 +7023,13 @@ js::IsAsmJSCompilationAvailable(JSContex
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // See EstablishPreconditions.
     bool available = cx->jitSupportsFloatingPoint() &&
                      cx->signalHandlersInstalled() &&
                      cx->gcSystemPageSize() == AsmJSPageSize &&
                      !cx->compartment()->debugMode() &&
-                     cx->compartment()->options().asmJS(cx);
+                     cx->runtime()->options().asmJS();
 
     args.rval().set(BooleanValue(available));
     return true;
 }
--- a/js/src/jit/BaselineJIT.h
+++ b/js/src/jit/BaselineJIT.h
@@ -307,17 +307,17 @@ struct BaselineScript
         JS_ASSERT(bytecodeTypeMapOffset_);
         return reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(this) + bytecodeTypeMapOffset_);
     }
 };
 
 inline bool
 IsBaselineEnabled(JSContext *cx)
 {
-    return cx->compartment()->options().baseline(cx);
+    return cx->runtime()->options().baseline();
 }
 
 MethodStatus
 CanEnterBaselineMethod(JSContext *cx, RunState &state);
 
 MethodStatus
 CanEnterBaselineAtBranch(JSContext *cx, StackFrame *fp, bool newType);
 
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -154,18 +154,18 @@ CodeGenerator *CompileBackEnd(MIRGenerat
 
 void AttachFinishedCompilations(JSContext *cx);
 void FinishOffThreadBuilder(IonBuilder *builder);
 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();
 }
 
 inline bool
 IsIonInlinablePC(jsbytecode *pc) {
     // CALL, FUNCALL, FUNAPPLY, EVAL, NEW (Normal Callsites)
     // GETPROP, CALLPROP, and LENGTH. (Inlined Getters)
     // SETPROP, SETNAME, SETGNAME (Inlined Setters)
--- a/js/src/jsapi-tests/testFuncCallback.cpp
+++ b/js/src/jsapi-tests/testFuncCallback.cpp
@@ -128,14 +128,14 @@ BEGIN_TEST(testFuncCallback_bug507012)
 // Make sure that the method jit is enabled.
 // We'll probably want to test in all modes.
 virtual
 JSContext *createContext()
 {
     JSContext *cx = JSAPITest::createContext();
     if (!cx)
         return nullptr;
-    JS::ContextOptionsRef(cx).setBaseline(true)
+    JS::RuntimeOptionsRef(cx).setBaseline(true)
                              .setIon(true);
     return cx;
 }
 
 END_TEST(testFuncCallback_bug507012)
--- a/js/src/jsapi-tests/testProfileStrings.cpp
+++ b/js/src/jsapi-tests/testProfileStrings.cpp
@@ -140,17 +140,17 @@ BEGIN_TEST(testProfileStrings_isCalledWi
     }
     return true;
 }
 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(); }");
     EXEC("function f() { g(); }");
     EXEC("function e() { f(); }");
     EXEC("function d() { e(); }");
     EXEC("function c() { d(); }");
     EXEC("function b() { c(); }");
@@ -192,17 +192,17 @@ BEGIN_TEST(testProfileStrings_isCalledWi
     }
     return true;
 }
 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'; }");
 
     reset(cx);
     JS::ContextOptionsRef(cx).setDontReportUncaught(true);
     {
         JS::RootedValue rval(cx);
@@ -217,17 +217,17 @@ BEGIN_TEST(testProfileStrings_isCalledWh
     }
     return true;
 }
 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(); }");
     EXEC("function a() { var p = new Prof(); p.enable(); b(p); }");
     reset(cx);
     js::EnableRuntimeProfilingStack(cx->runtime(), false);
     {
         /* enable it in the middle of JS and make sure things check out */
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -876,16 +876,28 @@ JS_StringToVersion(const char *string)
     int i;
 
     for (i = 0; v2smap[i].string; i++)
         if (strcmp(v2smap[i].string, string) == 0)
             return v2smap[i].version;
     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)
 {
     return cx->options();
 }
 
 JS_PUBLIC_API(const char *)
 JS_GetImplementationVersion(void)
@@ -2448,46 +2460,16 @@ class AutoHoldZone
   private:
     bool *holdp;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 } /* 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
 {
     return cloneSingletonsOverride_.get(cx->options().cloneSingletons());
 }
 
 JS::CompartmentOptions &
 JS::CompartmentOptions::setZone(ZoneSpecifier spec)
 {
@@ -4457,17 +4439,17 @@ JS::CompileOptions::CompileOptions(JSCon
 {
     this->version = (version != JSVERSION_UNKNOWN) ? version : cx->findVersion();
 
     compileAndGo = false;
     noScriptRval = cx->options().noScriptRval();
     strictOption = cx->options().strictMode();
     extraWarningsOption = cx->options().extraWarnings();
     werrorOption = cx->options().werror();
-    asmJSOption = cx->options().asmJS();
+    asmJSOption = cx->runtime()->options().asmJS();
 }
 
 bool
 JS::CompileOptions::wrap(JSContext *cx, JSCompartment *compartment)
 {
     if (!compartment->wrap(cx, &elementRoot))
         return false;
     if (elementAttributeNameRoot) {
@@ -5955,33 +5937,33 @@ JS_SetGCZeal(JSContext *cx, uint8_t zeal
 JS_PUBLIC_API(void)
 JS_ScheduleGC(JSContext *cx, uint32_t count)
 {
     cx->runtime()->gcNextScheduled = 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
 
     switch (opt) {
       case JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER:
         if (value == uint32_t(-1)) {
             jit::JitOptions defaultValues;
             value = defaultValues.baselineUsesBeforeCompile;
@@ -5994,51 +5976,51 @@ JS_SetGlobalJitCompilerOption(JSContext 
             break;
         }
         jit::js_JitOptions.setUsesBeforeCompile(value);
         if (value == 0)
             jit::js_JitOptions.setEagerCompilation();
         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;
       default:
         break;
     }
 #endif
 }
 
 JS_PUBLIC_API(int)
-JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt)
+JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt)
 {
 #ifdef JS_ION
     switch (opt) {
       case JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER:
         return jit::js_JitOptions.baselineUsesBeforeCompile;
       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;
     }
 #endif
     return 0;
 }
 
 /************************************************************************/
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1434,31 +1434,90 @@ JS_SetVersionForCompartment(JSCompartmen
 extern JS_PUBLIC_API(const char *)
 JS_VersionToString(JSVersion version);
 
 extern JS_PUBLIC_API(JSVersion)
 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()
       : extraWarnings_(false),
         werror_(false),
         varObjFix_(false),
         privateIsNSISupports_(false),
         dontReportUncaught_(false),
         noDefaultCompartmentObject_(false),
         noScriptRval_(false),
         strictMode_(false),
-        baseline_(false),
-        typeInference_(false),
-        ion_(false),
-        asmJS_(false),
         cloneSingletons_(false)
     {
     }
 
     bool extraWarnings() const { return extraWarnings_; }
     ContextOptions &setExtraWarnings(bool flag) {
         extraWarnings_ = flag;
         return *this;
@@ -1533,56 +1592,16 @@ class JS_PUBLIC_API(ContextOptions) {
         strictMode_ = flag;
         return *this;
     }
     ContextOptions &toggleStrictMode() {
         strictMode_ = !strictMode_;
         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;
         return *this;
     }
     ContextOptions &toggleCloneSingletons() {
         cloneSingletons_ = !cloneSingletons_;
         return *this;
@@ -1592,20 +1611,16 @@ class JS_PUBLIC_API(ContextOptions) {
     bool extraWarnings_ : 1;
     bool werror_ : 1;
     bool varObjFix_ : 1;
     bool privateIsNSISupports_ : 1;
     bool dontReportUncaught_ : 1;
     bool noDefaultCompartmentObject_ : 1;
     bool noScriptRval_ : 1;
     bool strictMode_ : 1;
-    bool baseline_ : 1;
-    bool typeInference_ : 1;
-    bool ion_ : 1;
-    bool asmJS_ : 1;
     bool cloneSingletons_ : 1;
 };
 
 JS_PUBLIC_API(ContextOptions &)
 ContextOptionsRef(JSContext *cx);
 
 class JS_PUBLIC_API(AutoSaveContextOptions) {
   public:
@@ -2642,28 +2657,16 @@ class JS_PUBLIC_API(CompartmentOptions)
     // allowed if this flag is set.  The invisibleToDebugger flag must also be
     // set for such compartments.
     bool mergeable() const { return mergeable_; }
     CompartmentOptions &setMergeable(bool flag) {
         mergeable_ = flag;
         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_; }
 
     void *zonePointer() const {
         JS_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
         return zone_.pointer;
     }
     ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
@@ -2676,20 +2679,16 @@ class JS_PUBLIC_API(CompartmentOptions)
     bool getSingletonsAsTemplates() const {
         return singletonsAsTemplates_;
     };
 
   private:
     JSVersion version_;
     bool invisibleToDebugger_;
     bool mergeable_;
-    Override baselineOverride_;
-    Override typeInferenceOverride_;
-    Override ionOverride_;
-    Override asmJSOverride_;
     Override cloneSingletonsOverride_;
     union {
         ZoneSpecifier spec;
         void *pointer; // js::Zone* is not exposed in the API.
     } zone_;
 
     // To XDR singletons, we need to ensure that all singletons are all used as
     // templates, by making JSOP_OBJECT return a clone of the JSScript
@@ -4659,20 +4658,20 @@ JS_NewObjectForConstructor(JSContext *cx
 extern JS_PUBLIC_API(void)
 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
 
 extern JS_PUBLIC_API(void)
 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") \
   Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger")           \
   Register(ION_ENABLE, "ion.enable")                               \
   Register(BASELINE_ENABLE, "baseline.enable")
 
 typedef enum JSJitCompilerOption {
@@ -4681,19 +4680,19 @@ typedef enum JSJitCompilerOption {
 
     JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
 #undef JIT_COMPILER_DECLARE
 
     JSJITCOMPILER_NOT_AN_OPTION
 } 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.
  */
 extern JS_PUBLIC_API(bool)
 JS_IndexToId(JSContext *cx, uint32_t index, JS::MutableHandleId);
 
 /*
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -516,17 +516,17 @@ class js::AutoDebugModeInvalidation
     }
 };
 
 namespace js {
 
 inline bool
 ExclusiveContext::typeInferenceEnabled() const
 {
-    return compartment_->options().typeInference(this);
+    return zone()->types.inferenceEnabled;
 }
 
 inline js::Handle<js::GlobalObject*>
 ExclusiveContext::global() const
 {
     /*
      * It's safe to use |unsafeGet()| here because any compartment that is
      * on-stack will be marked automatically, so there's no need for a read
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1857,17 +1857,17 @@ TypeCompartment::TypeCompartment()
 {
     PodZero(this);
 }
 
 void
 TypeZone::init(JSContext *cx)
 {
     if (!cx ||
-        !cx->options().typeInference() ||
+        !cx->runtime()->options().typeInference() ||
         !cx->runtime()->jitSupportsFloatingPoint)
     {
         return;
     }
 
     inferenceEnabled = true;
 }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -113,21 +113,17 @@ static size_t gMaxStackSize = 128 * size
  * Limit the timeout to 30 minutes to prevent an overflow on platfoms
  * that represent the time internally in microseconds using 32-bit int.
  */
 static double MAX_TIMEOUT_INTERVAL = 1800.0;
 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;
 static const char *jsCacheAsmJSPath = nullptr;
 static bool jsCachingEnabled = true;
 mozilla::Atomic<bool> jsCacheOpened(false);
 
 static bool
@@ -650,31 +646,32 @@ ResolvePath(JSContext *cx, HandleString 
     return JS_NewStringCopyZ(cx, buffer);
 }
 
 static bool
 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)
             return false;
         args[i].setString(str);
 
         JSAutoByteString opt(cx, str);
         if (!opt)
             return false;
 
         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)
             JS::ContextOptionsRef(cx).toggleStrictMode();
         else {
             char* msg = JS_sprintf_append(nullptr,
                                           "unknown option name '%s'."
                                           " The valid names are strict,"
@@ -688,29 +685,29 @@ Options(JSContext *cx, unsigned argc, js
             JS_ReportError(cx, msg);
             free(msg);
             return false;
         }
     }
 
     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;
     }
     if (!names) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
 
@@ -5505,24 +5502,16 @@ NewContext(JSRuntime *rt)
     JSShellContextData *data = NewContextData();
     if (!data) {
         DestroyContext(cx, false);
         return nullptr;
     }
 
     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;
 }
 
 static void
 DestroyContext(JSContext *cx, bool withGC)
 {
     JSShellContextData *data = GetContextData(cx);
     JS_SetContextPrivate(cx, nullptr);
@@ -5614,202 +5603,37 @@ BindScriptArgs(JSContext *cx, JSObject *
 
     return true;
 }
 
 // This function is currently only called from "#if defined(JS_ION)" chunks,
 // 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 */
 
 static int
 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();
 
     if (op->getBoolOption('d')) {
         JS_SetRuntimeDebugMode(JS_GetRuntime(cx), true);
         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;
 
     MultiStringRange filePaths = op->getMultiStringOption('f');
     MultiStringRange codeChunks = op->getMultiStringOption('e');
 
     if (filePaths.empty() && codeChunks.empty() && !op->getStringArg("script")) {
@@ -5843,30 +5667,185 @@ ProcessArgs(JSContext *cx, JSObject *obj
     }
 
     if (op->getBoolOption('i'))
         Process(cx, obj, nullptr, true);
 
     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
+
+#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
         fuzzingSafe = (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0');
 
     RootedObject glob(cx);
     JS::CompartmentOptions options;
     options.setVersion(JSVERSION_LATEST);
@@ -6072,53 +6051,48 @@ main(int argc, char **argv, char **envp)
     if (op.getHelpOption())
         return EXIT_SUCCESS;
 
 #ifdef DEBUG
     /*
      * Process OOM options as early as possible so that we can observe as many
      * allocations as possible.
      */
-    if (op.getBoolOption('O'))
-        OOM_printAllocationCount = true;
+    OOM_printAllocationCount = op.getBoolOption('O');
 
 #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;
-#endif
+
+#endif // DEBUG
 
     // Start the engine.
     if (!JS_Init())
         return 1;
 
     /* Use the same parameters as the browser in xpcjsruntime.cpp. */
     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;
 
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
 #ifdef JSGC_GENERATIONAL
     Maybe<JS::AutoDisableGenerationalGC> noggc;
     if (op.getBoolOption("no-ggc"))
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1699,16 +1699,17 @@ struct JSRuntime : public JS::shadow::Ru
         TriggerCallbackAnyThreadForkJoin
     };
 
     void triggerOperationCallback(OperationCallbackTrigger trigger);
 
     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *runtime);
 
   private:
+    JS::RuntimeOptions options_;
 
     JSUseHelperThreads useHelperThreads_;
 
     // Settings for how helper threads can be used.
     bool parallelIonCompilationEnabled_;
     bool parallelParsingEnabled_;
 
     // True iff this is a DOM Worker runtime.
@@ -1746,16 +1747,23 @@ struct JSRuntime : public JS::shadow::Ru
 
     void setIsWorkerRuntime() {
         isWorkerRuntime_ = true;
     }
     bool isWorkerRuntime() const {
         return isWorkerRuntime_;
     }
 
+    const JS::RuntimeOptions &options() const {
+        return options_;
+    }
+    JS::RuntimeOptions &options() {
+        return options_;
+    }
+
 #ifdef DEBUG
   public:
     js::AutoEnterPolicy *enteredPolicy;
 #endif
 
     /* See comment for JS::SetLargeAllocationFailureCallback in jsapi.h. */
     JS::LargeAllocationFailureCallback largeAllocationFailureCallback;
     /* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3241,36 +3241,51 @@ nsXPCComponents_Utils::Dispatch(HandleVa
                                                    getter_AddRefs(run));
     NS_ENSURE_SUCCESS(rv, rv);
     MOZ_ASSERT(run);
 
     // Dispatch.
     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)
-
-#undef GENERATE_JSOPTION_GETTER_SETTER
+#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;                                                   \
+    }
+
+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)
 {
 #ifdef JS_GC_ZEAL
     JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
 #endif
     return NS_OK;
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -41,16 +41,17 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/Attributes.h"
 #include "AccessCheck.h"
 #include "nsGlobalWindow.h"
 #include "nsAboutProtocolUtils.h"
 
 #include "GeckoProfiler.h"
+#include "nsIXULRuntime.h"
 #include "nsJSPrincipals.h"
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 using namespace mozilla;
 using namespace xpc;
@@ -1498,16 +1499,55 @@ void XPCJSRuntime::SystemIsBeingShutDown
 {
     DOM_ClearInterfaces();
 
     if (mDetachedWrappedNativeProtoMap)
         mDetachedWrappedNativeProtoMap->
             Enumerate(DetachedWrappedNativeProtoShutdownMarker, nullptr);
 }
 
+#define JS_OPTIONS_DOT_STR "javascript.options."
+
+static void
+ReloadPrefsCallback(const char *pref, void *data)
+{
+    XPCJSRuntime *runtime = reinterpret_cast<XPCJSRuntime *>(data);
+    JSRuntime *rt = runtime->Runtime();
+
+    bool safeMode = false;
+    nsCOMPtr<nsIXULRuntime> 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
     // actual JS_DestroyRuntime() call. But destroying the runtime triggers
     // one final GC, which can call back into the runtime with various
     // callback if we aren't careful. Null out the relevant callbacks.
     js::SetActivityCallback(Runtime(), nullptr, nullptr);
     JS_SetFinalizeCallback(Runtime(), nullptr);
@@ -1583,16 +1623,18 @@ XPCJSRuntime::~XPCJSRuntime()
         stack->sampleRuntime(nullptr);
 #endif
 
 #ifdef DEBUG
     for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
         MOZ_ASSERT(mScratchStrings[i].empty(), "Short lived string still in use");
     }
 #endif
+
+    Preferences::UnregisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this);
 }
 
 static void
 GetCompartmentName(JSCompartment *c, nsCString &name, bool replaceSlashes)
 {
     if (js::IsAtomsCompartment(c)) {
         name.AssignLiteral("atoms");
     } else if (JSPrincipals *principals = JS_GetCompartmentPrincipals(c)) {
@@ -3119,16 +3161,20 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     RegisterJSMainRuntimeCompartmentsUserDistinguishedAmount(JSMainRuntimeCompartmentsUserDistinguishedAmount);
     mozilla::RegisterJSSizeOfTab(JSSizeOfTab);
 
     // Install a JavaScript 'debugger' keyword handler in debug builds only
 #ifdef DEBUG
     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
 XPCJSRuntime*
 XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect)
 {
     NS_PRECONDITION(aXPConnect,"bad param");
 
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -1031,21 +1031,21 @@ ProcessArgsForCompartment(JSContext *cx,
                 return;
             break;
         case 'S':
             ContextOptionsRef(cx).toggleWerror();
         case 's':
             ContextOptionsRef(cx).toggleExtraWarnings();
             break;
         case 'I':
-            ContextOptionsRef(cx).toggleIon()
+            RuntimeOptionsRef(cx).toggleIon()
                                  .toggleAsmJS();
             break;
         case 'n':
-            ContextOptionsRef(cx).toggleTypeInference();
+            RuntimeOptionsRef(cx).toggleTypeInference();
             break;
         }
     }
 }
 
 static int
 ProcessArgs(JSContext *cx, JS::Handle<JSObject*> obj, char **argv, int argc, XPCShellDirProvider* aDirProvider)
 {
@@ -1478,19 +1478,16 @@ XRE_XPCShellMain(int argc, char **argv, 
         JS_SetOperationCallback(rt, XPCShellOperationCallback);
 
         cx = JS_NewContext(rt, 8192);
         if (!cx) {
             printf("JS_NewContext failed!\n");
             return 1;
         }
 
-        // Ion not enabled yet here because of bug 931861.
-        JS::ContextOptionsRef(cx).setBaseline(true);
-
         argc--;
         argv++;
         ProcessArgsForCompartment(cx, argv, argc);
 
         nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
         if (!xpc) {
             printf("failed to get nsXPConnect service!\n");
             return 1;
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -349,75 +349,32 @@ TraceXPCGlobal(JSTracer *trc, JSObject *
         return;
     }
 #endif
 
     if (js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL)
         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<nsIXULRuntime> 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);
 
     RootedObject global(cx,
                         JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal),
                                            JS::DontFireOnNewGlobalHook, aOptions));
     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);
 
 #ifdef DEBUG
     // Verify that the right trace hook is called. Note that this doesn't
     // work right for wrapped globals, since the tracing situation there is
     // more complicated. Manual inspection shows that they do the right thing.
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -751,25 +751,22 @@ pref("dom.event.clipboardevents.enabled"
 
 pref("dom.webcomponents.enabled",           false);
 
 pref("javascript.enabled",                  true);
 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
 // Comment 32 and Bug 613551.
 pref("javascript.options.mem.high_water_mark", 128);
 pref("javascript.options.mem.max", -1);
 pref("javascript.options.mem.gc_per_compartment", true);
 pref("javascript.options.mem.gc_incremental", true);