Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 27 Aug 2013 20:38:23 -0400
changeset 157478 416075f7724926c7a1e96cef08ed5df62e3bd7a0
parent 157477 cd5991a56874deb8db76d23aaece08f3f5bcc6dc (current diff)
parent 157439 57fa024dfc5f2cba46503c5a751f7dcb720f6917 (diff)
child 157523 aa33608f75c19d7edd9d0959fb9de2d89643ecdc
child 157550 f9e432ee236f3da593c76e7995d505abc7ddb399
child 157566 f9ada8ad0d4f6f662f6647b2e162cf93c0cf5144
child 170268 789554f52b7dd72a3daaff7fefe6e0657ef225c6
child 177430 3b67e23589f7d9bca1f57696eddfff33a3d73bf6
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
416075f77249 / 26.0a1 / 20130828030202 / files
nightly linux64
416075f77249 / 26.0a1 / 20130828030202 / files
nightly mac
416075f77249 / 26.0a1 / 20130828030202 / files
nightly win32
416075f77249 / 26.0a1 / 20130828030202 / files
nightly win64
416075f77249 / 26.0a1 / 20130828030202 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team.
dom/wifi/libhardware_legacy.js
dom/wifi/wifi_worker.js
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -25,17 +25,16 @@ MOCHITEST_A11Y_FILES =\
 		test_coalescence.html \
 		test_contextmenu.html \
 		test_docload_aria.html \
 		test_docload.html \
 		test_docload.xul \
 		test_dragndrop.html \
 		test_flush.html \
 		test_focus_aria_activedescendant.html \
-		test_focus_autocomplete.xul \
 		test_focus_browserui.xul \
 		test_focus_canvas.html \
 		test_focus_contextmenu.xul \
 		test_focus_controls.html \
 		test_focus_dialog.html \
 		test_focus_doc.html \
 		test_focus_general.html \
 		test_focus_general.xul \
@@ -57,9 +56,16 @@ MOCHITEST_A11Y_FILES =\
 		test_statechange.html \
 		test_text_alg.html \
 		test_text.html \
 		test_textattrchange.html \
 		test_tree.xul \
 		test_valuechange.html \
 		$(NULL)
 
+# Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
+ifeq (,$(filter Linux WINNT,$(OS_ARCH)))
+MOCHITEST_A11Y_FILES += \
+		test_focus_autocomplete.xul \
+		$(NULL)
+endif
+
 include $(topsrcdir)/config/rules.mk
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -752,16 +752,19 @@ var AlertsHelper = {
         for (let i = 0; i < messages.length; i++) {
           let message = messages[i];
           if (message === "notification") {
             return helper.fullLaunchPath();
           } else if (typeof message == "object" && "notification" in message) {
             return helper.resolveFromOrigin(message["notification"]);
           }
         }
+
+        // No message found...
+        return null;
       }
 
       listener.target = getNotificationURLFor(manifest.messages);
 
       // Bug 816944 - Support notification messages for entry_points.
     });
   },
 
@@ -828,17 +831,17 @@ var AlertsHelper = {
       id: name
     });
   },
 
   receiveMessage: function alert_receiveMessage(aMessage) {
     if (!aMessage.target.assertAppHasPermission("desktop-notification")) {
       Cu.reportError("Desktop-notification message " + aMessage.name +
                      " from a content process with no desktop-notification privileges.");
-      return null;
+      return;
     }
 
     let data = aMessage.data;
     let listener = {
       mm: aMessage.target,
       title: data.title,
       text: data.text,
       manifestURL: data.manifestURL,
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "e8f63cae5aff3b61c0a49a9209ae971092ddee22", 
+    "revision": "a183b055417d036b01e177750ab2ec6162d6fcd7", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/metro/shell/testing/metrotestharness.cpp
+++ b/browser/metro/shell/testing/metrotestharness.cpp
@@ -324,17 +324,20 @@ static int Launch()
 
   // Launch firefox
   hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI, &processID);
   if (FAILED(hr)) {
     Fail(true, L"ActivateApplication result %X", hr);
     return RETRY;
   }
 
-  Log(L"Activation succeeded. processid=%d", processID);
+  Log(L"Activation succeeded.");
+
+  // automation.py picks up on this, don't mess with it.
+  Log(L"METRO_BROWSER_PROCESS=%d", processID);
 
   HANDLE child = OpenProcess(SYNCHRONIZE, FALSE, processID);
   if (!child) {
     Fail(false, L"Couldn't find child process. (%d)", GetLastError());
     return FAILURE;
   }
 
   Log(L"Waiting on child process...");
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -537,41 +537,49 @@ class Automation(object):
 
     return env
 
   if IS_WIN32:
     PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
     GetLastError = ctypes.windll.kernel32.GetLastError
 
     def readWithTimeout(self, f, timeout):
-      """Try to read a line of output from the file object |f|.
-      |f| must be a  pipe, like the |stdout| member of a subprocess.Popen
-      object created with stdout=PIPE. If no output
-      is received within |timeout| seconds, return a blank line.
-      Returns a tuple (line, did_timeout), where |did_timeout| is True
-      if the read timed out, and False otherwise."""
+      """
+      Try to read a line of output from the file object |f|. |f| must be a
+      pipe, like the |stdout| member of a subprocess.Popen object created
+      with stdout=PIPE. Returns a tuple (line, did_timeout), where |did_timeout|
+      is True if the read timed out, and False otherwise. If no output is
+      received within |timeout| seconds, returns a blank line.
+      """
+
       if timeout is None:
-        # shortcut to allow callers to pass in "None" for no timeout.
-        return (f.readline(), False)
+        timeout = 0
+
       x = msvcrt.get_osfhandle(f.fileno())
       l = ctypes.c_long()
       done = time.time() + timeout
-      while time.time() < done:
+
+      buffer = ""
+      while timeout == 0 or time.time() < done:
         if self.PeekNamedPipe(x, None, 0, None, ctypes.byref(l), None) == 0:
           err = self.GetLastError()
           if err == 38 or err == 109: # ERROR_HANDLE_EOF || ERROR_BROKEN_PIPE
             return ('', False)
           else:
             self.log.error("readWithTimeout got error: %d", err)
-        if l.value > 0:
-          # we're assuming that the output is line-buffered,
-          # which is not unreasonable
-          return (f.readline(), False)
+        # read a character at a time, checking for eol. Return once we get there.
+        index = 0
+        while index < l.value:
+          char = f.read(1)
+          buffer += char
+          if char == '\n':
+            return (buffer, False)
+          index = index + 1
         time.sleep(0.01)
-      return ('', True)
+      return (buffer, True)
 
     def isPidAlive(self, pid):
       STILL_ACTIVE = 259
       PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
       pHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid)
       if not pHandle:
         return False
       pExitCode = ctypes.wintypes.DWORD()
@@ -720,35 +728,51 @@ class Automation(object):
       elif self.IS_DEBUG_BUILD and self.IS_LINUX:
         # Run logsource through fix-linux-stack.pl (uses addr2line)
         # This method is preferred for developer machines, so we don't have to run "make buildsymbols".
         stackFixerProcess = self.Process([self.PERL, os.path.join(utilityPath, "fix-linux-stack.pl")],
                                          stdin=logsource,
                                          stdout=subprocess.PIPE)
         logsource = stackFixerProcess.stdout
 
+      # With metro browser runs this script launches the metro test harness which launches the browser.
+      # The metro test harness hands back the real browser process id via log output which we need to
+      # pick up on and parse out. This variable tracks the real browser process id if we find it.
+      browserProcessId = -1
+
       (line, didTimeout) = self.readWithTimeout(logsource, timeout)
       while line != "" and not didTimeout:
         if stackFixerFunction:
           line = stackFixerFunction(line)
         self.log.info(line.rstrip().decode("UTF-8", "ignore"))
         if "TEST-START" in line and "|" in line:
           self.lastTestSeen = line.split("|")[1].strip()
         if not debuggerInfo and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
           self.dumpScreen(utilityPath)
 
         (line, didTimeout) = self.readWithTimeout(logsource, timeout)
+
+        if "METRO_BROWSER_PROCESS" in line:
+          index = line.find("=")
+          if index:
+            browserProcessId = line[index+1:].rstrip()
+            self.log.info("INFO | automation.py | metro browser sub process id detected: %s", browserProcessId)
+
         if not hitMaxTime and maxTime and datetime.now() - startTime > timedelta(seconds = maxTime):
           # Kill the application, but continue reading from stack fixer so as not to deadlock on stackFixerProcess.wait().
           hitMaxTime = True
           self.log.info("TEST-UNEXPECTED-FAIL | %s | application ran for longer than allowed maximum time of %d seconds", self.lastTestSeen, int(maxTime))
           self.killAndGetStack(proc.pid, utilityPath, debuggerInfo)
       if didTimeout:
+        if line:
+          self.log.info(line.rstrip().decode("UTF-8", "ignore"))
         self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed out after %d seconds with no output", self.lastTestSeen, int(timeout))
-        self.killAndGetStack(proc.pid, utilityPath, debuggerInfo)
+        if browserProcessId == -1:
+          browserProcessId = proc.pid
+        self.killAndGetStack(browserProcessId, utilityPath, debuggerInfo)
 
     status = proc.wait()
     if status == 0:
       self.lastTestSeen = "Main app process exited normally"
     if status != 0 and not didTimeout and not hitMaxTime:
       self.log.info("TEST-UNEXPECTED-FAIL | %s | Exited with code %d during test run", self.lastTestSeen, status)
     if stackFixerProcess is not None:
       fixerStatus = stackFixerProcess.wait()
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -351,17 +351,17 @@ Element::GetBindingURL(nsIDocument *aDoc
   *aResult = sc->StyleDisplay()->mBinding;
 
   return true;
 }
 
 JSObject*
 Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
-  JSObject* obj = nsINode::WrapObject(aCx, aScope);
+  JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aScope));
   if (!obj) {
     return nullptr;
   }
 
   nsIDocument* doc;
   if (HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     doc = OwnerDoc();
   }
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -748,16 +748,17 @@ GK_ATOM(onMozMousePixelScroll, "onMozMou
 GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
 GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
 GK_ATOM(onmoznetworkdownload, "onmoznetworkdownload")
 GK_ATOM(onnoupdate, "onnoupdate")
 GK_ATOM(onobsolete, "onobsolete")
 GK_ATOM(ononline, "ononline")
 GK_ATOM(onoffline, "onoffline")
 GK_ATOM(onopen, "onopen")
+GK_ATOM(onotastatuschange, "onotastatuschange")
 GK_ATOM(onoverflow, "onoverflow")
 GK_ATOM(onoverflowchanged, "onoverflowchanged")
 GK_ATOM(onpagehide, "onpagehide")
 GK_ATOM(onpageshow, "onpageshow")
 GK_ATOM(onpaint, "onpaint")
 GK_ATOM(onpairedstatuschanged, "onpairedstatuschanged")
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpopuphidden, "onpopuphidden")
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -867,16 +867,17 @@ private:
     void Draw_cleanup();
 
     void VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
     void VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
     void VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
     void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
 
     bool ValidateBufferFetching(const char *info);
+    bool BindArrayAttribToLocation0(WebGLProgram *program);
 
 // -----------------------------------------------------------------------------
 // PROTECTED
 protected:
     void SetDontKnowIfNeedFakeBlack() {
         mFakeBlackStatus = DontKnowIfNeedFakeBlack;
     }
 
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1961,16 +1961,46 @@ WebGLContext::IsTexture(WebGLTexture *te
     if (!IsContextStable())
         return false;
 
     return ValidateObjectAllowDeleted("isTexture", tex) &&
         !tex->IsDeleted() &&
         tex->HasEverBeenBound();
 }
 
+// Try to bind an attribute that is an array to location 0:
+bool WebGLContext::BindArrayAttribToLocation0(WebGLProgram *program)
+{
+    if (mBoundVertexArray->mAttribBuffers[0].enabled) {
+        return false;
+    }
+
+    GLint leastArrayLocation = -1;
+
+    std::map<GLint, nsCString>::iterator itr;
+    for (itr = program->mActiveAttribMap.begin();
+         itr != program->mActiveAttribMap.end();
+         itr++) {
+        int32_t index = itr->first;
+        if (mBoundVertexArray->mAttribBuffers[index].enabled &&
+            index < leastArrayLocation)
+        {
+            leastArrayLocation = index;
+        }
+    }
+
+    if (leastArrayLocation > 0) {
+        nsCString& attrName = program->mActiveAttribMap.find(leastArrayLocation)->second;
+        const char* attrNameCStr = attrName.get();
+        gl->fBindAttribLocation(program->GLName(), 0, attrNameCStr);
+        return true;
+    }
+    return false;
+}
+
 void
 WebGLContext::LinkProgram(WebGLProgram *program)
 {
     if (!IsContextStable())
         return;
 
     if (!ValidateObject("linkProgram", program))
         return;
@@ -1998,34 +2028,48 @@ WebGLContext::LinkProgram(WebGLProgram *
         mIsMesa &&
         program->UpperBoundNumSamplerUniforms() > 16)
     {
         GenerateWarning("Programs with more than 16 samplers are disallowed on Mesa drivers " "to avoid a Mesa crasher.");
         program->SetLinkStatus(false);
         return;
     }
 
-    GLint ok;
+    bool updateInfoSucceeded = false;
+    GLint ok = 0;
     if (gl->WorkAroundDriverBugs() &&
         program->HasBadShaderAttached())
     {
         // it's a common driver bug, caught by program-test.html, that linkProgram doesn't
         // correctly preserve the state of an in-use program that has been attached a bad shader
         // see bug 777883
         ok = false;
     } else {
         MakeContextCurrent();
         gl->fLinkProgram(progname);
         gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
+
+        if (ok) {
+            updateInfoSucceeded = program->UpdateInfo();
+            program->SetLinkStatus(updateInfoSucceeded);
+
+            if (BindArrayAttribToLocation0(program)) {
+                GenerateWarning("linkProgram: relinking program to make attrib0 an "
+                                "array.");
+                gl->fLinkProgram(progname);
+                gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
+                if (ok) {
+                    updateInfoSucceeded = program->UpdateInfo();
+                    program->SetLinkStatus(updateInfoSucceeded);
+                }
+            }
+        }
     }
 
     if (ok) {
-        bool updateInfoSucceeded = program->UpdateInfo();
-        program->SetLinkStatus(updateInfoSucceeded);
-
         // Bug 750527
         if (gl->WorkAroundDriverBugs() &&
             updateInfoSucceeded &&
             gl->Vendor() == gl::GLContext::VendorNVIDIA)
         {
             if (program == mCurrentProgram)
                 gl->fUseProgram(progname);
         }
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -81,16 +81,35 @@ WebGLProgram::UpdateInfo()
             for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
 	        const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
 	        const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
 	        mUniformInfoMap->Put(uniform.mapped, info);
             }
         }
     }
 
+    mActiveAttribMap.clear();
+
+    GLint numActiveAttrs = 0;
+    mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &numActiveAttrs);
+
+    // Spec says the maximum attrib name length is 256 chars, so this is
+    // sufficient to hold any attrib name.
+    char attrName[257];
+
+    GLint dummySize;
+    GLenum dummyType;
+    for (GLint i = 0; i < numActiveAttrs; i++) {
+        mContext->gl->fGetActiveAttrib(mGLName, i, 257, nullptr, &dummySize,
+                                       &dummyType, attrName);
+        GLint attrLoc = mContext->gl->fGetAttribLocation(mGLName, attrName);
+        MOZ_ASSERT(attrLoc >= 0);
+        mActiveAttribMap.insert(std::make_pair(attrLoc, nsCString(attrName)));
+    }
+
     return true;
 }
 
 bool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_FUNC_ADD:
         case LOCAL_GL_FUNC_SUBTRACT:
--- a/content/canvas/src/WebGLProgram.h
+++ b/content/canvas/src/WebGLProgram.h
@@ -105,16 +105,19 @@ public:
     }
 
     virtual JSObject* WrapObject(JSContext *cx,
                                  JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLProgram)
 
+    // public post-link data
+    std::map<GLint, nsCString> mActiveAttribMap;
+
 protected:
 
     WebGLuint mGLName;
     bool mLinkStatus;
     // attached shaders of the program object
     nsTArray<WebGLRefPtr<WebGLShader> > mAttachedShaders;
     CheckedUint32 mGeneration;
 
new file mode 100644
--- /dev/null
+++ b/content/xul/content/crashtests/509719-1-overlay.xul
@@ -0,0 +1,3 @@
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <window id="win" removeelement="true"/>
+</overlay>
new file mode 100644
--- /dev/null
+++ b/content/xul/content/crashtests/509719-1.xul
@@ -0,0 +1,3 @@
+<?xul-overlay href="509719-1-overlay.xul"?>
+<window id="win" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+</window>
new file mode 100644
--- /dev/null
+++ b/content/xul/content/crashtests/509719-2-overlay.xul
@@ -0,0 +1,8 @@
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script>
+    if (document.getElementById("testnode")) {
+      document.loadOverlay(window.location.href.substr(0,window.location.href.lastIndexOf('/')+1)+'509719-2-overlay.xul', null);
+    }
+  </script>
+  <box xmlns="http://www.w3.org/1999/xhtml" id="testnode" removeelement="true"/>
+</overlay>
new file mode 100644
--- /dev/null
+++ b/content/xul/content/crashtests/509719-2.xul
@@ -0,0 +1,7 @@
+<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
+<window id="win" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <box id="testnode" onDOMAttrModified="this.parentNode.removeChild(this)"/>
+  <script>
+document.loadOverlay(window.location.href.substr(0,window.location.href.lastIndexOf('/')+1)+'509719-2-overlay.xul', null);
+  </script>
+</window>
--- a/content/xul/content/crashtests/crashtests.list
+++ b/content/xul/content/crashtests/crashtests.list
@@ -15,8 +15,10 @@ load 363791-1.xul
 load 384740-1.xul
 load 384877-1.html
 load 386947-1.xul
 load 425821-1.xul
 load 429085-1.xhtml
 load 431906-1.html
 load 451311-1.xul
 load 461917-1.xhtml
+load 509719-1.xul
+asserts(3) load 509719-2.xul # bug 909819
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -3538,30 +3538,30 @@ XULDocument::OnStreamComplete(nsIStreamL
     }
 
     return OnScriptCompileComplete(mCurrentScriptProto->GetScriptObject(), rv);
 }
 
 NS_IMETHODIMP
 XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
 {
+    // When compiling off thread the script will not have been attached to the
+    // script proto yet.
+    if (aScript && !mCurrentScriptProto->GetScriptObject())
+        mCurrentScriptProto->Set(aScript);
+
     // Allow load events to be fired once off thread compilation finishes.
     if (mOffThreadCompiling) {
         mOffThreadCompiling = false;
         UnblockOnload(false);
     }
 
     // After compilation finishes the script's characters are no longer needed.
     mOffThreadCompileString.Truncate();
 
-    // When compiling off thread the script will not have been attached to the
-    // script proto yet.
-    if (aScript && !mCurrentScriptProto->GetScriptObject())
-        mCurrentScriptProto->Set(aScript);
-
     // Clear mCurrentScriptProto now, but save it first for use below in
     // the execute code, and in the while loop that resumes walks of other
     // documents that raced to load this script.
     nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
     mCurrentScriptProto = nullptr;
 
     // Clear the prototype's loading flag before executing the script or
     // resuming document walks, in case any of those control flows starts a
@@ -3659,17 +3659,17 @@ XULDocument::ExecuteScript(nsIScriptCont
 
     if (!aContext->GetScriptsEnabled())
         return NS_OK;
 
     // Execute the precompiled script with the given version
     nsAutoMicroTask mt;
     JSContext *cx = aContext->GetNativeContext();
     AutoCxPusher pusher(cx);
-    JSObject* global = mScriptGlobalObject->GetGlobalJSObject();
+    JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject());
     xpc_UnmarkGrayObject(global);
     xpc_UnmarkGrayScript(aScriptObject);
     JSAutoCompartment ac(cx, global);
     JS::Rooted<JS::Value> unused(cx);
     if (!JS_ExecuteScript(cx, global, aScriptObject, unused.address()))
         nsJSUtils::ReportPendingException(cx);
     return NS_OK;
 }
@@ -4062,17 +4062,18 @@ XULDocument::OverlayForwardReference::Me
         nsAutoString value;
         aOverlayNode->GetAttr(nameSpaceID, attr, value);
 
         // Element in the overlay has the 'removeelement' attribute set
         // so remove it from the actual document.
         if (attr == nsGkAtoms::removeelement &&
             value.EqualsLiteral("true")) {
 
-            nsCOMPtr<nsIContent> parent = aTargetNode->GetParent();
+            nsCOMPtr<nsINode> parent = aTargetNode->GetParentNode();
+            if (!parent) return NS_ERROR_FAILURE;
             rv = RemoveElement(parent, aTargetNode);
             if (NS_FAILED(rv)) return rv;
 
             return NS_OK;
         }
 
         rv = aTargetNode->SetAttr(nameSpaceID, attr, prefix, value, aNotify);
         if (!NS_FAILED(rv) && !aNotify)
@@ -4444,17 +4445,17 @@ XULDocument::CheckBroadcasterHookup(Elem
 #endif
 
     *aNeedsHookup = false;
     *aDidResolve = true;
     return NS_OK;
 }
 
 nsresult
-XULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild,
+XULDocument::InsertElement(nsINode* aParent, nsIContent* aChild,
                            bool aNotify)
 {
     // Insert aChild appropriately into aParent, accounting for a
     // 'pos' attribute set on aChild.
 
     nsAutoString posStr;
     bool wasInserted = false;
 
@@ -4525,17 +4526,17 @@ XULDocument::InsertElement(nsIContent* a
 
     if (!wasInserted) {
         return aParent->AppendChildTo(aChild, aNotify);
     }
     return NS_OK;
 }
 
 nsresult
-XULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild)
+XULDocument::RemoveElement(nsINode* aParent, nsINode* aChild)
 {
     int32_t nodeOffset = aParent->IndexOf(aChild);
 
     aParent->RemoveChildAt(nodeOffset, true);
     return NS_OK;
 }
 
 //----------------------------------------------------------------------
--- a/content/xul/document/src/XULDocument.h
+++ b/content/xul/document/src/XULDocument.h
@@ -586,21 +586,21 @@ protected:
 
     void
     SynchronizeBroadcastListener(Element *aBroadcaster,
                                  Element *aListener,
                                  const nsAString &aAttr);
 
     static
     nsresult
-    InsertElement(nsIContent* aParent, nsIContent* aChild, bool aNotify);
+    InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
 
     static 
     nsresult
-    RemoveElement(nsIContent* aParent, nsIContent* aChild);
+    RemoveElement(nsINode* aParent, nsINode* aChild);
 
     /**
      * The current prototype that we are walking to construct the
      * content model.
      */
     nsRefPtr<nsXULPrototypeDocument> mCurrentPrototype;
 
     /**
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1238,17 +1238,17 @@ DOMInterfaces = {
 {
     'implicitJSContext': [ 'createObjectURL', 'revokeObjectURL' ],
     'workers': True,
     'concrete': False,
 }],
 
 'WebGLActiveInfo': {
    'nativeType': 'mozilla::WebGLActiveInfo',
-   'headerFile': 'WebGLContext.h',
+   'headerFile': 'WebGLActiveInfo.h',
    'wrapperCache': False
 },
 
 'WebGLBuffer': {
    'nativeType': 'mozilla::WebGLBuffer',
    'headerFile': 'WebGLBuffer.h'
 },
 
--- a/dom/network/interfaces/moz.build
+++ b/dom/network/interfaces/moz.build
@@ -17,14 +17,15 @@ XPIDL_SOURCES += [
     'nsITCPSocketParent.idl',
 ]
 
 if CONFIG['MOZ_B2G_RIL']:
     XPIDL_SOURCES += [
         'nsIDOMCFStateChangeEvent.idl',
         'nsIDOMMobileConnection.idl',
         'nsIDOMMozEmergencyCbModeEvent.idl',
+        'nsIDOMMozOtaStatusEvent.idl',
         'nsIDOMNetworkStats.idl',
         'nsIDOMNetworkStatsManager.idl',
         'nsIMobileConnectionProvider.idl',
     ]
 
 XPIDL_MODULE = 'dom_network'
--- a/dom/network/interfaces/nsIDOMMobileConnection.idl
+++ b/dom/network/interfaces/nsIDOMMobileConnection.idl
@@ -6,17 +6,17 @@
 
 interface nsIDOMEventListener;
 interface nsIDOMDOMRequest;
 interface nsIDOMMozMobileConnectionInfo;
 interface nsIDOMMozMobileNetworkInfo;
 interface nsIDOMMozMobileCellInfo;
 interface nsIDOMMozMobileCFInfo;
 
-[scriptable, builtinclass, uuid(8284af62-c39d-4a59-b258-107040040418)]
+[scriptable, builtinclass, uuid(095b3720-058c-11e3-8ffd-0800200c9a66)]
 interface nsIDOMMozMobileConnection : nsIDOMEventTarget
 {
   const long ICC_SERVICE_CLASS_VOICE = (1 << 0);
   const long ICC_SERVICE_CLASS_DATA = (1 << 1);
   const long ICC_SERVICE_CLASS_FAX = (1 << 2);
   const long ICC_SERVICE_CLASS_SMS = (1 << 3);
   const long ICC_SERVICE_CLASS_DATA_SYNC = (1 << 4);
   const long ICC_SERVICE_CLASS_DATA_ASYNC = (1 << 5);
@@ -259,16 +259,31 @@ interface nsIDOMMozMobileConnection : ns
    *
    * Otherwise, the request's onerror will be called, and the request's error
    * will be either 'RadioNotAvailable', 'RequestNotSupported',
    * 'InvalidCallBarringOption' or 'GenericFailure'.
    */
   nsIDOMDOMRequest getCallBarringOption(in jsval option);
 
   /**
+   * Change call barring facility password.
+   *
+   * @param info
+   *        An object containing information about pin and newPin, and,
+   *        this object must have both "pin" and "newPin" attributes
+   *        to change the call barring facility password.
+   *
+   * Example:
+   *
+   *   changeCallBarringPassword({pin: "...",
+   *                              newPin: "..."});
+   */
+  nsIDOMDOMRequest changeCallBarringPassword(in jsval info);
+
+  /**
    * Configures call waiting options.
    *
    * @param enabled
    *        Value containing the desired call waiting status.
    *
    * If successful, the request's onsuccess will be called.
    *
    * Otherwise, the request's onerror will be called, and the request's error
@@ -357,16 +372,22 @@ interface nsIDOMMozMobileConnection : ns
    */
   [implicit_jscontext] attribute jsval oncfstatechange;
 
   /**
    * The 'emergencycbmodechange' event is notified whenever the emergency
    * callback mode changes.
    */
   [implicit_jscontext] attribute jsval onemergencycbmodechange;
+
+  /**
+   * The 'onotastatuschange' event is notified whenever the ota provision status
+   * changes.
+   */
+  [implicit_jscontext] attribute jsval onotastatuschange;
 };
 
 [scriptable, uuid(49706beb-a160-40b7-b745-50f62e389a2c)]
 interface nsIDOMMozMobileConnectionInfo : nsISupports
 {
   /**
    * State of the connection.
    *
new file mode 100644
--- /dev/null
+++ b/dom/network/interfaces/nsIDOMMozOtaStatusEvent.idl
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIDOMEvent.idl"
+
+[scriptable, builtinclass, uuid(d3592cdc-c5cf-4c24-a27c-6f789ac94959)]
+interface nsIDOMMozOtaStatusEvent : nsIDOMEvent
+{
+  readonly attribute DOMString status;
+
+  [noscript] void initMozOtaStatusEvent(in DOMString aType,
+                                        in boolean aCanBubble,
+                                        in boolean aCancelable,
+                                        in DOMString aStatus);
+};
+
+dictionary MozOtaStatusEventInit : EventInit
+{
+  DOMString status;
+};
--- a/dom/network/interfaces/nsIMobileConnectionProvider.idl
+++ b/dom/network/interfaces/nsIMobileConnectionProvider.idl
@@ -5,39 +5,40 @@
 #include "nsISupports.idl"
 
 interface nsIDOMDOMRequest;
 interface nsIDOMMozMobileCFInfo;
 interface nsIDOMMozMobileConnectionInfo;
 interface nsIDOMMozMobileNetworkInfo;
 interface nsIDOMWindow;
 
-[scriptable, uuid(7da2d9f6-eba1-4339-bde1-dc6732d42cdf)]
+[scriptable, uuid(f1878629-4151-4e02-a22a-8cec3d7eddee)]
 interface nsIMobileConnectionListener : nsISupports
 {
   void notifyVoiceChanged();
   void notifyDataChanged();
   void notifyUssdReceived(in DOMString message,
                           in boolean sessionEnded);
   void notifyDataError(in DOMString message);
   void notifyCFStateChange(in boolean success,
                            in unsigned short action,
                            in unsigned short reason,
                            in DOMString number,
                            in unsigned short timeSeconds,
                            in unsigned short serviceClass);
   void notifyEmergencyCbModeChanged(in boolean active,
                                     in unsigned long timeoutMs);
+  void notifyOtaStatusChanged(in DOMString status);
 };
 
 /**
  * XPCOM component (in the content process) that provides the mobile
  * network information.
  */
-[scriptable, uuid(576c7c00-7319-4309-aa9e-1dab102e0874)]
+[scriptable, uuid(c66652e0-0628-11e3-8ffd-0800200c9a66)]
 interface nsIMobileConnectionProvider : nsISupports
 {
   /**
    * Called when a content process registers receiving unsolicited messages from
    * RadioInterfaceLayer in the chrome process. Only a content process that has
    * the 'mobileconnection' permission is allowed to register.
    */
   void registerMobileConnectionMsg(in nsIMobileConnectionListener listener);
@@ -66,16 +67,18 @@ interface nsIMobileConnectionProvider : 
                                            in unsigned short reason);
   nsIDOMDOMRequest setCallForwardingOption(in nsIDOMWindow          window,
                                            in nsIDOMMozMobileCFInfo CFInfo);
 
   nsIDOMDOMRequest getCallBarringOption(in nsIDOMWindow window,
                                         in jsval        option);
   nsIDOMDOMRequest setCallBarringOption(in nsIDOMWindow window,
                                         in jsval        option);
+  nsIDOMDOMRequest changeCallBarringPassword(in nsIDOMWindow window,
+                                             in jsval info);
 
   nsIDOMDOMRequest setCallWaitingOption(in nsIDOMWindow   window,
                                         in bool enabled);
   nsIDOMDOMRequest getCallWaitingOption(in nsIDOMWindow   window);
 
   nsIDOMDOMRequest setCallingLineIdRestriction(in nsIDOMWindow   window,
                                                in unsigned short clirMode);
   nsIDOMDOMRequest getCallingLineIdRestriction(in nsIDOMWindow   window);
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -1,22 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MobileConnection.h"
-
 #include "GeneratedEvents.h"
 #include "mozilla/Preferences.h"
 #include "nsDOMEvent.h"
 #include "nsIDOMCFStateChangeEvent.h"
 #include "nsIDOMClassInfo.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIDOMDataErrorEvent.h"
 #include "nsIDOMMozEmergencyCbModeEvent.h"
+#include "nsIDOMMozOtaStatusEvent.h"
 #include "nsIDOMUSSDReceivedEvent.h"
 #include "nsIPermissionManager.h"
 
 #include "nsJSUtils.h"
 #include "nsJSON.h"
 #include "jsapi.h"
 #include "mozilla/Services.h"
 
@@ -71,16 +71,17 @@ NS_IMPL_ADDREF_INHERITED(MobileConnectio
 NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
 
 NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
 NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
 NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
 NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
 NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
 NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange)
 
 MobileConnection::MobileConnection()
 {
   mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
   mWindow = nullptr;
 
   // Not being able to acquire the provider isn't fatal since we check
   // for it explicitly below.
@@ -402,16 +403,33 @@ MobileConnection::SetCallBarringOption(c
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->SetCallBarringOption(GetOwner(), aOption, aRequest);
 }
 
 NS_IMETHODIMP
+MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
+                                            nsIDOMDOMRequest** aRequest)
+{
+  *aRequest = nullptr;
+
+  if (!CheckPermission("mobileconnection")) {
+    return NS_OK;
+  }
+
+  if (!mProvider) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return mProvider->ChangeCallBarringPassword(GetOwner(), aInfo, aRequest);
+}
+
+NS_IMETHODIMP
 MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
@@ -589,8 +607,27 @@ MobileConnection::NotifyEmergencyCbModeC
   nsCOMPtr<nsIDOMMozEmergencyCbModeEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitMozEmergencyCbModeEvent(
       NS_LITERAL_STRING("emergencycbmodechange"), false, false,
       aActive, aTimeoutMs);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
 }
+
+NS_IMETHODIMP
+MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
+{
+  if (!CheckPermission("mobileconnection")) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMMozOtaStatusEvent(getter_AddRefs(event), this, nullptr, nullptr);
+  MOZ_ASSERT(event);
+
+  nsCOMPtr<nsIDOMMozOtaStatusEvent> ce = do_QueryInterface(event);
+  nsresult rv = ce->InitMozOtaStatusEvent(NS_LITERAL_STRING("otastatuschange"),
+                                          false, false, aStatus);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return DispatchTrustedEvent(ce);
+}
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/network/tests/marionette/manifest.ini
@@ -11,8 +11,9 @@ disabled = Bug 808783
 [test_mobile_preferred_network_type.js]
 disabled = Bug 808783
 [test_mobile_data_location.js]
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
+[test_call_barring_change_password.js]
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/marionette/test_call_barring_change_password.js
@@ -0,0 +1,63 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+
+SpecialPowers.addPermission("mobileconnection", true, document);
+
+// Permission changes can't change existing Navigator.prototype
+// objects, so grab our objects from a new Navigator
+let ifr = document.createElement("iframe");
+let connection;
+ifr.onload = function() {
+  connection = ifr.contentWindow.navigator.mozMobileConnection;
+
+  ok(connection instanceof ifr.contentWindow.MozMobileConnection,
+     "connection is instanceof " + connection.constructor);
+
+  setTimeout(testChangeCallBarringPasswordWithFailure, 0);
+};
+document.body.appendChild(ifr);
+
+function testChangeCallBarringPasswordWithFailure() {
+  // Incorrect parameters, expect onerror callback.
+  let options = [
+    {pin: null, newPin: '0000'},
+    {pin: '0000', newPin: null},
+    {pin: null, newPin: null},
+    {pin: '000', newPin: '0000'},
+    {pin: '00000', newPin: '1111'},
+    {pin: 'abcd', newPin: 'efgh'},
+  ];
+
+  function do_test() {
+    for (let i = 0; i < options.length; i++) {
+      let request = connection.changeCallBarringPassword(options[i]);
+
+      request.onsuccess = function() {
+        ok(false, 'Unexpected result.');
+        setTimeout(cleanUp , 0);
+      };
+
+      request.onerror = function() {
+        ok(request.error.name === 'InvalidPassword', 'InvalidPassword');
+        if (i >= options.length) {
+          setTimeout(testChangeCallBarringPasswordWithSuccess, 0);
+        }
+      };
+    }
+  }
+
+  do_test();
+}
+
+function testChangeCallBarringPasswordWithSuccess() {
+  // TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on
+  // Emulator.
+  setTimeout(cleanUp , 0);
+}
+
+function cleanUp() {
+  SpecialPowers.removePermission("mobileconnection", document);
+  finish();
+}
--- a/dom/plugins/test/reftest/reftest.list
+++ b/dom/plugins/test/reftest/reftest.list
@@ -1,15 +1,15 @@
 # basic sanity checking
 random-if(!haveTestPlugin) != plugin-sanity.html about:blank
 random-if(!haveTestPlugin) != plugin-asyncbitmap-sanity.html about:blank
 fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
 fails-if(!haveTestPlugin) == plugin-asyncbitmap-sanity.html div-sanity.html
 fails-if(!haveTestPlugin) == plugin-asyncdxgi-sanity.html div-sanity.html
-skip-if(!haveTestPlugin) == plugin-asyncbitmap-update.html plugin-async-update-ref.html
+random-if(OSX==10.6||OSX==10.7) skip-if(!haveTestPlugin) == plugin-asyncbitmap-update.html plugin-async-update-ref.html
 random-if(OSX==10.6||OSX==10.7) skip-if(!haveTestPlugin) == plugin-asyncdxgi-update.html plugin-async-update-ref.html
 fails-if(!haveTestPlugin) == plugin-alpha-zindex.html div-alpha-zindex.html
 fails-if(!haveTestPlugin) == plugin-alpha-opacity.html div-alpha-opacity.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html # bug 631832
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html # bug 629430
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html # bug 629430
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) skip-if(Android||B2G) == border-padding-3.html border-padding-3-ref.html # bug 629430 # bug 773482
 # The following two "pluginproblemui-direction" tests are unreliable on all platforms. They should be re-written or replaced.
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -87,16 +87,17 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:CancelMMI",
   "RIL:StkCommand",
   "RIL:StkSessionEnd",
   "RIL:DataError",
   "RIL:SetCallForwardingOption",
   "RIL:GetCallForwardingOption",
   "RIL:SetCallBarringOption",
   "RIL:GetCallBarringOption",
+  "RIL:ChangeCallBarringPassword",
   "RIL:SetCallWaitingOption",
   "RIL:GetCallWaitingOption",
   "RIL:SetCallingLineIdRestriction",
   "RIL:GetCallingLineIdRestriction",
   "RIL:CellBroadcastReceived",
   "RIL:CfStateChanged",
   "RIL:IccOpenChannel",
   "RIL:IccCloseChannel",
@@ -104,17 +105,18 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:ReadIccContacts",
   "RIL:UpdateIccContact",
   "RIL:SetRoamingPreference",
   "RIL:GetRoamingPreference",
   "RIL:CdmaCallWaiting",
   "RIL:ExitEmergencyCbMode",
   "RIL:SetVoicePrivacyMode",
   "RIL:GetVoicePrivacyMode",
-  "RIL:ConferenceCallStateChanged"
+  "RIL:ConferenceCallStateChanged",
+  "RIL:OtaStatusChanged"
 ];
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
                                    "@mozilla.org/uuid-generator;1",
@@ -1097,16 +1099,41 @@ RILContentHelper.prototype = {
         enabled: option.enabled,
         password: option.password,
         serviceClass: option.serviceClass
       }
     });
     return request;
   },
 
+  changeCallBarringPassword: function changeCallBarringPassword(window, info) {
+    if (window == null) {
+      throw Components.Exception("Can't get window object",
+                                  Cr.NS_ERROR_UNEXPECTED);
+    }
+    let request = Services.DOMRequest.createRequest(window);
+    let requestId = this.getRequestId(request);
+
+    // Checking valid PIN for supplementary services. See TS.22.004 clause 5.2.
+    if (info.pin == null || !info.pin.match(/^\d{4}$/) ||
+        info.newPin == null || !info.newPin.match(/^\d{4}$/)) {
+      this.dispatchFireRequestError(requestId, "InvalidPassword");
+      return request;
+    }
+
+    if (DEBUG) debug("changeCallBarringPassword: " + JSON.stringify(info));
+    info.requestId = requestId;
+    cpmm.sendAsyncMessage("RIL:ChangeCallBarringPassword", {
+      clientId: 0,
+      data: info
+    });
+
+    return request;
+  },
+
   getCallWaitingOption: function getCallWaitingOption(window) {
     if (window == null) {
       throw Components.Exception("Can't get window object",
                                   Cr.NS_ERROR_UNEXPECTED);
     }
     let request = Services.DOMRequest.createRequest(window);
     let requestId = this.getRequestId(request);
 
@@ -1526,16 +1553,21 @@ RILContentHelper.prototype = {
         break;
       case "RIL:DataInfoChanged":
         this.updateConnectionInfo(msg.json.data,
                                   this.rilContext.dataConnectionInfo);
         this._deliverEvent("_mobileConnectionListeners",
                            "notifyDataChanged",
                            null);
         break;
+      case "RIL:OtaStatusChanged":
+        this._deliverEvent("_mobileConnectionListeners",
+                           "notifyOtaStatusChanged",
+                           [msg.json.data]);
+        break;
       case "RIL:EnumerateCalls":
         this.handleEnumerateCalls(msg.json.calls);
         break;
       case "RIL:GetAvailableNetworks":
         this.handleGetAvailableNetworks(msg.json);
         break;
       case "RIL:NetworkSelectionModeChanged":
         this.rilContext.networkSelectionMode = msg.json.data.mode;
@@ -1653,16 +1685,19 @@ RILContentHelper.prototype = {
         this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
         break;
       case "RIL:GetCallBarringOption":
         this.handleGetCallBarringOption(msg.json);
         break;
       case "RIL:SetCallBarringOption":
         this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
         break;
+      case "RIL:ChangeCallBarringPassword":
+        this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
+        break;
       case "RIL:GetCallWaitingOption":
         this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
                                  msg.json.enabled);
         break;
       case "RIL:SetCallWaitingOption":
         this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
         break;
       case "RIL:CfStateChanged": {
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -104,16 +104,17 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES
   "RIL:SelectNetworkAuto",
   "RIL:SendMMI",
   "RIL:CancelMMI",
   "RIL:RegisterMobileConnectionMsg",
   "RIL:SetCallForwardingOption",
   "RIL:GetCallForwardingOption",
   "RIL:SetCallBarringOption",
   "RIL:GetCallBarringOption",
+  "RIL:ChangeCallBarringPassword",
   "RIL:SetCallWaitingOption",
   "RIL:GetCallWaitingOption",
   "RIL:SetCallingLineIdRestriction",
   "RIL:GetCallingLineIdRestriction",
   "RIL:SetRoamingPreference",
   "RIL:GetRoamingPreference",
   "RIL:ExitEmergencyCbMode",
   "RIL:SetVoicePrivacyMode",
@@ -1012,16 +1013,19 @@ RadioInterface.prototype = {
         this.workerMessenger.sendWithIPCMessage(msg, "queryCallForwardStatus");
         break;
       case "RIL:SetCallBarringOption":
         this.workerMessenger.sendWithIPCMessage(msg, "setCallBarring");
         break;
       case "RIL:GetCallBarringOption":
         this.workerMessenger.sendWithIPCMessage(msg, "queryCallBarringStatus");
         break;
+      case "RIL:ChangeCallBarringPassword":
+        this.workerMessenger.sendWithIPCMessage(msg, "changeCallBarringPassword");
+        break;
       case "RIL:SetCallWaitingOption":
         this.workerMessenger.sendWithIPCMessage(msg, "setCallWaiting");
         break;
       case "RIL:GetCallWaitingOption":
         this.workerMessenger.sendWithIPCMessage(msg, "queryCallWaiting");
         break;
       case "RIL:SetCallingLineIdRestriction":
         this.setCallingLineIdRestriction(msg.target, msg.json.data);
@@ -1095,16 +1099,19 @@ RadioInterface.prototype = {
         this.handleDataCallError(message);
         break;
       case "signalstrengthchange":
         this.handleSignalStrengthChange(message);
         break;
       case "operatorchange":
         this.handleOperatorChange(message);
         break;
+      case "otastatuschange":
+        this.handleOtaStatus(message);
+        break;
       case "radiostatechange":
         this.handleRadioStateChange(message);
         break;
       case "cardstatechange":
         this.rilContext.cardState = message.cardState;
         gMessageManager.sendIccMessage("RIL:CardStateChanged",
                                        this.clientId, message);
         break;
@@ -1452,16 +1459,28 @@ RadioInterface.prototype = {
       // If the data is unregistered, no need to send RIL:DataInfoChanged.
       if (data.network && !batch) {
         gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
                                                     this.clientId, data);
       }
     }
   },
 
+  handleOtaStatus: function handleOtaStatus(message) {
+    if (message.status < 0 ||
+        RIL.CDMA_OTA_PROVISION_STATUS_TO_GECKO.length <= message.status) {
+      return;
+    }
+
+    let status = RIL.CDMA_OTA_PROVISION_STATUS_TO_GECKO[message.status];
+
+    gMessageManager.sendMobileConnectionMessage("RIL:OtaStatusChanged",
+                                                this.clientId, status);
+  },
+
   handleRadioStateChange: function handleRadioStateChange(message) {
     this._changingRadioPower = false;
 
     let newState = message.radioState;
     if (this.rilContext.radioState == newState) {
       return;
     }
     this.rilContext.radioState = newState;
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -2809,10 +2809,43 @@ this.SUPP_SVC_NOTIFICATION_CODE2_RETRIEV
 
 this.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD    = "RemoteHeld";
 this.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED = "RemoteResumed";
 
 this.GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2 = {};
 GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD] = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD;
 GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED]   = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED;
 
+/**
+ * The status for an Over-the-Air Service Provisioning / Over-the-Air
+ * Parameter Administration (OTASP/OTAPA) session.
+ *
+ * @see 3GPP2 C.S0016
+ */
+this.GECKO_OTA_STATUS_SPL_UNLOCKED          = "spl_unlocked";
+this.GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED  = "spc_retries_exceeded";
+this.GECKO_OTA_STATUS_A_KEY_EXCHANGED       = "a_key_exchanged";
+this.GECKO_OTA_STATUS_SSD_UPDATED           = "ssd_updated";
+this.GECKO_OTA_STATUS_NAM_DOWNLOADED        = "nam_downloaded";
+this.GECKO_OTA_STATUS_MDN_DOWNLOADED        = "mdn_downloaded";
+this.GECKO_OTA_STATUS_IMSI_DOWNLOADED       = "imsi_downloaded";
+this.GECKO_OTA_STATUS_PRL_DOWNLOADED        = "prl_downloaded";
+this.GECKO_OTA_STATUS_COMMITTED             = "committed";
+this.GECKO_OTA_STATUS_OTAPA_STARTED         = "otapa_started";
+this.GECKO_OTA_STATUS_OTAPA_STOPPED         = "otapa_stopped";
+this.GECKO_OTA_STATUS_OTAPA_ABORTED         = "otapa_aborted";
+this.CDMA_OTA_PROVISION_STATUS_TO_GECKO = [
+  GECKO_OTA_STATUS_SPL_UNLOCKED,
+  GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED,
+  GECKO_OTA_STATUS_A_KEY_EXCHANGED,
+  GECKO_OTA_STATUS_SSD_UPDATED,
+  GECKO_OTA_STATUS_NAM_DOWNLOADED,
+  GECKO_OTA_STATUS_MDN_DOWNLOADED,
+  GECKO_OTA_STATUS_IMSI_DOWNLOADED,
+  GECKO_OTA_STATUS_PRL_DOWNLOADED,
+  GECKO_OTA_STATUS_COMMITTED,
+  GECKO_OTA_STATUS_OTAPA_STARTED,
+  GECKO_OTA_STATUS_OTAPA_STOPPED,
+  GECKO_OTA_STATUS_OTAPA_ABORTED
+];
+
 // Allow this file to be imported via Components.utils.import().
 this.EXPORTED_SYMBOLS = Object.keys(this);
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2323,16 +2323,35 @@ let RIL = {
    *        One of ICC_SERVICE_CLASS_* constants.
    */
   setCallBarring: function setCallBarring(options) {
     options.facility = CALL_BARRING_PROGRAM_TO_FACILITY[options.program];
     this.setICCFacilityLock(options);
   },
 
   /**
+   * Change call barring facility password.
+   *
+   * @param pin
+   *        Old password.
+   * @param newPin
+   *        New password.
+   */
+  changeCallBarringPassword: function changeCallBarringPassword(options) {
+    Buf.newParcel(REQUEST_CHANGE_BARRING_PASSWORD, options);
+    Buf.writeUint32(3);
+    // Set facility to ICC_CB_FACILITY_BA_ALL by following TS.22.030 clause
+    // 6.5.4 and Table B.1.
+    Buf.writeString(ICC_CB_FACILITY_BA_ALL);
+    Buf.writeString(options.pin);
+    Buf.writeString(options.newPin);
+    Buf.sendParcel();
+  },
+
+  /**
    * Handle STK CALL_SET_UP request.
    *
    * @param hasConfirmed
    *        Does use have confirmed the call requested from ICC?
    */
   stkHandleCallSetup: function stkHandleCallSetup(options) {
      Buf.newParcel(REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM);
      Buf.writeUint32(1);
@@ -5313,17 +5332,23 @@ RIL[REQUEST_SET_FACILITY_LOCK] = functio
         break;
       case MMI_PROCEDURE_DEACTIVATION:
         options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
         break;
     }
   }
   this.sendChromeMessage(options);
 };
-RIL[REQUEST_CHANGE_BARRING_PASSWORD] = null;
+RIL[REQUEST_CHANGE_BARRING_PASSWORD] =
+  function REQUEST_CHANGE_BARRING_PASSWORD(length, options) {
+  if (options.rilRequestError) {
+    options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
+  }
+  this.sendChromeMessage(options);
+};
 RIL[REQUEST_SIM_OPEN_CHANNEL] = function REQUEST_SIM_OPEN_CHANNEL(length, options) {
   if (options.rilRequestError) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
   options.channel = Buf.readUint32();
@@ -5995,17 +6020,21 @@ RIL[UNSOLICITED_CDMA_CALL_WAITING] = fun
   call.namePresentation    = Buf.readUint32();
   call.isPresent           = Buf.readUint32();
   call.signalType          = Buf.readUint32();
   call.alertPitch          = Buf.readUint32();
   call.signal              = Buf.readUint32();
   this.sendChromeMessage({rilMessageType: "cdmaCallWaiting",
                           number: call.number});
 };
-RIL[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = null;
+RIL[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITED_CDMA_OTA_PROVISION_STATUS() {
+  let status = Buf.readUint32List()[0];
+  this.sendChromeMessage({rilMessageType: "otastatuschange",
+                          status: status});
+};
 RIL[UNSOLICITED_CDMA_INFO_REC] = null;
 RIL[UNSOLICITED_OEM_HOOK_RAW] = null;
 RIL[UNSOLICITED_RINGBACK_TONE] = null;
 RIL[UNSOLICITED_RESEND_INCALL_MUTE] = null;
 RIL[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE] = function UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE() {
   this._handleChangedEmergencyCbMode(false);
 };
 RIL[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length) {
--- a/dom/system/gonk/systemlibs.js
+++ b/dom/system/gonk/systemlibs.js
@@ -204,17 +204,17 @@ this.libnetutils = (function () {
     let serverbuf = ctypes.char.array(4096)();
     let lease = ctypes.int();
     let vendorbuf = ctypes.char.array(4096)();
     let domainbuf = ctypes.char.array(4096)();
     let c_dhcp_do_request;
     let c_dhcp_do_request_renew;
 
     // also changed for 16 and 18
-    if (sdkVersion >= 18) {
+    if (sdkVersion >= 18) { // 18 == JB 4.3
       dnslistbuf[0] = dns1buf;
       dnslistbuf[1] = dns2buf;
       c_dhcp_do_request =
         library.declare("dhcp_do_request", ctypes.default_abi,
                         ctypes.int,       // return value
                         ctypes.char.ptr,  // ifname
                         ctypes.char.ptr,  // ipaddr
                         ctypes.char.ptr,  // gateway
@@ -231,30 +231,30 @@ this.libnetutils = (function () {
                         ctypes.char.ptr,  // ipaddr
                         ctypes.char.ptr,  // gateway
                         ctypes.int.ptr,   // prefixlen
                         ctypes.char.ptr.array(),  // dns
                         ctypes.char.ptr,  // server
                         ctypes.int.ptr,   // lease
                         ctypes.char.ptr,  // vendorinfo
                         ctypes.char.ptr); // domain
-    } else if (sdkVersion >= 16) {
+    } else if (sdkVersion >= 16) { // 16 == JB 4.1
       c_dhcp_do_request =
         library.declare("dhcp_do_request", ctypes.default_abi,
                         ctypes.int,       // return value
                         ctypes.char.ptr,  // ifname
                         ctypes.char.ptr,  // ipaddr
                         ctypes.char.ptr,  // gateway
                         ctypes.int.ptr,   // prefixlen
                         ctypes.char.ptr,  // dns1
                         ctypes.char.ptr,  // dns2
                         ctypes.char.ptr,  // server
                         ctypes.int.ptr,   // lease
                         ctypes.char.ptr); // vendorinfo
-    } else {
+    } else { // ICS
       c_dhcp_do_request =
         library.declare("dhcp_do_request", ctypes.default_abi,
                         ctypes.int,      // return value
                         ctypes.char.ptr, // ifname
                         ctypes.char.ptr, // ipaddr
                         ctypes.char.ptr, // gateway
                         ctypes.int.ptr,  // prefixlen
                         ctypes.char.ptr, // dns1
@@ -332,17 +332,17 @@ this.libnetutils = (function () {
       library.declare("ifc_reset_connections",
                       ctypes.default_abi,
                       ctypes.int,
                       ctypes.char.ptr,
                       ctypes.int);
     iface.ifc_reset_connections = function(ifname, reset_mask) {
       return c_ifc_reset_connections(ifname, reset_mask) | 0;
     }
-  } else {
+  } else { // version < 15 - we don't care anymore.
     let ints = ctypes.int.array(8)();
     let c_dhcp_do_request =
       library.declare("dhcp_do_request", ctypes.default_abi,
                       ctypes.int,      // return value
                       ctypes.char.ptr, // ifname
                       ctypes.int.ptr,  // ipaddr
                       ctypes.int.ptr,  // gateway
                       ctypes.int.ptr,  // mask
new file mode 100644
--- /dev/null
+++ b/dom/system/gonk/tests/test_ril_worker_barring_password.js
@@ -0,0 +1,87 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
+
+function run_test() {
+  run_next_test();
+}
+
+const PIN = "0000";
+const NEW_PIN = "1234";
+
+/**
+ * Helper function.
+ */
+function newUint8Worker() {
+  let worker = newWorker();
+  let index = 0; // index for read
+  let buf = [];
+
+  worker.Buf.writeUint8 = function (value) {
+    buf.push(value);
+  };
+
+  worker.Buf.readUint8 = function () {
+    return buf[index++];
+  };
+
+  worker.Buf.seekIncoming = function (offset) {
+    index += offset;
+  };
+
+  worker.debug = do_print;
+
+  return worker;
+}
+
+add_test(function test_change_call_barring_password() {
+  let worker = newUint8Worker();
+  let buf = worker.Buf;
+
+  function do_test(facility, pin, newPin) {
+    buf.sendParcel = function fakeSendParcel () {
+      // Request Type.
+      do_check_eq(this.readUint32(), REQUEST_CHANGE_BARRING_PASSWORD);
+
+      // Token : we don't care.
+      this.readUint32();
+
+      let parcel = this.readStringList();
+      do_check_eq(parcel.length, 3);
+      do_check_eq(parcel[0], facility);
+      do_check_eq(parcel[1], pin);
+      do_check_eq(parcel[2], newPin);
+    };
+
+    let options = {facility: facility, pin: pin, newPin: newPin};
+    worker.RIL.changeCallBarringPassword(options);
+  }
+
+  do_test(ICC_CB_FACILITY_BA_ALL, PIN, NEW_PIN);
+
+  run_next_test();
+});
+
+add_test(function test_check_change_call_barring_password_result() {
+  let barringPasswordOptions;
+  let worker = newWorker({
+    postMessage: function fakePostMessage(message) {
+      do_check_eq(barringPasswordOptions.pin, PIN);
+      do_check_eq(barringPasswordOptions.newPin, NEW_PIN);
+      do_check_eq(message.errorMsg, GECKO_ERROR_SUCCESS);
+    }
+  });
+
+  worker.RIL.changeCallBarringPassword =
+    function fakeChangeCallBarringPassword(options) {
+      barringPasswordOptions = options;
+      worker.RIL[REQUEST_CHANGE_BARRING_PASSWORD](0, {
+        rilRequestError: ERROR_SUCCESS
+      });
+    }
+
+  worker.RIL.changeCallBarringPassword({pin: PIN, newPin: NEW_PIN});
+
+  run_next_test();
+});
--- a/dom/system/gonk/tests/xpcshell.ini
+++ b/dom/system/gonk/tests/xpcshell.ini
@@ -12,8 +12,9 @@ tail =
 [test_ril_worker_ruim.js]
 [test_ril_worker_cw.js]
 [test_ril_worker_clir.js]
 [test_ril_worker_clip.js]
 [test_ril_worker_ssn.js]
 [test_ril_worker_voiceprivacy.js]
 [test_ril_worker_ecm.js]
 [test_ril_worker_stk.js]
+[test_ril_worker_barring_password.js]
--- a/dom/tests/mochitest/geolocation/geolocation_common.js
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -1,79 +1,59 @@
 
 function sleep(delay)
 {
     var start = Date.now();
     while (Date.now() < start + delay);
 }
 
-function force_prompt(allow) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setBoolPref("geo.prompt.testing", true);
-  prefs.setBoolPref("geo.prompt.testing.allow", allow);
+function force_prompt(allow, callback) {
+  SpecialPowers.pushPrefEnv({"set": [["geo.prompt.testing", true], ["geo.prompt.testing.allow", allow]]}, callback);
 }
 
-function reset_prompt() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setBoolPref("geo.prompt.testing", false);
-  prefs.setBoolPref("geo.prompt.testing.allow", false);
+function start_sending_garbage(callback)
+{
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=respond-garbage"]]}, function() {
+    // we need to be sure that all location data has been purged/set.
+    sleep(1000);
+    callback.call();
+  });
 }
 
-
-function start_sending_garbage()
+function stop_sending_garbage(callback)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=respond-garbage");
-
-  // we need to be sure that all location data has been purged/set.
-  sleep(1000);
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, function() {
+    // we need to be sure that all location data has been purged/set.
+    sleep(1000);
+    callback.call();
+  });
 }
 
-function stop_sending_garbage()
+function stop_geolocationProvider(callback)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
-
-  // we need to be sure that all location data has been purged/set.
-  sleep(1000);
-}
-
-function stop_geolocationProvider()
-{
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding");
-
-  // we need to be sure that all location data has been purged/set.
-  sleep(1000);
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding"]]}, function() {
+    // we need to be sure that all location data has been purged/set.
+    sleep(1000);
+    callback.call();
+  });
 }
 
-function worse_geolocationProvider()
+function worse_geolocationProvider(callback)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=worse-accuracy");
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=worse-accuracy"]]}, callback);
 }
 
-function resume_geolocationProvider()
+function resume_geolocationProvider(callback)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, callback);
 }
 
-function delay_geolocationProvider(delay)
+function delay_geolocationProvider(delay, callback)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay);
+  SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
 }
 
 function check_geolocation(location) {
 
   ok(location, "Check to see if this location is non-null");
 
   ok("timestamp" in location, "Check to see if there is a timestamp");
 
--- a/dom/tests/mochitest/geolocation/test_allowCurrent.html
+++ b/dom/tests/mochitest/geolocation/test_allowCurrent.html
@@ -15,24 +15,27 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
+
 
 function successCallback(position) {
   check_geolocation(position);
-  reset_prompt();
   SimpleTest.finish();
 }
 
-navigator.geolocation.getCurrentPosition(successCallback);
-
+function test1() {
+  navigator.geolocation.getCurrentPosition(successCallback);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_allowWatch.html
+++ b/dom/tests/mochitest/geolocation/test_allowWatch.html
@@ -15,27 +15,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var watchID;
 
 function successCallback(position) {
   check_geolocation(position);
   navigator.geolocation.clearWatch(watchID);
-  reset_prompt();
   SimpleTest.finish();
 }
 
-watchID = navigator.geolocation.watchPosition(successCallback, null, null);
-
+function test1() {
+  watchID = navigator.geolocation.watchPosition(successCallback, null, null);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_cachedPosition.html
+++ b/dom/tests/mochitest/geolocation/test_cachedPosition.html
@@ -16,23 +16,24 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
-resume_geolocationProvider();
-force_prompt(true);
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 function done() {
-  reset_prompt();
-  resume_geolocationProvider();
-  SimpleTest.finish();
+  resume_geolocationProvider(function() {
+    SimpleTest.finish();
+  });
 }
 
 function errorCallback(err) {
   ok(false, "error callback should not have been called");
   done();
 }
 
 function testCachedPosition() {
@@ -40,42 +41,43 @@ function testCachedPosition() {
   navigator.geolocation.getCurrentPosition(function(pos) {
     // get cached position
     cached = pos;
 
     navigator.geolocation.getCurrentPosition(function(pos) {
       // force use of cached position, make sure
       // it's equal to what we have
       is(pos, cached, "position should be equal to cached position");
-      resume_geolocationProvider();
-
-      navigator.geolocation.getCurrentPosition(function(pos) {
-        // force new position, can't be the one we have
-        isnot(pos, cached, "new position should be different from the cached");
-        done();
-      }, errorCallback, {maximumAge: 0});
+      resume_geolocationProvider(function() {
+        navigator.geolocation.getCurrentPosition(function(pos) {
+          // force new position, can't be the one we have
+          isnot(pos, cached, "new position should be different from the cached");
+          done();
+        }, errorCallback, {maximumAge: 0});
+      });
     }, errorCallback, {maximumAge: 21600000});
   }, errorCallback, {maximumAge: 21600000});
 }
 
 // ensure we have a position in cache,
 // and stop receiving new positions once we do so the
 // cache doesn't change
 var watchID;
-watchID = navigator.geolocation.watchPosition(
-  function(pos) {
-    info("Stopping geolocation provider");
-    stop_geolocationProvider();
-  }, function(err) {
-    is(err.code, err.TIMEOUT, "got TIMEOUT for watchPosition");
+function test1() {
+  watchID = navigator.geolocation.watchPosition(
+    function(pos) {
+      info("Stopping geolocation provider");
+      stop_geolocationProvider(function() {});
+    }, function(err) {
+      is(err.code, err.TIMEOUT, "got TIMEOUT for watchPosition");
 
-    // no new positions in a while,
-    // the cache should be stable now.
-    navigator.geolocation.clearWatch(watchID);
-    testCachedPosition();
-  }, {maximumAge: 0, timeout: 1000}
-);
-
+      // no new positions in a while,
+      // the cache should be stable now.
+      navigator.geolocation.clearWatch(watchID);
+      testCachedPosition();
+    }, {maximumAge: 0, timeout: 1000}
+  );
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_cancelCurrent.html
+++ b/dom/tests/mochitest/geolocation/test_cancelCurrent.html
@@ -15,30 +15,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(false);
+
+resume_geolocationProvider(function() {
+  force_prompt(false, test1);
+});
 
 function failureCallback(error) {
   ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function successCallback(position){
   ok(0, "Success was called when it shouldn't have been.  major problem");
-  reset_prompt();
   SimpleTest.finish();
 }
 
-navigator.geolocation.getCurrentPosition(successCallback, failureCallback, null);
-
+function test1() {
+  navigator.geolocation.getCurrentPosition(successCallback, failureCallback, null);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_cancelWatch.html
+++ b/dom/tests/mochitest/geolocation/test_cancelWatch.html
@@ -15,34 +15,35 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(false);
+
+resume_geolocationProvider(function() {
+  force_prompt(false, test1);
+});
 
 var watchID;
 
 function failureCallback(error) {
   ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function successCallback(position){
   ok(0, "Success was called when it shouldn't have been.  major problem");
-  reset_prompt();
   SimpleTest.finish();
 }
 
-watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
-
+function test1() {
+  watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
+}
 </script>
 </pre>
 </body>
 </html>
 
 
 
--- a/dom/tests/mochitest/geolocation/test_clearWatch.html
+++ b/dom/tests/mochitest/geolocation/test_clearWatch.html
@@ -15,18 +15,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true)
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var hasBeenCleared = false;
 var successWasCalledAfterClear = false;
 var firstCallback = true;
 
 function failureCallback(error)
 {
   ok(0, "we should not be seeing failures from this watchPosition");
@@ -51,21 +53,20 @@ function clearWatch() {
   hasBeenCleared = true;
   SimpleTest.executeSoon(testAccepted);
 }
 
 function testAccepted() {
   ok(true, "testAccepted was called, hasBeenCleared=" + hasBeenCleared +
            ", successWasCalledAfterClear=" + successWasCalledAfterClear);
   ok(!successWasCalledAfterClear, "The successCallback should not be called after clear");
-  reset_prompt();
   SimpleTest.finish();
 }
 
-
-ok(true, "Getting the watchPosition");
-watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
-ok(true, "Waiting");
-
+function test1() {
+  ok(true, "Getting the watchPosition");
+  watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
+  ok(true, "Waiting");
+}
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_clearWatch_invalid.html
+++ b/dom/tests/mochitest/geolocation/test_clearWatch_invalid.html
@@ -13,28 +13,35 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463039">Mozilla Bug 463039</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-resume_geolocationProvider();
-force_prompt(true);
-navigator.geolocation.watchPosition(function(){});
+SimpleTest.waitForExplicitFinish();
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
-// there are no watches, so this should always throw
-for (x=-10; x<10; x++) {
+function test1() {
+  navigator.geolocation.watchPosition(function(){});
+
+  // there are no watches, so this should always throw
+  for (x=-10; x<10; x++) {
     navigator.geolocation.clearWatch(x);
     ok(1, "clearWatch should not throw");
-}
+  }
 
-// lets try something huge
-navigator.geolocation.clearWatch(Number.MAX_VALUE);
-ok(1, "clearWatch should not throw");
-reset_prompt();
+  // lets try something huge
+  navigator.geolocation.clearWatch(Number.MAX_VALUE);
+  ok(1, "clearWatch should not throw");
+
+  SimpleTest.finish();
+}
     
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_garbageWatch.html
+++ b/dom/tests/mochitest/geolocation/test_garbageWatch.html
@@ -16,41 +16,41 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 /** Test for Bug  **/
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
 
-start_sending_garbage();
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
+
+function test1() {
+  start_sending_garbage(test2);
+}
 
 function successCallback(pos){
   ok(false, "success should have never been called.");
-  stop_sending_garbage();
-  reset_prompt();
-  SimpleTest.finish();
+  stop_sending_garbage(function() {SimpleTest.finish();});
 }
 
 function errorCallback(err) {
   ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
-  stop_sending_garbage();
-  reset_prompt();
-  SimpleTest.finish();
+  stop_sending_garbage(function() { SimpleTest.finish(); });
 }
 
-
 var options = {
     maximumAge: 0,
     timeout: 1000,
 };
 
-navigator.geolocation.watchPosition(successCallback,
-                                    errorCallback,
-                                    options);
-
+function test2() {
+  navigator.geolocation.watchPosition(successCallback,
+                                      errorCallback,
+                                      options);
+}
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html
+++ b/dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html
@@ -15,41 +15,44 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var successCallbackCalled = 0;
 var failureCallbackCalled = 0;
 const totalResults = 100;
 
 function successCallback(position) {
   successCallbackCalled++;
   testPassed();
 }
 
 function failureCallback(code) {
   failureCallbackCalled++;
   testPassed();
 }
 
-for (var x = 0; x < totalResults; x++)
-  navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
+function test1() {
+  for (var x = 0; x < totalResults; x++)
+    navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
+}
 
 function testPassed() {
   if (successCallbackCalled + failureCallbackCalled != totalResults)
     return;
   is(failureCallbackCalled, 0, "no failure callbacks should have been received");
-  reset_prompt();
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyCurrentSerial.html
+++ b/dom/tests/mochitest/geolocation/test_manyCurrentSerial.html
@@ -16,31 +16,32 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
-resume_geolocationProvider();
-force_prompt(true)
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var keepGoing = 10;
 
 function successCallback(position) {
   if (keepGoing-- > 0) {
     setTimeout(function() {navigator.geolocation.getCurrentPosition(successCallback);}, 0);
     return; 
   }
 
   ok(1, "100 successful calls");
-  reset_prompt();
   SimpleTest.finish();
 }
 
-navigator.geolocation.getCurrentPosition(successCallback);
-
+function test1() {
+  navigator.geolocation.getCurrentPosition(successCallback);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyWatchConcurrent.html
+++ b/dom/tests/mochitest/geolocation/test_manyWatchConcurrent.html
@@ -15,40 +15,43 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var successCallbackCalled = 0;
 var failureCallbackCalled = 0;
 const totalResults = 100;
 
 function successCallback(position) {
   successCallbackCalled++;
   testPassed();
 }
 
 function failureCallback(code) {
   failureCallbackCalled++;
   testPassed();
 }
 
-for (var x = 0; x < totalResults; x++)
-  navigator.geolocation.watchPosition(successCallback, failureCallback);
+function test1() {
+  for (var x = 0; x < totalResults; x++)
+    navigator.geolocation.watchPosition(successCallback, failureCallback);
+}
 
 function testPassed() {
   if (successCallbackCalled + failureCallbackCalled != totalResults)
     return;
   is(failureCallbackCalled, 0, "no failure callbacks should have been received");
-  reset_prompt();
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_manyWatchSerial.html
+++ b/dom/tests/mochitest/geolocation/test_manyWatchSerial.html
@@ -15,38 +15,40 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var watchID = 0;
 var completeCount = 10;
 
 
 function successCallback(position) {
 
   navigator.geolocation.clearWatch(watchID);
 
   completeCount--;
 
   if (completeCount==0) {
     ok(1, "all watchPosition successCallbacks called");
-    reset_prompt();
     SimpleTest.finish();
     return;
   }
 
   watchID = navigator.geolocation.watchPosition(successCallback);
 }
 
-watchID = navigator.geolocation.watchPosition(successCallback);
-
+function test1() {
+  watchID = navigator.geolocation.watchPosition(successCallback);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyWindows.html
+++ b/dom/tests/mochitest/geolocation/test_manyWindows.html
@@ -16,50 +16,52 @@ href="https://bugzilla.mozilla.org/show_
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 // ensure we are using the right testing provider
-resume_geolocationProvider();
-force_prompt(true);
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 /** Test for Bug  **/
 
 var numberOfWindows = 5;  // 20 seems to be the default max popups during the mochitest run
 var loadedWindows = 0;
 
 var windows = new Array(numberOfWindows);
 
 addEventListener("message", function() {
   ++loadedWindows;
   if (loadedWindows == numberOfWindows) {
     SimpleTest.executeSoon(closeWindows);
   }
 }, false);
 
-for(var i = 0; i < numberOfWindows; i++) {
-  windows[i] = window.open("geolocation.html", "_blank", "width=700,height=400");
+function test1() {
+  for(var i = 0; i < numberOfWindows; i++) {
+    windows[i] = window.open("geolocation.html", "_blank", "width=700,height=400");
+  }
 }
 
 function closeWindows()
 {
   for(var i = 0; i < numberOfWindows; i++) {
     windows[i].close();
   }
   SimpleTest.waitForFocus(done);
 }
 
 SimpleTest.waitForExplicitFinish();
 
 function done()
 {
   ok(navigator.geolocation, "Opened a bunch of windows and didn't crash.");
-  reset_prompt();
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_mozsettings.html
+++ b/dom/tests/mochitest/geolocation/test_mozsettings.html
@@ -15,35 +15,41 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 if (SpecialPowers.isMainProcess()) {
   SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
 }
 
-SpecialPowers.addPermission("settings-read", true, document);
-SpecialPowers.addPermission("settings-write", true, document);
+function test1() {
+  //This pushPermissions call is after pushPrefEnv call and pushPrefEnv calls follow after this
+  SpecialPowers.pushPermissions([{'type': 'settings-read', 'allow': true, 'context': document}, {'type': 'settings-write', 'allow': true, 'context': document}], test2);
+}
 
-ok(navigator.geolocation, "get geolocation object");
+function test2() {
+  ok(navigator.geolocation, "get geolocation object");
 
-toggleGeolocationSetting(false, function() {
-    ok(true, "turned off geolocation via mozSettings");
-    setTimeout(function() {
-	navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOff,
-                                                 failureCallbackAfterMozsettingOff);
-      }, 500); // need to wait a bit for all of these async callbacks to finish
+  toggleGeolocationSetting(false, function() {
+      ok(true, "turned off geolocation via mozSettings");
+      setTimeout(function() {
+	  navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOff,
+                                                   failureCallbackAfterMozsettingOff);
+        }, 500); // need to wait a bit for all of these async callbacks to finish
   });
+}
 
 function successCallbackAfterMozsettingOff(position) {
   ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
 
   toggleGeolocationSetting(true, function() {
       ok(true, "turned on geolocation via mozSettings");
       setTimeout(function() {
          navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOn,
@@ -61,25 +67,21 @@ function failureCallbackAfterMozsettingO
          navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOn,
                                                   failureCallbackAfterMozsettingOn);
         }, 500); // need to wait a bit for all of these async callbacks to finish
     });
 }
 
 function successCallbackAfterMozsettingOn(position) {
   ok(true, "Geolocation worked after setting geolocation.enabled to true.");
-
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function failureCallbackAfterMozsettingOn(error) {
   ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
-
-  reset_prompt();
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_mozsettingsWatch.html
+++ b/dom/tests/mochitest/geolocation/test_mozsettingsWatch.html
@@ -15,36 +15,42 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 if (SpecialPowers.isMainProcess()) {
   SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
 }
 
-SpecialPowers.addPermission("settings-read", true, document);
-SpecialPowers.addPermission("settings-write", true, document);
-
-ok(navigator.geolocation, "get geolocation object");
+function test1() {
+  //This pushPermissions call is after pushPrefEnv call and pushPrefEnv calls follow after this
+  SpecialPowers.pushPermissions([{'type': 'settings-read', 'allow': true, 'context': document}, {'type': 'settings-write', 'allow': true, 'context': document}], test2);
+}
 
 var watchId;
-toggleGeolocationSetting(false, function() {
-    ok(true, "turned off geolocation via mozSettings");
-    setTimeout(function() {
-	 watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOff,
-                                                       failureCallbackAfterMozsettingOff);
+function test2() {
+  ok(navigator.geolocation, "get geolocation object");
+
+  toggleGeolocationSetting(false, function() {
+      ok(true, "turned off geolocation via mozSettings");
+      setTimeout(function() {
+	      watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOff,
+                                                           failureCallbackAfterMozsettingOff);
       }, 500); // need to wait a bit for all of these async callbacks to finish
   });
+}
 
 function successCallbackAfterMozsettingOff(position) {
   ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
 
   navigator.geolocation.clearWatch(watchId);
   toggleGeolocationSetting(true, function() {
       ok(true, "turned on geolocation via mozSettings");
       setTimeout(function() {
@@ -66,25 +72,23 @@ function failureCallbackAfterMozsettingO
         }, 500); // need to wait a bit for all of these async callbacks to finish
     });
 }
 
 function successCallbackAfterMozsettingOn(position) {
   ok(true, "Geolocation worked after setting geolocation.enabled to true.");
 
   navigator.geolocation.clearWatch(watchId);
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function failureCallbackAfterMozsettingOn(error) {
   ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
 
   navigator.geolocation.clearWatch(watchId);
-  reset_prompt();
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_optional_api_params.html
+++ b/dom/tests/mochitest/geolocation/test_optional_api_params.html
@@ -13,87 +13,90 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452566">Mozilla Bug 452566</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
+SimpleTest.waitForExplicitFinish();
+
 // ensure we are using the right testing provider
-resume_geolocationProvider();
-force_prompt(true)
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 /** Test for Bug 452566 **/
-
-ok(navigator.geolocation, "Should have geolocation");
+function test1() {
+  ok(navigator.geolocation, "Should have geolocation");
 
-var exception = null;
-try {
-  navigator.geolocation.getCurrentPosition();
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(exception, "Should have got an exception");
+  var exception = null;
+  try {
+    navigator.geolocation.getCurrentPosition();
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(exception, "Should have got an exception");
 
-exception = null;
-try {
-  navigator.geolocation.getCurrentPosition(function() {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(!exception, exception);
+  exception = null;
+  try {
+    navigator.geolocation.getCurrentPosition(function() {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
 
-exception = null;
-try {
-  navigator.geolocation.getCurrentPosition(function() {}, function() {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(!exception, exception);
+  exception = null;
+  try {
+    navigator.geolocation.getCurrentPosition(function() {}, function() {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
 
-exception = null;
-try {
-  navigator.geolocation.getCurrentPosition(function() {}, function() {}, {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(!exception, exception);
+  exception = null;
+  try {
+    navigator.geolocation.getCurrentPosition(function() {}, function() {}, {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
 
-exception = null;
-try {
-  navigator.geolocation.watchPosition();
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(exception, "Should have got an exception");
+  exception = null;
+  try {
+    navigator.geolocation.watchPosition();
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(exception, "Should have got an exception");
 
-exception = null;
-try {
-  navigator.geolocation.watchPosition(function() {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(!exception, exception);
+  exception = null;
+  try {
+    navigator.geolocation.watchPosition(function() {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
 
-exception = null;
-try {
-  navigator.geolocation.watchPosition(function() {}, function() {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
-}
-ok(!exception, exception);
+  exception = null;
+  try {
+    navigator.geolocation.watchPosition(function() {}, function() {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
 
-exception = null;
-try {
-  navigator.geolocation.watchPosition(function() {}, function() {}, {});
-} catch(ex if ex instanceof TypeError) {
-  exception = ex;
+  exception = null;
+  try {
+    navigator.geolocation.watchPosition(function() {}, function() {}, {});
+  } catch(ex if ex instanceof TypeError) {
+    exception = ex;
+  }
+  ok(!exception, exception);
+
+  SimpleTest.finish();
 }
-ok(!exception, exception);
-
-// so clean up ready for the next test.
-reset_prompt();
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_shutdown.html
+++ b/dom/tests/mochitest/geolocation/test_shutdown.html
@@ -16,39 +16,44 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
-resume_geolocationProvider();
-force_prompt(true);
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 function successCallback(position) {
   check_geolocation(position);
 
   SpecialPowers.pushPrefEnv({'set': [['geo.timeout', 100]]}, function() {
-      delay_geolocationProvider(1000);
-      force_prompt(true);
-      navigator.geolocation.getCurrentPosition(success2, handle_error, {maximumAge: 0});
+      delay_geolocationProvider(1000, function() {
+        force_prompt(true, function() {
+          navigator.geolocation.getCurrentPosition(success2, handle_error, {maximumAge: 0});
+        });
+      });
+
   });
 }
 
 function errorCallback() {
   ok(false, "unexpected error");
   SimpleTest.finish();
 }
 
-navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
+function test1() {
+  navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
+}
 
 function success2(position) {
   check_geolocation(position);
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function handle_error() {
   ok(false, "geolocation provider should not have timed out");
   SimpleTest.finish();
 }
 </script>
--- a/dom/tests/mochitest/geolocation/test_timeoutWatch.html
+++ b/dom/tests/mochitest/geolocation/test_timeoutWatch.html
@@ -16,45 +16,50 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 /** Test for Bug  **/
 
 // ensure we are using the right testing provider
-resume_geolocationProvider();
-force_prompt(true);
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 SimpleTest.waitForExplicitFinish();
 
-stop_geolocationProvider();
+function test1() {
+  stop_geolocationProvider(test2);
+}
 
 function successCallback(pos){
   ok(false, "success should have never been called.");
-  resume_geolocationProvider();
-  reset_prompt()
-  SimpleTest.finish();
+  resume_geolocationProvider(function() {
+    SimpleTest.finish();
+  });
 }
 
 function errorCallback(err) {
   if (err.code == err.POSITION_UNAVAILABLE)
     ok(false, "nothing is hooked up to test against.");
   else
     ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
-  resume_geolocationProvider();
-  reset_prompt()
-  SimpleTest.finish();
+  resume_geolocationProvider(function() {
+    SimpleTest.finish();
+  });
 }
 
 
 var options = {
     maximumAge: 0,
     timeout: 10
 };
 
-navigator.geolocation.watchPosition(successCallback,
-                                    errorCallback,
-                                    options);
+function test2() {
+  navigator.geolocation.watchPosition(successCallback,
+                                      errorCallback,
+                                      options);
+}
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_timerRestartWatch.html
+++ b/dom/tests/mochitest/geolocation/test_timerRestartWatch.html
@@ -17,45 +17,47 @@ https://bugzilla.mozilla.org/show_bug.cg
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
 // ensure we are using the right testing provider
-resume_geolocationProvider();
-force_prompt(true);
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 var watchID;
 var times = 0;
 
 function errorCallback(err) {
   ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
   times++;
 
   // make sure we got at least 3 times errorCallback
   if (times >= 3) {
     navigator.geolocation.clearWatch(watchID);
-    resume_geolocationProvider();
-    reset_prompt();
-    SimpleTest.finish();
+    resume_geolocationProvider(function() {
+      SimpleTest.finish();
+    });
   }
 }
 
 function successCallback(position) {
   // Now that we got a success callback, lets try to ensure
   // that we get a timeout error.
-  stop_geolocationProvider();
+  stop_geolocationProvider(function() {});
 }
 
 var options = {
     maximumAge: 0,
     timeout: 1000
 };
 
-watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
-
+function test1() {
+  watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_windowClose.html
+++ b/dom/tests/mochitest/geolocation/test_windowClose.html
@@ -17,21 +17,20 @@ https://bugzilla.mozilla.org/show_bug.cg
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function done() {
   ok(1, "no crash, so pass.");
   SimpleTest.finish();
-  reset_prompt();
 }
 
 SimpleTest.waitForExplicitFinish();
-force_prompt(true);
-
-window.open("windowTest.html");
+force_prompt(true, function() {
+  window.open("windowTest.html");
+});
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html
+++ b/dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html
@@ -15,30 +15,33 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
-resume_geolocationProvider();
-force_prompt(true);
+
+resume_geolocationProvider(function() {
+  force_prompt(true, test1);
+});
 
 function successCallback2(position) {
   check_geolocation(position);
-  reset_prompt();
   SimpleTest.finish();
 }
 
 function successCallback1(position) {
   check_geolocation(position);
-  worse_geolocationProvider();
-  navigator.geolocation.getCurrentPosition(successCallback2, null, { maximumAge: 0 });
+  worse_geolocationProvider(function() {
+    navigator.geolocation.getCurrentPosition(successCallback2, null, { maximumAge: 0 });
+  });
 }
 
-navigator.geolocation.getCurrentPosition(successCallback1, null, { maximumAge: 0 });
-
+function test1() {
+  navigator.geolocation.getCurrentPosition(successCallback1, null, { maximumAge: 0 });
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/webidl/DummyBinding.webidl
+++ b/dom/webidl/DummyBinding.webidl
@@ -18,13 +18,15 @@ interface DummyInterface {
   void funcDNSCacheDict(optional DNSCacheDict arg);
   void funcDNSLookupDict(optional DNSLookupDict arg);
   void funcConnStatusDict(optional ConnStatusDict arg);
   void frameRequestCallback(FrameRequestCallback arg);
   void MmsParameters(optional MmsParameters arg);
   void MmsAttachment(optional MmsAttachment arg);
   void AsyncScrollEventDetail(optional AsyncScrollEventDetail arg);
   void OpenWindowEventDetail(optional OpenWindowEventDetail arg);
+  void WifiOptions(optional WifiCommandOptions arg1,
+                   optional WifiResultOptions arg2);
 };
 
 interface DummyInterfaceWorkers {
   BlobPropertyBag blobBag();
 };
--- a/dom/webidl/InputMethod.webidl
+++ b/dom/webidl/InputMethod.webidl
@@ -53,41 +53,36 @@ interface MozInputMethodManager {
 
 // The input context, which consists of attributes and information of current input field.
 // It also hosts the methods available to the keyboard app to mutate the input field represented.
 // An "input context" gets void when the app is no longer allowed to interact with the text field,
 // e.g., the text field does no longer exist, the app is being switched to background, and etc.
 [JSImplementation="@mozilla.org/b2g-inputcontext;1"]
 interface MozInputContext: EventTarget {
    // The tag name of input field, which is enum of "input", "textarea", or "contenteditable"
-   readonly attribute DOMString type;
-
+   readonly attribute DOMString? type;
    // The type of the input field, which is enum of text, number, password, url, search, email, and so on.
    // See http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute
-   readonly attribute DOMString inputType;
-
+   readonly attribute DOMString? inputType;
    /*
     * The inputmode string, representing the input mode.
     * See http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#input-modalities:-the-inputmode-attribute
     */
-   readonly attribute DOMString inputMode;
-
+   readonly attribute DOMString? inputMode;
    /*
     * The primary language for the input field.
     * It is the value of HTMLElement.lang.
     * See http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#htmlelement
     */
-   readonly attribute DOMString lang;
-
+   readonly attribute DOMString? lang;
    /*
     * Get the whole text content of the input field.
     * @return DOMString
     */
    Promise getText(optional long offset, optional long length);
-
    // The start and stop position of the selection.
    readonly attribute long selectionStart;
    readonly attribute long selectionEnd;
 
     /*
      * Set the selection range of the the editable text.
      * Note: This method cannot be used to move the cursor during composition. Calling this
      * method will cancel composition.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MozOtaStatusEvent.webidl
@@ -0,0 +1,33 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+[Constructor(DOMString type, optional MozOtaStatusEventInit eventInitDict),
+ HeaderFile="GeneratedEventClasses.h"]
+interface MozOtaStatusEvent : Event
+{
+  /**
+   * One of the following values:
+   *
+   * spl_unlocked
+   * spc_retries_exceeded
+   * a_key_exchanged
+   * ssd_updated
+   * nam_downloaded
+   * mdn_downloaded
+   * imsi_downloaded
+   * prl_downloaded
+   * committed
+   * otapa_started
+   * otapa_stopped
+   * otapa_aborted
+   */
+  readonly attribute DOMString status;
+};
+
+dictionary MozOtaStatusEventInit : EventInit
+{
+  DOMString status = "";
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -379,16 +379,17 @@ webidl_files = \
   URLUtilsReadOnly.webidl \
   ValidityState.webidl \
   VideoPlaybackQuality.webidl \
   VideoStreamTrack.webidl \
   WaveShaperNode.webidl \
   WebComponents.webidl \
   WebSocket.webidl \
   WheelEvent.webidl \
+  WifiOptions.webidl \
   Window.webidl \
   WorkerLocation.webidl \
   WorkerNavigator.webidl \
   XMLDocument.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   XMLSerializer.webidl \
@@ -493,16 +494,17 @@ ifdef MOZ_B2G_RIL
 webidl_files += \
   CallEvent.webidl \
   CFStateChangeEvent.webidl \
   DataErrorEvent.webidl \
   IccCardLockErrorEvent.webidl \
   MozCellBroadcast.webidl \
   MozCellBroadcastEvent.webidl \
   MozEmergencyCbModeEvent.webidl \
+  MozOtaStatusEvent.webidl \
   MozVoicemailEvent.webidl \
   MozWifiConnectionInfoEvent.webidl \
   MozWifiStatusChangeEvent.webidl \
   USSDReceivedEvent.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_GAMEPAD
new file mode 100644
--- /dev/null
+++ b/dom/webidl/WifiOptions.webidl
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+  * This dictionnary holds the parameters sent to the wifi service.
+  */
+dictionary WifiCommandOptions
+{
+  long      id = 0;       // opaque id.
+  DOMString cmd = "";     // the command name.
+  DOMString request;      // for "command"
+  DOMString ifname;       // for "ifc_reset_connections", "ifc_enable",
+                          // "ifc_disable", "ifc_remove_host_routes",
+                          // "ifc_remove_default_route", "dhcp_stop",
+                          // "dhcp_release_lease", "ifc_get_default_route",
+                          // "ifc_add_host_route", "ifc_set_default_route",
+                          // "ifc_configure", "dhcp_do_request",
+                          // "dhcp_do_request_renew".
+  long route;             // for "ifc_add_host_route", "ifc_set_default_route".
+  long ipaddr;            // for "ifc_configure".
+  long mask;              // for "ifc_configure".
+  long gateway;           // for "ifc_configure".
+  long dns1;              // for "ifc_configure".
+  long dns2;              // for "ifc_configure".
+  DOMString key;          // for "property_get", "property_set".
+  DOMString value;        // for "property_set".
+  DOMString defaultValue; // for "property_get".
+};
+
+/**
+  * This dictionnary holds the parameters sent back to WifiWorker.js
+  */
+dictionary WifiResultOptions
+{
+  long      id = 0;             // opaque id.
+  long      status = 0;         // the return status of the command.
+                                // Used by most commands.
+  DOMString reply = "";         // for "command".
+  DOMString route = "";         // for "ifc_get_default_route".
+  DOMString error = "";         // for "dhcp_get_errmsg".
+  DOMString value = "";         // for "property_get".
+  DOMString ipaddr_str = "";    // The following are for the result of
+                                // dhcp_do_request.
+  DOMString gateway_str = "";
+  DOMString broadcast_str = "";
+  DOMString dns1_str = "";
+  DOMString dns2_str = "";
+  DOMString mask_str = "";
+  DOMString server_str = "";
+  DOMString vendor_str = "";
+  long      lease = 0;
+  long      mask = 0;
+  long      ipaddr = 0;
+  long      gateway = 0;
+  long      dns1 = 0;
+  long      dns2 = 0;
+  long      server = 0;
+};
--- a/dom/wifi/Makefile.in
+++ b/dom/wifi/Makefile.in
@@ -5,13 +5,15 @@
 DEPTH            = @DEPTH@
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME     = domwifi_s
+EXPORT_LIBRARY   = 1
+
 include $(topsrcdir)/dom/dom-config.mk
 
 include $(topsrcdir)/config/rules.mk
 
 
new file mode 100644
--- /dev/null
+++ b/dom/wifi/NetUtils.cpp
@@ -0,0 +1,139 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "NetUtils.h"
+#include <dlfcn.h>
+#include <errno.h>
+#include <cutils/properties.h>
+#include "prinit.h"
+#include "mozilla/Assertions.h"
+#include "nsDebug.h"
+
+static void* sNetUtilsLib;
+static PRCallOnceType sInitNetUtilsLib;
+
+static PRStatus
+InitNetUtilsLib()
+{
+  sNetUtilsLib = dlopen("/system/lib/libnetutils.so", RTLD_LAZY);
+  // We might fail to open the hardware lib. That's OK.
+  return PR_SUCCESS;
+}
+
+static void*
+GetNetUtilsLibHandle()
+{
+  PR_CallOnce(&sInitNetUtilsLib, InitNetUtilsLib);
+  return sNetUtilsLib;
+}
+
+// static
+void*
+NetUtils::GetSharedLibrary()
+{
+  void* netLib = GetNetUtilsLibHandle();
+  if (!netLib) {
+    NS_WARNING("No /system/lib/libnetutils.so");
+  }
+  return netLib;
+}
+
+// static
+int32_t
+NetUtils::SdkVersion()
+{
+  char propVersion[PROPERTY_VALUE_MAX];
+  property_get("ro.build.version.sdk", propVersion, "0");
+  int32_t version = strtol(propVersion, nullptr, 10);
+  return version;
+}
+
+DEFINE_DLFUNC(ifc_enable, int32_t, const char*)
+DEFINE_DLFUNC(ifc_disable, int32_t, const char*)
+DEFINE_DLFUNC(ifc_configure, int32_t, const char*, in_addr_t, uint32_t,
+              in_addr_t, in_addr_t, in_addr_t)
+DEFINE_DLFUNC(ifc_reset_connections, int32_t, const char*, const int32_t)
+DEFINE_DLFUNC(dhcp_stop, int32_t, const char*)
+
+int32_t NetUtils::do_ifc_enable(const char *ifname)
+{
+  USE_DLFUNC(ifc_enable)
+  return ifc_enable(ifname);
+}
+
+int32_t NetUtils::do_ifc_disable(const char *ifname)
+{
+  USE_DLFUNC(ifc_disable)
+  return ifc_disable(ifname);
+}
+
+int32_t NetUtils::do_ifc_configure(const char *ifname,
+                                       in_addr_t address,
+                                       uint32_t prefixLength,
+                                       in_addr_t gateway,
+                                       in_addr_t dns1,
+                                       in_addr_t dns2)
+{
+  USE_DLFUNC(ifc_configure)
+  int32_t ret = ifc_configure(ifname, address, prefixLength, gateway, dns1, dns2);
+  return ret;
+}
+
+int32_t NetUtils::do_ifc_reset_connections(const char *ifname,
+                                               const int32_t resetMask)
+{
+  USE_DLFUNC(ifc_reset_connections)
+  return ifc_reset_connections(ifname, resetMask);
+}
+
+int32_t NetUtils::do_dhcp_stop(const char *ifname)
+{
+  USE_DLFUNC(dhcp_stop)
+  return dhcp_stop(ifname);
+}
+
+int32_t NetUtils::do_dhcp_do_request(const char *ifname,
+                                         char *ipaddr,
+                                         char *gateway,
+                                         uint32_t *prefixLength,
+                                         char *dns1,
+                                         char *dns2,
+                                         char *server,
+                                         uint32_t  *lease,
+                                         char* vendorinfo)
+{
+  int32_t ret = -1;
+  uint32_t sdkVersion = SdkVersion();
+
+  if (sdkVersion == 15) {
+    // ICS
+    // http://androidxref.com/4.0.4/xref/system/core/libnetutils/dhcp_utils.c#149
+    DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*,  uint32_t*, char*, char*, char*, uint32_t*)
+    USE_DLFUNC(dhcp_do_request)
+    vendorinfo[0] = '\0';
+
+    ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2,
+                          server, lease);
+  } else if (sdkVersion == 16 || sdkVersion == 17) {
+    // JB 4.1 and 4.2
+    // http://androidxref.com/4.1.2/xref/system/core/libnetutils/dhcp_utils.c#175
+    // http://androidxref.com/4.2.2_r1/xref/system/core/include/netutils/dhcp.h#26
+    DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*,  uint32_t*, char*, char*, char*, uint32_t*, char*)
+    USE_DLFUNC(dhcp_do_request)
+    ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2,
+                          server, lease, vendorinfo);
+  } else if (sdkVersion == 18) {
+    // JB 4.3
+    // http://androidxref.com/4.3_r2.1/xref/system/core/libnetutils/dhcp_utils.c#181
+    DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*,  uint32_t*, char**, char*, uint32_t*, char*, char*)
+    USE_DLFUNC(dhcp_do_request)
+    char *dns[3] = {dns1, dns2, NULL};
+    char domains[PROPERTY_VALUE_MAX];
+    ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns,
+                          server, lease, vendorinfo, domains);
+  } else {
+    NS_WARNING("Unable to perform do_dhcp_request: unsupported sdk version!");
+  }
+  return ret;
+}
new file mode 100644
--- /dev/null
+++ b/dom/wifi/NetUtils.h
@@ -0,0 +1,60 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Abstraction on top of the network support from libnetutils that we
+ * use to set up network connections.
+ */
+
+#ifndef NetUtils_h
+#define NetUtils_h
+
+#include "arpa/inet.h"
+
+// Copied from ifc.h
+#define RESET_IPV4_ADDRESSES 0x01
+#define RESET_IPV6_ADDRESSES 0x02
+#define RESET_ALL_ADDRESSES  (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES)
+
+// Implements netutils functions. No need for an abstract class here since we
+// only have a one sdk specific method (dhcp_do_request)
+class NetUtils
+{
+public:
+  static void* GetSharedLibrary();
+
+  int32_t do_ifc_enable(const char *ifname);
+  int32_t do_ifc_disable(const char *ifname);
+  int32_t do_ifc_configure(const char *ifname,
+                           in_addr_t address,
+                           uint32_t prefixLength,
+                           in_addr_t gateway,
+                           in_addr_t dns1,
+                           in_addr_t dns2);
+  int32_t do_ifc_reset_connections(const char *ifname, const int32_t resetMask);
+  int32_t do_dhcp_stop(const char *ifname);
+  int32_t do_dhcp_do_request(const char *ifname,
+                             char *ipaddr,
+                             char *gateway,
+                             uint32_t *prefixLength,
+                             char *dns1,
+                             char *dns2,
+                             char *server,
+                             uint32_t  *lease,
+                             char* vendorinfo);
+
+  static int32_t SdkVersion();
+};
+
+// Defines a function type with the right arguments and return type.
+#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args);
+
+// Set up a dlsymed function ready to use.
+#define USE_DLFUNC(name)                                                      \
+  FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name);            \
+  if (!name) {                                                                \
+    MOZ_ASSERT("Symbol not found in shared library : " #name);                \
+  }
+
+#endif // NetUtils_h
new file mode 100644
--- /dev/null
+++ b/dom/wifi/WifiProxyService.cpp
@@ -0,0 +1,286 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WifiProxyService.h"
+#include "nsServiceManagerUtils.h"
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "nsXULAppAPI.h"
+#include "WifiUtils.h"
+#include "jsapi.h"
+#include "nsCxPusher.h"
+
+#define NS_WIFIPROXYSERVICE_CID \
+  { 0xc6c9be7e, 0x744f, 0x4222, {0xb2, 0x03, 0xcd, 0x55, 0xdf, 0xc8, 0xbc, 0x12} }
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+namespace mozilla {
+
+// The singleton Wifi service, to be used on the main thread.
+StaticRefPtr<WifiProxyService> gWifiProxyService;
+
+// The singleton supplicant class, that can be used on any thread.
+static nsAutoPtr<WpaSupplicant> gWpaSupplicant;
+
+// Runnable used dispatch the WaitForEvent result on the main thread.
+class WifiEventDispatcher : public nsRunnable
+{
+public:
+  WifiEventDispatcher(nsAString& aEvent): mEvent(aEvent)
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+  }
+
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    gWifiProxyService->DispatchWifiEvent(mEvent);
+    return NS_OK;
+  }
+
+private:
+  nsString mEvent;
+};
+
+// Runnable used to call WaitForEvent on the event thread.
+class EventRunnable : public nsRunnable
+{
+public:
+  EventRunnable()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+    nsAutoString event;
+    gWpaSupplicant->WaitForEvent(event);
+    if (!event.IsEmpty()) {
+      nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event);
+      NS_DispatchToMainThread(runnable);
+    }
+    return NS_OK;
+  }
+};
+
+// Runnable used dispatch the Command result on the main thread.
+class WifiResultDispatcher : public nsRunnable
+{
+public:
+  WifiResultDispatcher(WifiResultOptions& aResult)
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+
+    // XXX: is there a better way to copy webidl dictionnaries?
+    // the copy constructor is private.
+#define COPY_FIELD(prop) mResult.prop = aResult.prop;
+
+    COPY_FIELD(mId)
+    COPY_FIELD(mStatus)
+    COPY_FIELD(mReply)
+    COPY_FIELD(mRoute)
+    COPY_FIELD(mError)
+    COPY_FIELD(mValue)
+    COPY_FIELD(mIpaddr_str)
+    COPY_FIELD(mGateway_str)
+    COPY_FIELD(mBroadcast_str)
+    COPY_FIELD(mDns1_str)
+    COPY_FIELD(mDns2_str)
+    COPY_FIELD(mMask_str)
+    COPY_FIELD(mServer_str)
+    COPY_FIELD(mVendor_str)
+    COPY_FIELD(mLease)
+    COPY_FIELD(mMask)
+    COPY_FIELD(mIpaddr)
+    COPY_FIELD(mGateway)
+    COPY_FIELD(mDns1)
+    COPY_FIELD(mDns2)
+    COPY_FIELD(mServer)
+
+#undef COPY_FIELD
+  }
+
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    gWifiProxyService->DispatchWifiResult(mResult);
+    return NS_OK;
+  }
+
+private:
+  WifiResultOptions mResult;
+};
+
+// Runnable used to call SendCommand on the control thread.
+class ControlRunnable : public nsRunnable
+{
+public:
+  ControlRunnable(CommandOptions aOptions) : mOptions(aOptions) {
+    MOZ_ASSERT(!NS_IsMainThread());
+  }
+
+  NS_IMETHOD Run()
+  {
+    WifiResultOptions result;
+    if (gWpaSupplicant->ExecuteCommand(mOptions, result)) {
+      nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result);
+      NS_DispatchToMainThread(runnable);
+    }
+    return NS_OK;
+  }
+private:
+   CommandOptions mOptions;
+};
+
+NS_IMPL_ISUPPORTS1(WifiProxyService, nsIWifiProxyService)
+
+WifiProxyService::WifiProxyService()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!gWifiProxyService);
+}
+
+WifiProxyService::~WifiProxyService()
+{
+  MOZ_ASSERT(!gWifiProxyService);
+}
+
+already_AddRefed<WifiProxyService>
+WifiProxyService::FactoryCreate()
+{
+  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    return nullptr;
+  }
+
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!gWifiProxyService) {
+    gWifiProxyService = new WifiProxyService();
+    ClearOnShutdown(&gWifiProxyService);
+
+    gWpaSupplicant = new WpaSupplicant();
+    ClearOnShutdown(&gWpaSupplicant);
+  }
+
+  nsRefPtr<WifiProxyService> service = gWifiProxyService.get();
+  return service.forget();
+}
+
+NS_IMETHODIMP
+WifiProxyService::Start(nsIWifiEventListener* aListener)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aListener);
+
+  nsresult rv = NS_NewThread(getter_AddRefs(mEventThread));
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Can't create wifi event thread");
+    return NS_ERROR_FAILURE;
+  }
+
+  rv = NS_NewThread(getter_AddRefs(mControlThread));
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Can't create wifi control thread");
+    // Shutdown the event thread.
+    mEventThread->Shutdown();
+    mEventThread = nullptr;
+    return NS_ERROR_FAILURE;
+  }
+
+  mListener = aListener;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WifiProxyService::Shutdown()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  mEventThread->Shutdown();
+  mEventThread = nullptr;
+  mControlThread->Shutdown();
+  mControlThread = nullptr;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WifiProxyService::SendCommand(const JS::Value& aOptions, JSContext* aCx)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  WifiCommandOptions options;
+
+  if (!options.Init(aCx,
+                    JS::Handle<JS::Value>::fromMarkedLocation(&aOptions))) {
+    NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand");
+    return NS_ERROR_FAILURE;
+  }
+
+  // Dispatch the command to the control thread.
+  CommandOptions commandOptions(options);
+  nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions);
+  mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WifiProxyService::WaitForEvent()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  nsCOMPtr<nsIRunnable> runnable = new EventRunnable();
+  mEventThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+  return NS_OK;
+}
+
+void
+WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  mozilla::AutoSafeJSContext cx;
+  JS::RootedValue val(cx);
+
+  if (!aOptions.ToObject(cx, JS::NullPtr(), &val)) {
+    return;
+  }
+
+  // Call the listener with a JS value.
+  mListener->OnCommand(val);
+}
+
+void
+WifiProxyService::DispatchWifiEvent(const nsAString& aEvent)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  // Call the listener.
+  mListener->OnWaitEvent(aEvent);
+}
+
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiProxyService,
+                                         WifiProxyService::FactoryCreate)
+
+NS_DEFINE_NAMED_CID(NS_WIFIPROXYSERVICE_CID);
+
+static const mozilla::Module::CIDEntry kWifiProxyServiceCIDs[] = {
+  { &kNS_WIFIPROXYSERVICE_CID, false, nullptr, WifiProxyServiceConstructor },
+  { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kWifiProxyServiceContracts[] = {
+  { "@mozilla.org/wifi/service;1", &kNS_WIFIPROXYSERVICE_CID },
+  { nullptr }
+};
+
+static const mozilla::Module kWifiProxyServiceModule = {
+  mozilla::Module::kVersion,
+  kWifiProxyServiceCIDs,
+  kWifiProxyServiceContracts,
+  nullptr
+};
+
+} // namespace mozilla
+
+NSMODULE_DEFN(WifiProxyServiceModule) = &kWifiProxyServiceModule;
new file mode 100644
--- /dev/null
+++ b/dom/wifi/WifiProxyService.h
@@ -0,0 +1,38 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WifiProxyService_h
+#define WifiProxyService_h
+
+#include "nsIWifiService.h"
+#include "nsCOMPtr.h"
+#include "nsThread.h"
+#include "mozilla/dom/WifiOptionsBinding.h"
+
+namespace mozilla {
+
+class WifiProxyService MOZ_FINAL : public nsIWifiProxyService
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIWIFIPROXYSERVICE
+
+  static already_AddRefed<WifiProxyService>
+  FactoryCreate();
+
+  void DispatchWifiEvent(const nsAString& aEvent);
+  void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions);
+
+private:
+  WifiProxyService();
+  ~WifiProxyService();
+
+  nsCOMPtr<nsIThread> mEventThread;
+  nsCOMPtr<nsIThread> mControlThread;
+  nsCOMPtr<nsIWifiEventListener> mListener;
+};
+
+} // namespace mozilla
+
+#endif // WifiProxyService_h
new file mode 100644
--- /dev/null
+++ b/dom/wifi/WifiUtils.cpp
@@ -0,0 +1,382 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WifiUtils.h"
+#include <dlfcn.h>
+#include <errno.h>
+#include "prinit.h"
+#include "js/CharacterEncoding.h"
+#include "NetUtils.h"
+
+using namespace mozilla::dom;
+
+#define BUFFER_SIZE        4096
+#define PROPERTY_VALUE_MAX 80
+
+// Intentionally not trying to dlclose() this handle. That's playing
+// Russian roulette with security bugs.
+static void* sWifiLib;
+static PRCallOnceType sInitWifiLib;
+
+static PRStatus
+InitWifiLib()
+{
+  sWifiLib = dlopen("/system/lib/libhardware_legacy.so", RTLD_LAZY);
+  // We might fail to open the hardware lib. That's OK.
+  return PR_SUCCESS;
+}
+
+static void*
+GetSharedLibrary()
+{
+  PR_CallOnce(&sInitWifiLib, InitWifiLib);
+  return sWifiLib;
+}
+
+// This is the same algorithm as in InflateUTF8StringToBuffer with Copy and
+// while ignoring invalids.
+// https://mxr.mozilla.org/mozilla-central/source/js/src/vm/CharacterEncoding.cpp#231
+
+static const uint32_t REPLACE_UTF8 = 0xFFFD;
+
+void LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aOut)
+{
+  JS::UTF8Chars src(aInput, aLength);
+
+  PRUnichar dst[aLength]; // Allocating for worst case.
+
+  // First, count how many jschars need to be in the inflated string.
+  // |i| is the index into |src|, and |j| is the the index into |dst|.
+  size_t srclen = src.length();
+  uint32_t j = 0;
+  for (uint32_t i = 0; i < srclen; i++, j++) {
+    uint32_t v = uint32_t(src[i]);
+    if (!(v & 0x80)) {
+      // ASCII code unit.  Simple copy.
+      dst[j] = PRUnichar(v);
+    } else {
+      // Non-ASCII code unit.  Determine its length in bytes (n).
+      uint32_t n = 1;
+      while (v & (0x80 >> n))
+        n++;
+
+  #define INVALID(report, arg, n2)                          \
+      do {                                                  \
+        n = n2;                                             \
+        goto invalidMultiByteCodeUnit;                      \
+      } while (0)
+
+      // Check the leading byte.
+      if (n < 2 || n > 4)
+        INVALID(ReportInvalidCharacter, i, 1);
+
+      // Check that |src| is large enough to hold an n-byte code unit.
+      if (i + n > srclen)
+        INVALID(ReportBufferTooSmall, /* dummy = */ 0, 1);
+
+      // Check the second byte.  From Unicode Standard v6.2, Table 3-7
+      // Well-Formed UTF-8 Byte Sequences.
+      if ((v == 0xE0 && ((uint8_t)src[i + 1] & 0xE0) != 0xA0) ||  // E0 A0~BF
+        (v == 0xED && ((uint8_t)src[i + 1] & 0xE0) != 0x80) ||  // ED 80~9F
+        (v == 0xF0 && ((uint8_t)src[i + 1] & 0xF0) == 0x80) ||  // F0 90~BF
+        (v == 0xF4 && ((uint8_t)src[i + 1] & 0xF0) != 0x80))    // F4 80~8F
+      {
+        INVALID(ReportInvalidCharacter, i, 1);
+      }
+
+      // Check the continuation bytes.
+      for (uint32_t m = 1; m < n; m++)
+        if ((src[i + m] & 0xC0) != 0x80)
+          INVALID(ReportInvalidCharacter, i, m);
+
+      // Determine the code unit's length in jschars and act accordingly.
+      v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n);
+      if (v < 0x10000) {
+        // The n-byte UTF8 code unit will fit in a single jschar.
+        dst[j] = jschar(v);
+      } else {
+        v -= 0x10000;
+        if (v <= 0xFFFFF) {
+          // The n-byte UTF8 code unit will fit in two jschars.
+          dst[j] = jschar((v >> 10) + 0xD800);
+          j++;
+          dst[j] = jschar((v & 0x3FF) + 0xDC00);
+        } else {
+          // The n-byte UTF8 code unit won't fit in two jschars.
+          INVALID(ReportTooBigCharacter, v, 1);
+        }
+      }
+
+    invalidMultiByteCodeUnit:
+      // Move i to the last byte of the multi-byte code unit;  the loop
+      // header will do the final i++ to move to the start of the next
+      // code unit.
+      i += n - 1;
+    }
+  }
+
+  dst[j] = 0;
+  aOut = dst;
+}
+
+// Helper to check we have loaded the hardware shared library.
+#define CHECK_HWLIB(ret)                                                      \
+  void* hwLib = GetSharedLibrary();                                           \
+  if (!hwLib) {                                                               \
+    NS_WARNING("No /system/lib/libhardware_legacy.so");                       \
+    return ret;                                                               \
+  }
+
+#define DEFAULT_IMPL(name, ret, args...) \
+  DEFINE_DLFUNC(name, ret, args...)      \
+  ret do_##name(args) {                  \
+    USE_DLFUNC(name)                     \
+    return name(args);                   \
+  }
+
+// ICS implementation.
+class ICSWpaSupplicantImpl : public WpaSupplicantImpl
+{
+public:
+  DEFAULT_IMPL(wifi_load_driver, int32_t, )
+  DEFAULT_IMPL(wifi_unload_driver, int32_t, )
+  DEFAULT_IMPL(wifi_stop_supplicant, int32_t, )
+
+  DEFINE_DLFUNC(wifi_wait_for_event, int32_t, char*, size_t)
+  int32_t do_wifi_wait_for_event(const char *iface, char *buf, size_t len) {
+    USE_DLFUNC(wifi_wait_for_event)
+    return wifi_wait_for_event(buf, len);
+  }
+
+  DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*)
+  int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) {
+    USE_DLFUNC(wifi_command)
+    return wifi_command(cmd, buf, len);
+  }
+
+  DEFINE_DLFUNC(wifi_start_supplicant, int32_t, )
+  int32_t do_wifi_start_supplicant(int32_t) {
+    USE_DLFUNC(wifi_start_supplicant)
+    return wifi_start_supplicant();
+  }
+
+  DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, )
+  int32_t do_wifi_connect_to_supplicant(const char* iface) {
+    USE_DLFUNC(wifi_connect_to_supplicant)
+    return wifi_connect_to_supplicant();
+  }
+
+  DEFINE_DLFUNC(wifi_close_supplicant_connection, void, )
+  void do_wifi_close_supplicant_connection(const char* iface) {
+    USE_DLFUNC(wifi_close_supplicant_connection)
+    return wifi_close_supplicant_connection();
+  }
+};
+
+// JB implementation.
+// We only redefine the methods that have a different signature than on ICS.
+class JBWpaSupplicantImpl : public ICSWpaSupplicantImpl
+{
+public:
+  DEFINE_DLFUNC(wifi_wait_for_event, int32_t, const char*, char*, size_t)
+  int32_t do_wifi_wait_for_event(const char* iface, char* buf, size_t len) {
+    USE_DLFUNC(wifi_wait_for_event)
+    return wifi_wait_for_event(iface, buf, len);
+  }
+
+  DEFINE_DLFUNC(wifi_command, int32_t, const char*, const char*, char*, size_t*)
+  int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) {
+    USE_DLFUNC(wifi_command)
+    return wifi_command(iface, cmd, buf, len);
+  }
+
+  DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t)
+  int32_t do_wifi_start_supplicant(int32_t arg) {
+    USE_DLFUNC(wifi_start_supplicant)
+    return wifi_start_supplicant(arg);
+  }
+
+  DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, const char*)
+  int32_t do_wifi_connect_to_supplicant(const char* iface) {
+    USE_DLFUNC(wifi_connect_to_supplicant)
+    return wifi_connect_to_supplicant(iface);
+  }
+
+  DEFINE_DLFUNC(wifi_close_supplicant_connection, void, const char*)
+  void do_wifi_close_supplicant_connection(const char* iface) {
+    USE_DLFUNC(wifi_close_supplicant_connection)
+    wifi_close_supplicant_connection(iface);
+  }
+};
+
+// Concrete class to use to access the wpa supplicant.
+WpaSupplicant::WpaSupplicant()
+{
+  if (NetUtils::SdkVersion() < 16) {
+    mImpl = new ICSWpaSupplicantImpl();
+  } else {
+    mImpl = new JBWpaSupplicantImpl();
+  }
+  mNetUtils = new NetUtils();
+};
+
+void WpaSupplicant::WaitForEvent(nsAString& aEvent)
+{
+  CHECK_HWLIB()
+
+  char buffer[BUFFER_SIZE];
+  int32_t ret = mImpl->do_wifi_wait_for_event("wlan0", buffer, BUFFER_SIZE);
+  CheckBuffer(buffer, ret, aEvent);
+}
+
+#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get()
+
+/**
+ * Make a subnet mask.
+ */
+uint32_t WpaSupplicant::MakeMask(uint32_t len) {
+  uint32_t mask = 0;
+  for (uint32_t i = 0; i < len; ++i) {
+    mask |= (0x80000000 >> i);
+  }
+  return ntohl(mask);
+}
+
+bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
+                                   WifiResultOptions& aResult)
+{
+  CHECK_HWLIB(false)
+  if (!mNetUtils->GetSharedLibrary()) {
+    return false;
+  }
+
+  // Always correlate the opaque ids.
+  aResult.mId = aOptions.mId;
+
+  if (aOptions.mCmd.EqualsLiteral("command")) {
+    size_t len = BUFFER_SIZE - 1;
+    char buffer[BUFFER_SIZE];
+    NS_ConvertUTF16toUTF8 request(aOptions.mRequest);
+    aResult.mStatus = mImpl->do_wifi_command("wlan0", request.get(), buffer, &len);
+    nsString value;
+    if (aResult.mStatus == 0) {
+      if (buffer[len - 1] == '\n') { // remove trailing new lines.
+        len--;
+      }
+      buffer[len] = '\0';
+      CheckBuffer(buffer, len, value);
+    }
+    aResult.mReply = value;
+  } else if (aOptions.mCmd.EqualsLiteral("close_supplicant_connection")) {
+    mImpl->do_wifi_close_supplicant_connection("wlan0");
+  } else if (aOptions.mCmd.EqualsLiteral("load_driver")) {
+    aResult.mStatus = mImpl->do_wifi_load_driver();
+  } else if (aOptions.mCmd.EqualsLiteral("unload_driver")) {
+    aResult.mStatus = mImpl->do_wifi_unload_driver();
+  } else if (aOptions.mCmd.EqualsLiteral("start_supplicant")) {
+    aResult.mStatus = mImpl->do_wifi_start_supplicant(0);
+  } else if (aOptions.mCmd.EqualsLiteral("stop_supplicant")) {
+    aResult.mStatus = mImpl->do_wifi_stop_supplicant();
+  } else if (aOptions.mCmd.EqualsLiteral("connect_to_supplicant")) {
+    aResult.mStatus = mImpl->do_wifi_connect_to_supplicant("wlan0");
+  } else if (aOptions.mCmd.EqualsLiteral("ifc_enable")) {
+    aResult.mStatus = mNetUtils->do_ifc_enable(GET_CHAR(mIfname));
+  } else if (aOptions.mCmd.EqualsLiteral("ifc_disable")) {
+    aResult.mStatus = mNetUtils->do_ifc_disable(GET_CHAR(mIfname));
+  } else if (aOptions.mCmd.EqualsLiteral("ifc_configure")) {
+    aResult.mStatus = mNetUtils->do_ifc_configure(
+      GET_CHAR(mIfname), aOptions.mIpaddr, aOptions.mMask,
+      aOptions.mGateway, aOptions.mDns1, aOptions.mDns2
+    );
+  } else if (aOptions.mCmd.EqualsLiteral("ifc_reset_connections")) {
+    aResult.mStatus = mNetUtils->do_ifc_reset_connections(
+      GET_CHAR(mIfname), RESET_ALL_ADDRESSES
+    );
+  } else if (aOptions.mCmd.EqualsLiteral("dhcp_stop")) {
+    aResult.mStatus = mNetUtils->do_dhcp_stop(GET_CHAR(mIfname));
+  } else if (aOptions.mCmd.EqualsLiteral("dhcp_do_request")) {
+    char ipaddr[PROPERTY_VALUE_MAX];
+    char gateway[PROPERTY_VALUE_MAX];
+    uint32_t prefixLength;
+    char dns1[PROPERTY_VALUE_MAX];
+    char dns2[PROPERTY_VALUE_MAX];
+    char server[PROPERTY_VALUE_MAX];
+    uint32_t lease;
+    char vendorinfo[PROPERTY_VALUE_MAX];
+    aResult.mStatus =
+      mNetUtils->do_dhcp_do_request(GET_CHAR(mIfname),
+                                    ipaddr,
+                                    gateway,
+                                    &prefixLength,
+                                    dns1,
+                                    dns2,
+                                    server,
+                                    &lease,
+                                    vendorinfo);
+
+    if (aResult.mStatus == -1) {
+      // Early return since we failed.
+      return true;
+    }
+
+    aResult.mIpaddr_str = NS_ConvertUTF8toUTF16(ipaddr);
+    aResult.mGateway_str = NS_ConvertUTF8toUTF16(gateway);
+    aResult.mDns1_str = NS_ConvertUTF8toUTF16(dns1);
+    aResult.mDns2_str = NS_ConvertUTF8toUTF16(dns2);
+    aResult.mServer_str = NS_ConvertUTF8toUTF16(server);
+    aResult.mVendor_str = NS_ConvertUTF8toUTF16(vendorinfo);
+    aResult.mLease = lease;
+    aResult.mMask = MakeMask(prefixLength);
+
+    uint32_t inet4; // only support IPv4 for now.
+
+#define INET_PTON(var, field)                                                 \
+  PR_BEGIN_MACRO                                                              \
+    inet_pton(AF_INET, var, &inet4);                                          \
+    aResult.field = inet4;                                                    \
+  PR_END_MACRO
+
+    INET_PTON(ipaddr, mIpaddr);
+    INET_PTON(gateway, mGateway);
+
+    if (dns1[0] != '\0') {
+      INET_PTON(dns1, mDns1);
+    }
+
+    if (dns2[0] != '\0') {
+      INET_PTON(dns2, mDns2);
+    }
+
+    INET_PTON(server, mServer);
+
+    //aResult.mask_str = netHelpers.ipToString(obj.mask);
+    char inet_str[64];
+    if (inet_ntop(AF_INET, &aResult.mMask, inet_str, sizeof(inet_str))) {
+      aResult.mMask_str = NS_ConvertUTF8toUTF16(inet_str);
+    }
+
+    uint32_t broadcast = (aResult.mIpaddr & aResult.mMask) + ~aResult.mMask;
+    if (inet_ntop(AF_INET, &broadcast, inet_str, sizeof(inet_str))) {
+      aResult.mBroadcast_str = NS_ConvertUTF8toUTF16(inet_str);
+    }
+  } else {
+    NS_WARNING("WpaSupplicant::ExecuteCommand : Unknown command");
+    printf_stderr("WpaSupplicant::ExecuteCommand : Unknown command: %s",
+      NS_ConvertUTF16toUTF8(aOptions.mCmd).get());
+    return false;
+  }
+
+  return true;
+}
+
+// Checks the buffer and do the utf processing.
+void
+WpaSupplicant::CheckBuffer(char* buffer, int32_t length,
+                           nsAString& aEvent)
+{
+  if (length > 0 && length < BUFFER_SIZE) {
+    buffer[length] = 0;
+    LossyConvertUTF8toUTF16(buffer, length, aEvent);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/dom/wifi/WifiUtils.h
@@ -0,0 +1,133 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Abstraction on top of the wifi support from libhardware_legacy that we
+ * use to talk to the wpa_supplicant.
+ */
+
+#ifndef WifiUtils_h
+#define WifiUtils_h
+
+#include "nsString.h"
+#include "nsAutoPtr.h"
+#include "mozilla/dom/WifiOptionsBinding.h"
+#include "NetUtils.h"
+#include "nsCxPusher.h"
+
+// Needed to add a copy constructor to WifiCommandOptions.
+struct CommandOptions
+{
+public:
+  CommandOptions(const CommandOptions& aOther) {
+    mId = aOther.mId;
+    mCmd = aOther.mCmd;
+    mRequest = aOther.mRequest;
+    mIfname = aOther.mIfname;
+    mRoute = aOther.mRoute;
+    mIpaddr = aOther.mIpaddr;
+    mMask = aOther.mMask;
+    mGateway = aOther.mGateway;
+    mDns1 = aOther.mDns1;
+    mDns2 = aOther.mDns2;
+    mKey = aOther.mKey;
+    mValue = aOther.mValue;
+    mDefaultValue = aOther.mDefaultValue;
+  }
+
+  CommandOptions(const mozilla::dom::WifiCommandOptions& aOther) {
+
+#define COPY_OPT_FIELD(prop, defaultValue)            \
+    if (aOther.prop.WasPassed()) {                    \
+      prop = aOther.prop.Value();                     \
+    } else {                                          \
+      prop = defaultValue;                            \
+    }
+
+#define COPY_FIELD(prop) prop = aOther.prop;
+    COPY_FIELD(mId)
+    COPY_FIELD(mCmd)
+    COPY_OPT_FIELD(mRequest, EmptyString())
+    COPY_OPT_FIELD(mIfname, EmptyString())
+    COPY_OPT_FIELD(mIpaddr, 0)
+    COPY_OPT_FIELD(mRoute, 0)
+    COPY_OPT_FIELD(mMask, 0)
+    COPY_OPT_FIELD(mGateway, 0)
+    COPY_OPT_FIELD(mDns1, 0)
+    COPY_OPT_FIELD(mDns2, 0)
+    COPY_OPT_FIELD(mKey, EmptyString())
+    COPY_OPT_FIELD(mValue, EmptyString())
+    COPY_OPT_FIELD(mDefaultValue, EmptyString())
+
+#undef COPY_OPT_FIELD
+#undef COPY_FIELD
+  }
+
+  // All the fields, not Optional<> anymore to get copy constructors.
+  nsString mCmd;
+  nsString mDefaultValue;
+  int32_t mDns1;
+  int32_t mDns2;
+  int32_t mGateway;
+  int32_t mId;
+  nsString mIfname;
+  int32_t mIpaddr;
+  nsString mKey;
+  int32_t mMask;
+  nsString mRequest;
+  int32_t mRoute;
+  nsString mValue;
+};
+
+// Abstract class that exposes libhardware_legacy functions we need for
+// wifi management.
+// We use the ICS signatures here since they are likely more future-proof.
+class WpaSupplicantImpl
+{
+public:
+  virtual int32_t
+  do_wifi_wait_for_event(const char *iface, char *buf, size_t len) = 0; // ICS != JB
+
+  virtual int32_t
+  do_wifi_command(const char* iface, const char* cmd, char* buff, size_t* len) = 0; // ICS != JB
+
+  virtual int32_t
+  do_wifi_load_driver() = 0;
+
+  virtual int32_t
+  do_wifi_unload_driver() = 0;
+
+  virtual int32_t
+  do_wifi_start_supplicant(int32_t) = 0; // ICS != JB
+
+  virtual int32_t
+  do_wifi_stop_supplicant() = 0;
+
+  virtual int32_t
+  do_wifi_connect_to_supplicant(const char* iface) = 0; // ICS != JB
+
+  virtual void
+  do_wifi_close_supplicant_connection(const char* iface) = 0; // ICS != JB
+};
+
+// Concrete class to use to access the wpa supplicant.
+class WpaSupplicant MOZ_FINAL
+{
+public:
+  WpaSupplicant();
+
+  void WaitForEvent(nsAString& aEvent);
+  bool ExecuteCommand(CommandOptions aOptions,
+                      mozilla::dom::WifiResultOptions& result);
+
+private:
+  nsAutoPtr<WpaSupplicantImpl> mImpl;
+  nsAutoPtr<NetUtils> mNetUtils;
+
+protected:
+  void CheckBuffer(char* buffer, int32_t length, nsAString& aEvent);
+  uint32_t MakeMask(uint32_t len);
+};
+
+#endif // WifiUtils_h
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -100,81 +100,72 @@ var WifiManager = (function() {
       schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true,
       driverDelay: libcutils.property_get("ro.moz.wifi.driverDelay"),
       ifname: libcutils.property_get("wifi.interface")
     };
   }
 
   let {sdkVersion, unloadDriverEnabled, schedScanRecovery, driverDelay, ifname} = getStartupPrefs();
 
-  var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
-  var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
+  let wifiListener = {
+    onWaitEvent: function(event) {
+      if (handleEvent(event)) {
+        waitForEvent();
+      }
+    },
+
+    onCommand: function(event) {
+      onmessageresult(event);
+    }
+  }
+
+  let wifiService = Cc["@mozilla.org/wifi/service;1"];
+  if (wifiService) {
+    wifiService = wifiService.getService(Ci.nsIWifiProxyService);
+    wifiService.start(wifiListener);
+  } else {
+    debug("No wifi service component available!");
+  }
 
   var manager = {};
   manager.ifname = ifname;
   // Emulator build runs to here.
   // The debug() should only be used after WifiManager.
   if (!ifname) {
     manager.ifname = DEFAULT_WLAN_INTERFACE;
   }
   manager.schedScanRecovery = schedScanRecovery;
   manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT;
 
-  // Callbacks to invoke when a reply arrives from the controlWorker.
+  // Callbacks to invoke when a reply arrives from the wifi service.
   var controlCallbacks = Object.create(null);
   var idgen = 0;
 
   function controlMessage(obj, callback) {
     var id = idgen++;
     obj.id = id;
     if (callback)
       controlCallbacks[id] = callback;
-    controlWorker.postMessage(obj);
+    wifiService.sendCommand(obj);
   }
 
-  function onerror(e) {
-    // It is very important to call preventDefault on the event here.
-    // If an exception is thrown on the worker, it bubbles out to the
-    // component that created it. If that component doesn't have an
-    // onerror handler, the worker will try to call the error reporter
-    // on the context it was created on. However, That doesn't work
-    // for component contexts and can result in crashes. This onerror
-    // handler has to make sure that it calls preventDefault on the
-    // incoming event.
-    e.preventDefault();
-
-    var worker = (this === controlWorker) ? "control" : "event";
-
-    debug("Got an error from the " + worker + " worker: " + e.filename +
-          ":" + e.lineno + ": " + e.message + "\n");
-  }
-
-  controlWorker.onerror = onerror;
-  eventWorker.onerror = onerror;
-
-  controlWorker.onmessage = function(e) {
-    var data = e.data;
+  let onmessageresult = function(data) {
     var id = data.id;
     var callback = controlCallbacks[id];
     if (callback) {
       callback(data);
       delete controlCallbacks[id];
     }
-  };
+  }
 
   // Polling the status worker
   var recvErrors = 0;
-  eventWorker.onmessage = function(e) {
-    // Process the event and tell the event worker to listen for more events.
-    if (handleEvent(e.data.event))
-      waitForEvent();
-  };
 
   function waitForEvent() {
-    eventWorker.postMessage({ cmd: "wait_for_event" });
+    wifiService.waitForEvent();
   }
 
   // Commands to the control worker.
 
   function voidControlMessage(cmd, callback) {
     controlMessage({ cmd: cmd }, function (data) {
       callback(data.status);
     });
@@ -590,26 +581,27 @@ var WifiManager = (function() {
   function clearBlacklistCommand(callback) {
     doBooleanCommand("BLACKLIST clear", "OK", callback);
   }
 
   function setSuspendOptimizationsCommand(enabled, callback) {
     doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), "OK", callback);
   }
 
-  function getProperty(key, defaultValue, callback) {
-    controlMessage({ cmd: "property_get", key: key, defaultValue: defaultValue }, function(data) {
-      callback(data.status < 0 ? null : data.value);
-    });
-  }
-
+  // Wrapper around libcutils.property_set that returns true if setting the
+  // value was successful.
+  // Note that the callback is not called asynchronously.
   function setProperty(key, value, callback) {
-    controlMessage({ cmd: "property_set", key: key, value: value }, function(data) {
-      callback(!data.status);
-    });
+    let ok = true;
+    try {
+      libcutils.property_set(key, value);
+    } catch(e) {
+      ok = false;
+    }
+    callback(ok);
   }
 
   function enableInterface(ifname, callback) {
     controlMessage({ cmd: "ifc_enable", ifname: ifname }, function(data) {
       callback(!data.status);
     });
   }
 
@@ -773,19 +765,20 @@ var WifiManager = (function() {
 
   function getDhcpError(callback) {
     controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
       callback(data.error);
     });
   }
 
   function configureInterface(ifname, ipaddr, mask, gateway, dns1, dns2, callback) {
-    controlMessage({ cmd: "ifc_configure", ifname: ifname,
+    let message = { cmd: "ifc_configure", ifname: ifname,
                      ipaddr: ipaddr, mask: mask, gateway: gateway,
-                     dns1: dns1, dns2: dns2}, function(data) {
+                     dns1: dns1, dns2: dns2};
+    controlMessage(message, function(data) {
       callback(!data.status);
     });
   }
 
   function runDhcpRenew(ifname, callback) {
     controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
       if (!data.status)
         dhcpInfo = data;
deleted file mode 100644
--- a/dom/wifi/libhardware_legacy.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-"use strict";
-
-let libhardware_legacy = (function () {
-  let library = ctypes.open("libhardware_legacy.so");
-  let sdkVersion = libcutils.property_get("ro.build.version.sdk", "0");
-  sdkVersion = parseInt(sdkVersion, 10);
-
-  let iface = {
-    // Load wifi driver, 0 on success, < 0 on failure.
-    load_driver: library.declare("wifi_load_driver", ctypes.default_abi, ctypes.int),
-
-    // Unload wifi driver, 0 on success, < 0 on failure.
-    unload_driver: library.declare("wifi_unload_driver", ctypes.default_abi, ctypes.int),
-
-    // Start supplicant, 0 on success, < 0 on failure.
-    start_supplicant: library.declare("wifi_start_supplicant", ctypes.default_abi, ctypes.int),
-
-    // Stop supplicant, 0 on success, < 0 on failure.
-    stop_supplicant: library.declare("wifi_stop_supplicant", ctypes.default_abi, ctypes.int),
-
-    // Open a connection to the supplicant, 0 on success, < 0 on failure.
-    connect_to_supplicant: library.declare("wifi_connect_to_supplicant", ctypes.default_abi, ctypes.int),
-
-    // Close connection to connection to the supplicant, 0 on success, < 0 on failure.
-    close_supplicant_connection: library.declare("wifi_close_supplicant_connection", ctypes.default_abi, ctypes.void_t),
-
-    // Block until a wifi event is returned, buf is the buffer, len is the max length of the buffer.
-    // Return value is number of bytes in buffer, or 0 if no event (no connection for instance), and < 0 on failure.
-    wait_for_event: library.declare("wifi_wait_for_event", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.size_t),
-
-    // Issue a command to the wifi driver. command is the command string, reply will hold the reply, reply_len contains
-    // the maximum reply length initially and is updated with the actual length. 0 is returned on success, < 0 on failure.
-    command: library.declare("wifi_command", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.size_t.ptr),
-  };
-
-  if (sdkVersion >= 16) {
-    let c_start_supplicant =
-      library.declare("wifi_start_supplicant",
-                      ctypes.default_abi,
-                      ctypes.int,
-                      ctypes.int);
-    iface.start_supplicant = function () {
-      return c_start_supplicant(0);
-    };
-
-    let c_connect_to_supplicant =
-      library.declare("wifi_connect_to_supplicant",
-                      ctypes.default_abi,
-                      ctypes.int,
-                      ctypes.char.ptr);
-    iface.connect_to_supplicant = function () {
-      return c_connect_to_supplicant("wlan0");
-    };
-
-    let c_close_supplicant_connection =
-      library.declare("wifi_close_supplicant_connection",
-                      ctypes.default_abi,
-                      ctypes.void_t,
-                      ctypes.char.ptr);
-    iface.close_supplicant_connection = function () {
-      c_close_supplicant_connection("wlan0");
-    };
-
-    let c_wait_for_event =
-      library.declare("wifi_wait_for_event",
-                      ctypes.default_abi,
-                      ctypes.int,
-                      ctypes.char.ptr,
-                      ctypes.char.ptr,
-                      ctypes.size_t);
-    iface.wait_for_event = function (cbuf, len) {
-      return c_wait_for_event("wlan0", cbuf, len);
-    };
-
-    let c_command =
-      library.declare("wifi_command",
-                      ctypes.default_abi,
-                      ctypes.int,
-                      ctypes.char.ptr,
-                      ctypes.char.ptr,
-                      ctypes.char.ptr,
-                      ctypes.size_t.ptr);
-    iface.command = function (message, cbuf, len) {
-      return c_command("wlan0", message, cbuf, len);
-    };
-  }
-
-  return iface;
-})();
--- a/dom/wifi/moz.build
+++ b/dom/wifi/moz.build
@@ -3,28 +3,31 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIDOMMozWifiConnectionInfoEvent.idl',
     'nsIDOMMozWifiStatusChangeEvent.idl',
     'nsIWifi.idl',
+    'nsIWifiService.idl',
 ]
 
 XPIDL_MODULE = 'dom_wifi'
 
 MODULE = 'dom'
 
 EXTRA_COMPONENTS += [
     'DOMWifiManager.js',
     'DOMWifiManager.manifest',
     'WifiWorker.js',
     'WifiWorker.manifest',
 ]
 
-EXTRA_JS_MODULES += [
-    'libhardware_legacy.js',
-    'wifi_worker.js',
-]
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+    CPP_SOURCES = [
+        'NetUtils.cpp',
+        'WifiProxyService.cpp',
+        'WifiUtils.cpp',
+    ]
 
 LIBXUL_LIBRARY = True
 
new file mode 100644
--- /dev/null
+++ b/dom/wifi/nsIWifiService.idl
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(e3d54c8d-b1c7-4ed5-b760-e26d3075e3e5)]
+interface nsIWifiEventListener : nsISupports {
+  void onWaitEvent(in AString event);
+  void onCommand(in jsval result);
+};
+
+[scriptable, uuid(ac5ebae6-ec72-4212-89cb-cd25ed5a1b46)]
+interface nsIWifiProxyService : nsISupports {
+  void start(in nsIWifiEventListener listener);
+  void shutdown();
+  [implicit_jscontext]
+  void sendCommand(in jsval parameters);
+  void waitForEvent();
+};
deleted file mode 100644
--- a/dom/wifi/wifi_worker.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-importScripts("systemlibs.js", "libhardware_legacy.js");
-
-var cbuf = ctypes.char.array(4096)();
-var hwaddr = ctypes.uint8_t.array(6)();
-var len = ctypes.size_t();
-var ints = ctypes.int.array(8)();
-
-let DEBUG = false;
-
-let debug;
-if (DEBUG) {
-  debug = function (s) {
-    dump("-*- WifiWorker component: " + s + "\n");
-  };
-} else {
-  debug = function (s) {};
-}
-
-// TODO: consolidate with implementation in systemlibs.js
-let libcutils = (function () {
-  let library = ctypes.open("libcutils.so");
-
-  return {
-    property_get: library.declare("property_get", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.char.ptr),
-    property_set: library.declare("property_set", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr)
-  };
-})();
-
-self.onmessage = function(e) {
-  var data = e.data;
-  var id = data.id;
-  var cmd = data.cmd;
-
-  switch (cmd) {
-  case "command":
-    len.value = 4096;
-    var ret = libhardware_legacy.command(data.request, cbuf, len.address());
-    var reply = "";
-    if (!ret) {
-      // The return value from libhardware_legacy.command is not guaranteed to
-      // be null-terminated. At the same time we want to make sure that we
-      // don't return a response with a trailing newline, so handle both cases
-      // here. Note that if we wrote 4096 characters to cbuf, we don't have to
-      // null-terminate the buffer, as ctypes has the maximum size already.
-      // Note also that len.value is an object. We can ignore the high 32 bits
-      // because we know that the maximum that it can be is 4096.
-      var reply_len = ctypes.UInt64.lo(len.value);
-      if (reply_len !== 0) {
-        if (cbuf[reply_len - 1] === 10)
-          cbuf[--reply_len] = 0;
-        else if (reply_len !== 4096)
-          cbuf[reply_len] = 0;
-
-        reply = cbuf.readStringReplaceMalformed();
-      }
-
-      // Else if reply_len was 0, use the empty reply, set above.
-    }
-    postMessage({ id: id, status: ret, reply: reply });
-    break;
-  case "wait_for_event":
-    var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
-    // Check the array index.
-    if (ret > 0 && ret < 4096) {
-      // Make sure the string buffer is null terminated.
-      cbuf[ret] = 0;
-      // Use readStringReplaceMalformed() to handle non-UTF8-encoded string.
-      var event = cbuf.readStringReplaceMalformed();
-      postMessage({ id: id, event: event });
-    }
-    break;
-  case "ifc_reset_connections":
-    var ret = libnetutils.ifc_reset_connections(data.ifname,
-                                                libnetutils.RESET_ALL_ADDRESSES);
-    postMessage({ id: id, status: ret });
-    break;
-  case "ifc_enable":
-  case "ifc_disable":
-  case "ifc_remove_host_routes":
-  case "ifc_remove_default_route":
-  case "dhcp_stop":
-  case "dhcp_release_lease":
-    var ret = libnetutils[cmd](data.ifname);
-    postMessage({ id: id, status: ret });
-    break;
-  case "ifc_get_default_route":
-    var route = libnetutils.ifc_get_default_route(data.ifname);
-    postMessage({ id: id, route: route });
-    break;
-  case "ifc_add_host_route":
-  case "ifc_set_default_route":
-    var ret = libnetutils[cmd](data.ifname, data.route);
-    postMessage({ id: id, status: ret });
-    break;
-  case "ifc_configure":
-    debug("WIFI: data: " + uneval(data) + "\n");
-    var ret = libnetutils.ifc_configure(data.ifname, data.ipaddr, data.mask, data.gateway, data.dns1, data.dns2);
-    postMessage({ id: id, status: ret });
-    break;
-  case "dhcp_get_errmsg":
-    var error = libnetutils.get_dhcp_get_errmsg();
-    postMessage({ id: id, error: error.readString() });
-    break;
-  case "dhcp_do_request":
-  case "dhcp_do_request_renew":
-    var out = libnetutils[cmd](data.ifname);
-    out.id = id;
-    out.status = out.ret;
-    postMessage(out);
-    break;
-  case "property_get":
-    var ret = libcutils.property_get(data.key, cbuf, data.defaultValue);
-    postMessage({ id: id, status: ret, value: cbuf.readString() });
-    break;
-  case "property_set":
-    var ret = libcutils.property_set(data.key, data.value);
-    postMessage({ id: id, status: ret });
-    break;
-  case "close_supplicant_connection":
-    libhardware_legacy.close_supplicant_connection();
-    postMessage({ id: id, status: ret });
-    break;
-  default:
-    var f = libhardware_legacy[cmd] || libnetutils[cmd];
-    var ret = f();
-    debug("WIFI: " + cmd + " returned: " + ret);
-    postMessage({ id: id, status: ret });
-    break;
-  }
-}
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -27,16 +27,28 @@ static const char *sExtensionNames[] = {
     "EGL_KHR_fence_sync",
     nullptr
 };
 
 #if defined(ANDROID)
 
 static PRLibrary* LoadApitraceLibrary()
 {
+    static bool sUseApitraceInitialized = false;
+    static bool sUseApitrace = false;
+
+    if (!sUseApitraceInitialized) {
+        sUseApitrace = Preferences::GetBool("gfx.apitrace.enabled", false);
+        sUseApitraceInitialized = true;
+    }
+
+    if (!sUseApitrace) {
+        return nullptr;
+    }
+
     static PRLibrary* sApitraceLibrary = nullptr;
 
     if (sApitraceLibrary)
         return sApitraceLibrary;
 
     nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
 
     if (logFile.IsEmpty()) {
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -61,17 +61,17 @@ class SurfaceDescriptor;
  * by this layer forwarder (the matching uses a global map on the compositor side,
  * see CompositableMap in ImageBridgeParent.cpp)
  *
  * Subclasses: Thebes layers use ContentClients, ImageLayers use ImageClients,
  * Canvas layers use CanvasClients (but ImageHosts). We have a different subclass
  * where we have a different way of interfacing with the textures - in terms of
  * drawing into the compositable and/or passing its contents to the compostior.
  */
-class CompositableClient : public RefCounted<CompositableClient>
+class CompositableClient : public AtomicRefCounted<CompositableClient>
 {
 public:
   CompositableClient(CompositableForwarder* aForwarder);
 
   virtual ~CompositableClient();
 
   virtual TextureInfo GetTextureInfo() const = 0;
 
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -88,17 +88,17 @@ public:
  * TextureClient/Host pair only owns one buffer of image data through its
  * lifetime. This means that the lifetime of the underlying shared data
  * matches the lifetime of the TextureClient/Host pair. It also means
  * TextureClient/Host do not implement double buffering, which is the
  * responsibility of the compositable (which would use two Texture pairs).
  * In order to send several different buffers to the compositor side, use
  * several TextureClients.
  */
-class TextureClient : public RefCounted<TextureClient>
+class TextureClient : public AtomicRefCounted<TextureClient>
 {
 public:
   TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
   virtual ~TextureClient();
 
   virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; }
   virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -115,34 +115,32 @@ FPSState::DrawFPS(TimeStamp aNow,
 
   if (!mTexture) {
     // Bind the number of textures we need, in this case one.
     context->fGenTextures(1, &mTexture);
     context->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
     context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MIN_FILTER,LOCAL_GL_NEAREST);
     context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MAG_FILTER,LOCAL_GL_NEAREST);
 
-    uint32_t text[] = {
-      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-      0, 255, 255, 255,   0, 255, 255,   0,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255,   0, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,
-      0, 255,   0, 255,   0,   0, 255,   0,   0,   0,   0, 255,   0,   0,   0, 255,   0, 255,   0, 255,   0, 255,   0,   0,   0, 255,   0,   0,   0,   0,   0, 255,   0, 255,   0, 255,   0, 255,   0, 255,   0,
-      0, 255,   0, 255,   0,   0, 255,   0,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,   0,   0, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,
-      0, 255,   0, 255,   0,   0, 255,   0,   0, 255,   0,   0,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0, 255,   0, 255,   0,   0,   0, 255,   0, 255,   0, 255,   0,   0,   0, 255,   0,
-      0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,   0,   0, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,   0,   0, 255,   0, 255, 255, 255,   0,   0,   0, 255,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    };
+    const char *text =
+      "                                         "
+      " XXX XX  XXX XXX X X XXX XXX XXX XXX XXX "
+      " X X  X    X   X X X X   X     X X X X X "
+      " X X  X  XXX XXX XXX XXX XXX   X XXX XXX "
+      " X X  X  X     X   X   X X X   X X X   X "
+      " XXX XXX XXX XXX   X XXX XXX   X XXX   X "
+      "                                         ";
 
-    // convert from 8 bit to 32 bit so that don't have to write the text above out in 32 bit format
-    // we rely on int being 32 bits
-    unsigned int* buf = (unsigned int*)malloc(64 * 8 * 4);
+    // Convert the text encoding above to RGBA.
+    uint32_t* buf = (uint32_t *) malloc(64 * 8 * sizeof(uint32_t));
     for (int i = 0; i < 7; i++) {
       for (int j = 0; j < 41; j++) {
-        unsigned int purple = 0xfff000ff;
-        unsigned int white  = 0xffffffff;
-        buf[i * 64 + j] = (text[i * 41 + j] == 0) ? purple : white;
+        uint32_t purple = 0xfff000ff;
+        uint32_t white  = 0xffffffff;
+        buf[i * 64 + j] = (text[i * 41 + j] == ' ') ? purple : white;
       }
     }
     context->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 64, 8, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, buf);
     free(buf);
   }
 
   mVBOs.Reset();
 
new file mode 100644
--- /dev/null
+++ b/ipc/chromium/src/third_party/libevent-avoid-empty-sighandler.patch
@@ -0,0 +1,65 @@
+diff --git a/ipc/chromium/src/third_party/libevent/kqueue.c b/ipc/chromium/src/third_party/libevent/kqueue.c
+--- a/ipc/chromium/src/third_party/libevent/kqueue.c
++++ b/ipc/chromium/src/third_party/libevent/kqueue.c
+@@ -158,26 +158,20 @@ kq_init(struct event_base *base)
+ 	base->evsigsel = &kqsigops;
+ 
+ 	return (kqueueop);
+ err:
+ 	if (kqueueop)
+ 		kqop_free(kqueueop);
+ 
+ 	return (NULL);
+ }
+ 
+-static void
+-kq_sighandler(int sig)
+-{
+-	/* Do nothing here */
+-}
+-
+ #define ADD_UDATA 0x30303
+ 
+ static void
+ kq_setup_kevent(struct kevent *out, evutil_socket_t fd, int filter, short change)
+ {
+ 	memset(out, 0, sizeof(struct kevent));
+ 	out->ident = fd;
+ 	out->filter = filter;
+ 
+ 	if (change & EV_CHANGE_ADD) {
+@@ -431,24 +425,31 @@ kq_sig_add(struct event_base *base, int 
+ 	kev.ident = nsignal;
+ 	kev.filter = EVFILT_SIGNAL;
+ 	kev.flags = EV_ADD;
+ 
+ 	/* Be ready for the signal if it is sent any
+ 	 * time between now and the next call to
+ 	 * kq_dispatch. */
+ 	if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
+ 		return (-1);
+ 
+-	/* XXXX The manpage suggest we could use SIG_IGN instead of a
+-	 * do-nothing handler */
+-	if (_evsig_set_handler(base, nsignal, kq_sighandler) == -1)
++	/* Backported from
++	 * https://github.com/nmathewson/Libevent/commit/148458e0a1fd25e167aa2ef229d1c9a70b27c3e9 */
++	/* We can set the handler for most signals to SIG_IGN and
++	 * still have them reported to us in the queue.  However,
++	 * if the handler for SIGCHLD is SIG_IGN, the system reaps
++	 * zombie processes for us, and we don't get any notification.
++	 * This appears to be the only signal with this quirk. */
++	if (_evsig_set_handler(base, nsignal,
++	                       nsignal == SIGCHLD ? SIG_DFL : SIG_IGN) == -1) {
+ 		return (-1);
++	}
+ 
+ 	return (0);
+ }
+ 
+ static int
+ kq_sig_del(struct event_base *base, int nsignal, short old, short events, void *p)
+ {
+ 	struct kqop *kqop = base->evbase;
+ 	struct kevent kev;
+ 
--- a/ipc/chromium/src/third_party/libevent/kqueue.c
+++ b/ipc/chromium/src/third_party/libevent/kqueue.c
@@ -160,22 +160,16 @@ kq_init(struct event_base *base)
 	return (kqueueop);
 err:
 	if (kqueueop)
 		kqop_free(kqueueop);
 
 	return (NULL);
 }
 
-static void
-kq_sighandler(int sig)
-{
-	/* Do nothing here */
-}
-
 #define ADD_UDATA 0x30303
 
 static void
 kq_setup_kevent(struct kevent *out, evutil_socket_t fd, int filter, short change)
 {
 	memset(out, 0, sizeof(struct kevent));
 	out->ident = fd;
 	out->filter = filter;
@@ -433,20 +427,27 @@ kq_sig_add(struct event_base *base, int 
 	kev.flags = EV_ADD;
 
 	/* Be ready for the signal if it is sent any
 	 * time between now and the next call to
 	 * kq_dispatch. */
 	if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
 		return (-1);
 
-	/* XXXX The manpage suggest we could use SIG_IGN instead of a
-	 * do-nothing handler */
-	if (_evsig_set_handler(base, nsignal, kq_sighandler) == -1)
+	/* Backported from
+	 * https://github.com/nmathewson/Libevent/commit/148458e0a1fd25e167aa2ef229d1c9a70b27c3e9 */
+	/* We can set the handler for most signals to SIG_IGN and
+	 * still have them reported to us in the queue.  However,
+	 * if the handler for SIGCHLD is SIG_IGN, the system reaps
+	 * zombie processes for us, and we don't get any notification.
+	 * This appears to be the only signal with this quirk. */
+	if (_evsig_set_handler(base, nsignal,
+	                       nsignal == SIGCHLD ? SIG_DFL : SIG_IGN) == -1) {
 		return (-1);
+	}
 
 	return (0);
 }
 
 static int
 kq_sig_del(struct event_base *base, int nsignal, short old, short events, void *p)
 {
 	struct kqop *kqop = base->evbase;
--- a/js/src/assembler/assembler/ARMAssembler.h
+++ b/js/src/assembler/assembler/ARMAssembler.h
@@ -39,17 +39,17 @@
 #if ENABLE_ASSEMBLER && WTF_CPU_ARM_TRADITIONAL
 
 #include "assembler/assembler/AssemblerBufferWithConstantPool.h"
 #include "assembler/wtf/Assertions.h"
 
 // TODO: We don't print the condition code in our spew lines. Doing this
 // is awkward whilst maintaining a consistent field width.
 namespace js {
-    namespace ion {
+    namespace jit {
         class Assembler;
     }
 }
 
 namespace JSC {
 
     typedef uint32_t ARMWord;
 
@@ -255,17 +255,17 @@ namespace JSC {
         } Shift;
 
         static const ARMWord INVALID_IMM = 0xf0000000;
         static const ARMWord InvalidBranchTarget = 0xffffffff;
         static const int DefaultPrefetching = 2;
 
         class JmpSrc {
             friend class ARMAssembler;
-            friend class js::ion::Assembler;
+            friend class js::jit::Assembler;
         public:
             JmpSrc()
                 : m_offset(-1)
             {
             }
             int offset() {return m_offset;}
 
             bool isSet() const {
@@ -278,17 +278,17 @@ namespace JSC {
             {
             }
 
             int m_offset;
         };
 
         class JmpDst {
             friend class ARMAssembler;
-            friend class js::ion::Assembler;
+            friend class js::jit::Assembler;
         public:
             JmpDst()
                 : m_offset(-1)
                 , m_used(false)
             {
             }
 
             bool isUsed() const { return m_used; }
--- a/js/src/assembler/assembler/AssemblerBuffer.h
+++ b/js/src/assembler/assembler/AssemblerBuffer.h
@@ -268,17 +268,17 @@ namespace JSC {
 
         void spew(const char *fmt, ...)
 #ifdef __GNUC__
             __attribute__ ((format (printf, 2, 3)))
 #endif
         {
             if (printer
 #ifdef JS_ION
-                || js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
+                || js::jit::IonSpewEnabled(js::jit::IonSpew_Codegen)
 #endif
                 )
             {
                 // Buffer to hold the formatted string. Note that this may contain
                 // '%' characters, so do not pass it directly to printf functions.
                 char buf[200];
 
                 va_list va;
@@ -286,38 +286,38 @@ namespace JSC {
                 int i = vsnprintf(buf, sizeof(buf), fmt, va);
                 va_end(va);
 
                 if (i > -1) {
                     if (printer)
                         printer->printf("%s\n", buf);
 
 #ifdef JS_ION
-                    js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
+                    js::jit::IonSpew(js::jit::IonSpew_Codegen, "%s", buf);
 #endif
                 }
             }
         }
 
         static void staticSpew(const char *fmt, ...)
 #ifdef __GNUC__
             __attribute__ ((format (printf, 1, 2)))
 #endif
         {
 #ifdef JS_ION
-            if (js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)) {
+            if (js::jit::IonSpewEnabled(js::jit::IonSpew_Codegen)) {
                 char buf[200];
 
                 va_list va;
                 va_start(va, fmt);
                 int i = vsnprintf(buf, sizeof(buf), fmt, va);
                 va_end(va);
 
                 if (i > -1)
-                    js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
+                    js::jit::IonSpew(js::jit::IonSpew_Codegen, "%s", buf);
             }
 #endif
         }
     };
 
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -891,17 +891,17 @@ DisableSPSProfiling(JSContext *cx, unsig
         cx->runtime()->spsProfiler.enable(false);
     return true;
 }
 
 static bool
 EnableOsiPointRegisterChecks(JSContext *, unsigned, jsval *vp)
 {
 #ifdef CHECK_OSIPOINT_REGISTERS
-    ion::js_IonOptions.checkOsiPointRegisters = true;
+    jit::js_IonOptions.checkOsiPointRegisters = true;
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 DisplayName(JSContext *cx, unsigned argc, jsval *vp)
 {
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -151,17 +151,17 @@ frontend::MaybeCallSourceHandler(JSConte
 
 JSScript *
 frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject scopeChain,
                         HandleScript evalCaller,
                         const CompileOptions &options,
                         const jschar *chars, size_t length,
                         JSString *source_ /* = NULL */,
                         unsigned staticLevel /* = 0 */,
-                        SourceCompressionToken *extraSct /* = NULL */)
+                        SourceCompressionTask *extraSct /* = NULL */)
 {
     RootedString source(cx, source_);
     SkipRoot skip(cx, &chars);
 
 #if JS_TRACE_LOGGING
         js::AutoTraceLog logger(js::TraceLogging::defaultLogger(),
                                 js::TraceLogging::PARSER_COMPILE_SCRIPT_START,
                                 js::TraceLogging::PARSER_COMPILE_SCRIPT_STOP,
@@ -187,30 +187,22 @@ frontend::CompileScript(ExclusiveContext
         return NULL;
     if (options.filename && !ss->setFilename(cx, options.filename))
         return NULL;
 
     JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
     if (!sourceObject)
         return NULL;
 
-    // Saving source is not yet supported when parsing off thread.
-    JS_ASSERT_IF(!cx->isJSContext(),
-                 !extraSct && options.sourcePolicy != CompileOptions::SAVE_SOURCE);
-
-    SourceCompressionToken *sct = extraSct;
-    Maybe<SourceCompressionToken> mysct;
-    if (cx->isJSContext() && !sct) {
-        mysct.construct(cx->asJSContext());
-        sct = mysct.addr();
-    }
+    SourceCompressionTask mysct(cx);
+    SourceCompressionTask *sct = extraSct ? extraSct : &mysct;
 
     switch (options.sourcePolicy) {
       case CompileOptions::SAVE_SOURCE:
-        if (!ss->setSourceCopy(cx->asJSContext(), chars, length, false, sct))
+        if (!ss->setSourceCopy(cx, chars, length, false, sct))
             return NULL;
         break;
       case CompileOptions::LAZY_SOURCE:
         ss->setSourceRetrievable();
         break;
       case CompileOptions::NO_SOURCE:
         break;
     }
@@ -474,17 +466,17 @@ CompileFunctionBody(JSContext *cx, Mutab
     ScriptSource *ss = cx->new_<ScriptSource>(options.originPrincipals());
     if (!ss)
         return false;
     if (options.filename && !ss->setFilename(cx, options.filename))
         return false;
     JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
     if (!sourceObject)
         return false;
-    SourceCompressionToken sct(cx);
+    SourceCompressionTask sct(cx);
     JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
     if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
         if (!ss->setSourceCopy(cx, chars, length, true, &sct))
             return false;
     }
 
     bool canLazilyParse = CanLazilyParse(cx, options);
 
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -11,26 +11,26 @@
 
 class JSLinearString;
 
 namespace js {
 
 class AutoNameVector;
 class LazyScript;
 class LifoAlloc;
-struct SourceCompressionToken;
+struct SourceCompressionTask;
 
 namespace frontend {
 
 JSScript *
 CompileScript(ExclusiveContext *cx, LifoAlloc *alloc,
               HandleObject scopeChain, HandleScript evalCaller,
               const CompileOptions &options, const jschar *chars, size_t length,
               JSString *source_ = NULL, unsigned staticLevel = 0,
-              SourceCompressionToken *extraSct = NULL);
+              SourceCompressionTask *extraSct = NULL);
 
 bool
 CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *chars, size_t length);
 
 bool
 CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
                     const AutoNameVector &formals, const jschar *chars, size_t length);
 bool
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -317,17 +317,19 @@ class Parser : private AutoGCRooter, pub
     LifoAlloc::Mark     tempPoolMark;
 
     /* list of parsed objects for GC tracing */
     ObjectBox *traceListHead;
 
     /* innermost parse context (stack-allocated) */
     ParseContext<ParseHandler> *pc;
 
-    SourceCompressionToken *sct;        /* compression token for aborting */
+    /* Compression token for aborting. */
+    SourceCompressionTask *sct;
+
     ScriptSource        *ss;
 
     /* Root atoms and objects allocated for the parsed tree. */
     AutoKeepAtoms       keepAtoms;
 
     /* Perform constant-folding; must be true when interfacing with the emitter. */
     const bool          foldConstants:1;
 
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -81,17 +81,17 @@ namespace js {
 namespace gc {
 
 static void MarkChildren(JSTracer *trc, JSString *str);
 static void MarkChildren(JSTracer *trc, JSScript *script);
 static void MarkChildren(JSTracer *trc, LazyScript *lazy);
 static void MarkChildren(JSTracer *trc, Shape *shape);
 static void MarkChildren(JSTracer *trc, BaseShape *base);
 static void MarkChildren(JSTracer *trc, types::TypeObject *type);
-static void MarkChildren(JSTracer *trc, ion::IonCode *code);
+static void MarkChildren(JSTracer *trc, jit::IonCode *code);
 
 } /* namespace gc */
 } /* namespace js */
 
 /*** Object Marking ***/
 
 #ifdef DEBUG
 template<typename T>
@@ -358,17 +358,17 @@ Is##base##AboutToBeFinalized(type **thin
 bool                                                                                              \
 Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp)                                       \
 {                                                                                                 \
     return IsAboutToBeFinalized<type>(thingp->unsafeGet());                                       \
 }
 
 DeclMarkerImpl(BaseShape, BaseShape)
 DeclMarkerImpl(BaseShape, UnownedBaseShape)
-DeclMarkerImpl(IonCode, ion::IonCode)
+DeclMarkerImpl(IonCode, jit::IonCode)
 DeclMarkerImpl(Object, ArgumentsObject)
 DeclMarkerImpl(Object, ArrayBufferObject)
 DeclMarkerImpl(Object, ArrayBufferViewObject)
 DeclMarkerImpl(Object, DebugScopeObject)
 DeclMarkerImpl(Object, GlobalObject)
 DeclMarkerImpl(Object, JSObject)
 DeclMarkerImpl(Object, JSFunction)
 DeclMarkerImpl(Object, ScopeObject)
@@ -412,17 +412,17 @@ gc::MarkKind(JSTracer *trc, void **thing
         break;
       case JSTRACE_BASE_SHAPE:
         MarkInternal(trc, reinterpret_cast<BaseShape **>(thingp));
         break;
       case JSTRACE_TYPE_OBJECT:
         MarkInternal(trc, reinterpret_cast<types::TypeObject **>(thingp));
         break;
       case JSTRACE_IONCODE:
-        MarkInternal(trc, reinterpret_cast<ion::IonCode **>(thingp));
+        MarkInternal(trc, reinterpret_cast<jit::IonCode **>(thingp));
         break;
     }
 }
 
 static void
 MarkGCThingInternal(JSTracer *trc, void **thingp, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
@@ -834,17 +834,17 @@ PushMarkStack(GCMarker *gcmarker, Shape 
     JS_ASSERT(!IsInsideNursery(gcmarker->runtime, thing));
 
     /* We mark shapes directly rather than pushing on the stack. */
     if (thing->markIfUnmarked(gcmarker->getMarkColor()))
         ScanShape(gcmarker, thing);
 }
 
 static void
-PushMarkStack(GCMarker *gcmarker, ion::IonCode *thing)
+PushMarkStack(GCMarker *gcmarker, jit::IonCode *thing)
 {
     JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
     JS_ASSERT(!IsInsideNursery(gcmarker->runtime, thing));
 
     if (thing->markIfUnmarked(gcmarker->getMarkColor()))
         gcmarker->pushIonCode(thing);
 }
 
@@ -1158,17 +1158,17 @@ gc::MarkChildren(JSTracer *trc, types::T
         MarkShape(trc, &type->newScript->shape, "type_new_shape");
     }
 
     if (type->interpretedFunction)
         MarkObject(trc, &type->interpretedFunction, "type_function");
 }
 
 static void
-gc::MarkChildren(JSTracer *trc, ion::IonCode *code)
+gc::MarkChildren(JSTracer *trc, jit::IonCode *code)
 {
 #ifdef JS_ION
     code->trace(trc);
 #endif
 }
 
 template<typename T>
 static void
@@ -1206,17 +1206,17 @@ gc::PushArena(GCMarker *gcmarker, ArenaH
         PushArenaTyped<js::BaseShape>(gcmarker, aheader);
         break;
 
       case JSTRACE_TYPE_OBJECT:
         PushArenaTyped<js::types::TypeObject>(gcmarker, aheader);
         break;
 
       case JSTRACE_IONCODE:
-        PushArenaTyped<js::ion::IonCode>(gcmarker, aheader);
+        PushArenaTyped<js::jit::IonCode>(gcmarker, aheader);
         break;
     }
 }
 
 struct SlotArrayLayout
 {
     union {
         HeapSlot *end;
@@ -1332,17 +1332,17 @@ GCMarker::processMarkStackOther(SliceBud
         JS_ASSERT(!(addr & CellMask));
         JSObject *obj = reinterpret_cast<JSObject *>(addr);
         HeapValue *vp, *end;
         if (restoreValueArray(obj, (void **)&vp, (void **)&end))
             pushValueArray(obj, vp, end);
         else
             pushObject(obj);
     } else if (tag == IonCodeTag) {
-        MarkChildren(this, reinterpret_cast<ion::IonCode *>(addr));
+        MarkChildren(this, reinterpret_cast<jit::IonCode *>(addr));
     } else if (tag == ArenaTag) {
         ArenaHeader *aheader = reinterpret_cast<ArenaHeader *>(addr);
         AllocKind thingKind = aheader->getAllocKind();
         size_t thingSize = Arena::thingSize(thingKind);
 
         for ( ; aheader; aheader = aheader->next) {
             Arena *arena = aheader->getArena();
             FreeSpan firstSpan(aheader->getFirstFreeSpan());
@@ -1549,17 +1549,17 @@ js::TraceChildren(JSTracer *trc, void *t
         MarkChildren(trc, static_cast<LazyScript *>(thing));
         break;
 
       case JSTRACE_SHAPE:
         MarkChildren(trc, static_cast<Shape *>(thing));
         break;
 
       case JSTRACE_IONCODE:
-        MarkChildren(trc, (js::ion::IonCode *)thing);
+        MarkChildren(trc, (js::jit::IonCode *)thing);
         break;
 
       case JSTRACE_BASE_SHAPE:
         MarkChildren(trc, static_cast<BaseShape *>(thing));
         break;
 
       case JSTRACE_TYPE_OBJECT:
         MarkChildren(trc, (types::TypeObject *)thing);
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -86,17 +86,17 @@ void Mark##base##Range(JSTracer *trc, si
 void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name);            \
 bool Is##base##Marked(type **thingp);                                                             \
 bool Is##base##Marked(EncapsulatedPtr<type> *thingp);                                             \
 bool Is##base##AboutToBeFinalized(type **thingp);                                                 \
 bool Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp);
 
 DeclMarker(BaseShape, BaseShape)
 DeclMarker(BaseShape, UnownedBaseShape)
-DeclMarker(IonCode, ion::IonCode)
+DeclMarker(IonCode, jit::IonCode)
 DeclMarker(Object, ArgumentsObject)
 DeclMarker(Object, ArrayBufferObject)
 DeclMarker(Object, ArrayBufferViewObject)
 DeclMarker(Object, DebugScopeObject)
 DeclMarker(Object, GlobalObject)
 DeclMarker(Object, JSObject)
 DeclMarker(Object, JSFunction)
 DeclMarker(Object, ScopeObject)
@@ -272,17 +272,17 @@ Mark(JSTracer *trc, EncapsulatedPtrObjec
 
 inline void
 Mark(JSTracer *trc, EncapsulatedPtrScript *o, const char *name)
 {
     MarkScript(trc, o, name);
 }
 
 inline void
-Mark(JSTracer *trc, HeapPtr<ion::IonCode> *code, const char *name)
+Mark(JSTracer *trc, HeapPtr<jit::IonCode> *code, const char *name)
 {
     MarkIonCode(trc, code, name);
 }
 
 /* For use by WeakMap's HashKeyRef instantiation. */
 inline void
 Mark(JSTracer *trc, JSObject **objp, const char *name)
 {
@@ -341,27 +341,27 @@ IsAboutToBeFinalized(EncapsulatedPtrScri
 {
     return IsScriptAboutToBeFinalized(scriptp);
 }
 
 #ifdef JS_ION
 /* Nonsense to get WeakCache to work with new Marking semantics. */
 
 inline bool
-IsAboutToBeFinalized(const js::ion::VMFunction **vmfunc)
+IsAboutToBeFinalized(const js::jit::VMFunction **vmfunc)
 {
     /*
      * Preserves entries in the WeakCache<VMFunction, IonCode>
      * iff the IonCode has been marked.
      */
     return true;
 }
 
 inline bool
-IsAboutToBeFinalized(ReadBarriered<js::ion::IonCode> code)
+IsAboutToBeFinalized(ReadBarriered<js::jit::IonCode> code)
 {
     return IsIonCodeAboutToBeFinalized(code.unsafeGet());
 }
 #endif
 
 inline Cell *
 ToMarkable(const Value &v)
 {
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -19,17 +19,17 @@
 namespace js {
 
 class ObjectElements;
 
 namespace gc {
 class MinorCollectionTracer;
 } /* namespace gc */
 
-namespace ion {
+namespace jit {
 class CodeGenerator;
 class MacroAssembler;
 class ICStubCompiler;
 class BaselineCompiler;
 }
 
 class Nursery
 {
@@ -230,18 +230,18 @@ class Nursery
 
     /* Change the allocable space provided by the nursery. */
     void growAllocableSpace();
     void shrinkAllocableSpace();
 
     static void MinorGCCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind);
 
     friend class gc::MinorCollectionTracer;
-    friend class ion::CodeGenerator;
-    friend class ion::MacroAssembler;
-    friend class ion::ICStubCompiler;
-    friend class ion::BaselineCompiler;
+    friend class jit::CodeGenerator;
+    friend class jit::MacroAssembler;
+    friend class jit::ICStubCompiler;
+    friend class jit::BaselineCompiler;
 };
 
 } /* namespace js */
 
 #endif /* JSGC_GENERATIONAL */
 #endif /* gc_Nursery_h */
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -55,17 +55,17 @@ MarkExactStackRoot(JSTracer *trc, Rooted
     switch (kind) {
       case THING_ROOT_OBJECT:      MarkObjectRoot(trc, (JSObject **)addr, "exact-object"); break;
       case THING_ROOT_STRING:      MarkStringRoot(trc, (JSString **)addr, "exact-string"); break;
       case THING_ROOT_SCRIPT:      MarkScriptRoot(trc, (JSScript **)addr, "exact-script"); break;
       case THING_ROOT_SHAPE:       MarkShapeRoot(trc, (Shape **)addr, "exact-shape"); break;
       case THING_ROOT_BASE_SHAPE:  MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact-baseshape"); break;
       case THING_ROOT_TYPE:        MarkTypeRoot(trc, (types::Type *)addr, "exact-type"); break;
       case THING_ROOT_TYPE_OBJECT: MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact-typeobject"); break;
-      case THING_ROOT_ION_CODE:    MarkIonCodeRoot(trc, (ion::IonCode **)addr, "exact-ioncode"); break;
+      case THING_ROOT_ION_CODE:    MarkIonCodeRoot(trc, (jit::IonCode **)addr, "exact-ioncode"); break;
       case THING_ROOT_VALUE:       MarkValueRoot(trc, (Value *)addr, "exact-value"); break;
       case THING_ROOT_ID:          MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
       case THING_ROOT_PROPERTY_ID: MarkIdRoot(trc, &((js::PropertyId *)addr)->asId(), "exact-propertyid"); break;
       case THING_ROOT_BINDINGS:    ((Bindings *)addr)->trace(trc); break;
       case THING_ROOT_PROPERTY_DESCRIPTOR: ((JSPropertyDescriptor *)addr)->trace(trc); break;
       default: MOZ_ASSUME_UNREACHABLE("Invalid THING_ROOT kind"); break;
     }
 }
@@ -271,17 +271,17 @@ static void
 MarkRangeConservativelyAndSkipIon(JSTracer *trc, JSRuntime *rt, const uintptr_t *begin, const uintptr_t *end)
 {
     const uintptr_t *i = begin;
 
 #if JS_STACK_GROWTH_DIRECTION < 0 && defined(JS_ION)
     // Walk only regions in between JIT activations. Note that non-volatile
     // registers are spilled to the stack before the entry frame, ensuring
     // that the conservative scanner will still see them.
-    for (ion::JitActivationIterator iter(rt); !iter.done(); ++iter) {
+    for (jit::JitActivationIterator iter(rt); !iter.done(); ++iter) {
         uintptr_t *jitMin, *jitEnd;
         iter.jitStackRange(jitMin, jitEnd);
 
         MarkRangeConservatively(trc, i, jitMin);
         i = jitEnd;
     }
 #endif
 
@@ -513,24 +513,24 @@ AutoGCRooter::trace(JSTracer *trc)
       case HASHABLEVALUE: {
         AutoHashableValueRooter *rooter = static_cast<AutoHashableValueRooter *>(this);
         rooter->trace(trc);
         return;
       }
 
       case IONMASM: {
 #ifdef JS_ION
-        static_cast<js::ion::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc);
+        static_cast<js::jit::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc);
 #endif
         return;
       }
 
       case IONALLOC: {
 #ifdef JS_ION
-        static_cast<js::ion::AutoTempAllocatorRooter *>(this)->trace(trc);
+        static_cast<js::jit::AutoTempAllocatorRooter *>(this)->trace(trc);
 #endif
         return;
       }
 
       case WRAPPER: {
         /*
          * We need to use MarkValueUnbarriered here because we mark wrapper
          * roots in every slice. This is because of some rule-breaking in
@@ -691,17 +691,17 @@ js::gc::MarkRuntime(JSTracer *trc, bool 
 
     if (rt->hasContexts() &&
         !trc->runtime->isHeapMinorCollecting() &&
         (!IS_GC_MARKING_TRACER(trc) || rt->atomsCompartment()->zone()->isCollecting()))
     {
         MarkAtoms(trc);
         rt->staticStrings.trace(trc);
 #ifdef JS_ION
-        ion::IonRuntime::Mark(trc);
+        jit::IonRuntime::Mark(trc);
 #endif
     }
 
     for (ContextIter acx(rt); !acx.done(); acx.next())
         acx->mark(trc);
 
     for (ZonesIter zone(rt); !zone.done(); zone.next()) {
         if (IS_GC_MARKING_TRACER(trc) && !zone->isCollecting())
@@ -741,17 +741,17 @@ js::gc::MarkRuntime(JSTracer *trc, bool 
         /* Mark debug scopes, if present */
         if (c->debugScopes)
             c->debugScopes->mark(trc);
     }
 
     MarkInterpreterActivations(rt, trc);
 
 #ifdef JS_ION
-    ion::MarkJitActivations(rt, trc);
+    jit::MarkJitActivations(rt, trc);
 #endif
 
     if (!rt->isHeapMinorCollecting()) {
         /*
          * All JSCompartment::mark does is mark the globals for compartments
          * which have been entered. Globals aren't nursery allocated so there's
          * no need to do this for minor GCs.
          */
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -63,17 +63,17 @@ StoreBuffer::WholeCellEdges::mark(JSTrac
 {
     JSGCTraceKind kind = GetGCThingTraceKind(tenured);
     if (kind <= JSTRACE_OBJECT) {
         MarkChildren(trc, static_cast<JSObject *>(tenured));
         return;
     }
 #ifdef JS_ION
     JS_ASSERT(kind == JSTRACE_IONCODE);
-    static_cast<ion::IonCode *>(tenured)->trace(trc);
+    static_cast<jit::IonCode *>(tenured)->trace(trc);
 #else
     MOZ_ASSUME_UNREACHABLE("Only objects can be in the wholeCellBuffer if IonMonkey is disabled.");
 #endif
 }
 
 /*** MonoTypeBuffer ***/
 
 template <typename T>
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -120,17 +120,17 @@ CheckStackRootsRangeAndSkipJit(JSRuntime
     /*
      * Regions of the stack between Ion activiations are marked exactly through
      * a different mechanism. We need to skip these regions when checking the
      * stack so that we do not poison IonMonkey's things.
      */
     uintptr_t *i = begin;
 
 #if defined(JS_ION)
-    for (ion::JitActivationIterator iter(rt); !iter.done(); ++iter) {
+    for (jit::JitActivationIterator iter(rt); !iter.done(); ++iter) {
         uintptr_t *jitMin, *jitEnd;
         iter.jitStackRange(jitMin, jitEnd);
 
         uintptr_t *upto = Min(jitMin, end);
         if (upto > i)
             CheckStackRootsRange(rt, i, upto, rbegin, rend);
         else
             break;
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -63,17 +63,17 @@ Zone::init(JSContext *cx)
     return true;
 }
 
 void
 Zone::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon)
 {
 #ifdef JS_ION
     if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
-        ion::ToggleBarriers(this, needs);
+        jit::ToggleBarriers(this, needs);
         ionUsingBarriers_ = needs;
     }
 #endif
 
     if (needs && runtimeFromMainThread()->isAtomsZone(this))
         JS_ASSERT(!runtimeFromMainThread()->exclusiveThreadsPresent());
 
     JS_ASSERT_IF(needs, canCollect());
@@ -196,30 +196,30 @@ Zone::discardJitCode(FreeOp *fop, bool d
         /* Assert no baseline scripts are marked as active. */
         for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
             JS_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
         }
 # endif
 
         /* Mark baseline scripts on the stack as active. */
-        ion::MarkActiveBaselineScripts(this);
+        jit::MarkActiveBaselineScripts(this);
 
         /* Only mark OSI points if code is being discarded. */
-        ion::InvalidateAll(fop, this);
+        jit::InvalidateAll(fop, this);
 
         for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
-            ion::FinishInvalidation(fop, script);
+            jit::FinishInvalidation(fop, script);
 
             /*
              * Discard baseline script if it's not marked as active. Note that
              * this also resets the active flag.
              */
-            ion::FinishDiscardBaselineScript(fop, script);
+            jit::FinishDiscardBaselineScript(fop, script);
 
             /*
              * Use counts for scripts are reset on GC. After discarding code we
              * need to let it warm back up to get information such as which
              * opcodes are setting array holes or accessing getter properties.
              */
             script->resetUseCount();
         }
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -77,16 +77,19 @@ def main(argv):
     op.add_option('--remote', action='store_true',
                   help='Run tests on a remote device')
     op.add_option('--deviceIP', action='store',
                   type='string', dest='device_ip',
                   help='IP address of remote device to test')
     op.add_option('--devicePort', action='store',
                   type=int, dest='device_port', default=20701,
                   help='port of remote device to test')
+    op.add_option('--deviceSerial', action='store',
+                  type='string', dest='device_serial', default=None,
+                  help='ADB device serial number of remote device to test')
     op.add_option('--deviceTransport', action='store',
                   type='string', dest='device_transport', default='sut',
                   help='The transport to use to communicate with device: [adb|sut]; default=sut')
     op.add_option('--remoteTestRoot', dest='remote_test_root', action='store',
                   type='string', default='/data/local/tests',
                   help='The remote directory to use as test root (eg. /data/local/tests)')
     op.add_option('--localLib', dest='local_lib', action='store',
                   type='string',
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/generators/bug908920.js
@@ -0,0 +1,9 @@
+if (typeof schedulegc != 'undefined') {
+    Function("\
+        x = (function() { yield })();\
+        Set(x);\
+        schedulegc(1);\
+        print( /x/ );\
+        for (p in x) {}\
+    ")();
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug909505.js
@@ -0,0 +1,5 @@
+function f(type) {
+    for (var i = 0; i < 3; i++) {}
+    assertEq((new String) instanceof type, true);
+}
+f(String);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parallel/math-fcns.js
@@ -0,0 +1,82 @@
+// |jit-test| slow;
+load(libdir + "parallelarray-helpers.js");
+
+// The MathCache has 4096 entries, so ensure we overwrite at least one
+// entry by using > 4096 distinct inputs.
+
+var len = 5000;
+var iters = 100;
+
+// The problem we are trying to expose (Bugzilla 901000) is
+// a data-race on the MathCache; such a bug is inherently
+// non-deterministic.  On a 4 core Mac laptop:
+//
+// len == 10000 iters==1  replicates the problem on 2/10 runs,
+// len == 10000 iters==2  replicates the problem on 3/10 runs,
+// len == 10000 iters==5  replicates the problem on 6/10 runs,
+// len == 10000 iters==10 replicates the problem on 9/10 runs.
+//
+// len == 5000  iters==1  replicates the problem on 1/10 runs,
+// len == 5000  iters==2  replicates the problem on 4/10 runs,
+// len == 5000  iters==5  replicates the problem on 5/10 runs,
+// len == 5000  iters==10 replicates the problem on 9/10 runs.
+//
+// len == 2000  iters==1  replicates the problem on 0/10 runs,
+// len == 2000  iters==2  replicates the problem on 0/10 runs,
+// len == 2000  iters==5  replicates the problem on 0/10 runs,
+// len == 2000  iters==10 replicates the problem on 3/10 runs
+
+function check(fill) {
+  var seq = Array.build(len, fill);
+  for (var i = 0; i < iters; i++) {
+    var par = Array.buildPar(len, fill);
+    assertStructuralEq(par, seq);
+  }
+}
+
+function checkAbs(a)   { check(function (i) { return Math.abs(a[i]);   }); }
+function checkAcos(a)  { check(function (i) { return Math.acos(a[i]);  }); }
+function checkAsin(a)  { check(function (i) { return Math.asin(a[i]);  }); }
+function checkAtan(a)  { check(function (i) { return Math.atan(a[i]);  }); }
+function checkAtan2(a) { check(function (i) { return Math.atan2(a[i]); }); }
+function checkCeil(a)  { check(function (i) { return Math.ceil(a[i]);  }); }
+function checkCos(a)   { check(function (i) { return Math.cos(a[i]);   }); }
+function checkExp(a)   { check(function (i) { return Math.exp(a[i]);   }); }
+function checkFloor(a) { check(function (i) { return Math.floor(a[i]); }); }
+function checkLog(a)   { check(function (i) { return Math.log(a[i]);   }); }
+function checkRound(a) { check(function (i) { return Math.round(a[i]); }); }
+function checkSin(a)   { check(function (i) { return Math.sin(a[i]);   }); }
+function checkSqrt(a)  { check(function (i) { return Math.sqrt(a[i]);  }); }
+function checkTan(a)   { check(function (i) { return Math.tan(a[i]);   }); }
+
+function callVariousUnaryMathFunctions() {
+  // We might want to consider making this test adopt seedrandom.js
+  // and call Math.seedrandom("seed") here ...
+  // function fill(i) { return (2*Math.random())-1; }
+  // function fill(i) { return (20*Math.random())-10; }
+  //
+  // ... but its easiest to just drop the pseudo-random input entirely.
+  function fill(i) { return 10/i; }
+  var input = Array.build(len, fill);
+
+  checkAbs(input);    //print("abs");
+  checkAcos(input);   //print("acos");
+  checkAsin(input);   //print("asin");
+  checkAtan(input);   //print("atan");
+
+  checkAtan2(input);  //print("atan2");
+  checkCeil(input);   //print("ceil");
+  checkCos(input);    //print("cos");
+  checkExp(input);    //print("exp");
+
+  checkFloor(input);  //print("floor");
+  checkLog(input);    //print("log");
+  checkRound(input);  //print("round");
+  checkSin(input);    //print("sin");
+
+  checkSqrt(input);   //print("sqrt");
+  checkTan(input);    //print("tan");
+}
+
+if (getBuildConfiguration().parallelJS)
+  callVariousUnaryMathFunctions();
--- a/js/src/jit/AliasAnalysis.cpp
+++ b/js/src/jit/AliasAnalysis.cpp
@@ -10,17 +10,17 @@
 
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::Array;
 
 namespace {
 
 // Iterates over the flags in an AliasSet.
 class AliasSetIterator
 {
--- a/js/src/jit/AliasAnalysis.h
+++ b/js/src/jit/AliasAnalysis.h
@@ -6,17 +6,17 @@
 
 #ifndef jit_AliasAnalysis_h
 #define jit_AliasAnalysis_h
 
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MIRGraph;
 
 typedef Vector<MDefinition *, 4, IonAllocPolicy> InstructionVector;
 
 class LoopAliasInfo : public TempObject {
   private:
     LoopAliasInfo *outer_;
@@ -52,11 +52,11 @@ class AliasAnalysis
     LoopAliasInfo *loop_;
 
   public:
     AliasAnalysis(MIRGenerator *mir, MIRGraph &graph);
     bool analyze();
 };
 
 } // namespace js
-} // namespace ion
+} // namespace jit
 
 #endif /* jit_AliasAnalysis_h */
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -30,17 +30,17 @@
 #include "jsinferinlines.h"
 
 #include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
 #include "gc/Barrier-inl.h"
 
 using namespace js;
 using namespace js::frontend;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::AddToHash;
 using mozilla::ArrayLength;
 using mozilla::DebugOnly;
 using mozilla::HashGeneric;
 using mozilla::IsNaN;
 using mozilla::IsNegativeZero;
 using mozilla::Maybe;
@@ -4697,24 +4697,24 @@ CheckFunction(ModuleCompiler &m, LifoAll
 
 static bool
 GenerateCode(ModuleCompiler &m, ModuleCompiler::Func &func, MIRGenerator &mir, LIRGraph &lir)
 {
     int64_t before = PRMJ_Now();
 
     m.masm().bind(func.code());
 
-    ScopedJSDeletePtr<CodeGenerator> codegen(ion::GenerateCode(&mir, &lir, &m.masm()));
+    ScopedJSDeletePtr<CodeGenerator> codegen(jit::GenerateCode(&mir, &lir, &m.masm()));
     if (!codegen)
         return m.fail(NULL, "internal codegen failure (probably out of memory)");
 
     if (!m.collectAccesses(mir))
         return false;
 
-    ion::IonScriptCounts *counts = codegen->extractUnassociatedScriptCounts();
+    jit::IonScriptCounts *counts = codegen->extractUnassociatedScriptCounts();
     if (counts && !m.addFunctionCounts(counts)) {
         js_delete(counts);
         return false;
     }
 
 #ifdef MOZ_VTUNE
     if (IsVTuneProfilingActive() && !m.trackProfiledFunction(func, m.masm().size()))
         return false;
@@ -5373,17 +5373,17 @@ GenerateEntry(ModuleCompiler &m, const A
     // Before calling, we must ensure sp % 16 == 0. Since (sp % 16) = 8 on
     // entry, we need to push 8 (mod 16) bytes.
     //JS_ASSERT(AlignmentAtPrologue == 8);
     JS_ASSERT(masm.framePushed() % 8 == 4);
     unsigned stackDec = numStackArgs * sizeof(double) + (masm.framePushed() >> 2) % 2 * sizeof(uint32_t);
     masm.reserveStack(stackDec);
     //JS_ASSERT(masm.framePushed() % 8 == 0);
     if(getenv("GDB_BREAK")) {
-        masm.breakpoint(js::ion::Assembler::Always);
+        masm.breakpoint(js::jit::Assembler::Always);
     }
     // Copy parameters out of argv into the registers/stack-slots specified by
     // the system ABI.
     for (ABIArgTypeIter iter(func.sig().args()); !iter.done(); iter++) {
         unsigned argOffset = iter.index() * sizeof(uint64_t);
         switch (iter->kind()) {
           case ABIArg::GPR:
             masm.ma_ldr(Operand(argv, argOffset), iter->gpr());
--- a/js/src/jit/AsmJSLink.cpp
+++ b/js/src/jit/AsmJSLink.cpp
@@ -21,17 +21,17 @@
 # include "jit/PerfSpewer.h"
 #endif
 
 #include "jsfuninlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::IsNaN;
 
 static const unsigned MODULE_FUN_SLOT = 0;
 
 static bool
 LinkFail(JSContext *cx, const char *str)
 {
@@ -345,17 +345,17 @@ CallAsmJS(JSContext *cx, unsigned argc, 
             if (!ToNumber(cx, v, (double*)&coercedArgs[i]))
                 return false;
             break;
         }
     }
 
     {
         AsmJSActivation activation(cx, module);
-        ion::IonContext ictx(cx, NULL);
+        jit::IonContext ictx(cx, NULL);
         JitActivation jitActivation(cx, /* firstFrameIsConstructing = */ false, /* active */ false);
 
         // Call into generated code.
 #ifdef JS_CPU_ARM
         if (!func.code()(coercedArgs.begin(), module.globalData()))
             return false;
 #else
         if (!func.code()(coercedArgs.begin()))
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -28,21 +28,21 @@ AsmJSModule::patchHeapAccesses(ArrayBuff
 #if defined(JS_CPU_X86)
     void *heapOffset = (void*)heap->dataPointer();
     void *heapLength = (void*)heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchLengthAt(code_), heapLength);
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchOffsetAt(code_), heapOffset);
     }
 #elif defined(JS_CPU_ARM)
-    ion::IonContext ic(cx, NULL);
-    ion::AutoFlushCache afc("patchBoundsCheck");
+    jit::IonContext ic(cx, NULL);
+    jit::AutoFlushCache afc("patchBoundsCheck");
     uint32_t bits = mozilla::CeilingLog2(heap->byteLength());
     for (unsigned i = 0; i < heapAccesses_.length(); i++)
-        ion::Assembler::updateBoundsCheck(bits, (ion::Instruction*)(heapAccesses_[i].offset() + code_));
+        jit::Assembler::updateBoundsCheck(bits, (jit::Instruction*)(heapAccesses_[i].offset() + code_));
 #endif
 }
 
 static uint8_t *
 AllocateExecutableMemory(ExclusiveContext *cx, size_t totalBytes)
 {
     JS_ASSERT(totalBytes % AsmJSPageSize == 0);
 
@@ -105,17 +105,17 @@ AsmJSModule::~AsmJSModule()
 
             if (!exitDatum.fun->hasScript())
                 continue;
 
             JSScript *script = exitDatum.fun->nonLazyScript();
             if (!script->hasIonScript())
                 continue;
 
-            ion::DependentAsmJSModuleExit exit(this, i);
+            jit::DependentAsmJSModuleExit exit(this, i);
             script->ionScript()->removeDependentAsmJSModule(exit);
         }
 
         DeallocateExecutableMemory(code_, totalBytes_);
     }
 
     for (size_t i = 0; i < numFunctionCounts(); i++)
         js_delete(functionCounts(i));
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -309,34 +309,34 @@ class AsmJSModule
             MarkStringUnbarriered(trc, &name, "asm.js profiled function name");
         }
     };
 #endif
 
 #if defined(JS_ION_PERF)
     struct ProfiledBlocksFunction : public ProfiledFunction
     {
-        ion::PerfSpewer::BasicBlocksVector blocks;
+        jit::PerfSpewer::BasicBlocksVector blocks;
 
-        ProfiledBlocksFunction(JSAtom *name, unsigned start, unsigned end, ion::PerfSpewer::BasicBlocksVector &blocksVector)
+        ProfiledBlocksFunction(JSAtom *name, unsigned start, unsigned end, jit::PerfSpewer::BasicBlocksVector &blocksVector)
           : ProfiledFunction(name, start, end), blocks(mozilla::Move(blocksVector))
         { }
 
         ProfiledBlocksFunction(const ProfiledBlocksFunction &copy)
           : ProfiledFunction(copy.name, copy.startCodeOffset, copy.endCodeOffset), blocks(mozilla::Move(copy.blocks))
         { }
     };
 #endif
 
   private:
     typedef Vector<ExportedFunction, 0, SystemAllocPolicy> ExportedFunctionVector;
     typedef Vector<Global, 0, SystemAllocPolicy> GlobalVector;
     typedef Vector<Exit, 0, SystemAllocPolicy> ExitVector;
-    typedef Vector<ion::AsmJSHeapAccess, 0, SystemAllocPolicy> HeapAccessVector;
-    typedef Vector<ion::IonScriptCounts *, 0, SystemAllocPolicy> FunctionCountsVector;
+    typedef Vector<jit::AsmJSHeapAccess, 0, SystemAllocPolicy> HeapAccessVector;
+    typedef Vector<jit::IonScriptCounts *, 0, SystemAllocPolicy> FunctionCountsVector;
 #if defined(MOZ_VTUNE) or defined(JS_ION_PERF)
     typedef Vector<ProfiledFunction, 0, SystemAllocPolicy> ProfiledFunctionVector;
 #endif
 
     GlobalVector                          globals_;
     ExitVector                            exits_;
     ExportedFunctionVector                exports_;
     HeapAccessVector                      heapAccesses_;
@@ -471,17 +471,17 @@ class AsmJSModule
         if (SIZE_MAX - funcPtrTableAndExitBytes_ < sizeof(ExitDatum))
             return false;
         uint32_t globalDataOffset = globalDataBytes();
         JS_STATIC_ASSERT(sizeof(ExitDatum) % sizeof(void*) == 0);
         funcPtrTableAndExitBytes_ += sizeof(ExitDatum);
         *exitIndex = unsigned(exits_.length());
         return exits_.append(Exit(ffiIndex, globalDataOffset));
     }
-    bool addFunctionCounts(ion::IonScriptCounts *counts) {
+    bool addFunctionCounts(jit::IonScriptCounts *counts) {
         return functionCounts_.append(counts);
     }
 
     bool addExportedFunction(PropertyName *name, PropertyName *maybeFieldName,
                              mozilla::MoveRef<ArgCoercionVector> argCoercions,
                              ReturnType returnType)
     {
         ExportedFunction func(name, maybeFieldName, argCoercions, returnType);
@@ -517,17 +517,17 @@ class AsmJSModule
     }
     unsigned numPerfFunctions() const {
         return perfProfiledFunctions_.length();
     }
     const ProfiledFunction &perfProfiledFunction(unsigned i) const {
         return perfProfiledFunctions_[i];
     }
 
-    bool trackPerfProfiledBlocks(JSAtom *name, unsigned startCodeOffset, unsigned endCodeOffset, ion::PerfSpewer::BasicBlocksVector &basicBlocks) {
+    bool trackPerfProfiledBlocks(JSAtom *name, unsigned startCodeOffset, unsigned endCodeOffset, jit::PerfSpewer::BasicBlocksVector &basicBlocks) {
         ProfiledBlocksFunction func(name, startCodeOffset, endCodeOffset, basicBlocks);
         return perfProfiledBlocksFunctions_.append(func);
     }
     unsigned numPerfBlocksFunctions() const {
         return perfProfiledBlocksFunctions_.length();
     }
     const ProfiledBlocksFunction perfProfiledBlocksFunction(unsigned i) const {
         return perfProfiledBlocksFunctions_[i];
@@ -555,17 +555,17 @@ class AsmJSModule
         return exits_[i];
     }
     const Exit &exit(unsigned i) const {
         return exits_[i];
     }
     unsigned numFunctionCounts() const {
         return functionCounts_.length();
     }
-    ion::IonScriptCounts *functionCounts(unsigned i) {
+    jit::IonScriptCounts *functionCounts(unsigned i) {
         return functionCounts_[i];
     }
 
     // An Exit holds bookkeeping information about an exit; the ExitDatum
     // struct overlays the actual runtime data stored in the global data
     // section.
     struct ExitDatum
     {
@@ -628,26 +628,26 @@ class AsmJSModule
         JS_ASSERT(functionBytes_ % AsmJSPageSize == 0);
         return functionBytes_;
     }
     bool containsPC(void *pc) const {
         uint8_t *code = functionCode();
         return pc >= code && pc < (code + functionBytes());
     }
 
-    bool addHeapAccesses(const ion::AsmJSHeapAccessVector &accesses) {
+    bool addHeapAccesses(const jit::AsmJSHeapAccessVector &accesses) {
         return heapAccesses_.appendAll(accesses);
     }
     unsigned numHeapAccesses() const {
         return heapAccesses_.length();
     }
-    ion::AsmJSHeapAccess &heapAccess(unsigned i) {
+    jit::AsmJSHeapAccess &heapAccess(unsigned i) {
         return heapAccesses_[i];
     }
-    const ion::AsmJSHeapAccess &heapAccess(unsigned i) const {
+    const jit::AsmJSHeapAccess &heapAccess(unsigned i) const {
         return heapAccesses_[i];
     }
     void patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx);
 
     uint8_t *allocateCodeAndGlobalSegment(ExclusiveContext *cx, size_t bytesNeeded);
 
     uint8_t *functionCode() const {
         JS_ASSERT(code_);
--- a/js/src/jit/AsmJSSignalHandlers.cpp
+++ b/js/src/jit/AsmJSSignalHandlers.cpp
@@ -7,17 +7,17 @@
 #include "jit/AsmJSSignalHandlers.h"
 
 #include "assembler/assembler/MacroAssembler.h"
 #include "jit/AsmJSModule.h"
 
 #include "vm/ObjectImpl-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 using namespace mozilla;
 
 #if defined(XP_WIN)
 # define XMM_sig(p,i) ((p)->Xmm##i)
 # define EIP_sig(p) ((p)->Eip)
 # define RIP_sig(p) ((p)->Rip)
 # define RAX_sig(p) ((p)->Rax)
 # define RCX_sig(p) ((p)->Rcx)
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BacktrackingAllocator.h"
 
 #include "jsprf.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 bool
 BacktrackingAllocator::init()
 {
     RegisterSet remainingRegisters(allRegisters_);
     while (!remainingRegisters.empty(/* float = */ false)) {
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -14,17 +14,17 @@
 #include "jit/LiveRangeAllocator.h"
 
 // Backtracking priority queue based register allocator based on that described
 // in the following blog post:
 //
 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // Information about a group of registers. Registers may be grouped together
 // when (a) all of their lifetimes are disjoint, (b) they are of the same type
 // (double / non-double) and (c) it is desirable that they have the same
 // allocation.
 struct VirtualRegisterGroup : public TempObject
 {
     // All virtual registers in the group.
@@ -226,12 +226,12 @@ class BacktrackingAllocator : public Liv
 
     bool chooseIntervalSplit(LiveInterval *interval);
     bool trySplitAcrossHotcode(LiveInterval *interval, bool *success);
     bool trySplitAfterLastRegisterUse(LiveInterval *interval, bool *success);
     bool splitAtAllRegisterUses(LiveInterval *interval);
     bool splitAcrossCalls(LiveInterval *interval);
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_BacktrackingAllocator_h */
--- a/js/src/jit/Bailouts.cpp
+++ b/js/src/jit/Bailouts.cpp
@@ -14,17 +14,17 @@
 #include "jit/IonSpewer.h"
 #include "jit/SnapshotReader.h"
 
 #include "jsobjinlines.h"
 
 #include "vm/Stack-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 // These constructor are exactly the same except for the type of the iterator
 // which is given to the SnapshotIterator constructor. Doing so avoid the
 // creation of virtual functions for the IonIterator but may introduce some
 // weirdness as IonInlineIterator is using an IonFrameIterator reference.
 //
 // If a function relies on ionScript() or to use OsiIndex(), due to the
 // lack of virtual, these functions will use the IonFrameIterator reference
@@ -58,17 +58,17 @@ IonBailoutIterator::dump() const
             ++frames;
         }
     } else {
         IonFrameIterator::dump();
     }
 }
 
 uint32_t
-ion::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
+jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
 {
     JS_ASSERT(bailoutInfo);
     JSContext *cx = GetIonContext()->cx;
     // We don't have an exit frame.
     cx->mainThread().ionTop = NULL;
     JitActivationIterator jitActivations(cx->runtime());
     IonBailoutIterator iter(jitActivations, sp);
     JitActivation *activation = jitActivations.activation()->asJit();
@@ -86,17 +86,17 @@ ion::Bailout(BailoutStack *sp, BaselineB
 
     if (retval != BAILOUT_RETURN_OK)
         EnsureExitFrame(iter.jsFrame());
 
     return retval;
 }
 
 uint32_t
-ion::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
+jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
                          BaselineBailoutInfo **bailoutInfo)
 {
     sp->checkInvariants();
 
     JSContext *cx = GetIonContext()->cx;
 
     // We don't have an exit frame.
     cx->mainThread().ionTop = NULL;
@@ -149,17 +149,17 @@ IonBailoutIterator::IonBailoutIterator(c
 
     current_ = (uint8_t *) frame.fp();
     type_ = IonFrame_OptimizedJS;
     topFrameSize_ = frame.frameSize();
     snapshotOffset_ = osiIndex->snapshotOffset();
 }
 
 uint32_t
-ion::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
+jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
                              const ExceptionBailoutInfo &excInfo,
                              BaselineBailoutInfo **bailoutInfo)
 {
     JS_ASSERT(cx->isExceptionPending());
 
     cx->mainThread().ionTop = NULL;
     JitActivationIterator jitActivations(cx->runtime());
     IonBailoutIterator iter(jitActivations, frame.frame());
@@ -173,29 +173,29 @@ ion::ExceptionHandlerBailout(JSContext *
 
     JS_ASSERT((retval == BAILOUT_RETURN_OK) == (*bailoutInfo != NULL));
 
     return retval;
 }
 
 // Initialize the decl env Object, call object, and any arguments obj of the current frame.
 bool
-ion::EnsureHasScopeObjects(JSContext *cx, AbstractFramePtr fp)
+jit::EnsureHasScopeObjects(JSContext *cx, AbstractFramePtr fp)
 {
     if (fp.isFunctionFrame() &&
         fp.fun()->isHeavyweight() &&
         !fp.hasCallObj())
     {
         return fp.initFunctionScopeObjects(cx);
     }
     return true;
 }
 
 bool
-ion::CheckFrequentBailouts(JSContext *cx, JSScript *script)
+jit::CheckFrequentBailouts(JSContext *cx, JSScript *script)
 {
     if (script->hasIonScript()) {
         // Invalidate if this script keeps bailing out without invalidation. Next time
         // we compile this script LICM will be disabled.
         IonScript *ionScript = script->ionScript();
 
         if (ionScript->numBailouts() >= js_IonOptions.frequentBailoutThreshold &&
             !script->hadFrequentBailouts)
--- a/js/src/jit/Bailouts.h
+++ b/js/src/jit/Bailouts.h
@@ -9,17 +9,17 @@
 
 #include "jstypes.h"
 
 #include "jit/IonFrameIterator.h"
 #include "jit/IonFrames.h"
 #include "vm/Stack.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // A "bailout" is a condition in which we need to recover an interpreter frame
 // from an IonFrame. Bailouts can happen for the following reasons:
 //   (1) A deoptimization guard, for example, an add overflows or a type check
 //       fails.
 //   (2) A check or assumption held by the JIT is invalidated by the VM, and
 //       JIT code must be thrown away. This includes the GC possibly deciding
 //       to evict live JIT code, or a Type Inference reflow.
@@ -170,12 +170,12 @@ struct ExceptionBailoutInfo
 uint32_t ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
                                  const ExceptionBailoutInfo &excInfo,
                                  BaselineBailoutInfo **bailoutInfo);
 
 uint32_t FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo);
 
 bool CheckFrequentBailouts(JSContext *cx, JSScript *script);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_Bailouts_h */
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -12,17 +12,17 @@
 #include "vm/ArgumentsObject.h"
 
 #include "jsfuninlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/IonFrames-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 // BaselineStackBuilder may reallocate its buffer if the current one is too
 // small. To avoid dangling pointers, BufferPointer represents a pointer into
 // this buffer as a pointer to the header and a fixed offset.
 template <typename T>
 class BufferPointer
 {
     BaselineBailoutInfo **header_;
@@ -1174,17 +1174,17 @@ InitFromBailout(JSContext *cx, HandleScr
     JS_ASSERT(rectReturnAddr);
     if (!builder.writePtr(rectReturnAddr, "ReturnAddr"))
         return false;
 
     return true;
 }
 
 uint32_t
-ion::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIterator &iter,
+jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIterator &iter,
                           bool invalidate, BaselineBailoutInfo **bailoutInfo,
                           const ExceptionBailoutInfo *excInfo)
 {
     JS_ASSERT(bailoutInfo != NULL);
     JS_ASSERT(*bailoutInfo == NULL);
 
 #if JS_TRACE_LOGGING
     TraceLogging::defaultLogger()->log(TraceLogging::INFO_ENGINE_BASELINE);
@@ -1391,17 +1391,17 @@ HandleCachedShapeGuardFailure(JSContext 
     // an unoptimizable access was made, also preventing mono IC caching.
 
     IonSpew(IonSpew_BaselineBailouts, "Invalidating due to cached shape guard failure");
 
     return Invalidate(cx, outerScript);
 }
 
 uint32_t
-ion::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo)
+jit::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo)
 {
     // The caller pushes R0 and R1 on the stack without rooting them.
     // Since GC here is very unlikely just suppress it.
     JSContext *cx = GetIonContext()->cx;
     js::gc::AutoSuppressGC suppressGC(cx);
 
     IonSpew(IonSpew_BaselineBailouts, "  Done restoring frames");
 
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -14,17 +14,17 @@
 #include "jit/IonSpewer.h"
 #include "jit/VMFunctions.h"
 
 #include "jsscriptinlines.h"
 
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 BaselineCompiler::BaselineCompiler(JSContext *cx, HandleScript script)
   : BaselineCompilerSpecific(cx, script),
     modifiesArguments_(false)
 {
 }
 
 bool
@@ -329,17 +329,17 @@ BaselineCompiler::emitIC(ICStub *stub, b
     entry->setReturnOffset(masm.currentOffset());
     if (!addICLoadLabel(patchOffset))
         return false;
 
     return true;
 }
 
 typedef bool (*DebugPrologueFn)(JSContext *, BaselineFrame *, bool *);
-static const VMFunction DebugPrologueInfo = FunctionInfo<DebugPrologueFn>(ion::DebugPrologue);
+static const VMFunction DebugPrologueInfo = FunctionInfo<DebugPrologueFn>(jit::DebugPrologue);
 
 bool
 BaselineCompiler::emitDebugPrologue()
 {
     if (!debugMode_)
         return true;
 
     // Load pointer to BaselineFrame in R0.
@@ -359,21 +359,21 @@ BaselineCompiler::emitDebugPrologue()
         masm.jump(&return_);
     }
     masm.bind(&done);
     return true;
 }
 
 typedef bool (*StrictEvalPrologueFn)(JSContext *, BaselineFrame *);
 static const VMFunction StrictEvalPrologueInfo =
-    FunctionInfo<StrictEvalPrologueFn>(ion::StrictEvalPrologue);
+    FunctionInfo<StrictEvalPrologueFn>(jit::StrictEvalPrologue);
 
 typedef bool (*HeavyweightFunPrologueFn)(JSContext *, BaselineFrame *);
 static const VMFunction HeavyweightFunPrologueInfo =
-    FunctionInfo<HeavyweightFunPrologueFn>(ion::HeavyweightFunPrologue);
+    FunctionInfo<HeavyweightFunPrologueFn>(jit::HeavyweightFunPrologue);
 
 bool
 BaselineCompiler::initScopeChain()
 {
     RootedFunction fun(cx, function());
     if (fun) {
         // Use callee->environment as scope chain. Note that we do
         // this also for heavy-weight functions, so that the scope
@@ -2373,17 +2373,17 @@ BaselineCompiler::emit_JSOP_RETSUB()
 {
     frame.popRegsAndSync(2);
 
     ICRetSub_Fallback::Compiler stubCompiler(cx);
     return emitOpIC(stubCompiler.getStub(&stubSpace_));
 }
 
 typedef bool (*EnterBlockFn)(JSContext *, BaselineFrame *, Handle<StaticBlockObject *>);
-static const VMFunction EnterBlockInfo = FunctionInfo<EnterBlockFn>(ion::EnterBlock);
+static const VMFunction EnterBlockInfo = FunctionInfo<EnterBlockFn>(jit::EnterBlock);
 
 bool
 BaselineCompiler::emitEnterBlock()
 {
     StaticBlockObject &blockObj = script->getObject(pc)->as<StaticBlockObject>();
 
     if (JSOp(*pc) == JSOP_ENTERBLOCK) {
         for (size_t i = 0; i < blockObj.slotCount(); i++)
@@ -2418,17 +2418,17 @@ BaselineCompiler::emit_JSOP_ENTERLET0()
 
 bool
 BaselineCompiler::emit_JSOP_ENTERLET1()
 {
     return emitEnterBlock();
 }
 
 typedef bool (*LeaveBlockFn)(JSContext *, BaselineFrame *);
-static const VMFunction LeaveBlockInfo = FunctionInfo<LeaveBlockFn>(ion::LeaveBlock);
+static const VMFunction LeaveBlockInfo = FunctionInfo<LeaveBlockFn>(jit::LeaveBlock);
 
 bool
 BaselineCompiler::emitLeaveBlock()
 {
     // Call a stub to pop the block from the block chain.
     prepareVMCall();
 
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
@@ -2485,17 +2485,17 @@ BaselineCompiler::emit_JSOP_EXCEPTION()
         return false;
 
     frame.push(R0);
     return true;
 }
 
 typedef bool (*OnDebuggerStatementFn)(JSContext *, BaselineFrame *, jsbytecode *pc, bool *);
 static const VMFunction OnDebuggerStatementInfo =
-    FunctionInfo<OnDebuggerStatementFn>(ion::OnDebuggerStatement);
+    FunctionInfo<OnDebuggerStatementFn>(jit::OnDebuggerStatement);
 
 bool
 BaselineCompiler::emit_JSOP_DEBUGGER()
 {
     prepareVMCall();
     pushArg(ImmWord(pc));
 
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
@@ -2511,17 +2511,17 @@ BaselineCompiler::emit_JSOP_DEBUGGER()
         masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
         masm.jump(&return_);
     }
     masm.bind(&done);
     return true;
 }
 
 typedef bool (*DebugEpilogueFn)(JSContext *, BaselineFrame *, bool);
-static const VMFunction DebugEpilogueInfo = FunctionInfo<DebugEpilogueFn>(ion::DebugEpilogue);
+static const VMFunction DebugEpilogueInfo = FunctionInfo<DebugEpilogueFn>(jit::DebugEpilogue);
 
 bool
 BaselineCompiler::emitReturn()
 {
     if (debugMode_) {
         // Move return value into the frame's rval slot.
         masm.storeValue(JSReturnOperand, frame.addressOfReturnValue());
         masm.or32(Imm32(BaselineFrame::HAS_RVAL), frame.addressOfFlags());
@@ -2699,17 +2699,17 @@ BaselineCompiler::emit_JSOP_CALLEE()
 bool
 BaselineCompiler::emit_JSOP_POPV()
 {
     return emit_JSOP_SETRVAL();
 }
 
 typedef bool (*NewArgumentsObjectFn)(JSContext *, BaselineFrame *, MutableHandleValue);
 static const VMFunction NewArgumentsObjectInfo =
-    FunctionInfo<NewArgumentsObjectFn>(ion::NewArgumentsObject);
+    FunctionInfo<NewArgumentsObjectFn>(jit::NewArgumentsObject);
 
 bool
 BaselineCompiler::emit_JSOP_ARGUMENTS()
 {
     frame.syncStack(0);
 
     Label done;
     if (!script->argumentsHasVarBinding() || !script->needsArgsObj()) {
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -19,17 +19,17 @@
 # include "jit/x86/BaselineCompiler-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/BaselineCompiler-x64.h"
 #else
 # include "jit/arm/BaselineCompiler-arm.h"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
 #define OPCODE_LIST(_)         \
     _(JSOP_NOP)                \
     _(JSOP_LABEL)              \
     _(JSOP_NOTEARG)            \
     _(JSOP_POP)                \
     _(JSOP_POPN)               \
     _(JSOP_DUP)                \
@@ -258,14 +258,14 @@ class BaselineCompiler : public Baseline
 
     bool addPCMappingEntry(bool addIndexEntry);
 
     void getScopeCoordinateObject(Register reg);
     Address getScopeCoordinateAddressFromObject(Register objReg, Register reg);
     Address getScopeCoordinateAddress(Register reg);
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineCompiler_h */
--- a/js/src/jit/BaselineFrame-inl.h
+++ b/js/src/jit/BaselineFrame-inl.h
@@ -13,17 +13,17 @@
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
 #include "jit/IonFrames.h"
 #include "vm/ScopeObject.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 inline void
 BaselineFrame::pushOnScopeChain(ScopeObject &scope)
 {
     JS_ASSERT(*scopeChain() == scope.enclosingScope() ||
               *scopeChain() == scope.as<CallObject>().enclosingScope().as<DeclEnvObject>().enclosingScope());
     scopeChain_ = &scope;
 }
@@ -74,14 +74,14 @@ BaselineFrame::callObj() const
     JS_ASSERT(fun()->isHeavyweight());
 
     JSObject *obj = scopeChain();
     while (!obj->is<CallObject>())
         obj = obj->enclosingScope();
     return obj->as<CallObject>();
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineFrame_inl_h */
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -13,17 +13,17 @@
 #include "vm/ScopeObject.h"
 
 #include "jsobjinlines.h"
 
 #include "jit/IonFrames-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 void
 BaselineFrame::trace(JSTracer *trc)
 {
     replaceCalleeToken(MarkCalleeToken(trc, calleeToken()));
 
     gc::MarkValueRoot(trc, &thisValue(), "baseline-this");
 
--- a/js/src/jit/BaselineFrame.h
+++ b/js/src/jit/BaselineFrame.h
@@ -11,17 +11,17 @@
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
 #include "jit/IonFrames.h"
 #include "vm/Stack.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // The stack looks like this, fp is the frame pointer:
 //
 // fp+y   arguments
 // fp+x   IonJSFrameLayout (frame header)
 // fp  => saved frame pointer
 // fp-x   BaselineFrame
 //        locals
@@ -343,26 +343,26 @@ class BaselineFrame
 
     IonJSFrameLayout *framePrefix() const {
         uint8_t *fp = (uint8_t *)this + Size() + FramePointerOffset;
         return (IonJSFrameLayout *)fp;
     }
 
     // Methods below are used by the compiler.
     static size_t offsetOfCalleeToken() {
-        return FramePointerOffset + js::ion::IonJSFrameLayout::offsetOfCalleeToken();
+        return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfCalleeToken();
     }
     static size_t offsetOfThis() {
-        return FramePointerOffset + js::ion::IonJSFrameLayout::offsetOfThis();
+        return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfThis();
     }
     static size_t offsetOfArg(size_t index) {
-        return FramePointerOffset + js::ion::IonJSFrameLayout::offsetOfActualArg(index);
+        return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfActualArg(index);
     }
     static size_t offsetOfNumActualArgs() {
-        return FramePointerOffset + js::ion::IonJSFrameLayout::offsetOfNumActualArgs();
+        return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfNumActualArgs();
     }
     static size_t Size() {
         return sizeof(BaselineFrame);
     }
 
     // The reverseOffsetOf methods below compute the offset relative to the
     // frame's base pointer. Since the stack grows down, these offsets are
     // negative.
@@ -393,14 +393,14 @@ class BaselineFrame
     static int reverseOffsetOfLocal(size_t index) {
         return -int(Size()) - (index + 1) * sizeof(Value);
     }
 };
 
 // Ensure the frame is 8-byte aligned (required on ARM).
 JS_STATIC_ASSERT(((sizeof(BaselineFrame) + BaselineFrame::FramePointerOffset) % 8) == 0);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineFrame_h */
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BaselineFrameInfo.h"
 
 #include "jit/IonSpewer.h"
 #include "jit/shared/BaselineCompiler-shared.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 bool
 FrameInfo::init() {
     // One slot is always needed for this/arguments type checks.
     size_t nstack = Max(script->nslots - script->nfixed, 1);
     if (!stack.init(nstack))
         return false;
 
--- a/js/src/jit/BaselineFrameInfo.h
+++ b/js/src/jit/BaselineFrameInfo.h
@@ -14,17 +14,17 @@
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineJIT.h"
 #include "jit/BaselineRegisters.h"
 #include "jit/BytecodeAnalysis.h"
 #include "jit/FixedList.h"
 #include "jit/IonMacroAssembler.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // FrameInfo overview.
 //
 // FrameInfo is used by the compiler to track values stored in the frame. This
 // includes locals, arguments and stack values. Locals and arguments are always
 // fully synced. Stack values can either be synced, stored as constant, stored in
 // a Value register or refer to a local slot. Syncing a StackValue ensures it's
 // stored on the stack, e.g. kind == Stack.
@@ -322,14 +322,14 @@ class FrameInfo
 #ifdef DEBUG
     // Assert the state is valid before excuting "pc".
     void assertValidState(const BytecodeInfo &info);
 #else
     inline void assertValidState(const BytecodeInfo &info) {}
 #endif
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineFrameInfo_h */
--- a/js/src/jit/BaselineHelpers.h
+++ b/js/src/jit/BaselineHelpers.h
@@ -15,16 +15,16 @@
 # include "jit/x64/BaselineHelpers-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/BaselineHelpers-arm.h"
 #else
 # error "Unknown architecture!"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineHelpers_h */
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -19,17 +19,17 @@
 
 #include "jsboolinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Interpreter-inl.h"
 #include "vm/ScopeObject-inl.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 #ifdef DEBUG
 void
 FallbackICSpew(JSContext *cx, ICFallbackStub *stub, const char *fmt, ...)
 {
     if (IonSpewEnabled(IonSpew_BaselineICFallback)) {
         RootedScript script(cx, GetTopIonJSScript(cx));
         jsbytecode *pc = stub->icEntry()->pc(script);
@@ -852,17 +852,17 @@ PrepareOsrTempData(JSContext *cx, ICUseC
 static bool
 DoUseCountFallback(JSContext *cx, ICUseCount_Fallback *stub, BaselineFrame *frame,
                    IonOsrTempData **infoPtr)
 {
     JS_ASSERT(infoPtr);
     *infoPtr = NULL;
 
     // A TI OOM will disable TI and Ion.
-    if (!ion::IsEnabled(cx))
+    if (!jit::IsIonEnabled(cx))
         return true;
 
     RootedScript script(cx, frame->script());
     jsbytecode *pc = stub->icEntry()->pc(script);
     bool isLoopEntry = JSOp(*pc) == JSOP_LOOPENTRY;
 
     FallbackICSpew(cx, stub, "UseCount(%d)", isLoopEntry ? int(pc - script->code) : int(-1));
 
@@ -8611,10 +8611,10 @@ ICGetProp_DOMProxyShadowed::ICGetProp_DO
                                                        uint32_t pcOffset)
   : ICMonitoredStub(ICStub::GetProp_DOMProxyShadowed, stubCode, firstMonitorStub),
     shape_(shape),
     proxyHandler_(proxyHandler),
     name_(name),
     pcOffset_(pcOffset)
 { }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -13,17 +13,17 @@
 #include "jscompartment.h"
 #include "jsgc.h"
 #include "jsopcode.h"
 
 #include "jit/BaselineJIT.h"
 #include "jit/BaselineRegisters.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 //
 // Baseline Inline Caches are polymorphic caches that aggressively
 // share their stub code.
 //
 // Every polymorphic site contains a linked list of stubs which are
 // specific to that site.  These stubs are composed of a |StubData|
 // structure that stores parametrization information (e.g.
@@ -1024,16 +1024,17 @@ class ICStubCompiler
     // given label.
     void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip);
 
     inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const {
         GeneralRegisterSet regs(GeneralRegisterSet::All());
         JS_ASSERT(!regs.has(BaselineStackReg));
 #ifdef JS_CPU_ARM
         JS_ASSERT(!regs.has(BaselineTailCallReg));
+        regs.take(BaselineSecondScratchReg);
 #endif
         regs.take(BaselineFrameReg);
         regs.take(BaselineStubReg);
 #ifdef JS_CPU_X64
         regs.take(ExtractTemp0);
         regs.take(ExtractTemp1);
 #endif
 
@@ -5613,14 +5614,14 @@ class ICRetSub_Resume : public ICStub
         { }
 
         ICStub *getStub(ICStubSpace *space) {
             return ICRetSub_Resume::New(space, getStubCode(), pcOffset_, addr_);
         }
     };
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineIC_h */
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -6,17 +6,17 @@
 
 #include "jit/BaselineInspector.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "jit/BaselineIC.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 bool
 SetElemICInspector::sawOOBDenseWrite() const
 {
     if (!icEntry_)
         return false;
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -9,17 +9,17 @@
 
 #ifdef JS_ION
 
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/MIR.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class BaselineInspector;
 
 class ICInspector
 {
   protected:
     BaselineInspector *inspector_;
     jsbytecode *pc_;
@@ -104,14 +104,14 @@ class BaselineInspector
     MIRType expectedBinaryArithSpecialization(jsbytecode *pc);
 
     bool hasSeenNonNativeGetElement(jsbytecode *pc);
     bool hasSeenNegativeIndexGetElement(jsbytecode *pc);
     bool hasSeenAccessedGetter(jsbytecode *pc);
     bool hasSeenDoubleResult(jsbytecode *pc);
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineInspector_h */
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -18,17 +18,17 @@
 #include "jsobjinlines.h"
 #include "jsopcodeinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/IonFrames-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 /* static */ PCMappingSlotInfo::SlotLocation
 PCMappingSlotInfo::ToSlotLocation(const StackValue *stackVal)
 {
     if (stackVal->kind() == StackValue::Register) {
         if (stackVal->reg() == R0)
             return SlotInR0;
         JS_ASSERT(stackVal->reg() == R1);
@@ -81,17 +81,17 @@ IsJSDEnabled(JSContext *cx)
 {
     return cx->compartment()->debugMode() && cx->runtime()->debugHooks.callHook;
 }
 
 static IonExecStatus
 EnterBaseline(JSContext *cx, EnterJitData &data)
 {
     JS_CHECK_RECURSION(cx, return IonExec_Aborted);
-    JS_ASSERT(ion::IsBaselineEnabled(cx));
+    JS_ASSERT(jit::IsBaselineEnabled(cx));
     JS_ASSERT_IF(data.osrFrame, CheckFrame(data.osrFrame));
 
     EnterIonCode enter = cx->runtime()->ionRuntime()->enterBaseline();
 
     // Caller must construct |this| before invoking the Ion function.
     JS_ASSERT_IF(data.constructing, data.maxArgv[0].isObject());
 
     data.result.setInt32(data.numActualArgs);
@@ -124,17 +124,17 @@ EnterBaseline(JSContext *cx, EnterJitDat
     // Release temporary buffer used for OSR into Ion.
     cx->runtime()->getIonRuntime(cx)->freeOsrTempData();
 
     JS_ASSERT_IF(data.result.isMagic(), data.result.isMagic(JS_ION_ERROR));
     return data.result.isMagic() ? IonExec_Error : IonExec_Ok;
 }
 
 IonExecStatus
-ion::EnterBaselineMethod(JSContext *cx, RunState &state)
+jit::EnterBaselineMethod(JSContext *cx, RunState &state)
 {
     BaselineScript *baseline = state.script()->baselineScript();
 
     EnterJitData data(cx);
     data.jitcode = baseline->method()->raw();
 
     AutoValueVector vals(cx);
     if (!SetEnterJitData(cx, data, state, vals))
@@ -144,17 +144,17 @@ ion::EnterBaselineMethod(JSContext *cx, 
     if (status != IonExec_Ok)
         return status;
 
     state.setReturnValue(data.result);
     return IonExec_Ok;
 }
 
 IonExecStatus
-ion::EnterBaselineAtBranch(JSContext *cx, StackFrame *fp, jsbytecode *pc)
+jit::EnterBaselineAtBranch(JSContext *cx, StackFrame *fp, jsbytecode *pc)
 {
     JS_ASSERT(JSOp(*pc) == JSOP_LOOPENTRY);
 
     BaselineScript *baseline = fp->script()->baselineScript();
 
     EnterJitData data(cx);
     data.jitcode = baseline->nativeCodeForPC(fp->script(), pc);
 
@@ -230,17 +230,17 @@ BaselineCompile(JSContext *cx, HandleScr
         script->setBaselineScript(BASELINE_DISABLED_SCRIPT);
 
     return status;
 }
 
 static MethodStatus
 CanEnterBaselineJIT(JSContext *cx, HandleScript script, bool osr)
 {
-    JS_ASSERT(ion::IsBaselineEnabled(cx));
+    JS_ASSERT(jit::IsBaselineEnabled(cx));
 
     // Skip if the script has been disabled.
     if (!script->canBaselineCompile())
         return Method_Skipped;
 
     if (script->length > BaselineScript::MAX_JSSCRIPT_LENGTH)
         return Method_CantCompile;
 
@@ -281,17 +281,17 @@ CanEnterBaselineJIT(JSContext *cx, Handl
                 return status;
         }
     }
 
     return BaselineCompile(cx, script);
 }
 
 MethodStatus
-ion::CanEnterBaselineAtBranch(JSContext *cx, StackFrame *fp, bool newType)
+jit::CanEnterBaselineAtBranch(JSContext *cx, StackFrame *fp, bool newType)
 {
    // If constructing, allocate a new |this| object.
    if (fp->isConstructing() && fp->functionThis().isPrimitive()) {
        RootedObject callee(cx, &fp->callee());
        RootedObject obj(cx, CreateThisForFunction(cx, callee, newType));
        if (!obj)
            return Method_Skipped;
        fp->functionThis().setObject(*obj);
@@ -300,17 +300,17 @@ ion::CanEnterBaselineAtBranch(JSContext 
    if (!CheckFrame(fp))
        return Method_CantCompile;
 
    RootedScript script(cx, fp->script());
    return CanEnterBaselineJIT(cx, script, /* osr = */true);
 }
 
 MethodStatus
-ion::CanEnterBaselineMethod(JSContext *cx, RunState &state)
+jit::CanEnterBaselineMethod(JSContext *cx, RunState &state)
 {
     if (state.isInvoke()) {
         InvokeState &invoke = *state.asInvoke();
 
         if (invoke.args().length() > BASELINE_MAX_ARGS_LENGTH) {
             IonSpew(IonSpew_BaselineAbort, "Too many arguments (%u)", invoke.args().length());
             return Method_CantCompile;
         }
@@ -832,17 +832,17 @@ BaselineScript::purgeOptimizedStubs(Zone
             JS_ASSERT(stub->allocatedInFallbackSpace());
             stub = stub->next();
         }
     }
 #endif
 }
 
 void
-ion::FinishDiscardBaselineScript(FreeOp *fop, JSScript *script)
+jit::FinishDiscardBaselineScript(FreeOp *fop, JSScript *script)
 {
     if (!script->hasBaselineScript())
         return;
 
     if (script->baselineScript()->active()) {
         // Script is live on the stack. Keep the BaselineScript, but destroy
         // stubs allocated in the optimized stub space.
         script->baselineScript()->purgeOptimizedStubs(script->zone());
@@ -854,52 +854,52 @@ ion::FinishDiscardBaselineScript(FreeOp 
     }
 
     BaselineScript *baseline = script->baselineScript();
     script->setBaselineScript(NULL);
     BaselineScript::Destroy(fop, baseline);
 }
 
 void
-ion::IonCompartment::toggleBaselineStubBarriers(bool enabled)
+jit::IonCompartment::toggleBaselineStubBarriers(bool enabled)
 {
     for (ICStubCodeMap::Enum e(*stubCodes_); !e.empty(); e.popFront()) {
         IonCode *code = *e.front().value.unsafeGet();
         code->togglePreBarriers(enabled);
     }
 }
 
 void
-ion::SizeOfBaselineData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf, size_t *data,
+jit::SizeOfBaselineData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf, size_t *data,
                         size_t *fallbackStubs)
 {
     *data = 0;
     *fallbackStubs = 0;
 
     if (script->hasBaselineScript())
         script->baselineScript()->sizeOfIncludingThis(mallocSizeOf, data, fallbackStubs);
 }
 
 void
-ion::ToggleBaselineSPS(JSRuntime *runtime, bool enable)
+jit::ToggleBaselineSPS(JSRuntime *runtime, bool enable)
 {
     for (ZonesIter zone(runtime); !zone.done(); zone.next()) {
         for (gc::CellIter i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
             if (!script->hasBaselineScript())
                 continue;
             script->baselineScript()->toggleSPS(enable);
         }
     }
 }
 
 static void
 MarkActiveBaselineScripts(JSRuntime *rt, const JitActivationIterator &activation)
 {
-    for (ion::IonFrameIterator iter(activation); !iter.done(); ++iter) {
+    for (jit::IonFrameIterator iter(activation); !iter.done(); ++iter) {
         switch (iter.type()) {
           case IonFrame_BaselineJS:
             iter.script()->baselineScript()->setActive();
             break;
           case IonFrame_OptimizedJS: {
             // Keep the baseline script around, since bailouts from the ion
             // jitcode might need to re-enter into the baseline jitcode.
             iter.script()->baselineScript()->setActive();
@@ -908,16 +908,16 @@ MarkActiveBaselineScripts(JSRuntime *rt,
             break;
           }
           default:;
         }
     }
 }
 
 void
-ion::MarkActiveBaselineScripts(Zone *zone)
+jit::MarkActiveBaselineScripts(Zone *zone)
 {
     JSRuntime *rt = zone->runtimeFromMainThread();
     for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
         if (iter.activation()->compartment()->zone() == zone)
             MarkActiveBaselineScripts(rt, iter);
     }
 }
--- a/js/src/jit/BaselineJIT.h
+++ b/js/src/jit/BaselineJIT.h
@@ -15,17 +15,17 @@
 #include "jscompartment.h"
 
 #include "ds/LifoAlloc.h"
 #include "jit/Bailouts.h"
 #include "jit/IonCode.h"
 #include "jit/IonMacroAssembler.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class StackValue;
 class ICEntry;
 class ICStub;
 
 class PCMappingSlotInfo
 {
     uint8_t slotInfo_;
@@ -342,14 +342,14 @@ BailoutIonToBaseline(JSContext *cx, JitA
                      bool invalidate, BaselineBailoutInfo **bailoutInfo,
                      const ExceptionBailoutInfo *exceptionInfo = NULL);
 
 // Mark baseline scripts on the stack as active, so that they are not discarded
 // during GC.
 void
 MarkActiveBaselineScripts(Zone *zone);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineJIT_h */
--- a/js/src/jit/BaselineRegisters.h
+++ b/js/src/jit/BaselineRegisters.h
@@ -13,16 +13,16 @@
 # include "jit/x86/BaselineRegisters-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/BaselineRegisters-x64.h"
 #else
 # include "jit/arm/BaselineRegisters-arm.h"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_BaselineRegisters_h */
--- a/js/src/jit/BitSet.cpp
+++ b/js/src/jit/BitSet.cpp
@@ -2,17 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BitSet.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 BitSet *
 BitSet::New(unsigned int max)
 {
     BitSet *result = new BitSet(max);
     if (!result->init())
         return NULL;
     return result;
--- a/js/src/jit/BitSet.h
+++ b/js/src/jit/BitSet.h
@@ -7,17 +7,17 @@
 #ifndef jit_BitSet_h
 #define jit_BitSet_h
 
 #include "mozilla/MathAlgorithms.h"
 
 #include "jit/IonAllocPolicy.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // Provides constant time set insertion and removal, and fast linear
 // set operations such as intersection, difference, and union.
 // N.B. All set operations must be performed on sets with the same maximum.
 class BitSet : private TempObject
 {
   public:
     static size_t RawLengthForBits(size_t bits) {
--- a/js/src/jit/BytecodeAnalysis.cpp
+++ b/js/src/jit/BytecodeAnalysis.cpp
@@ -6,17 +6,17 @@
 
 #include "jit/BytecodeAnalysis.h"
 
 #include "jsopcode.h"
 
 #include "jsopcodeinlines.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 BytecodeAnalysis::BytecodeAnalysis(JSScript *script)
   : script_(script),
     infos_()
 {
 }
 
 // Bytecode range containing only catch or finally code.
--- a/js/src/jit/BytecodeAnalysis.h
+++ b/js/src/jit/BytecodeAnalysis.h
@@ -6,17 +6,17 @@
 
 #ifndef jit_BytecodeAnalysis_h
 #define jit_BytecodeAnalysis_h
 
 #include "jit/IonAllocPolicy.h"
 #include "js/Vector.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // Basic information about bytecodes in the script.  Used to help baseline compilation.
 struct BytecodeInfo
 {
     static const uint16_t MAX_STACK_DEPTH = 0xffffU;
     uint16_t stackDepth;
     bool initialized : 1;
     bool jumpTarget : 1;
@@ -52,12 +52,12 @@ class BytecodeAnalysis
     BytecodeInfo *maybeInfo(jsbytecode *pc) {
         if (infos_[pc - script_->code].initialized)
             return &infos_[pc - script_->code];
         return NULL;
     }
 };
 
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_BytecodeAnalysis_h */
--- a/js/src/jit/C1Spewer.cpp
+++ b/js/src/jit/C1Spewer.cpp
@@ -12,17 +12,17 @@
 
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/LinearScan.h"
 #include "jit/LIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 bool
 C1Spewer::init(const char *path)
 {
     spewout_ = fopen(path, "w");
     return (spewout_ != NULL);
 }
 
--- a/js/src/jit/C1Spewer.h
+++ b/js/src/jit/C1Spewer.h
@@ -9,17 +9,17 @@
 
 #ifdef DEBUG
 
 #include "jsapi.h"
 
 #include "js/RootingAPI.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MDefinition;
 class MInstruction;
 class MBasicBlock;
 class MIRGraph;
 class LinearScanAllocator;
 class LInstruction;
 
@@ -42,14 +42,14 @@ class C1Spewer
     void finish();
 
   private:
     void spewPass(FILE *fp, MBasicBlock *block);
     void spewIntervals(FILE *fp, LinearScanAllocator *regalloc, LInstruction *ins, size_t &nextId);
     void spewIntervals(FILE *fp, MBasicBlock *block, LinearScanAllocator *regalloc, size_t &nextId);
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* DEBUG */
 
 #endif /* jit_C1Spewer_h */
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -29,23 +29,23 @@
 
 #include "jsboolinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 using mozilla::Maybe;
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // This out-of-line cache is used to do a double dispatch including it-self and
 // the wrapped IonCache.
 class OutOfLineUpdateCache :
   public OutOfLineCodeBase<CodeGenerator>,
   public IonCacheVisitor
 {
   private:
@@ -3362,17 +3362,17 @@ CodeGenerator::visitCreateThisWithProto(
     else
         pushArg(ToRegister(callee));
 
     return callVM(CreateThisWithProtoInfo, lir);
 }
 
 typedef JSObject *(*NewGCThingFn)(JSContext *cx, gc::AllocKind allocKind, size_t thingSize);
 static const VMFunction NewGCThingInfo =
-    FunctionInfo<NewGCThingFn>(js::ion::NewGCThing);
+    FunctionInfo<NewGCThingFn>(js::jit::NewGCThing);
 
 bool
 CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
 {
     JSObject *templateObject = lir->mir()->getTemplateObject();
     gc::AllocKind allocKind = templateObject->tenuredGetAllocKind();
     int thingSize = (int)gc::Arena::thingSize(allocKind);
     Register objReg = ToRegister(lir->output());
@@ -3623,85 +3623,89 @@ CodeGenerator::visitMathFunctionD(LMathF
 
     MathCache *mathCache = ins->mir()->cache();
 
     masm.setupUnalignedABICall(2, temp);
     masm.movePtr(ImmWord(mathCache), temp);
     masm.passABIArg(temp);
     masm.passABIArg(input);
 
+#   define MAYBE_CACHED(fcn) (mathCache ? (void*)fcn ## _impl : (void*)fcn ## _uncached)
+
     void *funptr = NULL;
     switch (ins->mir()->function()) {
       case MMathFunction::Log:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_log_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_log));
         break;
       case MMathFunction::Sin:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_sin_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_sin));
         break;
       case MMathFunction::Cos:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_cos_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_cos));
         break;
       case MMathFunction::Exp:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_exp_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_exp));
         break;
       case MMathFunction::Tan:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_tan_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_tan));
         break;
       case MMathFunction::ATan:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_atan_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_atan));
         break;
       case MMathFunction::ASin:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_asin_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_asin));
         break;
       case MMathFunction::ACos:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_acos_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_acos));
         break;
       case MMathFunction::Log10:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_log10_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_log10));
         break;
       case MMathFunction::Log2:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_log2_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_log2));
         break;
       case MMathFunction::Log1P:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_log1p_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_log1p));
         break;
       case MMathFunction::ExpM1:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_expm1_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_expm1));
         break;
       case MMathFunction::CosH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_cosh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_cosh));
         break;
       case MMathFunction::SinH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_sinh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_sinh));
         break;
       case MMathFunction::TanH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_tanh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_tanh));
         break;
       case MMathFunction::ACosH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_acosh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_acosh));
         break;
       case MMathFunction::ASinH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_asinh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_asinh));
         break;
       case MMathFunction::ATanH:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_atanh_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_atanh));
         break;
       case MMathFunction::Sign:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_sign_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_sign));
         break;
       case MMathFunction::Trunc:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_trunc_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_trunc));
         break;
       case MMathFunction::Cbrt:
-        funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_cbrt_impl);
+        funptr = JS_FUNC_TO_DATA_PTR(void *, MAYBE_CACHED(js::math_cbrt));
         break;
       default:
         MOZ_ASSUME_UNREACHABLE("Unknown math function");
     }
 
+#   undef MAYBE_CACHED
+
     masm.callWithABI(funptr, MacroAssembler::DOUBLE);
     return true;
 }
 
 bool
 CodeGenerator::visitModD(LModD *ins)
 {
     FloatRegister lhs = ToFloatRegister(ins->lhs());
@@ -3764,21 +3768,21 @@ CodeGenerator::visitBinaryV(LBinaryV *li
       default:
         MOZ_ASSUME_UNREACHABLE("Unexpected binary op");
     }
 }
 
 typedef bool (*StringCompareFn)(JSContext *, HandleString, HandleString, bool *);
 typedef ParallelResult (*StringCompareParFn)(ForkJoinSlice *, HandleString, HandleString, bool *);
 static const VMFunctionsModal StringsEqualInfo = VMFunctionsModal(
-    FunctionInfo<StringCompareFn>(ion::StringsEqual<true>),
-    FunctionInfo<StringCompareParFn>(ion::StringsEqualPar));
+    FunctionInfo<StringCompareFn>(jit::StringsEqual<true>),
+    FunctionInfo<StringCompareParFn>(jit::StringsEqualPar));
 static const VMFunctionsModal StringsNotEqualInfo = VMFunctionsModal(
-    FunctionInfo<StringCompareFn>(ion::StringsEqual<false>),
-    FunctionInfo<StringCompareParFn>(ion::StringsUnequalPar));
+    FunctionInfo<StringCompareFn>(jit::StringsEqual<false>),
+    FunctionInfo<StringCompareParFn>(jit::StringsUnequalPar));
 
 bool
 CodeGenerator::emitCompareS(LInstruction *lir, JSOp op, Register left, Register right,
                             Register output, Register temp)
 {
     JS_ASSERT(lir->isCompareS() || lir->isCompareStrictS());
 
     OutOfLineCode *ool = NULL;
@@ -3837,39 +3841,39 @@ CodeGenerator::visitCompareS(LCompareS *
 
     return emitCompareS(lir, op, left, right, output, temp);
 }
 
 typedef bool (*CompareFn)(JSContext *, MutableHandleValue, MutableHandleValue, bool *);
 typedef ParallelResult (*CompareParFn)(ForkJoinSlice *, MutableHandleValue, MutableHandleValue,
                                        bool *);
 static const VMFunctionsModal EqInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::LooselyEqual<true>),
-    FunctionInfo<CompareParFn>(ion::LooselyEqualPar));
+    FunctionInfo<CompareFn>(jit::LooselyEqual<true>),
+    FunctionInfo<CompareParFn>(jit::LooselyEqualPar));
 static const VMFunctionsModal NeInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::LooselyEqual<false>),
-    FunctionInfo<CompareParFn>(ion::LooselyUnequalPar));
+    FunctionInfo<CompareFn>(jit::LooselyEqual<false>),
+    FunctionInfo<CompareParFn>(jit::LooselyUnequalPar));
 static const VMFunctionsModal StrictEqInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::StrictlyEqual<true>),
-    FunctionInfo<CompareParFn>(ion::StrictlyEqualPar));
+    FunctionInfo<CompareFn>(jit::StrictlyEqual<true>),
+    FunctionInfo<CompareParFn>(jit::StrictlyEqualPar));
 static const VMFunctionsModal StrictNeInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::StrictlyEqual<false>),
-    FunctionInfo<CompareParFn>(ion::StrictlyUnequalPar));
+    FunctionInfo<CompareFn>(jit::StrictlyEqual<false>),
+    FunctionInfo<CompareParFn>(jit::StrictlyUnequalPar));
 static const VMFunctionsModal LtInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::LessThan),
-    FunctionInfo<CompareParFn>(ion::LessThanPar));
+    FunctionInfo<CompareFn>(jit::LessThan),
+    FunctionInfo<CompareParFn>(jit::LessThanPar));
 static const VMFunctionsModal LeInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::LessThanOrEqual),
-    FunctionInfo<CompareParFn>(ion::LessThanOrEqualPar));
+    FunctionInfo<CompareFn>(jit::LessThanOrEqual),
+    FunctionInfo<CompareParFn>(jit::LessThanOrEqualPar));
 static const VMFunctionsModal GtInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::GreaterThan),
-    FunctionInfo<CompareParFn>(ion::GreaterThanPar));
+    FunctionInfo<CompareFn>(jit::GreaterThan),
+    FunctionInfo<CompareParFn>(jit::GreaterThanPar));
 static const VMFunctionsModal GeInfo = VMFunctionsModal(
-    FunctionInfo<CompareFn>(ion::GreaterThanOrEqual),
-    FunctionInfo<CompareParFn>(ion::GreaterThanOrEqualPar));
+    FunctionInfo<CompareFn>(jit::GreaterThanOrEqual),
+    FunctionInfo<CompareParFn>(jit::GreaterThanOrEqualPar));
 
 bool
 CodeGenerator::visitCompareVM(LCompareVM *lir)
 {
     pushArg(ToValue(lir, LBinaryV::RhsInput));
     pushArg(ToValue(lir, LBinaryV::LhsInput));
 
     switch (lir->mir()->jsop()) {
@@ -4341,17 +4345,17 @@ IonCompartment::generateStringConcatStub
     masm.movePtr(ImmWord((void *)NULL), output);
     masm.ret();
 
     Linker linker(masm);
     return linker.newCode(cx, JSC::OTHER_CODE);
 }
 
 typedef bool (*CharCodeAtFn)(JSContext *, HandleString, int32_t, uint32_t *);
-static const VMFunction CharCodeAtInfo = FunctionInfo<CharCodeAtFn>(ion::CharCodeAt);
+static const VMFunction CharCodeAtInfo = FunctionInfo<CharCodeAtFn>(jit::CharCodeAt);
 
 bool
 CodeGenerator::visitCharCodeAt(LCharCodeAt *lir)
 {
     Register str = ToRegister(lir->str());
     Register index = ToRegister(lir->index());
     Register output = ToRegister(lir->output());
 
@@ -4369,17 +4373,17 @@ CodeGenerator::visitCharCodeAt(LCharCode
     masm.loadPtr(charsAddr, output);
     masm.load16ZeroExtend(BaseIndex(output, index, TimesTwo, 0), output);
 
     masm.bind(ool->rejoin());
     return true;
 }
 
 typedef JSFlatString *(*StringFromCharCodeFn)(JSContext *, int32_t);
-static const VMFunction StringFromCharCodeInfo = FunctionInfo<StringFromCharCodeFn>(ion::StringFromCharCode);
+static const VMFunction StringFromCharCodeInfo = FunctionInfo<StringFromCharCodeFn>(jit::StringFromCharCode);
 
 bool
 CodeGenerator::visitFromCharCode(LFromCharCode *lir)
 {
     Register code = ToRegister(lir->code());
     Register output = ToRegister(lir->output());
 
     OutOfLineCode *ool = oolCallVM(StringFromCharCodeInfo, lir, (ArgList(), code), StoreRegisterTo(output));
@@ -4853,18 +4857,18 @@ CodeGenerator::visitOutOfLineStoreElemen
         return true;
     }
 
     JS_ASSERT(false);
     return false;
 }
 
 typedef bool (*ArrayPopShiftFn)(JSContext *, HandleObject, MutableHandleValue);
-static const VMFunction ArrayPopDenseInfo = FunctionInfo<ArrayPopShiftFn>(ion::ArrayPopDense);
-static const VMFunction ArrayShiftDenseInfo = FunctionInfo<ArrayPopShiftFn>(ion::ArrayShiftDense);
+static const VMFunction ArrayPopDenseInfo = FunctionInfo<ArrayPopShiftFn>(jit::ArrayPopDense);
+static const VMFunction ArrayShiftDenseInfo = FunctionInfo<ArrayPopShiftFn>(jit::ArrayShiftDense);
 
 bool
 CodeGenerator::emitArrayPopShift(LInstruction *lir, const MArrayPopShift *mir, Register obj,
                                  Register elementsTemp, Register lengthTemp, TypedOrValueRegister out)
 {
     OutOfLineCode *ool;
 
     if (mir->mode() == MArrayPopShift::Pop) {
@@ -4962,17 +4966,17 @@ CodeGenerator::visitArrayPopShiftT(LArra
     Register elements = ToRegister(lir->temp0());
     Register length = ToRegister(lir->temp1());
     TypedOrValueRegister out(lir->mir()->type(), ToAnyRegister(lir->output()));
     return emitArrayPopShift(lir, lir->mir(), obj, elements, length, out);
 }
 
 typedef bool (*ArrayPushDenseFn)(JSContext *, HandleObject, HandleValue, uint32_t *);
 static const VMFunction ArrayPushDenseInfo =
-    FunctionInfo<ArrayPushDenseFn>(ion::ArrayPushDense);
+    FunctionInfo<ArrayPushDenseFn>(jit::ArrayPushDense);
 
 bool
 CodeGenerator::emitArrayPush(LInstruction *lir, const MArrayPush *mir, Register obj,
                              ConstantOrRegister value, Register elementsTemp, Register length)
 {
     OutOfLineCode *ool = oolCallVM(ArrayPushDenseInfo, lir, (ArgList(), obj, value), StoreRegisterTo(length));
     if (!ool)
         return false;
@@ -5217,17 +5221,17 @@ CodeGenerator::visitIteratorNext(LIterat
     // Increase the cursor.
     masm.addPtr(Imm32(sizeof(JSString *)), Address(temp, offsetof(NativeIterator, props_cursor)));
 
     masm.bind(ool->rejoin());
     return true;
 }
 
 typedef bool (*IteratorMoreFn)(JSContext *, HandleObject, bool *);
-static const VMFunction IteratorMoreInfo = FunctionInfo<IteratorMoreFn>(ion::IteratorMore);
+static const VMFunction IteratorMoreInfo = FunctionInfo<IteratorMoreFn>(jit::IteratorMore);
 
 bool
 CodeGenerator::visitIteratorMore(LIteratorMore *lir)
 {
     const Register obj = ToRegister(lir->object());
     const Register output = ToRegister(lir->output());
     const Register temp = ToRegister(lir->temp());
 
@@ -5504,17 +5508,17 @@ CodeGenerator::generate()
 }
 
 bool
 CodeGenerator::link()
 {
     JSContext *cx = GetIonContext()->cx;
 
     // Check to make sure we didn't have a mid-build invalidation. If so, we
-    // will trickle to ion::Compile() and return Method_Skipped.
+    // will trickle to jit::Compile() and return Method_Skipped.
     if (cx->compartment()->types.compiledInfo.compilerOutput(cx)->isInvalidated())
         return true;
 
     ExecutionMode executionMode = gen->info().executionMode();
 
     uint32_t scriptFrameSize = frameClass_ == FrameSizeClass::None()
                            ? frameDepth_
                            : FrameSizeClass::FromDepth(frameDepth_).frameSize();
@@ -7394,10 +7398,10 @@ CodeGenerator::visitAssertRangeV(LAssert
         masm.bind(&isNotDouble);
     }
 
     masm.breakpoint();
     masm.bind(&done);
     return true;
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -15,17 +15,17 @@
 # include "jit/x64/CodeGenerator-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/CodeGenerator-arm.h"
 #else
 #error "CPU Not Supported"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class OutOfLineNewParallelArray;
 class OutOfLineTestObject;
 class OutOfLineNewArray;
 class OutOfLineNewObject;
 class CheckOverRecursedFailure;
 class CheckOverRecursedFailurePar;
 class OutOfLineCheckInterruptPar;
@@ -359,12 +359,12 @@ class CodeGenerator : public CodeGenerat
     bool emitAssertRangeD(Range *r, FloatRegister input, FloatRegister temp);
 
     // Script counts created when compiling code with no associated JSScript.
     IonScriptCounts *unassociatedScriptCounts_;
 
     PerfSpewer perfSpewer_;
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_CodeGenerator_h */
--- a/js/src/jit/CompactBuffer.h
+++ b/js/src/jit/CompactBuffer.h
@@ -8,17 +8,17 @@
 #define jit_Compactbuffer_h
 
 #include "jsalloc.h"
 
 #include "jit/IonTypes.h"
 #include "js/Vector.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class CompactBufferWriter;
 
 // CompactBuffers are byte streams designed for compressable integers. It has
 // helper functions for writing bytes, fixed-size integers, and variable-sized
 // integers. Variable sized integers are encoded in 1-5 bytes, each byte
 // containing 7 bits of the integer and a bit which specifies whether the next
 // byte is also part of the integer.
@@ -149,12 +149,12 @@ class CompactBufferWriter
 };
 
 CompactBufferReader::CompactBufferReader(const CompactBufferWriter &writer)
   : buffer_(writer.buffer()),
     end_(writer.buffer() + writer.length())
 {
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_Compactbuffer_h */
--- a/js/src/jit/CompileInfo-inl.h
+++ b/js/src/jit/CompileInfo-inl.h
@@ -7,17 +7,17 @@
 #ifndef jit_CompileInfo_inl_h
 #define jit_CompileInfo_inl_h
 
 #include "jit/CompileInfo.h"
 
 #include "jsscriptinlines.h"
 
 using namespace js;
-using namespace ion;
+using namespace jit;
 
 inline RegExpObject *
 CompileInfo::getRegExp(jsbytecode *pc) const
 {
     return script_->getRegExp(GET_UINT32_INDEX(pc));
 }
 
 inline JSFunction *
--- a/js/src/jit/CompileInfo.h
+++ b/js/src/jit/CompileInfo.h
@@ -7,17 +7,17 @@
 #ifndef jit_CompileInfo_h
 #define jit_CompileInfo_h
 
 #include "jsfun.h"
 
 #include "jit/Registers.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 inline unsigned
 StartArgSlot(JSScript *script, JSFunction *fun)
 {
     // First slot is for scope chain.
     // Second one may be for arguments object.
     return 1 + (script->argumentsHasVarBinding() ? 1 : 0);
 }
@@ -235,12 +235,12 @@ class CompileInfo
     unsigned nslots_;
     JSScript *script_;
     JSFunction *fun_;
     jsbytecode *osrPc_;
     bool constructing_;
     ExecutionMode executionMode_;
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_CompileInfo_h */
--- a/js/src/jit/CompilerRoot.h
+++ b/js/src/jit/CompilerRoot.h
@@ -11,17 +11,17 @@
 
 #include "jscntxt.h"
 
 #include "jit/Ion.h"
 #include "jit/IonAllocPolicy.h"
 #include "js/RootingAPI.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // Roots a read-only GCThing for the lifetime of a single compilation.
 // Each root is maintained in a linked list that is walked over during tracing.
 // The CompilerRoot must be heap-allocated and may not go out of scope.
 template <typename T>
 class CompilerRoot : public CompilerRootNode
 {
   public:
@@ -57,14 +57,14 @@ class CompilerRoot : public CompilerRoot
 
 typedef CompilerRoot<JSObject*> CompilerRootObject;
 typedef CompilerRoot<JSFunction*> CompilerRootFunction;
 typedef CompilerRoot<JSScript*> CompilerRootScript;
 typedef CompilerRoot<PropertyName*> CompilerRootPropertyName;
 typedef CompilerRoot<Shape*> CompilerRootShape;
 typedef CompilerRoot<Value> CompilerRootValue;
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_CompilerRoot_h */
--- a/js/src/jit/EdgeCaseAnalysis.cpp
+++ b/js/src/jit/EdgeCaseAnalysis.cpp
@@ -8,17 +8,17 @@
 
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 EdgeCaseAnalysis::EdgeCaseAnalysis(MIRGenerator *mir, MIRGraph &graph)
   : mir(mir), graph(graph)
 {
 }
 
 bool
 EdgeCaseAnalysis::analyzeLate()
--- a/js/src/jit/EdgeCaseAnalysis.h
+++ b/js/src/jit/EdgeCaseAnalysis.h
@@ -5,27 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_EdgeCaseAnalysis_h
 #define jit_EdgeCaseAnalysis_h
 
 #include "jit/MIRGenerator.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MIRGraph;
 
 class EdgeCaseAnalysis
 {
     MIRGenerator *mir;
     MIRGraph &graph;
 
   public:
     EdgeCaseAnalysis(MIRGenerator *mir, MIRGraph &graph);
     bool analyzeLate();
 };
 
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_EdgeCaseAnalysis_h */
--- a/js/src/jit/EffectiveAddressAnalysis.cpp
+++ b/js/src/jit/EffectiveAddressAnalysis.cpp
@@ -2,17 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/EffectiveAddressAnalysis.h"
 
 using namespace js;
-using namespace ion;
+using namespace jit;
 
 static void
 AnalyzeLsh(MBasicBlock *block, MLsh *lsh)
 {
     if (lsh->specialization() != MIRType_Int32)
         return;
 
     MDefinition *index = lsh->lhs();
--- a/js/src/jit/EffectiveAddressAnalysis.h
+++ b/js/src/jit/EffectiveAddressAnalysis.h
@@ -6,26 +6,26 @@
 
 #ifndef jit_EffectiveAddressAnalysis_h
 #define jit_EffectiveAddressAnalysis_h
 
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class EffectiveAddressAnalysis
 {
     MIRGraph &graph_;
 
   public:
     EffectiveAddressAnalysis(MIRGraph &graph)
       : graph_(graph)
     {}
 
     bool analyze();
 };
 
-} /* namespace ion */
+} /* namespace jit */
 } /* namespace js */
 
 #endif /* jit_EffectiveAddressAnalysis_h */
--- a/js/src/jit/ExecutionModeInlines.h
+++ b/js/src/jit/ExecutionModeInlines.h
@@ -9,17 +9,17 @@
 
 #ifdef JS_ION
 
 #include "jit/CompileInfo.h"
 
 #include "jsscriptinlines.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 static inline bool
 HasIonScript(JSScript *script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->hasIonScript();
       case ParallelExecution: return script->hasParallelIonScript();
     }
@@ -98,14 +98,14 @@ CompilerOutputKind(ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return types::CompilerOutput::Ion;
       case ParallelExecution: return types::CompilerOutput::ParallelIon;
     }
     MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif  // JS_ION
 
 #endif /* jit_ExecutionModeInlines_h */
--- a/js/src/jit/FixedList.h
+++ b/js/src/jit/FixedList.h
@@ -8,17 +8,17 @@
 #define jit_FixedList_h
 
 #include <stddef.h>
 
 #include "jit/Ion.h"
 #include "jit/IonAllocPolicy.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // List of a fixed length, but the length is unknown until runtime.
 template <typename T>
 class FixedList
 {
     size_t length_;
     T *list_;
 
@@ -68,12 +68,12 @@ class FixedList
         return list_[index];
     }
     const T &operator [](size_t index) const {
         JS_ASSERT(index < length_);
         return list_[index];
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_FixedList_h */
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -53,67 +53,67 @@
 #include "jscompartmentinlines.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Shape-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 // Global variables.
-IonOptions ion::js_IonOptions;
+IonOptions jit::js_IonOptions;
 
 // Assert that IonCode is gc::Cell aligned.
 JS_STATIC_ASSERT(sizeof(IonCode) % gc::CellSize == 0);
 
 #ifdef JS_THREADSAFE
 static bool IonTLSInitialized = false;
 static unsigned IonTLSIndex;
 
 static inline IonContext *
 CurrentIonContext()
 {
     return (IonContext *)PR_GetThreadPrivate(IonTLSIndex);
 }
 
 bool
-ion::SetIonContext(IonContext *ctx)
+jit::SetIonContext(IonContext *ctx)
 {
     return PR_SetThreadPrivate(IonTLSIndex, ctx) == PR_SUCCESS;
 }
 
 #else
 
 static IonContext *GlobalIonContext;
 
 static inline IonContext *
 CurrentIonContext()
 {
     return GlobalIonContext;
 }
 
 bool
-ion::SetIonContext(IonContext *ctx)
+jit::SetIonContext(IonContext *ctx)
 {
     GlobalIonContext = ctx;
     return true;
 }
 #endif
 
 IonContext *
-ion::GetIonContext()
+jit::GetIonContext()
 {
     JS_ASSERT(CurrentIonContext());
     return CurrentIonContext();
 }
 
 IonContext *
-ion::MaybeGetIonContext()
+jit::MaybeGetIonContext()
 {
     return CurrentIonContext();
 }
 
 IonContext::IonContext(JSContext *cx, TempAllocator *temp)
   : runtime(cx->runtime()),
     cx(cx),
     compartment(cx->compartment()),
@@ -158,17 +158,17 @@ IonContext::IonContext(JSRuntime *rt)
 }
 
 IonContext::~IonContext()
 {
     SetIonContext(prev_);
 }
 
 bool
-ion::InitializeIon()
+jit::InitializeIon()
 {
 #ifdef JS_THREADSAFE
     if (!IonTLSInitialized) {
         PRStatus status = PR_NewThreadPrivateIndex(&IonTLSIndex, NULL);
         if (status != PR_SUCCESS)
             return false;
 
         IonTLSInitialized = true;
@@ -420,17 +420,17 @@ IonRuntime::patchIonBackedges(JSRuntime 
         PatchableBackedge *patchableBackedge = *iter;
         PatchJump(patchableBackedge->backedge, target == BackedgeLoopHeader
                                                ? patchableBackedge->loopHeader
                                                : patchableBackedge->interruptCheck);
     }
 }
 
 void
-ion::TriggerOperationCallbackForIonCode(JSRuntime *rt,
+jit::TriggerOperationCallbackForIonCode(JSRuntime *rt,
                                         JSRuntime::OperationCallbackTrigger trigger)
 {
     IonRuntime *ion = rt->ionRuntime();
     if (!ion)
         return;
 
     JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
 
@@ -508,17 +508,17 @@ IonCompartment::ensureIonStubsExist(JSCo
             return false;
     }
 #endif
 
     return true;
 }
 
 void
-ion::FinishOffThreadBuilder(IonBuilder *builder)
+jit::FinishOffThreadBuilder(IonBuilder *builder)
 {
     ExecutionMode executionMode = builder->info().executionMode();
 
     // Clean up if compilation did not succeed.
     if (CompilingOffThread(builder->script(), executionMode)) {
         types::TypeCompartment &types = builder->script()->compartment()->types;
         builder->recompileInfo.compilerOutput(types)->invalidate();
         SetIonScript(builder->script(), executionMode, NULL);
@@ -1158,17 +1158,17 @@ IonScript::destroyBackedges(JSRuntime *r
 
     // Clear the list of backedges, so that this method is idempotent. It is
     // called during destruction, and may be additionally called when the
     // script is invalidated.
     backedgeEntries_ = 0;
 }
 
 void
-ion::ToggleBarriers(JS::Zone *zone, bool needs)
+jit::ToggleBarriers(JS::Zone *zone, bool needs)
 {
     JSRuntime *rt = zone->runtimeFromMainThread();
     IonContext ictx(rt);
     if (!rt->hasIonRuntime())
         return;
 
     AutoFlushCache afc("ToggleBarriers", rt->ionRuntime());
     for (gc::CellIterUnderGC i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
@@ -1181,17 +1181,17 @@ ion::ToggleBarriers(JS::Zone *zone, bool
 
     for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
         if (comp->ionCompartment())
             comp->ionCompartment()->toggleBaselineStubBarriers(needs);
     }
 }
 
 namespace js {
-namespace ion {
+namespace jit {
 
 bool
 OptimizeMIR(MIRGenerator *mir)
 {
     MIRGraph &graph = mir->graph();
 
     IonSpewPass("BuildSSA");
     AssertBasicGraphCoherency(graph);
@@ -1803,18 +1803,18 @@ CanIonCompileScript(JSContext *cx, Handl
 
     return CheckScriptSize(cx, script) == Method_Compiled;
 }
 
 static MethodStatus
 Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode *osrPc,
         bool constructing, ExecutionMode executionMode)
 {
-    JS_ASSERT(ion::IsEnabled(cx));
-    JS_ASSERT(ion::IsBaselineEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
+    JS_ASSERT(jit::IsBaselineEnabled(cx));
     JS_ASSERT_IF(osrPc != NULL, (JSOp)*osrPc == JSOP_LOOPENTRY);
 
     if (executionMode == SequentialExecution && !script->hasBaselineScript())
         return Method_Skipped;
 
     if (cx->compartment()->debugMode()) {
         IonSpew(IonSpew_Abort, "debugging");
         return Method_CantCompile;
@@ -1848,26 +1848,26 @@ Compile(JSContext *cx, HandleScript scri
     AbortReason reason = IonCompile(cx, script, osrFrame, osrPc, constructing, executionMode);
     if (reason == AbortReason_Disable)
         return Method_CantCompile;
 
     // Compilation succeeded or we invalidated right away or an inlining/alloc abort
     return HasIonScript(script, executionMode) ? Method_Compiled : Method_Skipped;
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 // Decide if a transition from interpreter execution to Ion code should occur.
 // May compile or recompile the target JSScript.
 MethodStatus
-ion::CanEnterAtBranch(JSContext *cx, JSScript *script, BaselineFrame *osrFrame,
+jit::CanEnterAtBranch(JSContext *cx, JSScript *script, BaselineFrame *osrFrame,
                       jsbytecode *pc, bool isConstructing)
 {
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
     JS_ASSERT((JSOp)*pc == JSOP_LOOPENTRY);
 
     // Skip if the script has been disabled.
     if (!script->canIonCompile())
         return Method_Skipped;
 
     // Skip if the script is being compiled off thread.
     if (script->isIonCompilingOffThread())
@@ -1909,19 +1909,19 @@ ion::CanEnterAtBranch(JSContext *cx, JSS
     }
 
     script->ionScript()->resetOsrPcMismatchCounter();
 
     return Method_Compiled;
 }
 
 MethodStatus
-ion::CanEnter(JSContext *cx, RunState &state)
+jit::CanEnter(JSContext *cx, RunState &state)
 {
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
 
     JSScript *script = state.script();
 
     // Skip if the script has been disabled.
     if (!script->canIonCompile())
         return Method_Skipped;
 
     // Skip if the script is being compiled off thread.
@@ -1943,17 +1943,17 @@ ion::CanEnter(JSContext *cx, RunState &s
             ForbidCompilation(cx, script);
             return Method_CantCompile;
         }
 
         if (invoke.constructing() && invoke.args().thisv().isPrimitive()) {
             RootedScript scriptRoot(cx, script);
             RootedObject callee(cx, &invoke.args().callee());
             RootedObject obj(cx, CreateThisForFunction(cx, callee, invoke.useNewType()));
-            if (!obj || !ion::IsEnabled(cx)) // Note: OOM under CreateThis can disable TI.
+            if (!obj || !jit::IsIonEnabled(cx)) // Note: OOM under CreateThis can disable TI.
                 return Method_Skipped;
             invoke.args().setThis(ObjectValue(*obj));
             script = scriptRoot;
         }
     } else if (state.isGenerator()) {
         IonSpew(IonSpew_Abort, "generator frame");
         ForbidCompilation(cx, script);
         return Method_CantCompile;
@@ -1976,20 +1976,20 @@ ion::CanEnter(JSContext *cx, RunState &s
             ForbidCompilation(cx, rscript);
         return status;
     }
 
     return Method_Compiled;
 }
 
 MethodStatus
-ion::CompileFunctionForBaseline(JSContext *cx, HandleScript script, BaselineFrame *frame,
+jit::CompileFunctionForBaseline(JSContext *cx, HandleScript script, BaselineFrame *frame,
                                 bool isConstructing)
 {
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
     JS_ASSERT(frame->fun()->nonLazyScript()->canIonCompile());
     JS_ASSERT(!frame->fun()->nonLazyScript()->isIonCompilingOffThread());
     JS_ASSERT(!frame->fun()->nonLazyScript()->hasIonScript());
     JS_ASSERT(frame->isFunctionFrame());
 
     // Mark as forbidden if frame can't be handled.
     if (!CheckFrame(frame)) {
         ForbidCompilation(cx, script);
@@ -2003,17 +2003,17 @@ ion::CompileFunctionForBaseline(JSContex
             ForbidCompilation(cx, script);
         return status;
     }
 
     return Method_Compiled;
 }
 
 MethodStatus
-ion::CanEnterInParallel(JSContext *cx, HandleScript script)
+jit::CanEnterInParallel(JSContext *cx, HandleScript script)
 {
     // Skip if the script has been disabled.
     //
     // Note: We return Method_Skipped in this case because the other
     // CanEnter() methods do so. However, ForkJoin.cpp detects this
     // condition differently treats it more like an error.
     if (!script->canParallelIonCompile())
         return Method_Skipped;
@@ -2046,19 +2046,19 @@ ion::CanEnterInParallel(JSContext *cx, H
             script.get(), script->filename(), script->lineno);
         return Method_Skipped;
     }
 
     return Method_Compiled;
 }
 
 MethodStatus
-ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs)
+jit::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs)
 {
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
 
     // Skip if the code is expected to result in a bailout.
     if (!script->hasIonScript() || script->ionScript()->bailoutExpected())
         return Method_Skipped;
 
     // Don't handle arguments underflow, to make this work we would have to pad
     // missing arguments with |undefined|.
     if (numActualArgs < script->function()->nargs)
@@ -2076,17 +2076,17 @@ ion::CanEnterUsingFastInvoke(JSContext *
 
     return Method_Compiled;
 }
 
 static IonExecStatus
 EnterIon(JSContext *cx, EnterJitData &data)
 {
     JS_CHECK_RECURSION(cx, return IonExec_Aborted);
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
     JS_ASSERT(!data.osrFrame);
 
     EnterIonCode enter = cx->runtime()->ionRuntime()->enterIon();
 
     // Caller must construct |this| before invoking the Ion function.
     JS_ASSERT_IF(data.constructing, data.maxArgv[0].isObject());
 
     data.result.setInt32(data.numActualArgs);
@@ -2111,17 +2111,17 @@ EnterIon(JSContext *cx, EnterJitData &da
     // Release temporary buffer used for OSR into Ion.
     cx->runtime()->getIonRuntime(cx)->freeOsrTempData();
 
     JS_ASSERT_IF(data.result.isMagic(), data.result.isMagic(JS_ION_ERROR));
     return data.result.isMagic() ? IonExec_Error : IonExec_Ok;
 }
 
 bool
-ion::SetEnterJitData(JSContext *cx, EnterJitData &data, RunState &state, AutoValueVector &vals)
+jit::SetEnterJitData(JSContext *cx, EnterJitData &data, RunState &state, AutoValueVector &vals)
 {
     data.osrFrame = NULL;
 
     if (state.isInvoke()) {
         CallArgs &args = state.asInvoke()->args();
         unsigned numFormals = state.script()->function()->nargs;
         data.constructing = state.asInvoke()->constructing();
         data.numActualArgs = args.length();
@@ -2163,17 +2163,17 @@ ion::SetEnterJitData(JSContext *cx, Ente
                 data.calleeToken = CalleeToToken(iter.callee());
         }
     }
 
     return true;
 }
 
 IonExecStatus
-ion::Cannon(JSContext *cx, RunState &state)
+jit::Cannon(JSContext *cx, RunState &state)
 {
     IonScript *ion = state.script()->ionScript();
 
     EnterJitData data(cx);
     data.jitcode = ion->method()->raw();
 
     AutoValueVector vals(cx);
     if (!SetEnterJitData(cx, data, state, vals))
@@ -2183,25 +2183,25 @@ ion::Cannon(JSContext *cx, RunState &sta
 
     if (status == IonExec_Ok)
         state.setReturnValue(data.result);
 
     return status;
 }
 
 IonExecStatus
-ion::FastInvoke(JSContext *cx, HandleFunction fun, CallArgs &args)
+jit::FastInvoke(JSContext *cx, HandleFunction fun, CallArgs &args)
 {
     JS_CHECK_RECURSION(cx, return IonExec_Error);
 
     IonScript *ion = fun->nonLazyScript()->ionScript();
     IonCode *code = ion->method();
     void *jitcode = code->raw();
 
-    JS_ASSERT(ion::IsEnabled(cx));
+    JS_ASSERT(jit::IsIonEnabled(cx));
     JS_ASSERT(!ion->bailoutExpected());
 
     JitActivation activation(cx, /* firstFrameIsConstructing = */false);
 
     EnterIonCode enter = cx->runtime()->ionRuntime()->enterIon();
     void *calleeToken = CalleeToToken(fun);
 
     RootedValue result(cx, Int32Value(args.length()));
@@ -2346,17 +2346,17 @@ InvalidateActivation(FreeOp *fop, uint8_
                 ionScript, ionScript->refcount(), (void *) osiPatchPoint.raw());
         Assembler::patchWrite_NearCall(osiPatchPoint, invalidateEpilogue);
     }
 
     IonSpew(IonSpew_Invalidate, "END invalidating activation");
 }
 
 void
-ion::InvalidateAll(FreeOp *fop, Zone *zone)
+jit::InvalidateAll(FreeOp *fop, Zone *zone)
 {
     for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
         if (!comp->ionCompartment())
             continue;
         CancelOffThreadIonCompile(comp, NULL);
         FinishAllOffThreadCompilations(comp->ionCompartment());
     }
 
@@ -2367,17 +2367,17 @@ ion::InvalidateAll(FreeOp *fop, Zone *zo
             IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC");
             InvalidateActivation(fop, iter.jitTop(), true);
         }
     }
 }
 
 
 void
-ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
+jit::Invalidate(types::TypeCompartment &types, FreeOp *fop,
                 const Vector<types::RecompileInfo> &invalid, bool resetUses)
 {
     IonSpew(IonSpew_Invalidate, "Start invalidation.");
     AutoFlushCache afc ("Invalidate");
 
     // Add an invalidation reference to all invalidated IonScripts to indicate
     // to the traversal which frames have been invalidated.
     bool anyInvalidation = false;
@@ -2440,23 +2440,23 @@ ion::Invalidate(types::TypeCompartment &
         //     closure of potential callees, to avoid compiling things
         //     that are never run at all).
         if (resetUses && executionMode != ParallelExecution)
             script->resetUseCount();
     }
 }
 
 void
-ion::Invalidate(JSContext *cx, const Vector<types::RecompileInfo> &invalid, bool resetUses)
+jit::Invalidate(JSContext *cx, const Vector<types::RecompileInfo> &invalid, bool resetUses)
 {
-    ion::Invalidate(cx->compartment()->types, cx->runtime()->defaultFreeOp(), invalid, resetUses);
+    jit::Invalidate(cx->compartment()->types, cx->runtime()->defaultFreeOp(), invalid, resetUses);
 }
 
 bool
-ion::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetUses)
+jit::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetUses)
 {
     JS_ASSERT(script->hasIonScript());
 
     Vector<types::RecompileInfo> scripts(cx);
 
     switch (mode) {
       case SequentialExecution:
         JS_ASSERT(script->hasIonScript());
@@ -2470,17 +2470,17 @@ ion::Invalidate(JSContext *cx, JSScript 
         break;
     }
 
     Invalidate(cx, scripts, resetUses);
     return true;
 }
 
 bool
-ion::Invalidate(JSContext *cx, JSScript *script, bool resetUses)
+jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses)
 {
     return Invalidate(cx, script, SequentialExecution, resetUses);
 }
 
 static void
 FinishInvalidationOf(FreeOp *fop, JSScript *script, IonScript *ionScript, bool parallel)
 {
     // In all cases, NULL out script->ion or script->parallelIon to avoid
@@ -2491,50 +2491,50 @@ FinishInvalidationOf(FreeOp *fop, JSScri
         script->setIonScript(NULL);
 
     // If this script has Ion code on the stack, invalidation() will return
     // true. In this case we have to wait until destroying it.
     if (!ionScript->invalidated()) {
         types::TypeCompartment &types = script->compartment()->types;
         ionScript->recompileInfo().compilerOutput(types)->invalidate();
 
-        ion::IonScript::Destroy(fop, ionScript);
+        jit::IonScript::Destroy(fop, ionScript);
     }
 }
 
 void
-ion::FinishInvalidation(FreeOp *fop, JSScript *script)
+jit::FinishInvalidation(FreeOp *fop, JSScript *script)
 {
     if (script->hasIonScript())
         FinishInvalidationOf(fop, script, script->ionScript(), false);
 
     if (script->hasParallelIonScript())
         FinishInvalidationOf(fop, script, script->parallelIonScript(), true);
 }
 
 void
-ion::MarkValueFromIon(JSRuntime *rt, Value *vp)
+jit::MarkValueFromIon(JSRuntime *rt, Value *vp)
 {
     gc::MarkValueUnbarriered(&rt->gcMarker, vp, "write barrier");
 }
 
 void
-ion::MarkShapeFromIon(JSRuntime *rt, Shape **shapep)
+jit::MarkShapeFromIon(JSRuntime *rt, Shape **shapep)
 {
     gc::MarkShapeUnbarriered(&rt->gcMarker, shapep, "write barrier");
 }
 
 void
-ion::ForbidCompilation(JSContext *cx, JSScript *script)
+jit::ForbidCompilation(JSContext *cx, JSScript *script)
 {
     ForbidCompilation(cx, script, SequentialExecution);
 }
 
 void
-ion::ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode)
+jit::ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode)
 {
     IonSpew(IonSpew_Abort, "Disabling Ion mode %d compilation of script %s:%d",
             mode, script->filename(), script->lineno);
 
     CancelOffThreadIonCompile(cx->compartment(), script);
 
     switch (mode) {
       case SequentialExecution:
@@ -2560,17 +2560,17 @@ ion::ForbidCompilation(JSContext *cx, JS
         script->setParallelIonScript(ION_DISABLED_SCRIPT);
         return;
     }
 
     MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 uint32_t
-ion::UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc)
+jit::UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(pc == script->code || JSOp(*pc) == JSOP_LOOPENTRY);
 
     uint32_t minUses = js_IonOptions.usesBeforeCompile;
 
     // If the script is too large to compile on the main thread, we can still
     // compile it off thread. In these cases, increase the use count threshold
     // to improve the compilation's type information and hopefully avoid later
@@ -2649,56 +2649,56 @@ AutoFlushInhibitor::~AutoFlushInhibitor(
     JS_ASSERT(ic_->flusher() == NULL);
     // Ensure any future modifications are recorded
     ic_->setFlusher(afc);
     if (afc)
         IonSpewCont(IonSpew_CacheFlush, "{");
 }
 
 void
-ion::PurgeCaches(JSScript *script, Zone *zone)
+jit::PurgeCaches(JSScript *script, Zone *zone)
 {
     if (script->hasIonScript())
         script->ionScript()->purgeCaches(zone);
 
     if (script->hasParallelIonScript())
         script->parallelIonScript()->purgeCaches(zone);
 }
 
 size_t
-ion::SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf)
+jit::SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf)
 {
     size_t result = 0;
 
     if (script->hasIonScript())
         result += script->ionScript()->sizeOfIncludingThis(mallocSizeOf);
 
     if (script->hasParallelIonScript())
         result += script->parallelIonScript()->sizeOfIncludingThis(mallocSizeOf);
 
     return result;
 }
 
 void
-ion::DestroyIonScripts(FreeOp *fop, JSScript *script)
+jit::DestroyIonScripts(FreeOp *fop, JSScript *script)
 {
     if (script->hasIonScript())
-        ion::IonScript::Destroy(fop, script->ionScript());
+        jit::IonScript::Destroy(fop, script->ionScript());
 
     if (script->hasParallelIonScript())
-        ion::IonScript::Destroy(fop, script->parallelIonScript());
+        jit::IonScript::Destroy(fop, script->parallelIonScript());
 
     if (script->hasBaselineScript())
-        ion::BaselineScript::Destroy(fop, script->baselineScript());
+        jit::BaselineScript::Destroy(fop, script->baselineScript());
 }
 
 void
-ion::TraceIonScripts(JSTracer* trc, JSScript *script)
+jit::TraceIonScripts(JSTracer* trc, JSScript *script)
 {
     if (script->hasIonScript())
-        ion::IonScript::Trace(trc, script->ionScript());
+        jit::IonScript::Trace(trc, script->ionScript());
 
     if (script->hasParallelIonScript())
-        ion::IonScript::Trace(trc, script->parallelIonScript());
+        jit::IonScript::Trace(trc, script->parallelIonScript());
 
     if (script->hasBaselineScript())
-        ion::BaselineScript::Trace(trc, script->baselineScript());
+        jit::BaselineScript::Trace(trc, script->baselineScript());
 }
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -13,17 +13,17 @@
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
 #include "jit/CompileInfo.h"
 #include "jit/IonCode.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class TempAllocator;
 
 // Possible register allocators which may be used.
 enum IonRegisterAllocator {
     RegisterAllocator_LSRA,
     RegisterAllocator_Backtracking,
     RegisterAllocator_Stupid
@@ -354,17 +354,17 @@ bool OptimizeMIR(MIRGenerator *mir);
 LIRGraph *GenerateLIR(MIRGenerator *mir);
 CodeGenerator *GenerateCode(MIRGenerator *mir, LIRGraph *lir, MacroAssembler *maybeMasm = NULL);
 CodeGenerator *CompileBackEnd(MIRGenerator *mir, MacroAssembler *maybeMasm = NULL);
 
 void AttachFinishedCompilations(JSContext *cx);
 void FinishOffThreadBuilder(IonBuilder *builder);
 
 static inline bool
-IsEnabled(JSContext *cx)
+IsIonEnabled(JSContext *cx)
 {
     return cx->hasOption(JSOPTION_ION) &&
         cx->hasOption(JSOPTION_BASELINE) &&
         cx->typeInferenceEnabled();
 }
 
 inline bool
 IsIonInlinablePC(jsbytecode *pc) {
@@ -380,14 +380,14 @@ uint32_t UsesBeforeIonRecompile(JSScript
 
 void PurgeCaches(JSScript *script, JS::Zone *zone);
 size_t SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf);
 void DestroyIonScripts(FreeOp *fop, JSScript *script);
 void TraceIonScripts(JSTracer* trc, JSScript *script);
 
 void TriggerOperationCallbackForIonCode(JSRuntime *rt, JSRuntime::OperationCallbackTrigger trigger);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_Ion_h */
--- a/js/src/jit/IonAllocPolicy.h
+++ b/js/src/jit/IonAllocPolicy.h
@@ -11,17 +11,17 @@
 
 #include "jscntxt.h"
 
 #include "ds/LifoAlloc.h"
 #include "jit/InlineList.h"
 #include "jit/Ion.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class TempAllocator
 {
     LifoAllocScope lifoScope_;
 
     // Linked list of GCThings rooted by this allocator.
     CompilerRootNode *rootList_;
 
@@ -153,12 +153,12 @@ class TempObjectPool
     void free(T *obj) {
         freed_.pushFront(obj);
     }
     void clear() {
         freed_.clear();
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonAllocPolicy_h */
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -9,23 +9,23 @@
 #include "jsanalyze.h"
 
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/LIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 // A critical edge is an edge which is neither its successor's only predecessor
 // nor its predecessor's only successor. Critical edges must be split to
 // prevent copy-insertion and code motion from affecting other edges.
 bool
-ion::SplitCriticalEdges(MIRGraph &graph)
+jit::SplitCriticalEdges(MIRGraph &graph)
 {
     for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
         if (block->numSuccessors() < 2)
             continue;
         for (size_t i = 0; i < block->numSuccessors(); i++) {
             MBasicBlock *target = block->getSuccessor(i);
             if (target->numPredecessors() < 2)
                 continue;
@@ -49,17 +49,17 @@ ion::SplitCriticalEdges(MIRGraph &graph)
 // block and have no uses outside the block or at points later than the resume
 // point.
 //
 // This is intended to ensure that extra resume points within a basic block
 // will not artificially extend the lifetimes of any SSA values. This could
 // otherwise occur if the new resume point captured a value which is created
 // between the old and new resume point and is dead at the new resume point.
 bool
-ion::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
+jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
 {
     // If we are compiling try blocks, locals and arguments may be observable
     // from catch or finally blocks (which Ion does not compile). For now just
     // disable the pass in this case.
     if (graph.hasTryBlock())
         return true;
 
     for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
@@ -143,17 +143,17 @@ ion::EliminateDeadResumePointOperands(MI
 
     return true;
 }
 
 // Instructions are useless if they are unused and have no side effects.
 // This pass eliminates useless instructions.
 // The graph itself is unchanged.
 bool
-ion::EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph)
+jit::EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph)
 {
     // Traverse in postorder so that we hit uses before definitions.
     // Traverse instruction list backwards for the same reason.
     for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
         if (mir->shouldCancel("Eliminate Dead Code (main loop)"))
             return false;
 
         // Remove unused instructions.
@@ -238,17 +238,17 @@ IsPhiRedundant(MPhi *phi)
     // Propagate the Folded flag if |phi| is replaced with another phi.
     if (phi->isFolded())
         first->setFoldedUnchecked();
 
     return first;
 }
 
 bool
-ion::EliminatePhis(MIRGenerator *mir, MIRGraph &graph,
+jit::EliminatePhis(MIRGenerator *mir, MIRGraph &graph,
                    Observability observe)
 {
     // Eliminates redundant or unobservable phis from the graph.  A
     // redundant phi is something like b = phi(a, a) or b = phi(a, b),
     // both of which can be replaced with a.  An unobservable phi is
     // one that whose value is never used in the program.
     //
     // Note that we must be careful not to eliminate phis representing
@@ -661,28 +661,28 @@ TypeAnalyzer::analyze()
     if (!specializePhis())
         return false;
     if (!insertConversions())
         return false;
     return true;
 }
 
 bool
-ion::ApplyTypeInformation(MIRGenerator *mir, MIRGraph &graph)
+jit::ApplyTypeInformation(MIRGenerator *mir, MIRGraph &graph)
 {
     TypeAnalyzer analyzer(mir, graph);
 
     if (!analyzer.analyze())
         return false;
 
     return true;
 }
 
 bool
-ion::RenumberBlocks(MIRGraph &graph)
+jit::RenumberBlocks(MIRGraph &graph)
 {
     size_t id = 0;
     for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++)
         block->setId(id++);
 
     return true;
 }
 
@@ -778,17 +778,17 @@ ComputeImmediateDominators(MIRGraph &gra
     // Assert that all blocks have dominator information.
     for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
         JS_ASSERT(block->immediateDominator() != NULL);
     }
 #endif
 }
 
 bool
-ion::BuildDominatorTree(MIRGraph &graph)
+jit::BuildDominatorTree(MIRGraph &graph)
 {
     ComputeImmediateDominators(graph);
 
     // Traversing through the graph in post-order means that every use
     // of a definition is visited before the def itself. Since a def
     // dominates its uses, by the time we reach a particular
     // block, we have processed all of its dominated children, so
     // block->numDominated() is accurate.
@@ -841,17 +841,17 @@ ion::BuildDominatorTree(MIRGraph &graph)
         }
         index++;
     }
 
     return true;
 }
 
 bool
-ion::BuildPhiReverseMapping(MIRGraph &graph)
+jit::BuildPhiReverseMapping(MIRGraph &graph)
 {
     // Build a mapping such that given a basic block, whose successor has one or
     // more phis, we can find our specific input to that phi. To make this fast
     // mapping work we rely on a specific property of our structured control
     // flow graph: For a block with phis, its predecessors each have only one
     // successor with phis. Consider each case:
     //   * Blocks with less than two predecessors cannot have phis.
     //   * Breaks. A break always has exactly one successor, and the break
@@ -953,17 +953,17 @@ CheckUseImpliesOperand(MInstruction *ins
 
     JS_ASSERT(consumer->isResumePoint());
     MResumePoint *res = consumer->toResumePoint();
     return (res->getOperand(index) == ins);
 }
 #endif // DEBUG
 
 void
-ion::AssertBasicGraphCoherency(MIRGraph &graph)
+jit::AssertBasicGraphCoherency(MIRGraph &graph)
 {
 #ifdef DEBUG
     // Assert successor and predecessor list coherency.
     uint32_t count = 0;
     for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
         count++;
 
         for (size_t i = 0; i < block->numSuccessors(); i++)
@@ -1003,26 +1003,26 @@ AssertReversePostOrder(MIRGraph &graph)
         block->mark();
     }
 
     graph.unmarkBlocks();
 }
 #endif
 
 void
-ion::AssertGraphCoherency(MIRGraph &graph)
+jit::AssertGraphCoherency(MIRGraph &graph)
 {
 #ifdef DEBUG
     AssertBasicGraphCoherency(graph);
     AssertReversePostOrder(graph);
 #endif
 }
 
 void
-ion::AssertExtendedGraphCoherency(MIRGraph &graph)
+jit::AssertExtendedGraphCoherency(MIRGraph &graph)
 {
     // Checks the basic GraphCoherency but also other conditions that
     // do not hold immediately (such as the fact that critical edges
     // are split)
 
 #ifdef DEBUG
     AssertGraphCoherency(graph);
 
@@ -1108,17 +1108,17 @@ FindDominatingBoundsCheck(BoundsCheckMap
         return check;
     }
 
     return p->value.check;
 }
 
 // Extract a linear sum from ins, if possible (otherwise giving the sum 'ins + 0').
 SimpleLinearSum
-ion::ExtractLinearSum(MDefinition *ins)
+jit::ExtractLinearSum(MDefinition *ins)
 {
     if (ins->isBeta())
         ins = ins->getOperand(0);
 
     if (ins->type() != MIRType_Int32)
         return SimpleLinearSum(ins, 0);
 
     if (ins->isConstant()) {
@@ -1151,17 +1151,17 @@ ion::ExtractLinearSum(MDefinition *ins)
     }
 
     return SimpleLinearSum(ins, 0);
 }
 
 // Extract a linear inequality holding when a boolean test goes in the
 // specified direction, of the form 'lhs + lhsN <= rhs' (or >=).
 bool
-ion::ExtractLinearInequality(MTest *test, BranchDirection direction,
+jit::ExtractLinearInequality(MTest *test, BranchDirection direction,
                              SimpleLinearSum *plhs, MDefinition **prhs, bool *plessEqual)
 {
     if (!test->getOperand(0)->isCompare())
         return false;
 
     MCompare *compare = test->getOperand(0)->toCompare();
 
     MDefinition *lhs = compare->getOperand(0);
@@ -1374,17 +1374,17 @@ TryEliminateTypeBarrier(MTypeBarrier *ba
 // check with the same length and the indexes differ by only a constant amount.
 // In this case we eliminate the redundant bounds check and update the other one
 // to cover the ranges of both checks.
 //
 // Bounds checks are added to a hash map and since the hash function ignores
 // differences in constant offset, this offers a fast way to find redundant
 // checks.
 bool
-ion::EliminateRedundantChecks(MIRGraph &graph)
+jit::EliminateRedundantChecks(MIRGraph &graph)
 {
     BoundsCheckMap checks;
 
     if (!checks.init())
         return false;
 
     // Stack for pre-order CFG traversal.
     Vector<MBasicBlock *, 1, IonAllocPolicy> worklist;
@@ -1460,17 +1460,17 @@ FindLeadingGoto(LBlock *bb)
     return NULL;
 }
 
 // Eliminate blocks containing nothing interesting besides gotos. These are
 // often created by optimizer, which splits all critical edges. If these
 // splits end up being unused after optimization and register allocation,
 // fold them back away to avoid unnecessary branching.
 bool
-ion::UnsplitEdges(LIRGraph *lir)
+jit::UnsplitEdges(LIRGraph *lir)
 {
     for (size_t i = 0; i < lir->numBlocks(); i++) {
         LBlock *bb = lir->getBlock(i);
         MBasicBlock *mirBlock = bb->mir();
 
         // Renumber the MIR blocks as we go, since we may remove some.
         mirBlock->setId(i);
 
--- a/js/src/jit/IonAnalysis.h
+++ b/js/src/jit/IonAnalysis.h
@@ -8,17 +8,17 @@
 #define jit_IonAnalysis_h
 
 // This file declares various analysis passes that operate on MIR.
 
 #include "jit/IonAllocPolicy.h"
 #include "jit/MIR.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MIRGenerator;
 class MIRGraph;
 
 bool
 SplitCriticalEdges(MIRGraph &graph);
 
 enum Observability {
@@ -119,12 +119,12 @@ class LinearSum
 
     void print(Sprinter &sp) const;
 
   private:
     Vector<LinearTerm, 2, IonAllocPolicy> terms_;
     int32_t constant_;
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonAnalysis_h */
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -23,17 +23,17 @@
 
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/CompileInfo-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
                        BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame,
                        size_t inliningDepth, uint32_t loopDepth)
   : MIRGenerator(cx->compartment(), temp, graph, info),
     backgroundCodegen_(NULL),
@@ -6200,17 +6200,17 @@ IonBuilder::getStaticName(HandleObject s
     if (barrier)
         rvalType = MIRType_Value;
 
     return loadSlot(obj, shape, rvalType, barrier, types);
 }
 
 // Whether 'types' includes all possible values represented by input/inputTypes.
 bool
-ion::TypeSetIncludes(types::TypeSet *types, MIRType input, types::TypeSet *inputTypes)
+jit::TypeSetIncludes(types::TypeSet *types, MIRType input, types::TypeSet *inputTypes)
 {
     switch (input) {
       case MIRType_Undefined:
       case MIRType_Null:
       case MIRType_Boolean:
       case MIRType_Int32:
       case MIRType_Double:
       case MIRType_String:
@@ -6225,17 +6225,17 @@ ion::TypeSetIncludes(types::TypeSet *typ
 
       default:
         MOZ_ASSUME_UNREACHABLE("Bad input type");
     }
 }
 
 // Whether a write of the given value may need a post-write barrier for GC purposes.
 bool
-ion::NeedsPostBarrier(CompileInfo &info, MDefinition *value)
+jit::NeedsPostBarrier(CompileInfo &info, MDefinition *value)
 {
     return info.executionMode() != ParallelExecution && value->mightBeType(MIRType_Object);
 }
 
 bool
 IonBuilder::setStaticName(HandleObject staticObject, HandlePropertyName name)
 {
     RootedId id(cx, NameToId(name));
@@ -8988,16 +8988,18 @@ IonBuilder::jsop_instanceof()
             break;
 
         types::HeapTypeSet *protoTypes =
             rhsType->getProperty(cx, NameToId(cx->names().classPrototype), false);
         JSObject *protoObject = protoTypes ? protoTypes->getSingleton(cx) : NULL;
         if (!protoObject)
             break;
 
+        rhs->setFoldedUnchecked();
+
         MInstanceOf *ins = new MInstanceOf(obj, protoObject);
 
         current->add(ins);
         current->push(ins);
 
         return resumeAfter(ins);
     } while (false);
 
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -11,17 +11,17 @@
 
 // This file declares the data structures for building a MIRGraph from a
 // JSScript.
 
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class CodeGenerator;
 class CallInfo;
 class BaselineInspector;
 
 class IonBuilder : public MIRGenerator
 {
     enum ControlStatus {
@@ -850,14 +850,14 @@ class CallInfo
         return passArg;
     }
 };
 
 bool TypeSetIncludes(types::TypeSet *types, MIRType input, types::TypeSet *inputTypes);
 
 bool NeedsPostBarrier(CompileInfo &info, MDefinition *value);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonBuilder_h */
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -14,17 +14,17 @@
 #include "jit/IonSpewer.h"
 #include "jit/PerfSpewer.h"
 #include "jit/VMFunctions.h"
 #include "vm/Shape.h"
 
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 void
 CodeLocationJump::repoint(IonCode *code, MacroAssembler *masm)
 {
     JS_ASSERT(state_ == Relative);
     size_t new_off = (size_t)raw_;
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -17,17 +17,17 @@
 class JSFunction;
 class JSScript;
 
 namespace js {
 
 class LockedJSContext;
 class TypedArrayObject;
 
-namespace ion {
+namespace jit {
 
 #define IONCACHE_KIND_LIST(_)                                   \
     _(GetProperty)                                              \
     _(SetProperty)                                              \
     _(GetElement)                                               \
     _(SetElement)                                               \
     _(BindName)                                                 \
     _(Name)                                                     \
@@ -1080,12 +1080,12 @@ class GetElementParIC : public ParallelI
     const ickind##IC &IonCache::to##ickind() const                      \
     {                                                                   \
         JS_ASSERT(is##ickind());                                        \
         return *static_cast<const ickind##IC *>(this);                  \
     }
 IONCACHE_KIND_LIST(CACHE_CASTS)
 #undef OPCODE_CASTS
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonCaches_h */
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -20,17 +20,17 @@ namespace JSC {
 }
 
 class JSScript;
 
 namespace js {
 
 class AsmJSModule;
 
-namespace ion {
+namespace jit {
 
 // The maximum size of any buffer associated with an assembler or code object.
 // This is chosen to not overflow a signed integer, leaving room for an extra
 // bit on offsets.
 static const uint32_t MAX_BUFFER_SIZE = (1 << 30) - 1;
 
 // Maximum number of scripted arg slots.
 static const uint32_t SNAPSHOT_MAX_NARGS = 127;
@@ -742,22 +742,22 @@ struct AutoFlushCache
 struct AutoFlushInhibitor {
   private:
     IonCompartment *ic_;
     AutoFlushCache *afc;
   public:
     AutoFlushInhibitor(IonCompartment *ic);
     ~AutoFlushInhibitor();
 };
-} // namespace ion
+} // namespace jit
 
 namespace gc {
 
 inline bool
-IsMarked(const ion::VMFunction *)
+IsMarked(const jit::VMFunction *)
 {
     // VMFunction are only static objects which are used by WeakMaps as keys.
     // It is considered as a root object which is always marked.
     return true;
 }
 
 } // namespace gc
 
--- a/js/src/jit/IonCompartment.h
+++ b/js/src/jit/IonCompartment.h
@@ -16,17 +16,17 @@
 #include "jit/CompileInfo.h"
 #include "jit/IonCode.h"
 #include "jit/IonFrames.h"
 #include "jit/shared/Assembler-shared.h"
 #include "js/Value.h"
 #include "vm/Stack.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class FrameSizeClass;
 
 enum EnterJitType {
     EnterJitBaseline = 0,
     EnterJitOptimized = 1
 };
 
@@ -442,14 +442,14 @@ class IonCompartment
         return &optimizedStubSpace_;
     }
 };
 
 // Called from JSCompartment::discardJitCode().
 void InvalidateAll(FreeOp *fop, JS::Zone *zone);
 void FinishInvalidation(FreeOp *fop, JSScript *script);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonCompartment_h */
--- a/js/src/jit/IonFrameIterator-inl.h
+++ b/js/src/jit/IonFrameIterator-inl.h
@@ -10,17 +10,17 @@
 #ifdef JS_ION
 
 #include "jit/IonFrameIterator.h"
 
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 template <AllowGC allowGC>
 inline
 InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
                                                 JSContext *cx, const IonBailoutIterator *iter)
   : frame_(iter),
     framesRead_(0),
     callee_(cx),
@@ -34,14 +34,14 @@ InlineFrameIteratorMaybeGC<allowGC>::Inl
 
 inline BaselineFrame *
 IonFrameIterator::baselineFrame() const
 {
     JS_ASSERT(isBaselineJS());
     return (BaselineFrame *)(fp() - BaselineFrame::FramePointerOffset - BaselineFrame::Size());
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonFrameIterator_inl_h */
--- a/js/src/jit/IonFrameIterator.h
+++ b/js/src/jit/IonFrameIterator.h
@@ -15,17 +15,17 @@
 #include "jit/IonCode.h"
 #include "jit/SnapshotReader.h"
 
 namespace js {
     class ActivationIterator;
 };
 
 namespace js {
-namespace ion {
+namespace jit {
 
 enum FrameType
 {
     // A JS frame is analagous to a js::StackFrame, representing one scripted
     // functon activation. OptimizedJS frames are used by the optimizing compiler.
     IonFrame_OptimizedJS,
 
     // JS frame used by the baseline JIT.
@@ -495,14 +495,14 @@ class InlineFrameIteratorMaybeGC
 
   private:
     InlineFrameIteratorMaybeGC() MOZ_DELETE;
     InlineFrameIteratorMaybeGC(const InlineFrameIteratorMaybeGC &iter) MOZ_DELETE;
 };
 typedef InlineFrameIteratorMaybeGC<CanGC> InlineFrameIterator;
 typedef InlineFrameIteratorMaybeGC<NoGC> InlineFrameIteratorNoGC;
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonFrameIterator_h */
--- a/js/src/jit/IonFrames-inl.h
+++ b/js/src/jit/IonFrames-inl.h
@@ -12,17 +12,17 @@
 #include "jit/IonFrames.h"
 
 #include "jit/IonFrameIterator.h"
 #include "jit/LIR.h"
 
 #include "jit/IonFrameIterator-inl.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 inline void
 SafepointIndex::resolve()
 {
     JS_ASSERT(!resolved);
     safepointOffset_ = safepoint_->offset();
     resolved = true;
 }
@@ -73,14 +73,14 @@ GetTopBaselineFrame(JSContext *cx)
     JS_ASSERT(iter.type() == IonFrame_Exit);
     ++iter;
     if (iter.isBaselineStub())
         ++iter;
     JS_ASSERT(iter.isBaselineJS());
     return iter.baselineFrame();
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonFrames_inl_h */
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -26,17 +26,17 @@
 
 #include "jsfuninlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/IonFrameIterator-inl.h"
 #include "vm/Probes-inl.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 IonFrameIterator::IonFrameIterator(const ActivationIterator &activations)
     : current_(activations.jitTop()),
       type_(IonFrame_Exit),
       returnAddressToFp_(NULL),
       frameSize_(0),
       cachedSafepointIndex_(NULL),
       activation_(activations.activation()->asJit())
@@ -419,17 +419,17 @@ HandleExceptionBaseline(JSContext *cx, c
 
           case JSTRAP_CONTINUE:
           case JSTRAP_THROW:
             JS_ASSERT(cx->isExceptionPending());
             break;
 
           case JSTRAP_RETURN:
             JS_ASSERT(baselineFrame->hasReturnValue());
-            if (ion::DebugEpilogue(cx, baselineFrame, true)) {
+            if (jit::DebugEpilogue(cx, baselineFrame, true)) {
                 rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
                 rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
                 rfe->stackPointer = reinterpret_cast<uint8_t *>(baselineFrame);
                 return;
             }
 
             // DebugEpilogue threw an exception. Propagate to the caller frame.
             *calledDebugEpilogue = true;
@@ -568,17 +568,17 @@ HandleException(ResumeFromException *rfe
             // to be.  Unset the flag here so that if we call DebugEpilogue below,
             // it doesn't try to pop the SPS frame again.
             iter.baselineFrame()->unsetPushedSPSFrame();
  
             if (cx->compartment()->debugMode() && !calledDebugEpilogue) {
                 // If DebugEpilogue returns |true|, we have to perform a forced
                 // return, e.g. return frame->returnValue() to the caller.
                 BaselineFrame *frame = iter.baselineFrame();
-                if (ion::DebugEpilogue(cx, frame, false)) {
+                if (jit::DebugEpilogue(cx, frame, false)) {
                     JS_ASSERT(frame->hasReturnValue());
                     rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
                     rfe->framePointer = iter.fp() - BaselineFrame::FramePointerOffset;
                     rfe->stackPointer = reinterpret_cast<uint8_t *>(frame);
                     return;
                 }
             }
         }
@@ -1657,10 +1657,10 @@ IonFrameIterator::dump() const
         break;
       case IonFrame_Osr:
         fprintf(stderr, "Warning! OSR frame are not defined yet.\n");
         break;
     };
     fputc('\n', stderr);
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
--- a/js/src/jit/IonFrames.h
+++ b/js/src/jit/IonFrames.h
@@ -19,17 +19,17 @@
 #include "jit/IonCode.h"
 #include "jit/IonFrameIterator.h"
 #include "jit/Registers.h"
 
 class JSFunction;
 class JSScript;
 
 namespace js {
-namespace ion {
+namespace jit {
 
 typedef void * CalleeToken;
 
 enum CalleeTokenTag
 {
     CalleeToken_Function = 0x0, // untagged
     CalleeToken_Script = 0x1,
     CalleeToken_ParallelFunction = 0x2
@@ -98,17 +98,17 @@ ScriptFromCalleeToken(CalleeToken token)
 // In between every two frames lies a small header describing both frames. This
 // header, minimally, contains a returnAddress word and a descriptor word. The
 // descriptor describes the size and type of the previous frame, whereas the
 // returnAddress describes the address the newer frame (the callee) will return
 // to. The exact mechanism in which frames are laid out is architecture
 // dependent.
 //
 // Two special frame types exist. Entry frames begin an ion activation, and
-// therefore there is exactly one per activation of ion::Cannon. Exit frames
+// therefore there is exactly one per activation of jit::Cannon. Exit frames
 // are necessary to leave JIT code and enter C++, and thus, C++ code will
 // always begin iterating from the topmost exit frame.
 
 class LSafepoint;
 
 // Two-tuple that lets you look up the safepoint entry given the
 // displacement of a call instruction within the JIT code.
 class SafepointIndex
@@ -313,29 +313,29 @@ GetTopIonJSScript(PerThreadData *pt, voi
 }
 
 inline JSScript *
 GetTopIonJSScript(ThreadSafeContext *cx, void **returnAddrOut = NULL)
 {
     return GetTopIonJSScript(cx->perThreadData, returnAddrOut);
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #if defined(JS_CPU_X86) || defined (JS_CPU_X64)
 # include "jit/shared/IonFrames-x86-shared.h"
 #elif defined (JS_CPU_ARM)
 # include "jit/arm/IonFrames-arm.h"
 #else
 # error "unsupported architecture"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
 void
 GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes);
 
 // Given a slot index, returns the offset, in bytes, of that slot from an
 // IonJSFrameLayout. Slot distances are uniform across architectures, however,
 // the distance does depend on the size of the frame header.
 static inline int32_t
@@ -356,14 +356,14 @@ static inline double
 ReadFrameDoubleSlot(IonJSFrameLayout *fp, int32_t slot)
 {
     return *(double *)((char *)fp + OffsetOfFrameSlot(slot));
 }
 
 CalleeToken
 MarkCalleeToken(JSTracer *trc, CalleeToken token);
 
-} /* namespace ion */
+} /* namespace jit */
 } /* namespace js */
 
 #endif // JS_ION
 
 #endif /* jit_IonFrames_h */
--- a/js/src/jit/IonInstrumentation.h
+++ b/js/src/jit/IonInstrumentation.h
@@ -6,17 +6,17 @@
 
 #ifndef jit_IonInstrumentatjit_h
 #define jit_IonInstrumentatjit_h
 
 namespace js {
 
 class SPSProfiler;
 
-namespace ion {
+namespace jit {
 
 class MacroAssembler;
 
 typedef SPSInstrumentation<MacroAssembler, Register> BaseInstrumentation;
 
 class IonInstrumentation : public BaseInstrumentation
 {
     jsbytecode **trackedPc_;
@@ -29,12 +29,12 @@ class IonInstrumentation : public BaseIn
         JS_ASSERT(pc != NULL);
     }
 
     void leave(MacroAssembler &masm, Register reg) {
         BaseInstrumentation::leave(*trackedPc_, masm, reg);
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonInstrumentatjit_h */
--- a/js/src/jit/IonLinker.h
+++ b/js/src/jit/IonLinker.h
@@ -12,17 +12,17 @@
 #include "jsgc.h"
 
 #include "assembler/jit/ExecutableAllocator.h"
 #include "jit/IonCode.h"
 #include "jit/IonCompartment.h"
 #include "jit/IonMacroAssembler.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class Linker
 {
     MacroAssembler &masm;
 
     IonCode *fail(JSContext *cx) {
         js_ReportOutOfMemory(cx);
         return NULL;
@@ -90,12 +90,12 @@ class Linker
         if (!alloc)
             return NULL;
 
         return newCode(cx, alloc, JSC::ION_CODE);
 #endif
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonLinker_h */
--- a/js/src/jit/IonMacroAssembler.cpp
+++ b/js/src/jit/IonMacroAssembler.cpp
@@ -18,17 +18,17 @@
 #include "vm/ForkJoin.h"
 
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 
 #include "vm/Shape-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 namespace {
 
 // Emulate a TypeSet logic from a Type object to avoid duplicating the guard
 // logic.
 class TypeWrapper {
     types::Type t_;
 
@@ -1104,20 +1104,20 @@ MacroAssembler::handleFailure(ExecutionM
     // running function and never come back
     if (sps_)
         sps_->skipNextReenter();
     leaveSPSFrame();
 
     void *handler;
     switch (executionMode) {
       case SequentialExecution:
-        handler = JS_FUNC_TO_DATA_PTR(void *, ion::HandleException);
+        handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleException);
         break;
       case ParallelExecution:
-        handler = JS_FUNC_TO_DATA_PTR(void *, ion::HandleParallelFailure);
+        handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleParallelFailure);
         break;
       default:
         MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
     MacroAssemblerSpecific::handleFailureWithHandler(handler);
 
     // Doesn't actually emit code, but balances the leave()
     if (sps_)
--- a/js/src/jit/IonMacroAssembler.h
+++ b/js/src/jit/IonMacroAssembler.h
@@ -22,17 +22,17 @@
 #include "jit/IonInstrumentation.h"
 #include "jit/ParallelFunctions.h"
 #include "jit/VMFunctions.h"
 #include "vm/ProxyObject.h"
 #include "vm/Shape.h"
 #include "vm/TypedArrayObject.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // The public entrypoint for emitting assembly. Note that a MacroAssembler can
 // use cx->lifoAlloc, so take care not to interleave masm use with other
 // lifoAlloc use if one will be destroyed before the other.
 class MacroAssembler : public MacroAssemblerSpecific
 {
     MacroAssembler *thisFromCtor() {
         return this;
@@ -99,17 +99,17 @@ class MacroAssembler : public MacroAssem
     // This constructor should only be used when there is no IonContext active
     // (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp).
     MacroAssembler(JSContext *cx)
       : enoughMemory_(true),
         embedsNurseryPointers_(false),
         sps_(NULL)
     {
         constructRoot(cx);
-        ionContext_.construct(cx, (js::ion::TempAllocator *)NULL);
+        ionContext_.construct(cx, (js::jit::TempAllocator *)NULL);
         alloc_.construct(cx);
 #ifdef JS_CPU_ARM
         initWithAllocator();
         m_buffer.id = GetIonContext()->getNextAssemblerId();
 #endif
     }
 
     // asm.js compilation handles its own IonContet-pushing
@@ -1046,14 +1046,14 @@ JSOpToCondition(JSOp op, bool isSigned)
           case JSOP_GE:
             return Assembler::AboveOrEqual;
           default:
             MOZ_ASSUME_UNREACHABLE("Unrecognized comparison operation");
         }
     }
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_IonMacroAssembler_h */
--- a/js/src/jit/IonSpewer.cpp
+++ b/js/src/jit/IonSpewer.cpp
@@ -18,17 +18,17 @@
 # elif defined(__ANDROID__)
 #  define ION_SPEW_DIR "/data/local/tmp/"
 # else
 #  define ION_SPEW_DIR "/tmp/"
 # endif
 #endif
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 // IonSpewer singleton.
 static IonSpewer ionspewer;
 
 static bool LoggingChecked = false;
 static uint32_t LoggingBits = 0;
 static uint32_t filteredOutCompilations = 0;
 
@@ -67,55 +67,55 @@ FilterContainsLocation(HandleScript func
             }
         }
         index = strstr(index + filelen, filename);
     }
     return false;
 }
 
 void
-ion::EnableIonDebugLogging()
+jit::EnableIonDebugLogging()
 {
     EnableChannel(IonSpew_Logs);
     ionspewer.init();
 }
 
 void
-ion::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
+jit::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
 {
     if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime)) {
         ionspewer.beginFunction(graph, func);
     } else {
         if (func) {
             IonSpew(IonSpew_Logs,
                     "Can't log script %s:%d. (Compiled on background thread.)",
                     func->filename(), func->lineno);
         } else {
             IonSpew(IonSpew_Logs,
                     "Can't log asm.js compilation. (Compiled on background thread.)");
         }
     }
 }
 
 void
-ion::IonSpewPass(const char *pass)
+jit::IonSpewPass(const char *pass)
 {
     if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
         ionspewer.spewPass(pass);
 }
 
 void
-ion::IonSpewPass(const char *pass, LinearScanAllocator *ra)
+jit::IonSpewPass(const char *pass, LinearScanAllocator *ra)
 {
     if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
         ionspewer.spewPass(pass, ra);
 }
 
 void
-ion::IonSpewEndFunction()
+jit::IonSpewEndFunction()
 {
     if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
         ionspewer.endFunction();
 }
 
 
 IonSpewer::~IonSpewer()
 {
@@ -208,33 +208,33 @@ IonSpewer::endFunction()
 
     c1Spewer.endFunction();
     jsonSpewer.endFunction();
 
     this->graph = NULL;
 }
 
 
-FILE *ion::IonSpewFile = NULL;
+FILE *jit::IonSpewFile = NULL;
 
 static bool
 ContainsFlag(const char *str, const char *flag)
 {
     size_t flaglen = strlen(flag);
     const char *index = strstr(str, flag);
     while (index) {
         if ((index == str || index[-1] == ',') && (index[flaglen] == 0 || index[flaglen] == ','))
             return true;
         index = strstr(index + flaglen, flag);
     }
     return false;
 }
 
 void
-ion::CheckLogging()
+jit::CheckLogging()
 {
     if (LoggingChecked)
         return;
     LoggingChecked = true;
     const char *env = getenv("IONFLAGS");
     if (!env)
         return;
     if (strstr(env, "help")) {
@@ -255,17 +255,17 @@ ion::CheckLogging()
             "  codegen    Native code generation\n"
             "  bailouts   Bailouts\n"
             "  caches     Inline caches\n"
             "  osi        Invalidation\n"
             "  safepoints Safepoints\n"
             "  pools      Literal Pools (ARM only for now)\n"
             "  cacheflush Instruction Cache flushes (ARM only for now)\n"
             "  logs       C1 and JSON visualization logging\n"
-            "  trace      Generate calls to js::ion::Trace() for effectful instructions\n"
+            "  trace      Generate calls to js::jit::Trace() for effectful instructions\n"
             "  all        Everything\n"
             "\n"
             "  bl-aborts  Baseline compiler abort messages\n"
             "  bl-scripts Baseline script-compilation\n"
             "  bl-op      Baseline compiler detailed op-specific messages\n"
             "  bl-ic      Baseline inline-cache messages\n"
             "  bl-ic-fb   Baseline IC fallback stub messages\n"
             "  bl-osr     Baseline IC OSR messages\n"
@@ -343,100 +343,100 @@ ion::CheckLogging()
 
     if (LoggingBits != 0)
         EnableIonDebugLogging();
 
     IonSpewFile = stderr;
 }
 
 void
-ion::IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap)
+jit::IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap)
 {
     if (!IonSpewEnabled(channel))
         return;
 
     IonSpewHeader(channel);
     vfprintf(stderr, fmt, ap);
 }
 
 void
-ion::IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap)
+jit::IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap)
 {
     if (!IonSpewEnabled(channel))
         return;
 
     vfprintf(stderr, fmt, ap);
 }
 
 void
-ion::IonSpewFin(IonSpewChannel channel)
+jit::IonSpewFin(IonSpewChannel channel)
 {
     if (!IonSpewEnabled(channel))
         return;
 
     fprintf(stderr, "\n");
 }
 
 void
-ion::IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap)
+jit::IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap)
 {
     IonSpewStartVA(channel, fmt, ap);
     IonSpewFin(channel);
 }
 
 void
-ion::IonSpew(IonSpewChannel channel, const char *fmt, ...)
+jit::IonSpew(IonSpewChannel channel, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
     IonSpewVA(channel, fmt, ap);
     va_end(ap);
 }
 
 void
-ion::IonSpewStart(IonSpewChannel channel, const char *fmt, ...)
+jit::IonSpewStart(IonSpewChannel channel, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
     IonSpewStartVA(channel, fmt, ap);
     va_end(ap);
 }
 void
-ion::IonSpewCont(IonSpewChannel channel, const char *fmt, ...)
+jit::IonSpewCont(IonSpewChannel channel, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
     IonSpewContVA(channel, fmt, ap);
     va_end(ap);
 }
 
 void
-ion::IonSpewHeader(IonSpewChannel channel)
+jit::IonSpewHeader(IonSpewChannel channel)
 {
     if (!IonSpewEnabled(channel))
         return;
 
     fprintf(stderr, "[%s] ", ChannelNames[channel]);
 }
 
 bool
-ion::IonSpewEnabled(IonSpewChannel channel)
+jit::IonSpewEnabled(IonSpewChannel channel)
 {
     JS_ASSERT(LoggingChecked);
     return (LoggingBits & (1 << uint32_t(channel))) && !filteredOutCompilations;
 }
 
 void
-ion::EnableChannel(IonSpewChannel channel)
+jit::EnableChannel(IonSpewChannel channel)
 {
     JS_ASSERT(LoggingChecked);
     LoggingBits |= (1 << uint32_t(channel));
 }
 
 void
-ion::DisableChannel(IonSpewChannel channel)
+jit::DisableChannel(IonSpewChannel channel)
 {
     JS_ASSERT(LoggingChecked);
     LoggingBits &= ~(1 << uint32_t(channel));
 }
 
 #endif /* DEBUG */
 
--- a/js/src/jit/IonSpewer.h
+++ b/js/src/jit/IonSpewer.h
@@ -10,17 +10,17 @@
 #include "mozilla/DebugOnly.h"
 
 #include <stdarg.h>
 
 #include "jit/C1Spewer.h"
 #include "jit/JSONSpewer.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 // New channels may be added below.
 #define IONSPEW_CHANNEL_LIST(_)             \
     /* Used to abort SSA construction */    \
     _(Abort)                                \
     /* Information about compiled scripts */\
     _(Scripts)                              \
     /* Information during MIR building */   \
@@ -48,17 +48,17 @@ namespace ion {
     /* Debug info about snapshots */        \
     _(Snapshots)                            \
     /* Generated inline cache stubs */      \
     _(InlineCaches)                         \
     /* Debug info about safepoints */       \
     _(Safepoints)                           \
     /* Debug info about Pools*/             \
     _(Pools)                                \
-    /* Calls to js::ion::Trace() */         \
+    /* Calls to js::jit::Trace() */         \
     _(Trace)                                \
     /* Debug info about the I$ */           \
     _(CacheFlush)                           \
                                             \
     /* BASELINE COMPILER SPEW */            \
                                             \
     /* Aborting Script Compilation. */      \
     _(BaselineAbort)                        \
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -7,17 +7,17 @@
 #ifndef jit_IonTypes_h
 #define jit_IonTypes_h
 
 #include "jstypes.h"
 
 #include "js/Value.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 typedef uint32_t SnapshotOffset;
 typedef uint32_t BailoutId;
 
 static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1);
 
 // Different kinds of bailouts. When extending this enum, make sure to check
 // the bits reserved for bailout kinds in Bailouts.h
@@ -210,12 +210,12 @@ IsNullOrUndefined(MIRType type)
 //
 // Skip this check in rooting analysis builds, which poison unrooted
 // pointers on the stack.
 #  if defined(JS_ION) && !defined(JSGC_ROOT_ANALYSIS)
 #    define CHECK_OSIPOINT_REGISTERS 1
 #  endif
 #endif
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_IonTypes_h */
--- a/js/src/jit/JSONSpewer.cpp
+++ b/js/src/jit/JSONSpewer.cpp
@@ -10,17 +10,17 @@
 
 #include "jit/LinearScan.h"
 #include "jit/LIR.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/RangeAnalysis.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 JSONSpewer::~JSONSpewer()
 {
     if (fp_)
         fclose(fp_);
 }
 
 void
--- a/js/src/jit/JSONSpewer.h
+++ b/js/src/jit/JSONSpewer.h
@@ -7,17 +7,17 @@
 #ifndef jit_JSONSpewer_h
 #define jit_JSONSpewer_h
 
 #include <stdio.h>
 
 class JSScript;
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MDefinition;
 class MInstruction;
 class MBasicBlock;
 class MIRGraph;
 class MResumePoint;
 class LinearScanAllocator;
 class LInstruction;
@@ -64,12 +64,12 @@ class JSONSpewer
     void spewLIns(LInstruction *ins);
     void spewLIR(MIRGraph *mir);
     void spewIntervals(LinearScanAllocator *regalloc);
     void endPass();
     void endFunction();
     void finish();
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_JSONSpewer_h */
--- a/js/src/jit/LICM.cpp
+++ b/js/src/jit/LICM.cpp
@@ -10,17 +10,17 @@
 
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 namespace {
 
 typedef Vector<MBasicBlock*, 1, IonAllocPolicy> BlockQueue;
 typedef Vector<MInstruction*, 1, IonAllocPolicy> InstructionQueue;
 
 class Loop
 {
--- a/js/src/jit/LICM.h
+++ b/js/src/jit/LICM.h
@@ -10,24 +10,24 @@
 #include "jit/IonAllocPolicy.h"
 #include "jit/IonAnalysis.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 // This file represents the Loop Invariant Code Motion optimization pass
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class LICM
 {
     MIRGenerator *mir;
     MIRGraph &graph;
 
   public:
     LICM(MIRGenerator *mir, MIRGraph &graph);
     bool analyze();
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_LICM_h */
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -8,17 +8,17 @@
 #define jit_LIR_Common_h
 
 #include "jit/RangeAnalysis.h"
 #include "jit/shared/Assembler-shared.h"
 
 // This file declares LIR instructions that are common to every platform.
 
 namespace js {
-namespace ion {
+namespace jit {
 
 template <size_t Temps, size_t ExtraUses = 0>
 class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps>
 {
   public:
     const LAllocation *lhs() {
         return this->getOperand(0);
     }
@@ -4998,12 +4998,12 @@ class LAssertRangeV : public LInstructio
     MAssertRange *mir() {
         return mir_->toAssertRange();
     }
     Range *range() {
         return mir()->range();
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_LIR_Common_h */
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -11,17 +11,17 @@
 #include "jsprf.h"
 
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/shared/CodeGenerator-shared.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 LIRGraph::LIRGraph(MIRGraph *mir)
   : numVirtualRegisters_(0),
     numInstructions_(1), // First id is 1.
     localSlotCount_(0),
     argumentSlotCount_(0),
     entrySnapshot_(NULL),
     osrBlock_(NULL),
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -19,17 +19,17 @@
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/Registers.h"
 #include "jit/Safepoints.h"
 #include "jit/shared/Assembler-shared.h"
 #include "jit/VMFunctions.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class LUse;
 class LGeneralReg;
 class LFloatReg;
 class LStackSlot;
 class LArgument;
 class LConstantIndex;
 class MBasicBlock;
@@ -1452,17 +1452,17 @@ AnyRegister
 LAllocation::toRegister() const
 {
     JS_ASSERT(isRegister());
     if (isFloatReg())
         return AnyRegister(toFloatReg()->reg());
     return AnyRegister(toGeneralReg()->reg());
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #define LIR_HEADER(opcode)                                                  \
     Opcode op() const {                                                     \
         return LInstruction::LOp_##opcode;                                  \
     }                                                                       \
     bool accept(LInstructionVisitor *visitor) {                             \
         visitor->setInstruction(this);                                      \
@@ -1494,17 +1494,17 @@ LAllocation::toRegister() const
 # include "jit/shared/LIR-x86-shared.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/LIR-arm.h"
 #endif
 
 #undef LIR_HEADER
 
 namespace js {
-namespace ion {
+namespace jit {
 
 #define LIROP(name)                                                         \
     L##name *LInstruction::to##name()                                       \
     {                                                                       \
         JS_ASSERT(is##name());                                              \
         return static_cast<L##name *>(this);                                \
     }
     LIR_OPCODE_LIST(LIROP)
@@ -1563,12 +1563,12 @@ static inline unsigned
 BaseOfNunboxSlot(LDefinition::Type type, unsigned slot)
 {
     if (type == LDefinition::PAYLOAD)
         return slot + (NUNBOX32_PAYLOAD_OFFSET / STACK_SLOT_SIZE);
     return slot + (NUNBOX32_TYPE_OFFSET / STACK_SLOT_SIZE);
 }
 #endif
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_LIR_h */
--- a/js/src/jit/LinearScan.cpp
+++ b/js/src/jit/LinearScan.cpp
@@ -8,17 +8,17 @@
 
 #include "mozilla/DebugOnly.h"
 
 #include "jit/BitSet.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 /*
  * Merge virtual register intervals into the UnhandledQueue, taking advantage
  * of their nearly-sorted ordering.
  */
 void
--- a/js/src/jit/LinearScan.h
+++ b/js/src/jit/LinearScan.h
@@ -7,17 +7,17 @@
 #ifndef jit_LinearScan_h
 #define jit_LinearScan_h
 
 #include "jit/BitSet.h"
 #include "jit/LiveRangeAllocator.h"
 #include "js/Vector.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class LinearScanVirtualRegister : public VirtualRegister
 {
   private:
     LAllocation *canonicalSpill_;
     CodePosition spillPosition_ ;
 
     bool spillAtDefinition_ : 1;
@@ -124,12 +124,12 @@ class LinearScanAllocator : public LiveR
     LinearScanAllocator(MIRGenerator *mir, LIRGenerator *lir, LIRGraph &graph)
       : LiveRangeAllocator<LinearScanVirtualRegister>(mir, lir, graph, /* forLSRA = */ true)
     {
     }
 
     bool go();
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_LinearScan_h */
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -7,17 +7,17 @@
 #include "jit/LiveRangeAllocator.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "jit/BacktrackingAllocator.h"
 #include "jit/LinearScan.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 int
 Requirement::priority() const
 {
     switch (kind_) {
       case Requirement::FIXED:
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -12,17 +12,17 @@
 
 #include "jit/RegisterAllocator.h"
 #include "jit/StackSlotAllocator.h"
 
 // Common structures and functions used by register allocators that operate on
 // virtual register live ranges.
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class Requirement
 {
   public:
     enum Kind {
         NONE,
         REGISTER,
         FIXED,
@@ -641,12 +641,12 @@ class LiveRangeAllocator : public Regist
             LInstruction *ins = graph.getSafepoint(i);
             if (interval->start() <= inputOf(ins))
                 break;
         }
         return i;
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_LiveRangeAllocator_h */
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -16,17 +16,17 @@
 #include "jit/MIRGraph.h"
 #include "jit/RangeAnalysis.h"
 
 #include "jsinferinlines.h"
 
 #include "jit/shared/Lowering-shared-inl.h"
 
 using namespace js;
-using namespace ion;
+using namespace jit;
 
 bool
 LIRGenerator::visitParameter(MParameter *param)
 {
     ptrdiff_t offset;
     if (param->index() == MParameter::THIS_SLOT)
         offset = THIS_FRAME_SLOT;
     else
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -19,17 +19,17 @@
 # include "jit/x64/Lowering-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/Lowering-arm.h"
 #else
 # error "CPU!"
 #endif
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class LIRGenerator : public LIRGeneratorSpecific
 {
     void updateResumeState(MInstruction *ins);
     void updateResumeState(MBasicBlock *block);
 
     // The active depth of the (perhaps nested) call argument vectors.
     uint32_t argslots_;
@@ -245,12 +245,12 @@ class LIRGenerator : public LIRGenerator
     bool visitAsmJSVoidReturn(MAsmJSVoidReturn *ins);
     bool visitAsmJSPassStackArg(MAsmJSPassStackArg *ins);
     bool visitAsmJSCall(MAsmJSCall *ins);
     bool visitAsmJSCheckOverRecursed(MAsmJSCheckOverRecursed *ins);
     bool visitSetDOMProperty(MSetDOMProperty *ins);
     bool visitGetDOMProperty(MGetDOMProperty *ins);
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_Lowering_h */
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -12,17 +12,17 @@
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 #include "jsscriptinlines.h"
 
 #include "vm/StringObject-inl.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 IonBuilder::InliningStatus
 IonBuilder::inlineNativeCall(CallInfo &callInfo, JSNative native)
 {
     // Array natives.
     if (native == js_Array)
         return inlineArray(callInfo);
     if (native == js::array_pop)
@@ -1511,10 +1511,10 @@ IonBuilder::inlineBailout(CallInfo &call
     current->add(MBail::New());
 
     MConstant *undefined = MConstant::New(UndefinedValue());
     current->add(undefined);
     current->push(undefined);
     return InliningStatus_Inlined;
 }
 
-} // namespace ion
+} // namespace jit
 } // namespace js
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -22,17 +22,17 @@
 #include "jit/RangeAnalysis.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 
 #include "vm/Shape-inl.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 using mozilla::DoublesAreIdentical;
 
 void
 MDefinition::PrintOpcodeName(FILE *fp, MDefinition::Opcode op)
 {
     static const char * const names[] =
     {
@@ -358,17 +358,17 @@ MDefinition::emptyResultTypeSet() const
 
 MConstant *
 MConstant::New(const Value &v)
 {
     return new MConstant(v);
 }
 
 types::StackTypeSet *
-ion::MakeSingletonTypeSet(JSObject *obj)
+jit::MakeSingletonTypeSet(JSObject *obj)
 {
     LifoAlloc *alloc = GetIonContext()->temp->lifoAlloc();
     types::StackTypeSet *types = alloc->new_<types::StackTypeSet>();
     if (!types)
         return NULL;
     types::Type objectType = types::Type::ObjectType(obj);
     types->addObject(objectType.objectKey(), alloc);
     return types;
@@ -681,17 +681,17 @@ MakeMIRTypeSet(MIRType type)
     JS_ASSERT(type != MIRType_Value);
     types::Type ntype = type == MIRType_Object
                         ? types::Type::AnyObjectType()
                         : types::Type::PrimitiveType(ValueTypeFromMIRType(type));
     return GetIonContext()->temp->lifoAlloc()->new_<types::StackTypeSet>(ntype);
 }
 
 void
-ion::MergeTypes(MIRType *ptype, types::StackTypeSet **ptypeSet,
+jit::MergeTypes(MIRType *ptype, types::StackTypeSet **ptypeSet,
                 MIRType newType, types::StackTypeSet *newTypeSet)
 {
     if (newTypeSet && newTypeSet->empty())
         return;
     if (newType != *ptype) {
         if (IsNumberType(newType) && IsNumberType(*ptype)) {
             *ptype = MIRType_Double;
         } else if (*ptype != MIRType_Value) {
@@ -2432,69 +2432,69 @@ MAsmJSCall::New(Callee callee, const Arg
         call->setOperand(i, args[i].def);
     if (callee.which() == Callee::Dynamic)
         call->setOperand(call->numArgs_, callee.dynamic());
 
     return call;
 }
 
 bool
-ion::ElementAccessIsDenseNative(MDefinition *obj, MDefinition *id)
+jit::ElementAccessIsDenseNative(MDefinition *obj, MDefinition *id)
 {
     if (obj->mightBeType(MIRType_String))
         return false;
 
     if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
         return false;
 
     types::StackTypeSet *types = obj->resultTypeSet();
     if (!types)
         return false;
 
     Class *clasp = types->getKnownClass();
     return clasp && clasp->isNative();
 }
 
 bool
-ion::ElementAccessIsTypedArray(MDefinition *obj, MDefinition *id, int *arrayType)
+jit::ElementAccessIsTypedArray(MDefinition *obj, MDefinition *id, int *arrayType)
 {
     if (obj->mightBeType(MIRType_String))
         return false;
 
     if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
         return false;
 
     types::StackTypeSet *types = obj->resultTypeSet();
     if (!types)
         return false;
 
     *arrayType = types->getTypedArrayType();
     return *arrayType != TypedArrayObject::TYPE_MAX;
 }
 
 bool
-ion::ElementAccessIsPacked(JSContext *cx, MDefinition *obj)
+jit::ElementAccessIsPacked(JSContext *cx, MDefinition *obj)
 {
     types::StackTypeSet *types = obj->resultTypeSet();
     return types && !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
 }
 
 bool
-ion::ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj)
+jit::ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj)
 {
     types::StackTypeSet *types = obj->resultTypeSet();
 
     if (!types || types->hasObjectFlags(cx, types::OBJECT_FLAG_LENGTH_OVERFLOW))
         return true;
 
     return types::TypeCanHaveExtraIndexedProperties(cx, types);
 }
 
 MIRType
-ion::DenseNativeElementType(JSContext *cx, MDefinition *obj)
+jit::DenseNativeElementType(JSContext *cx, MDefinition *obj)
 {
     types::StackTypeSet *types = obj->resultTypeSet();
     MIRType elementType = MIRType_None;
     unsigned count = types->getObjectCount();
 
     for (unsigned i = 0; i < count; i++) {
         if (types::TypeObject *object = types->getTypeOrSingleObject(cx, i)) {
             if (object->unknownProperties())
@@ -2514,17 +2514,17 @@ ion::DenseNativeElementType(JSContext *c
                 return MIRType_None;
         }
     }
 
     return elementType;
 }
 
 bool
-ion::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name,
+jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name,
                                   types::StackTypeSet *observed, bool updateObserved)
 {
     // If the object being read from has types for the property which haven't
     // been observed at this access site, the read could produce a new type and
     // a barrier is needed. Note that this only covers reads from properties
     // which are accounted for by type information, i.e. native data properties
     // and elements.
 
@@ -2581,17 +2581,17 @@ ion::PropertyReadNeedsTypeBarrier(JSCont
         }
     }
 
     property->addFreeze(cx);
     return false;
 }
 
 bool
-ion::PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name,
+jit::PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name,
                                   types::StackTypeSet *observed)
 {
     if (observed->unknown())
         return false;
 
     types::TypeSet *types = obj->resultTypeSet();
     if (!types || types->unknownObject())
         return true;
@@ -2602,17 +2602,17 @@ ion::PropertyReadNeedsTypeBarrier(JSCont
         if (object && PropertyReadNeedsTypeBarrier(cx, object, name, observed, updateObserved))
             return true;
     }
 
     return false;
 }
 
 bool
-ion::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name)
+jit::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name)
 {
     // Determine if reading a property from obj is likely to be idempotent.
 
     jsid id = types::IdToTypeId(NameToId(name));
 
     types::TypeSet *types = obj->resultTypeSet();
     if (!types || types->unknownObject())
         return false;
@@ -2628,17 +2628,17 @@ ion::PropertyReadIsIdempotent(JSContext 
                 return false;
         }
     }
 
     return true;
 }
 
 void
-ion::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
+jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
                                types::StackTypeSet *observed)
 {
     // Add objects to observed which *could* be observed by reading name from obj,
     // to hopefully avoid unnecessary type barriers and code invalidations.
 
     JS_ASSERT(observed->noConstraints());
 
     types::StackTypeSet *types = obj->resultTypeSet();
@@ -2760,17 +2760,17 @@ AddTypeGuard(MBasicBlock *current, MDefi
 
     // For now, never move type object guards.
     guard->setNotMovable();
 
     return guard;
 }
 
 bool
-ion::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj,
+jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj,
                                    PropertyName *name, MDefinition **pvalue, bool canModify)
 {
     // If any value being written is not reflected in the type information for
     // objects which obj could represent, a type barrier is needed when writing
     // the value. As for propertyReadNeedsTypeBarrier, this only applies for
     // properties that are accounted for by type information, i.e. normal data
     // properties and elements.
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -25,17 +25,17 @@
 #include "jit/MOpcodes.h"
 #include "jit/TypePolicy.h"
 #include "vm/ScopeObject.h"
 
 namespace js {
 
 class StringObject;
 
-namespace ion {
+namespace jit {
 
 class BaselineInspector;
 class ValueNumberData;
 class Range;
 
 static const inline
 MIRType MIRTypeFromValue(const js::Value &vp)
 {
@@ -3397,16 +3397,18 @@ class MMathFunction
       : MUnaryInstruction(input), function_(function), cache_(cache)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(MathFunction)
+
+    // A NULL cache means this function will neither access nor update the cache.
     static MMathFunction *New(MDefinition *input, Function function, MathCache *cache) {
         return new MMathFunction(input, function, cache);
     }
     Function function() const {
         return function_;
     }
     MathCache *cache() const {
         return cache_;
@@ -8428,12 +8430,12 @@ bool PropertyReadNeedsTypeBarrier(JSCont
                                   types::StackTypeSet *observed);
 bool PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name);
 void AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
                                types::StackTypeSet *observed);
 bool PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj,
                                    PropertyName *name, MDefinition **pvalue,
                                    bool canModify = true);
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_MIR_h */
--- a/js/src/jit/MIRGenerator.h
+++ b/js/src/jit/MIRGenerator.h
@@ -19,17 +19,17 @@
 #include "jit/IonAllocPolicy.h"
 #include "jit/IonCompartment.h"
 #if defined(JS_ION_PERF)
 # include "jit/PerfSpewer.h"
 #endif
 #include "jit/RegisterSets.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MBasicBlock;
 class MIRGraph;
 class MStart;
 
 struct AsmJSGlobalAccess
 {
     unsigned offset;
@@ -151,12 +151,12 @@ class MIRGenerator
 #if defined(JS_ION_PERF)
     AsmJSPerfSpewer asmJSPerfSpewer_;
 
   public:
     AsmJSPerfSpewer &perfSpewer() { return asmJSPerfSpewer_; }
 #endif
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_MIRGenerator_h */
--- a/js/src/jit/MIRGraph.cpp
+++ b/js/src/jit/MIRGraph.cpp
@@ -11,17 +11,17 @@
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 
 #include "jsinferinlines.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 MIRGenerator::MIRGenerator(JSCompartment *compartment,
                            TempAllocator *temp, MIRGraph *graph, CompileInfo *info)
   : compartment(compartment),
     info_(info),
     temp_(temp),
     graph_(graph),
     error_(false),
--- a/js/src/jit/MIRGraph.h
+++ b/js/src/jit/MIRGraph.h
@@ -11,17 +11,17 @@
 // containing MIR.
 
 #include "jit/FixedList.h"
 #include "jit/IonAllocPolicy.h"
 #include "jit/MIR.h"
 #include "jit/MIRGenerator.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MBasicBlock;
 class MIRGraph;
 class MStart;
 
 class MDefinitionIterator;
 
 typedef InlineListIterator<MInstruction> MInstructionIterator;
@@ -749,12 +749,12 @@ class MDefinitionIterator
     }
 
     MDefinition *operator ->() {
         return getIns();
     }
 
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_MIRGraph_h */
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -3,17 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_MOpcodes_h
 #define jit_MOpcodes_h
 
 namespace js {
-namespace ion {
+namespace jit {
 
 #define MIR_OPCODE_LIST(_)                                                  \
     _(Constant)                                                             \
     _(Parameter)                                                            \
     _(Callee)                                                               \
     _(TableSwitch)                                                          \
     _(Goto)                                                                 \
     _(Test)                                                                 \
@@ -216,12 +216,12 @@ class MInstructionVisitor // interface i
 class MInstructionVisitorWithDefaults : public MInstructionVisitor
 {
   public:
 #define VISIT_INS(op) virtual bool visit##op(M##op *) { MOZ_ASSUME_UNREACHABLE("NYI: " #op); }
     MIR_OPCODE_LIST(VISIT_INS)
 #undef VISIT_INS
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_MOpcodes_h */
--- a/js/src/jit/MoveResolver.cpp
+++ b/js/src/jit/MoveResolver.cpp
@@ -2,17 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/MoveResolver.h"
 
 using namespace js;
-using namespace js::ion;
+using namespace js::jit;
 
 MoveResolver::MoveResolver()
   : hasCycles_(false)
 {
 }
 
 void
 MoveResolver::resetState()
--- a/js/src/jit/MoveResolver.h
+++ b/js/src/jit/MoveResolver.h
@@ -7,17 +7,17 @@
 #ifndef jit_MoveResolver_h
 #define jit_MoveResolver_h
 
 #include "jit/InlineList.h"
 #include "jit/IonAllocPolicy.h"
 #include "jit/Registers.h"
 
 namespace js {
-namespace ion {
+namespace jit {
 
 class MoveResolver
 {
   public:
     // This is similar to Operand, but carries more information. We're also not
     // guaranteed that Operand looks like this on all ISAs.
     class MoveOperand
     {
@@ -208,12 +208,12 @@ class MoveResolver
     bool hasCycles() const {
         return hasCycles_;
     }
     void clearTempObjectPool() {
         movePool_.clear();
     }
 };
 
-} // namespace ion
+} // namespace jit
 } // namespace js
 
 #endif /* jit_MoveResolver_h */
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -10,45 +10,45 @@
 #include "vm/ArrayObject.h"
 
 #include "jsfuninlines.h"
 #include "jsgcinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
-using namespace ion;
+using namespace jit;
 
 using parallel::Spew;
 using parallel::SpewOps;
 using parallel::SpewBailouts;
 using parallel::SpewBailoutIR;
 
 // Load the current thread context.
 ForkJoinSlice *
-ion::ForkJoinSlicePar()
+jit::ForkJoinSlicePar()
 {
     return ForkJoinSlice::Current();
 }
 
 // NewGCThingPar() is called in place of NewGCThing() when executing
 // parallel code.  It uses the ArenaLists for the current thread and
 // allocates from there.
 JSObject *
-ion::NewGCThingPar(gc::AllocKind allocKind)
+jit::NewGCThingPar(gc::AllocKind allocKind)
 {
     ForkJoinSlice *slice = ForkJoinSlice::Current();
     uint32_t thingSize = (uint32_t)gc::Arena::thingSize(allocKind);
     return gc::NewGCThing<JSObject, NoGC>(slice, allocKind, thingSize, gc::DefaultHeap);
 }
 
 // Check that the object was created by the current thread
 // (and hence is writable).
 bool
-ion::IsThreadLocalObject(ForkJoinSlice *slice, JSObject *object)
+jit::IsThreadLocalObject(ForkJoinSlice *slice, JSObject *object)
 {
     JS_ASSERT(ForkJoinSlice::Current() == slice);
     return !IsInsideNursery(slice->runtime(), object) &&
            slice->allocator()->arenas.containsArena(slice->runtime(), object->arenaHeader());
 }
 
 #ifdef DEBUG
 static void
@@ -58,17 +58,17 @@ printTrace(const char *prefix, struct Io
             prefix,
             cached->bblock, cached->lir, cached->execModeInt, cached->lirOpName);
 }
 
 struct IonLIRTraceData seqTraceData;
 #endif
 
 void
-ion::TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt,
+jit::TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt,
               const char *lirOpName, const char *mirOpName,
               JSScript *script, jsbytecode *pc)
 {
 #ifdef DEBUG
     static enum { NotSet, All, Bailouts } traceMode;
 
     // If you set IONFLAGS=trace, this function will be invoked before every LIR.
     //
@@ -113,17 +113,17 @@ ion::TraceLIR(uint32_t bblock, uint32_t 
     cached->pc = pc;
 
     if (traceMode == All)
         printTrace("Exec", cached);
 #endif
 }
 
 bool
-ion::CheckOverRecursedPar(ForkJoinSlice *slice)
+jit::CheckOverRecursedPar(ForkJoinSlice *slice)
 {
     JS_ASSERT(ForkJoinSlice::Current() == slice);
     int stackDummy_;
 
     // When an interrupt is triggered, the main thread stack limit is
     // overwritten with a sentinel value that brings us here.
     // Therefore, we must check whether this is really a stack overrun
     // and, if not, check whether an interrupt is needed.
@@ -143,88 +143,88 @@ ion::CheckOverRecursedPar(ForkJoinSlice 
                                        NULL, NULL, NULL);
         return false;
     }
 
     return CheckInterruptPar(slice);
 }
 
 bool
-ion::CheckInterruptPar(ForkJoinSlice *slice)
+jit::CheckInterruptPar(ForkJoinSlice *slice)
 {
     JS_ASSERT(ForkJoinSlice::Current() == slice);
     bool result = slice->check();
     if (!result) {
         // Do not set the cause here.  Either it was set by this
         // thread already by some code that then triggered an abort,
         // or else we are just picking up an abort from some other
         // thread.  Either way we have nothing useful to contribute so
         // we might as well leave our bailout case unset.
         return false;
     }
     return true;
 }
 
 JSObject *
-ion::PushPar(PushParArgs *args)
+jit::PushPar(PushParArgs *args)
 {
     // It is awkward to have the MIR pass the current slice in, so
     // just fetch it from TLS.  Extending the array is kind of the
     // slow path anyhow as it reallocates the elements vector.
     ForkJoinSlice *slice = js::ForkJoinSlice::Current();
     JSObject::EnsureDenseResult res =
         args->object->parExtendDenseElements(slice, &args->value, 1);
     if (res != JSObject::ED_OK)
         return NULL;
     return args->object;
 }
 
 JSObject *
-ion::ExtendArrayPar(ForkJoinSlice *slice, JSObject *array, uint32_t length)
+jit::ExtendArrayPar(ForkJoinSlice *slice, JSObject *array, uint32_t length)
 {
     JSObject::EnsureDenseResult res =
         array->parExtendDenseElements(slice, NULL, length);
     if (res != JSObject::ED_OK)
         return NULL;
     return array;
 }
 
 ParallelResult
-ion::ConcatStringsPar(ForkJoinSlice *slice, HandleString left, HandleString right,
+jit::ConcatStringsPar(ForkJoinSlice *slice, HandleString left, HandleString right,
                       MutableHandleString out)
 {
     JSString *str = ConcatStrings<NoGC>(slice, left, right);
     if (!str)
         return TP_RETRY_SEQUENTIALLY;
     out.set(str);
     return TP_SUCCESS;
 }
 
 ParallelResult
-ion::IntToStringPar(ForkJoinSlice *slice, int i, MutableHandleString out)
+jit::IntToStringPar(ForkJoinSlice *slice, int i, MutableHandleString out)
 {
     JSFlatString *str = Int32ToString<NoGC>(slice, i);
     if (!str)
         return TP_RETRY_SEQUENTIALLY;
     out.set(str);
     return TP_SUCCESS;
 }
 
 ParallelResult
-ion::DoubleToStringPar(ForkJoinSlice *slice, double d, MutableHandleString out)
+jit::DoubleToStringPar(ForkJoinSlice *slice, double d, MutableHandleString out)
 {
     JSString *str = js_NumberToString<NoGC>(slice, d);
     if (!str)
         return TP_RETRY_SEQUENTIALLY;
     out.set(str);
     return TP_SUCCESS;
 }
 
 ParallelResult
-ion::StringToNumberPar(ForkJoinSlice *slice, JSString *str, double *out)
+jit::StringToNumberPar(ForkJoinSlice *slice, JSString *str, double *out)
 {
     return StringToNumber(slice, str, out) ? TP_SUCCESS : TP_FATAL;
 }
 
 #define PAR_RELATIONAL_OP(OP, EXPECTED)                                         \
 do {                                                                            \
     /* Optimize for two int-tagged operands (typical loop control). */          \
     if (lhs.isInt32() && rhs.isInt32()) {                                       \
@@ -283,23 +283,23 @@ CompareMaybeStringsPar(ForkJoinSlice *sl
 template<bool Equal>
 ParallelResult
 LooselyEqualImplPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     PAR_RELATIONAL_OP(==, Equal);
 }
 
 ParallelResult
-js::ion::LooselyEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::LooselyEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     return LooselyEqualImplPar<true>(slice, lhs, rhs, res);
 }
 
 ParallelResult
-js::ion::LooselyUnequalPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::LooselyUnequalPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     return LooselyEqualImplPar<false>(slice, lhs, rhs, res);
 }
 
 template<bool Equal>
 ParallelResult
 StrictlyEqualImplPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
@@ -333,47 +333,47 @@ StrictlyEqualImplPar(ForkJoinSlice *slic
             return LooselyEqualImplPar<Equal>(slice, lhs, rhs, res);
     }
 
     *res = false;
     return TP_SUCCESS;
 }
 
 ParallelResult
-js::ion::StrictlyEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::StrictlyEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     return StrictlyEqualImplPar<true>(slice, lhs, rhs, res);
 }
 
 ParallelResult
-js::ion::StrictlyUnequalPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::StrictlyUnequalPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     return StrictlyEqualImplPar<false>(slice, lhs, rhs, res);
 }
 
 ParallelResult
-js::ion::LessThanPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::LessThanPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     PAR_RELATIONAL_OP(<, true);
 }
 
 ParallelResult
-js::ion::LessThanOrEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::LessThanOrEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     PAR_RELATIONAL_OP(<=, true);
 }
 
 ParallelResult
-js::ion::GreaterThanPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::GreaterThanPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     PAR_RELATIONAL_OP(>, true);
 }
 
 ParallelResult
-js::ion::GreaterThanOrEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
+js::jit::GreaterThanOrEqualPar(ForkJoinSlice *slice, MutableHandleValue lhs, MutableHandleValue rhs, bool *res)
 {
     PAR_RELATIONAL_OP(>=, true);
 }
 
 template<bool Equal>
 ParallelResult
 StringsEqualImplPar(ForkJoinSlice *slice, HandleString lhs, HandleString rhs, bool *res)
 {
@@ -381,29 +381,29 @@ StringsEqualImplPar(ForkJoinSlice *slice
     ParallelResult ret = CompareStringsPar(slice, lhs, rhs, &vsZero);
     if (ret != TP_SUCCESS)
         return ret;
     *res = (vsZero == 0) == Equal;
     return TP_SUCCESS;
 }
 
 ParallelResult
-js::ion::StringsEqualPar(ForkJoinSlice *slice, HandleString v1, HandleString v2, bool *res)
+js::jit::StringsEqualPar(ForkJoinSlice *slice, HandleString v1, HandleString v2, bool *res)
 {
     return StringsEqualImplPar<true>(slice, v1, v2, res);
 }
 
 ParallelResult
-js::ion::StringsUnequalPar(ForkJoinSlice *slice, HandleString v1, HandleS