Backed out changeset 802aa43ae8cc (bug 939562) for PGO mochitest regression on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 26 Feb 2014 16:02:15 +0100
changeset 171036 c3fc351a1c5512a93560f321572aaf66936a4a18
parent 171035 c90e26bbcdf58173fbef9118a9a7092c4a813d62
child 171037 9dd9e9cf9646b62b33b241257fd699527e4dd11c
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
bugs939562
milestone30.0a1
backs out802aa43ae8cc5948062a132efd3f9e798b949376
Backed out changeset 802aa43ae8cc (bug 939562) for PGO mochitest regression on a CLOSED TREE
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,18 +716,29 @@ 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);
@@ -740,27 +751,69 @@ 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 kRequiredContextOptions =
+const JS::ContextOptions kRequiredJSContextOptions =
   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
-LoadRuntimeAndContextOptions(const char* aPrefName, void* /* aClosure */)
+LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
 {
   AssertIsOnMainThread();
 
   RuntimeService* rts = RuntimeService::GetService();
   if (!rts && !gRuntimeServiceDuringInit) {
     // May be shutting down, just bail.
     return;
   }
@@ -325,57 +325,61 @@ LoadRuntimeAndContextOptions(const char*
 
 #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 commonContextOptions = kRequiredContextOptions;
+  JS::ContextOptions commonOptions = kRequiredJSContextOptions;
   if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict"))) {
-    commonContextOptions.setExtraWarnings(true);
+    commonOptions.setExtraWarnings(true);
   }
   if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror"))) {
-    commonContextOptions.setWerror(true);
+    commonOptions.setWerror(true);
+  }
+  if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs"))) {
+    commonOptions.setAsmJS(true);
   }
 
   // Content options.
-  JS::ContextOptions contentContextOptions = commonContextOptions;
+  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);
+  }
 
   // Chrome options.
-  JS::ContextOptions chromeContextOptions = commonContextOptions;
+  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);
+  }
 #ifdef DEBUG
   if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict.debug"))) {
-    chromeContextOptions.setExtraWarnings(true);
+    chromeOptions.setExtraWarnings(true);
   }
 #endif
 
-  RuntimeService::SetDefaultRuntimeAndContextOptions(runtimeOptions,
-                                                     contentContextOptions,
-                                                     chromeContextOptions);
+  RuntimeService::SetDefaultJSContextOptions(contentOptions, chromeOptions);
 
   if (rts) {
-    rts->UpdateAllWorkerRuntimeAndContextOptions();
+    rts->UpdateAllWorkerJSContextOptions();
   }
 }
 
 #ifdef JS_GC_ZEAL
 void
 LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */)
 {
   AssertIsOnMainThread();
@@ -762,18 +766,16 @@ 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);
@@ -1607,21 +1609,20 @@ nsresult
 RuntimeService::Init()
 {
   AssertIsOnMainThread();
 
   nsLayoutStatics::AddRef();
 
   // Initialize JSSettings.
   if (!sDefaultJSSettings.gcSettings[0].IsSet()) {
-    sDefaultJSSettings.runtimeOptions = JS::RuntimeOptions();
-    sDefaultJSSettings.chrome.contextOptions = kRequiredContextOptions;
+    sDefaultJSSettings.chrome.contextOptions = kRequiredJSContextOptions;
     sDefaultJSSettings.chrome.maxScriptRuntime = -1;
     sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST);
-    sDefaultJSSettings.content.contextOptions = kRequiredContextOptions;
+    sDefaultJSSettings.content.contextOptions = kRequiredJSContextOptions;
     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);
@@ -1686,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(LoadRuntimeAndContextOptions,
+      NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions,
                                               PREF_JS_OPTIONS_PREFIX,
                                               nullptr)) ||
       NS_FAILED(Preferences::RegisterCallbackAndCall(
-                                                   LoadRuntimeAndContextOptions,
-                                                   PREF_WORKERS_OPTIONS_PREFIX,
-                                                   nullptr)) ||
+                                                    LoadJSContextOptions,
+                                                    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'!");
@@ -1839,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(LoadRuntimeAndContextOptions,
+        NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
                                                   PREF_JS_OPTIONS_PREFIX,
                                                   nullptr)) ||
-        NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions,
+        NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
                                                   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
@@ -2224,20 +2225,19 @@ 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::UpdateAllWorkerRuntimeAndContextOptions()
+RuntimeService::UpdateAllWorkerJSContextOptions()
 {
-  BROADCAST_ALL_WORKERS(UpdateRuntimeAndContextOptions,
-                        sDefaultJSSettings.runtimeOptions,
+  BROADCAST_ALL_WORKERS(UpdateJSContextOptions,
                         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,29 +169,26 @@ public:
   static void
   GetDefaultPreferences(bool aPreferences[WORKERPREF_COUNT])
   {
     AssertIsOnMainThread();
     memcpy(aPreferences, sDefaultPreferences, WORKERPREF_COUNT * sizeof(bool));
   }
 
   static void
-  SetDefaultRuntimeAndContextOptions(
-                                    const JS::RuntimeOptions& aRuntimeOptions,
-                                    const JS::ContextOptions& aContentCxOptions,
-                                    const JS::ContextOptions& aChromeCxOptions)
+  SetDefaultJSContextOptions(const JS::ContextOptions& aContentOptions,
+                             const JS::ContextOptions& aChromeOptions)
   {
     AssertIsOnMainThread();
-    sDefaultJSSettings.runtimeOptions = aRuntimeOptions;
-    sDefaultJSSettings.content.contextOptions = aContentCxOptions;
-    sDefaultJSSettings.chrome.contextOptions = aChromeCxOptions;
+    sDefaultJSSettings.content.contextOptions = aContentOptions;
+    sDefaultJSSettings.chrome.contextOptions = aChromeOptions;
   }
 
   void
-  UpdateAllWorkerRuntimeAndContextOptions();
+  UpdateAllWorkerJSContextOptions();
 
   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
@@ -1511,42 +1511,35 @@ private:
       mTimer->Cancel();
       mTimer = nullptr;
     }
 
     return true;
   }
 };
 
-class UpdateRuntimeAndContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable
+class UpdateJSContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable
 {
-  JS::RuntimeOptions mRuntimeOptions;
-  JS::ContextOptions mContentCxOptions;
-  JS::ContextOptions mChromeCxOptions;
+  JS::ContextOptions mContentOptions;
+  JS::ContextOptions mChromeOptions;
 
 public:
-  UpdateRuntimeAndContextOptionsRunnable(
-                                    WorkerPrivate* aWorkerPrivate,
-                                    const JS::RuntimeOptions& aRuntimeOptions,
-                                    const JS::ContextOptions& aContentCxOptions,
-                                    const JS::ContextOptions& aChromeCxOptions)
+  UpdateJSContextOptionsRunnable(WorkerPrivate* aWorkerPrivate,
+                                 const JS::ContextOptions& aContentOptions,
+                                 const JS::ContextOptions& aChromeOptions)
   : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
-    mRuntimeOptions(aRuntimeOptions),
-    mContentCxOptions(aContentCxOptions),
-    mChromeCxOptions(aChromeCxOptions)
+    mContentOptions(aContentOptions), mChromeOptions(aChromeOptions)
   { }
 
 private:
   virtual bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE
   {
-    aWorkerPrivate->UpdateRuntimeAndContextOptionsInternal(aCx,
-                                                           mRuntimeOptions,
-                                                           mContentCxOptions,
-                                                           mChromeCxOptions);
+    aWorkerPrivate->UpdateJSContextOptionsInternal(aCx, mContentOptions,
+                                                   mChromeOptions);
     return true;
   }
 };
 
 class UpdatePreferenceRunnable MOZ_FINAL : public WorkerControlRunnable
 {
   WorkerPreference mPref;
   bool mValue;
@@ -2840,36 +2833,32 @@ 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>::UpdateRuntimeAndContextOptions(
-                                    JSContext* aCx,
-                                    const JS::RuntimeOptions& aRuntimeOptions,
-                                    const JS::ContextOptions& aContentCxOptions,
-                                    const JS::ContextOptions& aChromeCxOptions)
+WorkerPrivateParent<Derived>::UpdateJSContextOptions(
+                                      JSContext* aCx,
+                                      const JS::ContextOptions& aContentOptions,
+                                      const JS::ContextOptions& aChromeOptions)
 {
   AssertIsOnParentThread();
 
   {
     MutexAutoLock lock(mMutex);
-    mJSSettings.runtimeOptions = aRuntimeOptions;
-    mJSSettings.content.contextOptions = aContentCxOptions;
-    mJSSettings.chrome.contextOptions = aChromeCxOptions;
-  }
-
-  nsRefPtr<UpdateRuntimeAndContextOptionsRunnable> runnable =
-    new UpdateRuntimeAndContextOptionsRunnable(ParentAsWorkerPrivate(),
-                                               aRuntimeOptions,
-                                               aContentCxOptions,
-                                               aChromeCxOptions);
+    mJSSettings.content.contextOptions = aContentOptions;
+    mJSSettings.chrome.contextOptions = aChromeOptions;
+  }
+
+  nsRefPtr<UpdateJSContextOptionsRunnable> runnable =
+    new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aContentOptions,
+                                       aChromeOptions);
   if (!runnable->Dispatch(aCx)) {
     NS_WARNING("Failed to update worker context options!");
     JS_ClearPendingException(aCx);
   }
 }
 
 template <class Derived>
 void
@@ -5497,31 +5486,27 @@ WorkerPrivate::RescheduleTimeoutTimer(JS
     JS_ReportError(aCx, "Failed to start timer!");
     return false;
   }
 
   return true;
 }
 
 void
-WorkerPrivate::UpdateRuntimeAndContextOptionsInternal(
-                                    JSContext* aCx,
-                                    const JS::RuntimeOptions& aRuntimeOptions,
-                                    const JS::ContextOptions& aContentCxOptions,
-                                    const JS::ContextOptions& aChromeCxOptions)
+WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx,
+                                              const JS::ContextOptions& aContentOptions,
+                                              const JS::ContextOptions& aChromeOptions)
 {
   AssertIsOnWorkerThread();
 
-  JS::RuntimeOptionsRef(aCx) = aRuntimeOptions;
-  JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeCxOptions : aContentCxOptions;
+  JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeOptions : aContentOptions;
 
   for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
-    mChildWorkers[index]->UpdateRuntimeAndContextOptions(aCx, aRuntimeOptions,
-                                                         aContentCxOptions,
-                                                         aChromeCxOptions);
+    mChildWorkers[index]->UpdateJSContextOptions(aCx, aContentOptions,
+                                                 aChromeOptions);
   }
 }
 
 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,20 +384,18 @@ public:
                                uint64_t aMessagePortSerial,
                                JSAutoStructuredCloneBuffer&& aBuffer,
                                nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
 
   uint64_t
   GetInnerWindowId();
 
   void
-  UpdateRuntimeAndContextOptions(JSContext* aCx,
-                                 const JS::RuntimeOptions& aRuntimeOptions,
-                                 const JS::ContextOptions& aContentCxOptions,
-                                 const JS::ContextOptions& aChromeCxOptions);
+  UpdateJSContextOptions(JSContext* aCx, const JS::ContextOptions& aChromeOptions,
+                         const JS::ContextOptions& aContentOptions);
 
   void
   UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
 
   void
   UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
                                 uint32_t value);
 
@@ -903,21 +901,18 @@ public:
   void
   CloseHandlerFinished()
   {
     AssertIsOnWorkerThread();
     mCloseHandlerFinished = true;
   }
 
   void
-  UpdateRuntimeAndContextOptionsInternal(
-                                    JSContext* aCx,
-                                    const JS::RuntimeOptions& aRuntimeOptions,
-                                    const JS::ContextOptions& aContentCxOptions,
-                                    const JS::ContextOptions& aChromeCxOptions);
+  UpdateJSContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContentOptions,
+                                 const JS::ContextOptions& aChromeOptions);
 
   void
   UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
 
   void
   UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
 
   void
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -102,17 +102,16 @@ 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
@@ -1650,31 +1650,39 @@ 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).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);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdContext::SetOptions(uint32_t options)
 {
     ASSERT_VALID_EPHEMERAL;
 
@@ -1685,17 +1693,21 @@ 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);
+                                .setStrictMode(options & JSOPTION_STRICT_MODE)
+                                .setBaseline(options & JSOPTION_BASELINE)
+                                .setTypeInference(options & JSOPTION_TYPE_INFERENCE)
+                                .setIon(options & JSOPTION_ION)
+                                .setAsmJS(options & JSOPTION_ASMJS);
     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->runtime(), opt, uint32_t(number));
+    JS_SetGlobalJitCompilerOption(cx, 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->runtime(), opt)); \
-    if (!JS_SetProperty(cx, info, string, value))                      \
+#define JIT_COMPILER_MATCH(key, string)                         \
+    opt = JSJITCOMPILER_ ## key;                                \
+    value.setInt32(JS_GetGlobalJitCompilerOption(cx, 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
@@ -6947,13 +6947,13 @@ js::IsAsmJSCompilationAvailable(JSContex
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // See EstablishPreconditions.
     bool available = cx->jitSupportsFloatingPoint() &&
                      cx->signalHandlersInstalled() &&
                      cx->gcSystemPageSize() == AsmJSPageSize &&
                      !cx->compartment()->debugMode() &&
-                     cx->runtime()->options().asmJS();
+                     cx->compartment()->options().asmJS(cx);
 
     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->runtime()->options().baseline();
+    return cx->compartment()->options().baseline(cx);
 }
 
 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->runtime()->options().ion() &&
-        cx->runtime()->options().baseline() &&
+    return cx->compartment()->options().ion(cx) &&
+        cx->compartment()->options().baseline(cx) &&
         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::RuntimeOptionsRef(cx).setBaseline(true)
+    JS::ContextOptionsRef(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
@@ -136,17 +136,17 @@ BEGIN_TEST(testProfileStrings_isCalledWi
     }
     return true;
 }
 END_TEST(testProfileStrings_isCalledWithInterpreter)
 
 BEGIN_TEST(testProfileStrings_isCalledWithJIT)
 {
     CHECK(initialize(cx));
-    JS::RuntimeOptionsRef(cx).setBaseline(true)
+    JS::ContextOptionsRef(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(); }");
@@ -185,17 +185,17 @@ BEGIN_TEST(testProfileStrings_isCalledWi
     }
     return true;
 }
 END_TEST(testProfileStrings_isCalledWithJIT)
 
 BEGIN_TEST(testProfileStrings_isCalledWhenError)
 {
     CHECK(initialize(cx));
-    JS::RuntimeOptionsRef(cx).setBaseline(true)
+    JS::ContextOptionsRef(cx).setBaseline(true)
                              .setIon(true);
 
     EXEC("function check2() { throw 'a'; }");
 
     reset(cx);
     JS::ContextOptionsRef(cx).setDontReportUncaught(true);
     {
         JS::RootedValue rval(cx);
@@ -209,17 +209,17 @@ BEGIN_TEST(testProfileStrings_isCalledWh
     }
     return true;
 }
 END_TEST(testProfileStrings_isCalledWhenError)
 
 BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
 {
     CHECK(initialize(cx));
-    JS::RuntimeOptionsRef(cx).setBaseline(true)
+    JS::ContextOptionsRef(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
@@ -877,28 +877,16 @@ 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)
@@ -2461,16 +2449,46 @@ 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)
 {
@@ -4417,17 +4435,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->runtime()->options().asmJS();
+    asmJSOption = cx->options().asmJS();
 }
 
 bool
 JS::CompileOptions::wrap(JSContext *cx, JSCompartment *compartment)
 {
     if (!compartment->wrap(cx, &elementRoot))
         return false;
     if (elementAttributeNameRoot) {
@@ -5982,33 +6000,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(JSRuntime *rt, bool enabled)
+JS_SetParallelParsingEnabled(JSContext *cx, bool enabled)
 {
 #ifdef JS_ION
-    rt->setParallelParsingEnabled(enabled);
+    cx->runtime()->setParallelParsingEnabled(enabled);
 #endif
 }
 
 JS_PUBLIC_API(void)
-JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled)
+JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled)
 {
 #ifdef JS_ION
-    rt->setParallelIonCompilationEnabled(enabled);
+    cx->runtime()->setParallelIonCompilationEnabled(enabled);
 #endif
 }
 
 JS_PUBLIC_API(void)
-JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value)
+JS_SetGlobalJitCompilerOption(JSContext *cx, 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;
@@ -6021,51 +6039,51 @@ JS_SetGlobalJitCompilerOption(JSRuntime 
             break;
         }
         jit::js_JitOptions.setUsesBeforeCompile(value);
         if (value == 0)
             jit::js_JitOptions.setEagerCompilation();
         break;
       case JSJITCOMPILER_ION_ENABLE:
         if (value == 1) {
-            JS::RuntimeOptionsRef(rt).setIon(true);
+            JS::ContextOptionsRef(cx).setIon(true);
             IonSpew(js::jit::IonSpew_Scripts, "Enable ion");
         } else if (value == 0) {
-            JS::RuntimeOptionsRef(rt).setIon(false);
+            JS::ContextOptionsRef(cx).setIon(false);
             IonSpew(js::jit::IonSpew_Scripts, "Disable ion");
         }
         break;
       case JSJITCOMPILER_BASELINE_ENABLE:
         if (value == 1) {
-            JS::RuntimeOptionsRef(rt).setBaseline(true);
+            JS::ContextOptionsRef(cx).setBaseline(true);
             IonSpew(js::jit::IonSpew_BaselineScripts, "Enable baseline");
         } else if (value == 0) {
-            JS::RuntimeOptionsRef(rt).setBaseline(false);
+            JS::ContextOptionsRef(cx).setBaseline(false);
             IonSpew(js::jit::IonSpew_BaselineScripts, "Disable baseline");
         }
         break;
       default:
         break;
     }
 #endif
 }
 
 JS_PUBLIC_API(int)
-JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt)
+JS_GetGlobalJitCompilerOption(JSContext *cx, 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::RuntimeOptionsRef(rt).ion();
+        return JS::ContextOptionsRef(cx).ion();
       case JSJITCOMPILER_BASELINE_ENABLE:
-        return JS::RuntimeOptionsRef(rt).baseline();
+        return JS::ContextOptionsRef(cx).baseline();
       default:
         break;
     }
 #endif
     return 0;
 }
 
 /************************************************************************/
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1433,90 +1433,31 @@ 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;
@@ -1591,16 +1532,56 @@ 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;
@@ -1610,16 +1591,20 @@ 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:
@@ -2656,16 +2641,28 @@ 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; }
@@ -2678,16 +2675,20 @@ 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
@@ -4695,20 +4696,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(JSRuntime *rt, bool enabled);
+JS_SetParallelParsingEnabled(JSContext *cx, bool enabled);
 
 extern JS_PUBLIC_API(void)
-JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled);
+JS_SetParallelIonCompilationEnabled(JSContext *cx, 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 {
@@ -4717,19 +4718,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(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value);
+JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value);
 extern JS_PUBLIC_API(int)
-JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt);
+JS_GetGlobalJitCompilerOption(JSContext *cx, 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 zone()->types.inferenceEnabled;
+    return compartment_->options().typeInference(this);
 }
 
 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
@@ -1826,17 +1826,17 @@ TypeCompartment::TypeCompartment()
 {
     PodZero(this);
 }
 
 void
 TypeZone::init(JSContext *cx)
 {
     if (!cx ||
-        !cx->runtime()->options().typeInference() ||
+        !cx->options().typeInference() ||
         !cx->runtime()->jitSupportsFloatingPoint)
     {
         return;
     }
 
     inferenceEnabled = true;
 }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -113,17 +113,21 @@ 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
@@ -643,32 +647,31 @@ ResolvePath(JSContext *cx, HandleString 
     return JS_NewStringCopyZ(cx, buffer);
 }
 
 static bool
 Options(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
-    JS::RuntimeOptions oldRuntimeOptions = JS::RuntimeOptionsRef(cx);
-    JS::ContextOptions oldContextOptions = JS::ContextOptionsRef(cx);
+    JS::ContextOptions oldOptions = 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::RuntimeOptionsRef(cx).toggleTypeInference();
+            JS::ContextOptionsRef(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,"
@@ -682,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 && oldContextOptions.extraWarnings()) {
+    if (!names && oldOptions.extraWarnings()) {
         names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict");
         found = true;
     }
-    if (!names && oldRuntimeOptions.typeInference()) {
+    if (!names && oldOptions.typeInference()) {
         names = JS_sprintf_append(names, "%s%s", found ? "," : "", "typeinfer");
         found = true;
     }
-    if (!names && oldContextOptions.werror()) {
+    if (!names && oldOptions.werror()) {
         names = JS_sprintf_append(names, "%s%s", found ? "," : "", "werror");
         found = true;
     }
-    if (!names && oldContextOptions.strictMode()) {
+    if (!names && oldOptions.strictMode()) {
         names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict_mode");
         found = true;
     }
     if (!names) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
 
@@ -5594,16 +5597,24 @@ 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);
@@ -5695,37 +5706,202 @@ 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 bool
+static int
 OptionFailure(const char *option, const char *str)
 {
     fprintf(stderr, "Unrecognized option for %s: %s\n", option, str);
-    return false;
+    return EXIT_FAILURE;
 }
 #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")) {
@@ -5759,201 +5935,30 @@ 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
-
-#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
         fuzzingSafe = (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0');
 
     RootedObject glob(cx);
     JS::CompartmentOptions options;
     options.setVersion(JSVERSION_LATEST);
@@ -6159,31 +6164,53 @@ 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.
      */
-    OOM_printAllocationCount = op.getBoolOption('O');
+    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;
 #endif
 
     // 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
@@ -1678,17 +1678,16 @@ 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.
@@ -1726,23 +1725,16 @@ 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
@@ -3240,51 +3240,36 @@ nsXPCComponents_Utils::Dispatch(HandleVa
                                                    getter_AddRefs(run));
     NS_ENSURE_SUCCESS(rv, rv);
     MOZ_ASSERT(run);
 
     // Dispatch.
     return NS_DispatchToMainThread(run);
 }
 
-#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;                                                   \
+#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_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
+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
 
 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,17 +41,16 @@
 #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;
@@ -1494,55 +1493,16 @@ 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);
@@ -1618,18 +1578,16 @@ 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)) {
@@ -3198,20 +3156,16 @@ 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
@@ -1034,21 +1034,21 @@ ProcessArgsForCompartment(JSContext *cx,
                 return;
             break;
         case 'S':
             ContextOptionsRef(cx).toggleWerror();
         case 's':
             ContextOptionsRef(cx).toggleExtraWarnings();
             break;
         case 'I':
-            RuntimeOptionsRef(cx).toggleIon()
+            ContextOptionsRef(cx).toggleIon()
                                  .toggleAsmJS();
             break;
         case 'n':
-            RuntimeOptionsRef(cx).toggleTypeInference();
+            ContextOptionsRef(cx).toggleTypeInference();
             break;
         }
     }
 }
 
 static int
 ProcessArgs(JSContext *cx, JS::Handle<JSObject*> obj, char **argv, int argc, XPCShellDirProvider* aDirProvider)
 {
@@ -1482,16 +1482,19 @@ 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
@@ -356,32 +356,75 @@ 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
@@ -735,22 +735,25 @@ 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",      true);
-pref("javascript.options.ion",              true);
+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.asmjs",            true);
 pref("javascript.options.parallel_parsing", true);
 pref("javascript.options.ion.parallel_compilation", true);
-pref("javascript.options.typeinference",    true);
+pref("javascript.options.typeinference.content", true);
+pref("javascript.options.typeinference.chrome", 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);