Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 15 May 2013 21:14:58 -0400
changeset 132002 19cc1efe80976702ee0815cc325962a4fa164956
parent 131906 2e416d6f022d83522a0dea0a47e8fb938a7a0256 (current diff)
parent 132001 7bd6c6f5e55444d69e1cf11eb54c61301108eef2 (diff)
child 132008 cc139752bed4ee2ac2cf8c05ec93e7ddad9d16d9
child 132039 8aee4c03f01384147dfd45ef929776a0c3c2607b
push id24678
push userryanvm@gmail.com
push dateThu, 16 May 2013 01:15:09 +0000
treeherdermozilla-central@19cc1efe8097 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
gfx/2d/ScaledFontFreetype.cpp
gfx/2d/ScaledFontFreetype.h
js/src/methodjit/BaseAssembler.h
js/src/methodjit/BaseCompiler.h
js/src/methodjit/CodeGenIncludes.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastArithmetic.cpp
js/src/methodjit/FastBuiltins.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/FrameEntry.h
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.cpp
js/src/methodjit/FrameState.h
js/src/methodjit/ICChecker.h
js/src/methodjit/ICLabels.h
js/src/methodjit/ICRepatcher.h
js/src/methodjit/ImmutableSync.cpp
js/src/methodjit/ImmutableSync.h
js/src/methodjit/InlineFrameAssembler.h
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/Logging.cpp
js/src/methodjit/Logging.h
js/src/methodjit/LoopState.cpp
js/src/methodjit/LoopState.h
js/src/methodjit/MachineRegs.h
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/MonoIC.h
js/src/methodjit/NunboxAssembler.h
js/src/methodjit/PolyIC.cpp
js/src/methodjit/PolyIC.h
js/src/methodjit/PunboxAssembler.h
js/src/methodjit/RematInfo.h
js/src/methodjit/Retcon.cpp
js/src/methodjit/Retcon.h
js/src/methodjit/StubCalls-inl.h
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
js/src/methodjit/StubCompiler.cpp
js/src/methodjit/StubCompiler.h
js/src/methodjit/TrampolineCompiler.cpp
js/src/methodjit/TrampolineCompiler.h
js/src/methodjit/TrampolineMIPS.cpp
js/src/methodjit/TrampolineMasmX64.asm
js/src/methodjit/TrampolineMingwX64.s
js/src/methodjit/TrampolineSUNWX64.s
js/src/methodjit/TrampolineSUNWX86.s
js/src/methodjit/TrampolineSparc.s
js/src/methodjit/TypedArrayIC.h
toolkit/content/DeferredTask.jsm
toolkit/content/Deprecated.jsm
toolkit/content/Dict.jsm
toolkit/content/Geometry.jsm
toolkit/content/InlineSpellChecker.jsm
toolkit/content/LightweightThemeConsumer.jsm
toolkit/content/PageMenu.jsm
toolkit/content/PopupNotifications.jsm
toolkit/content/PrivateBrowsingUtils.jsm
toolkit/content/PropertyListUtils.jsm
toolkit/content/Services.jsm
toolkit/content/Task.jsm
toolkit/content/Troubleshoot.jsm
toolkit/content/UpdateChannel.jsm
toolkit/content/WindowDraggingUtils.jsm
toolkit/content/debug.js
toolkit/content/tests/browser/browser_DeferredTask.js
toolkit/content/tests/browser/browser_Deprecated.js
toolkit/content/tests/browser/browser_Geometry.js
toolkit/content/tests/browser/browser_InlineSpellChecker.js
toolkit/content/tests/browser/browser_Services.js
toolkit/content/tests/browser/browser_Troubleshoot.js
toolkit/content/tests/unit/propertyLists/bug710259_propertyListBinary.plist
toolkit/content/tests/unit/propertyLists/bug710259_propertyListXML.plist
toolkit/content/tests/unit/test_dict.js
toolkit/content/tests/unit/test_propertyListsUtils.js
toolkit/content/tests/unit/test_task.js
toolkit/mozapps/shared/CertUtils.jsm
toolkit/mozapps/shared/FileUtils.jsm
toolkit/mozapps/shared/Makefile.in
toolkit/mozapps/shared/moz.build
toolkit/mozapps/shared/test/chrome/Makefile.in
toolkit/mozapps/shared/test/chrome/moz.build
toolkit/mozapps/shared/test/chrome/test_bug544442_checkCert.xul
toolkit/mozapps/shared/test/unit/test_FileUtils.js
toolkit/mozapps/shared/test/unit/test_readCertPrefs.js
toolkit/mozapps/shared/test/unit/xpcshell.ini
--- a/CLOBBER
+++ b/CLOBBER
@@ -12,10 +12,9 @@
 #          O               O
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
-Bug 866093 - Change in .gyp file for Android builds.
-Bug 861039 - Nuking and rebuilding gfx/angle without clobber caused: "No rule to make target `../../../../gfx/angle/src/compiler/ArrayBoundsClamper.cpp', needed by `ArrayBoundsClamper.o'. Stop."
+Bug 852687 - changing an idl without clobbering resulted test failures
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1103,23 +1103,57 @@ NS_IMETHODIMP
 HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
                                         AccessibleTextBoundary aBoundaryType,
                                         int32_t* aStartOffset,
                                         int32_t* aEndOffset, nsAString& aText)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
-    return NS_OK;
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
+
+  switch (aBoundaryType) {
+    case BOUNDARY_CHAR:
+      GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
+      return NS_OK;
+
+    case BOUNDARY_WORD_START:
+      // Move word forward twice to find start and end offsets.
+      *aStartOffset = FindWordBoundary(offset, eDirNext, eStartWord);
+      *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord);
+      return GetText(*aStartOffset, *aEndOffset, aText);
+
+    case BOUNDARY_WORD_END:
+      // If the offset is a word end (except 0 offset) then move forward to find
+      // end offset (start offset is the given offset). Otherwise move forward
+      // twice to find both start and end offsets.
+      if (offset == 0) {
+        *aStartOffset = FindWordBoundary(offset, eDirNext, eEndWord);
+        *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
+      } else {
+        *aEndOffset = FindWordBoundary(offset, eDirNext, eEndWord);
+        *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
+        if (*aStartOffset != offset) {
+          *aStartOffset = *aEndOffset;
+          *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
+        }
+      }
+      return GetText(*aStartOffset, *aEndOffset, aText);
+
+    case BOUNDARY_LINE_START:
+    case BOUNDARY_LINE_END:
+    case BOUNDARY_ATTRIBUTE_RANGE:
+      return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
+                           aStartOffset, aEndOffset, aText);
+
+    default:
+      return NS_ERROR_INVALID_ARG;
   }
-
-  return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
-                       aStartOffset, aEndOffset, aText);
 }
 
 // nsIPersistentProperties
 // nsIAccessibleText::getTextAttributes(in boolean includeDefAttrs,
 //                                      in long offset,
 //                                      out long rangeStartOffset,
 //                                      out long rangeEndOffset);
 NS_IMETHODIMP
--- a/accessible/tests/mochitest/text/test_multiline.html
+++ b/accessible/tests/mochitest/text/test_multiline.html
@@ -53,60 +53,30 @@
       testTextAfterOffset(8, BOUNDARY_CHAR, "t", 9, 10,
                           "div", kOk, kOk, kOk,
                           "divbr", kOk, kOk, kOk,
                           "editable", kOk, kOk, kOk,
                           "editablebr", kOk, kOk, kOk,
                           "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_WORD_START
-      testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+      testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
       testTextAfterOffset(8, BOUNDARY_WORD_START, "two ", 9, 13,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(9, BOUNDARY_WORD_START, "words\n", 13, 19,
-                          "div", kTodo, kTodo, kTodo,
+                          "div", kOk, kOk, kOk,
                           "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
+                          "editable", kOk, kOk, kOk,
                           "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "textarea", kOk, kOk, kOk);
+      testTextAfterOffset(9, BOUNDARY_WORD_START, "words\n", 13, 19, IDs);
 
       // BOUNDARY_WORD_END
-      testTextAfterOffset(0, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(6, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(7, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                          "div", kOk, kOk, kOk,
-                          "divbr", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "editablebr", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(8, BOUNDARY_WORD_END, " words", 12, 18,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+      testTextAfterOffset(0, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
+      testTextAfterOffset(6, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
+      testTextAfterOffset(7, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
+      testTextAfterOffset(8, BOUNDARY_WORD_END, " words", 12, 18, IDs);
 
       // BOUNDARY_LINE_START
       testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
--- a/accessible/tests/mochitest/text/test_singleline.html
+++ b/accessible/tests/mochitest/text/test_singleline.html
@@ -7,19 +7,19 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 20);
+      SimpleTest.expectAssertions(0, 14);
     } else {
-      SimpleTest.expectAssertions(20);
+      SimpleTest.expectAssertions(14);
     }
 
     function doTest()
     {
       // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 
       ////////////////////////////////////////////////////////////////////////
@@ -54,118 +54,38 @@
       // get an offset for?
       testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
 			  "input", kOk, kTodo, kTodo,
 			  "div", kOk, kTodo, kTodo,
 			  "editable", kOk, kTodo, kTodo);
       testCharAfterOffset("textarea", 15, "", 16, 16);
 
       // BOUNDARY_WORD_START
-      testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(5, BOUNDARY_WORD_START, "my ", 6, 9,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(6, BOUNDARY_WORD_START, "friend", 9, 15,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(7, BOUNDARY_WORD_START, "friend", 9, 15,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(8, BOUNDARY_WORD_START, "friend", 9, 15,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(9, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(11, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kOk, kOk, kOk,
-                          "div", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "textarea", kTodo, kOk, kTodo);
+      testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAfterOffset(5, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAfterOffset(6, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAfterOffset(7, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAfterOffset(8, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAfterOffset(9, BOUNDARY_WORD_START, "", 15, 15, IDs);
+      testTextAfterOffset(11, BOUNDARY_WORD_START, "", 15, 15, IDs);
+      testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15, IDs);
+      testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15, IDs);
 
       // BOUNDARY_WORD_END
-      testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(5, BOUNDARY_WORD_END, " my", 5, 8,
-                          "input", kOk, kOk, kOk,
-                          "div", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(6, BOUNDARY_WORD_END, " friend", 8, 15,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(7, BOUNDARY_WORD_END, " friend", 8, 15,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(8, BOUNDARY_WORD_END, " friend", 8, 15,
-                          "input", kOk, kOk, kOk,
-                          "div", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(9, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(11, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kOk, kOk, kOk,
-                          "div", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "textarea", kTodo, kOk, kTodo);
+      testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAfterOffset(5, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAfterOffset(6, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAfterOffset(7, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAfterOffset(8, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAfterOffset(9, BOUNDARY_WORD_END, "", 15, 15, IDs);
+      testTextAfterOffset(11, BOUNDARY_WORD_END, "", 15, 15, IDs);
+      testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15, IDs);
+      testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15, IDs);
 
       // BOUNDARY_LINE_START
       testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(1, BOUNDARY_LINE_START, "", 15, 15,
--- a/accessible/tests/mochitest/text/test_whitespaces.html
+++ b/accessible/tests/mochitest/text/test_whitespaces.html
@@ -8,22 +8,16 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
 
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
-    if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 3);
-    } else {
-      SimpleTest.expectAssertions(3);
-    }
-
     function doTest()
     {
       // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
 
       ////////////////////////////////////////////////////////////////////////
       // characterCount
 
@@ -55,138 +49,78 @@
       testCharAfterOffset(IDs, 9, " ", 10, 11);
       testCharAfterOffset(IDs, 10, "R", 11, 12);
       testCharAfterOffset(IDs, 15, " ", 16, 17);
       testCharAfterOffset(IDs, 16, " ", 17, 18);
       testCharAfterOffset(IDs, 17, " ", 18, 19);
       testCharAfterOffset(IDs, 18, "r", 19, 20);
 
       // BOUNDARY_WORD_START
-      testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+      testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
+      testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
+      testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
       testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kTodo);
-
-      // BOUNDARY_WORD_END
-      testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(4, BOUNDARY_WORD_END, " Sir", 5, 9,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9,
                           "input", kOk, kOk, kOk,
                           "div", kOk, kOk, kOk,
                           "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(6, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(8, BOUNDARY_WORD_END, "   Robin", 9, 16,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(9, BOUNDARY_WORD_END, "  Robin", 9, 16,
+                          "textarea", kOk, kTodo, kTodo);
+
+      // BOUNDARY_WORD_END
+      testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAfterOffset(4, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAfterOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAfterOffset(6, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAfterOffset(8, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAfterOffset(9, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAfterOffset(10, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAfterOffset(11, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAfterOffset(15, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAfterOffset(16, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
                           "input", kOk, kOk, kOk,
                           "div", kOk, kOk, kOk,
                           "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(10, BOUNDARY_WORD_END, "   ran", 16, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(11, BOUNDARY_WORD_END, "   ran", 16, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(15, BOUNDARY_WORD_END, "   ran", 16, 22,
-                          "input", kTodo, kTodo, kTodo,
-                          "div", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(16, BOUNDARY_WORD_END, "   ran", 16, 22,
+                          "textarea", kTodo, kOk, kTodo);
+      testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
                           "input", kOk, kOk, kOk,
                           "div", kOk, kOk, kOk,
                           "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
       testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
                           "input", kOk, kOk, kOk,
                           "div", kOk, kOk, kOk,
                           "editable", kOk, kOk, kOk,
-                          "textarea", kTodo, kOk, kTodo);
+                          "textarea", kOk, kTodo, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_CHAR
       testCharBeforeOffset(IDs, 0, "", 0, 0);
--- a/browser/devtools/netmonitor/test/browser_net_autoscroll.js
+++ b/browser/devtools/netmonitor/test/browser_net_autoscroll.js
@@ -15,17 +15,16 @@ function test() {
     let topNode = win.document.getElementById("requests-menu-contents");
     requestsContainer = topNode.getElementsByTagName("scrollbox")[0];
     ok(!!requestsContainer, "Container element exists as expected.");
   })
 
   // (1) Check that the scroll position is maintained at the bottom
   // when the requests overflow the vertical size of the container.
   .then(() => {
-    debuggee.performRequests();
     return waitForRequestsToOverflowContainer(monitor, requestsContainer);
   }).then(() => {
     ok(scrolledToBottom(requestsContainer), "Scrolled to bottom on overflow.");
   })
 
   // (2) Now set the scroll position somewhere in the middle and check
   // that additional requests do not change the scroll position.
   .then(() => {
--- a/browser/devtools/netmonitor/test/browser_net_sort-02.js
+++ b/browser/devtools/netmonitor/test/browser_net_sort-02.js
@@ -4,16 +4,20 @@
 /**
  * Test if sorting columns in the network table works correctly.
  */
 
 function test() {
   initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
     info("Starting test... ");
 
+    // It seems that this test may be slow on debug builds. This could be because
+    // of the heavy dom manipulation associated with sorting.
+    requestLongerTimeout(2);
+
     let { $, L10N, NetMonitorView } = aMonitor.panelWin;
     let { RequestsMenu } = NetMonitorView;
 
     RequestsMenu.lazyUpdate = false;
 
     waitForNetworkEvents(aMonitor, 5).then(() => {
       EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
 
@@ -167,52 +171,57 @@ function test() {
         "The requests menu items aren't ordered correctly. Third item is misplaced.");
       is(RequestsMenu.getItemAtIndex(3), RequestsMenu.allItems[3],
         "The requests menu items aren't ordered correctly. Fourth item is misplaced.");
       is(RequestsMenu.getItemAtIndex(4), RequestsMenu.allItems[4],
         "The requests menu items aren't ordered correctly. Fifth item is misplaced.");
 
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a),
         "GET1", SORTING_SJS + "?index=1", {
+          fuzzyUrl: true,
           status: 101,
           statusText: "Meh",
           type: "1",
           fullMimeType: "text/1",
           size: L10N.getFormatStr("networkMenu.sizeKB", 0),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b),
         "GET2", SORTING_SJS + "?index=2", {
+          fuzzyUrl: true,
           status: 200,
           statusText: "Meh",
           type: "2",
           fullMimeType: "text/2",
           size: L10N.getFormatStr("networkMenu.sizeKB", 0.01),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c),
         "GET3", SORTING_SJS + "?index=3", {
+          fuzzyUrl: true,
           status: 300,
           statusText: "Meh",
           type: "3",
           fullMimeType: "text/3",
           size: L10N.getFormatStr("networkMenu.sizeKB", 0.02),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d),
         "GET4", SORTING_SJS + "?index=4", {
+          fuzzyUrl: true,
           status: 400,
           statusText: "Meh",
           type: "4",
           fullMimeType: "text/4",
           size: L10N.getFormatStr("networkMenu.sizeKB", 0.03),
           time: true
         });
       verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e),
         "GET5", SORTING_SJS + "?index=5", {
+          fuzzyUrl: true,
           status: 500,
           statusText: "Meh",
           type: "5",
           fullMimeType: "text/5",
           size: L10N.getFormatStr("networkMenu.sizeKB", 0.04),
           time: true
         });
 
--- a/browser/devtools/netmonitor/test/browser_net_sort-03.js
+++ b/browser/devtools/netmonitor/test/browser_net_sort-03.js
@@ -4,16 +4,20 @@
 /**
  * Test if sorting columns in the network table works correctly with new requests.
  */
 
 function test() {
   initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
     info("Starting test... ");
 
+    // It seems that this test may be slow on debug builds. This could be because
+    // of the heavy dom manipulation associated with sorting.
+    requestLongerTimeout(2);
+
     let { $, L10N, NetMonitorView } = aMonitor.panelWin;
     let { RequestsMenu } = NetMonitorView;
 
     RequestsMenu.lazyUpdate = false;
 
     waitForNetworkEvents(aMonitor, 5).then(() => {
       EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
 
@@ -104,60 +108,65 @@ function test() {
       for (let i = 0; i < aOrder.length; i++) {
         is(RequestsMenu.getItemAtIndex(i), RequestsMenu.allItems[i],
           "The requests menu items aren't ordered correctly. Misplaced item " + i + ".");
       }
 
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
           "GET1", SORTING_SJS + "?index=1", {
+            fuzzyUrl: true,
             status: 101,
             statusText: "Meh",
             type: "1",
             fullMimeType: "text/1",
             size: L10N.getFormatStr("networkMenu.sizeKB", 0),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
           "GET2", SORTING_SJS + "?index=2", {
+            fuzzyUrl: true,
             status: 200,
             statusText: "Meh",
             type: "2",
             fullMimeType: "text/2",
             size: L10N.getFormatStr("networkMenu.sizeKB", 0.01),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
           "GET3", SORTING_SJS + "?index=3", {
+            fuzzyUrl: true,
             status: 300,
             statusText: "Meh",
             type: "3",
             fullMimeType: "text/3",
             size: L10N.getFormatStr("networkMenu.sizeKB", 0.02),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
           "GET4", SORTING_SJS + "?index=4", {
+            fuzzyUrl: true,
             status: 400,
             statusText: "Meh",
             type: "4",
             fullMimeType: "text/4",
             size: L10N.getFormatStr("networkMenu.sizeKB", 0.03),
             time: true
           });
       }
       for (let i = 0, len = aOrder.length / 5; i < len; i++) {
         verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
           "GET5", SORTING_SJS + "?index=5", {
+            fuzzyUrl: true,
             status: 500,
             statusText: "Meh",
             type: "5",
             fullMimeType: "text/5",
             size: L10N.getFormatStr("networkMenu.sizeKB", 0.04),
             time: true
           });
       }
--- a/browser/devtools/netmonitor/test/head.js
+++ b/browser/devtools/netmonitor/test/head.js
@@ -180,37 +180,46 @@ function waitForNetworkEvents(aMonitor, 
 
   return deferred.promise;
 }
 
 function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
   info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource());
   info("> Request: " + aRequestItem.attachment.toSource());
 
-  let { status, statusText, type, fullMimeType, size, time } = aData;
+  let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
   let { attachment, target } = aRequestItem
 
   let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
   let name = uri.fileName || "/";
   let query = uri.query;
   let hostPort = uri.hostPort;
 
-  is(attachment.method, aMethod,
-    "The attached method is incorrect.");
-
-  is(attachment.url, aUrl,
-    "The attached url is incorrect.");
+  if (fuzzyUrl) {
+    ok(attachment.method.startsWith(aMethod), "The attached method is incorrect.");
+    ok(attachment.url.startsWith(aUrl), "The attached url is incorrect.");
+  } else {
+    is(attachment.method, aMethod, "The attached method is incorrect.");
+    is(attachment.url, aUrl, "The attached url is incorrect.");
+  }
 
   is(target.querySelector(".requests-menu-method").getAttribute("value"),
     aMethod, "The displayed method is incorrect.");
 
-  is(target.querySelector(".requests-menu-file").getAttribute("value"),
-    name + (query ? "?" + query : ""), "The displayed file is incorrect.");
-  is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"),
-    name + (query ? "?" + query : ""), "The tooltip file is incorrect.");
+  if (fuzzyUrl) {
+    ok(target.querySelector(".requests-menu-file").getAttribute("value").startsWith(
+      name + (query ? "?" + query : "")), "The displayed file is incorrect.");
+    ok(target.querySelector(".requests-menu-file").getAttribute("tooltiptext").startsWith(
+      name + (query ? "?" + query : "")), "The tooltip file is incorrect.");
+  } else {
+    is(target.querySelector(".requests-menu-file").getAttribute("value"),
+      name + (query ? "?" + query : ""), "The displayed file is incorrect.");
+    is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"),
+      name + (query ? "?" + query : ""), "The tooltip file is incorrect.");
+  }
 
   is(target.querySelector(".requests-menu-domain").getAttribute("value"),
     hostPort, "The displayed domain is incorrect.");
   is(target.querySelector(".requests-menu-domain").getAttribute("tooltiptext"),
     hostPort, "The tooltip domain is incorrect.");
 
   if (status !== undefined) {
     let value = target.querySelector(".requests-menu-status").getAttribute("code");
--- a/browser/devtools/netmonitor/test/html_infinite-get-page.html
+++ b/browser/devtools/netmonitor/test/html_infinite-get-page.html
@@ -20,17 +20,17 @@
           }
         };
         xhr.send(null);
       }
 
       // Use a count parameter to defeat caching.
       var count = 0;
 
-      function performRequests() {
+      (function performRequests() {
         get("request_" + (count++), function() {
           setTimeout(performRequests, 0);
         });
-      }
+      })();
     </script>
   </body>
 
 </html>
--- a/browser/devtools/netmonitor/test/html_sorting-test-page.html
+++ b/browser/devtools/netmonitor/test/html_sorting-test-page.html
@@ -7,17 +7,18 @@
   </head>
 
   <body>
     <p>Sorting test</p>
 
     <script type="text/javascript">
       function get(aAddress, aIndex, aCallback) {
         var xhr = new XMLHttpRequest();
-        xhr.open("GET" + aIndex, aAddress + "?index=" + aIndex, true);
+        // Use a random parameter to defeat caching.
+        xhr.open("GET" + aIndex, aAddress + "?index=" + aIndex + "&" + Math.random(), true);
 
         xhr.onreadystatechange = function() {
           if (this.readyState == this.DONE) {
             aCallback();
           }
         };
         xhr.send(null);
       }
--- a/browser/devtools/netmonitor/test/sjs_sorting-test-server.sjs
+++ b/browser/devtools/netmonitor/test/sjs_sorting-test-server.sjs
@@ -9,10 +9,10 @@ function handleRequest(request, response
   let params = request.queryString.split("&");
   let index = params.filter((s) => s.contains("index="))[0].split("=")[1];
 
   Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer).initWithCallback(() => {
     response.setStatusLine(request.httpVersion, index == 1 ? 101 : index * 100, "Meh");
     response.setHeader("Content-Type", "text/" + index, false);
     response.write(new Array(index * 10).join(index)); // + 0.01 KB
     response.finish();
-  }, 50, Ci.nsITimer.TYPE_ONE_SHOT); // Make sure this request takes a few ms.
+  }, 10, Ci.nsITimer.TYPE_ONE_SHOT); // Make sure this request takes a few ms.
 }
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -568,36 +568,36 @@
           <!-- for text inputs, this will cut selected text -->
           <richlistitem id="context-cut" type="cut" onclick="ContextCommands.cut();">
             <label value="&contextTextCut.label;"/>
           </richlistitem>
           <!-- for text inputs, this will copy selected text -->
           <richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();">
             <label value="&contextTextCopy.label;"/>
           </richlistitem>
-          <!-- only displayed if there is text on the clipboard -->
-          <richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
-            <label value="&contextTextPaste.label;"/>
-          </richlistitem>
           <!-- Search Bing for "(text..)", displayed on selected content text only -->
           <richlistitem id="context-search" type="selected-text,!input-text" onclick="ContextCommands.searchText(this);">
             <label id="context-search-label" value=""/>
           </richlistitem>
-          <!-- only display if there is text on the clipboard and the target is the urlbar -->
-          <richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
-            <label value="&contextTextPasteAndGo.label;"/>
-          </richlistitem>
           <!-- only displayed in inputs with text that do not have selection -->
           <richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();">
             <label value="&contextTextSelect.label;"/>
           </richlistitem>
           <!-- only displayed in inputs with text that do not have selection -->
           <richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();">
             <label value="&contextTextSelectAll.label;"/>
           </richlistitem>
+          <!-- only displayed if there is text on the clipboard -->
+          <richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
+            <label value="&contextTextPaste.label;"/>
+          </richlistitem>
+          <!-- only display if there is text on the clipboard and the target is the urlbar -->
+          <richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
+            <label value="&contextTextPasteAndGo.label;"/>
+          </richlistitem>
 
           <!-- Image related -->
           <!-- save image to user pictures library -->
           <richlistitem id="context-save-image-lib" type="image" onclick="ContextCommands.saveImageToLib();">
             <label value="&contextSaveImageLib.label;"/>
           </richlistitem>
           <!-- copy image data to clipboard -->
           <richlistitem id="context-copy-image" type="image" onclick="ContextCommands.copyImage();">
--- a/browser/metro/base/content/history.js
+++ b/browser/metro/base/content/history.js
@@ -41,17 +41,17 @@ HistoryView.prototype = {
     let result = this._navHistoryService.executeQuery(query, options);
     let rootNode = result.root;
     rootNode.containerOpen = true;
     let childCount = rootNode.childCount;
 
     for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) {
       let node = rootNode.getChild(i);
       let uri = node.uri;
-      let title = node.title || uri;
+      let title = (node.title && node.title.length) ? node.title : uri;
 
       // If item is marked for deletion, skip it.
       if (this._toRemove && this._toRemove.indexOf(uri) !== -1)
         continue;
 
       let items = this._set.getItemsByUrl(uri);
 
       // Item has been unpinned, skip if filterUnpinned set.
--- a/browser/metro/theme/flyoutpanel.css
+++ b/browser/metro/theme/flyoutpanel.css
@@ -2,20 +2,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/. */
 
 %filter substitution
 %include defines.inc
 
 flyoutpanel {
   height: 100%;
-  border-width: 2px;
-  border-color: #d7d6d6;
   background-color: #ffffff;
-  -moz-border-start-style: solid;
   visibility: collapse;
   position: fixed;
   transition: transform @metro_animation_duration@ @metro_animation_easing@;
   transform: translateX(100%);
   font-size: 11pt;
   right: 0;
 }
 
@@ -36,16 +33,19 @@ flyoutpanel[visible] {
 /* XUL flexbox layout doesn't work in a position:fixed container, so we have
  * this normally-positioned inside for layout purposes. */
 .flyoutpanel-wrapper {
   height: 100%;
   width: 100%;
 }
 
 .flyoutpanel-header {
+  border-width: 1px;
+  -moz-border-start-style: solid;
+  border-color: #1b1b1b;
   background-color: #002147;
   height: 80px;
   width: 100%;
   color: #ffffff;
   font-weight: lighter;
   font-size: 20pt;
 }
 
@@ -55,16 +55,19 @@ flyoutpanel[visible] {
 }
 
 .flyout-header-label {
   margin-top: 30px !important;
   -moz-margin-start: 10px !important;
 }
 
 .flyoutpanel-contents {
+  border-width: 1px;
+  -moz-border-start-style: solid;
+  border-color: #c2c2c2;
   padding: 40px;
   width: 100%;
 }
 
 .flyout-close-button {
   border: 0 none;
   -moz-appearance: none;
   list-style-image: url(chrome://browser/skin/images/flyout-back-button.png);
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -694,31 +694,18 @@ arrowbox {
   list-style-image: url("chrome://browser/skin/images/arrowbox-horiz.png");
   margin-left: -@margin_normal@;
 }
 
 /*.meta -------------------------------------------------------------------- */
 
 .meta {
   background-color: @panel_light_color@;
-  background-image: radial-gradient(circle farthest-corner at left bottom,
-                                    rgba(255, 127, 0, 0.2) 0%,
-                                    rgba(255, 212, 0, 0) 30%),
-                    radial-gradient(circle farthest-corner at 40% 100%,
-                                    rgba(0, 120, 255, 0.15) 0%,
-                                    rgba(0, 186, 255, 0) 20%),
-                    radial-gradient(circle farthest-corner at 60% 100%,
-                                    rgba(0, 120, 255, 0.125) 0%,
-                                    rgba(0, 186, 255, 0) 20%),
-                    radial-gradient(circle farthest-corner at right bottom,
-                                    rgba(185, 17, 255, 0.1) 0%,
-                                    rgba(255, 84, 253, 0) 30%),
-                    url("chrome://browser/skin/images/firefox-watermark.png"),
-                    @panel_light_background@;
-  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat;
+  background-image: url("chrome://browser/skin/images/firefox-watermark.png");
+  background-repeat: no-repeat;
   background-position: center center;
   padding: @metro_spacing_normal@ @metro_spacing_xxnormal@;
   overflow: auto;
   max-width: 100%;
   width: 100%;
 }
 
 .meta-section {
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -84,17 +84,17 @@ class RemoteAutomation(Automation):
                       "allowed maximum time" % (self.lastTestSeen)
             proc.kill()
 
         return status
 
     def checkForJavaException(self, logcat):
         found_exception = False
         for i, line in enumerate(logcat):
-            if "REPORTING UNCAUGHT EXCEPTION" in line:
+            if "REPORTING UNCAUGHT EXCEPTION" in line or "FATAL EXCEPTION" in line:
                 # Strip away the date, time, logcat tag and pid from the next two lines and
                 # concatenate the remainder to form a concise summary of the exception. 
                 #
                 # For example:
                 #
                 # 01-30 20:15:41.937 E/GeckoAppShell( 1703): >>> REPORTING UNCAUGHT EXCEPTION FROM THREAD 9 ("GeckoBackgroundThread")
                 # 01-30 20:15:41.937 E/GeckoAppShell( 1703): java.lang.NullPointerException
                 # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at org.mozilla.gecko.GeckoApp$21.run(GeckoApp.java:1833)
--- a/configure.in
+++ b/configure.in
@@ -481,34 +481,17 @@ case "$target" in
 
         CXX_VERSION=`"${CXX}" -v 2>&1 | sed -nre "$_MSVC_VER_FILTER"`
         _CXX_MAJOR_VERSION=`echo ${CXX_VERSION} | $AWK -F\. '{ print $1 }'`
 
         if test "$_CC_MAJOR_VERSION" != "$_CXX_MAJOR_VERSION"; then
             AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
         fi
 
-        if test "$_CC_MAJOR_VERSION" = "14"; then
-            dnl Require VC8SP1 or newer.
-            dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762.
-            if test "$_CC_RELEASE" -lt 50727 -o \
-                    \( "$_CC_RELEASE" -eq 50727 -a "$_CC_BUILD" -lt 762 \); then
-              AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. You probably need to install Service Pack 1 of Visual Studio 2005. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
-            fi
-
-            _CC_SUITE=8
-            _MSVS_VERSION=2005
-            AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
-            AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
-        elif test "$_CC_MAJOR_VERSION" = "15"; then
-            _CC_SUITE=9
-            _MSVS_VERSION=2008
-            AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
-            AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
-        elif test "$_CC_MAJOR_VERSION" = "16"; then
+        if test "$_CC_MAJOR_VERSION" = "16"; then
             _CC_SUITE=10
             _MSVS_VERSION=2010
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
             AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
         elif test "$_CC_MAJOR_VERSION" = "17"; then
             _CC_SUITE=11
             _MSVS_VERSION=2012
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1435,17 +1435,18 @@ nsContentSink::EndUpdate(nsIDocument *aD
     UpdateChildCounts();
   }
 }
 
 void
 nsContentSink::DidBuildModelImpl(bool aTerminated)
 {
   if (mDocument) {
-    MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
+    MOZ_ASSERT(aTerminated ||
+               mDocument->GetReadyStateEnum() ==
                nsIDocument::READYSTATE_LOADING, "Bad readyState");
     mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
   }
 
   if (mScriptLoader) {
     mScriptLoader->ParsingComplete(aTerminated);
   }
 
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -88,19 +88,17 @@ NS_IMPL_EVENT_HANDLER(nsDOMFileReader, l
 NS_IMPL_EVENT_HANDLER(nsDOMFileReader, loadstart)
 NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, abort, FileIOObject)
 NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, progress, FileIOObject)
 NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
 
 void
 nsDOMFileReader::RootResultArrayBuffer()
 {
-  nsContentUtils::PreserveWrapper(
-    static_cast<EventTarget*>(
-      static_cast<nsDOMEventTargetHelper*>(this)), this);
+  NS_HOLD_JS_OBJECTS(this, nsDOMFileReader);
 }
 
 //nsDOMFileReader constructors/initializers
 
 nsDOMFileReader::nsDOMFileReader()
   : mFileData(nullptr),
     mDataLen(0), mDataFormat(FILE_AS_BINARY),
     mResultArrayBuffer(nullptr)
@@ -108,17 +106,18 @@ nsDOMFileReader::nsDOMFileReader()
   nsLayoutStatics::AddRef();
   SetDOMStringToNull(mResult);
   SetIsDOMBinding();
 }
 
 nsDOMFileReader::~nsDOMFileReader()
 {
   FreeFileData();
-
+  mResultArrayBuffer = nullptr;
+  NS_DROP_JS_OBJECTS(this, nsDOMFileReader);
   nsLayoutStatics::Release();
 }
 
 
 /**
  * This Init method is called from the factory constructor.
  */
 nsresult
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -319,25 +319,27 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
   if (mState & (XML_HTTP_REQUEST_SENT |
                 XML_HTTP_REQUEST_LOADING)) {
     Abort();
   }
 
   NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
   mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
 
+  mResultJSON = JSVAL_VOID;
+  mResultArrayBuffer = nullptr;
+  NS_DROP_JS_OBJECTS(this, nsXMLHttpRequest);
+
   nsLayoutStatics::Release();
 }
 
 void
 nsXMLHttpRequest::RootJSResultObjects()
 {
-  nsContentUtils::PreserveWrapper(
-    static_cast<EventTarget*>(
-      static_cast<nsDOMEventTargetHelper*>(this)), this);
+  NS_HOLD_JS_OBJECTS(this, nsXMLHttpRequest);
 }
 
 /**
  * This Init method is called from the factory constructor.
  */
 nsresult
 nsXMLHttpRequest::Init()
 {
@@ -2640,17 +2642,18 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
   mUploadTransferred = 0;
   mUploadTotal = 0;
   // By default we don't have any upload, so mark upload complete.
   mUploadComplete = true;
   mErrorLoad = false;
   mLoadLengthComputable = false;
   mLoadTotal = 0;
   if ((aVariant || !aBody.IsNull()) && httpChannel &&
-      !method.EqualsLiteral("GET")) {
+      !method.LowerCaseEqualsLiteral("get") &&
+      !method.LowerCaseEqualsLiteral("head")) {
 
     nsAutoCString charset;
     nsAutoCString defaultContentType;
     nsCOMPtr<nsIInputStream> postDataStream;
 
     rv = GetRequestBody(aVariant, aBody, getter_AddRefs(postDataStream),
                         &mUploadTotal, defaultContentType, charset);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/content/canvas/test/webgl/skipped_tests_winxp.txt
+++ b/content/canvas/test/webgl/skipped_tests_winxp.txt
@@ -1,1 +1,3 @@
+conformance/more/conformance/quickCheckAPI-B2.html
+conformance/more/conformance/quickCheckAPI-B3.html
 conformance/more/functions/bufferSubDataBadArgs.html
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -5023,18 +5023,16 @@ HTMLInputElement::GetStep() const
     return kStepAny;
   }
 
   Decimal step = StringToDecimal(stepStr);
   if (!step.isFinite() || step <= 0) {
     step = GetDefaultStep();
   }
 
-  // TODO: This multiplication can lead to inexact results, we should use a
-  // type that supports a better precision than double. Bug 783607.
   return step * GetStepScaleFactor();
 }
 
 // nsIConstraintValidation
 
 NS_IMETHODIMP
 HTMLInputElement::SetCustomValidity(const nsAString& aError)
 {
@@ -5215,25 +5213,16 @@ HTMLInputElement::HasStepMismatch() cons
     return false;
   }
 
   Decimal step = GetStep();
   if (step == kStepAny) {
     return false;
   }
 
-  if (mType == NS_FORM_INPUT_DATE) {
-    // The multiplication by the stepScaleFactor for date can easily lead
-    // to precision loss, since in most use cases this value should be
-    // an integer (millisecond precision), we can get rid of the precision
-    // loss by rounding step. This will however lead to erroneous results
-    // when step was intented to have a precision superior to a millisecond.
-    step = step.round();
-  }
-
   // Value has to be an integral multiple of step.
   return NS_floorModulo(value - GetStepBase(), step) != 0;
 }
 
 void
 HTMLInputElement::UpdateTooLongValidityState()
 {
   // TODO: this code will be re-enabled with bug 613016 and bug 613019.
--- a/content/html/content/test/forms/Makefile.in
+++ b/content/html/content/test/forms/Makefile.in
@@ -55,12 +55,13 @@ MOCHITEST_FILES = \
 		test_input_typing_sanitization.html \
 		test_input_sanitization.html \
 		test_valueasdate_attribute.html \
 		test_input_textarea_set_value_no_scroll.html \
 		test_submit_invalid_file.html \
 		submit_invalid_file.sjs \
 		test_input_file_picker.html \
 		test_input_event.html \
+		test_input_number_rounding.html \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
copy from content/html/content/test/forms/test_input_range_rounding.html
copy to content/html/content/test/forms/test_input_number_rounding.html
--- a/content/html/content/test/forms/test_input_range_rounding.html
+++ b/content/html/content/test/forms/test_input_number_rounding.html
@@ -1,32 +1,32 @@
 <!DOCTYPE HTML>
 <html>
 <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=853525
+https://bugzilla.mozilla.org/show_bug.cgi?id=783607
 -->
 <head>
-  <title>Test key events for range</title>
+  <title>Test rounding behaviour for &lt;input type='number'&gt;</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <meta charset="UTF-8">
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=853525">Mozilla Bug 853525</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783607">Mozilla Bug 783607</a>
 <p id="display"></p>
 <div id="content">
-  <input id=range type=range value=0 step=0.01 max=1>
+  <input id=number type=number value=0 step=0.01 max=1>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /**
- * Test for Bug 853525
- * This test checks that when <input type=range> has fractional step values,
+ * Test for Bug 783607.
+ * This test checks that when <input type=number> has fractional step values,
  * the values that a content author will see in their script will not have
  * ugly rounding errors.
  **/
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(function() {
   test();
   SimpleTest.finish();
 });
@@ -51,41 +51,54 @@ var stepVals = [
   "1"
 ];
 
 var pgUpDnVals = [
   "0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1"
 ];
 
 function test() {
-  var elem = document.getElementById("range");
+  var elem = document.getElementById("number");
 
   elem.focus();
 
+  /**
+   * TODO:
+   * When <input type='number'> widget will have a widge we should test PAGE_UP,
+   * PAGE_DOWN, UP and DOWN keys. For the moment, there is no widget so those
+   * keys do not have any effect.
+   * The tests using those keys as marked as todo_is() hoping that at least part
+   * of them will fail when the widget will be implemented.
+   */
+
   for (var i = 1; i < pgUpDnVals.length; ++i) {
     synthesizeKey("VK_PAGE_UP", {});
-    is(elem.value, pgUpDnVals[i], "Test VK_PAGE_UP");
+    todo_is(elem.value, pgUpDnVals[i], "Test VK_PAGE_UP");
     is(elem.validity.valid, true, "Check element is valid for value " + pgUpDnVals[i]);
   }
 
   for (var i = pgUpDnVals.length - 2; i >= 0; --i) {
     synthesizeKey("VK_PAGE_DOWN", {});
-    is(elem.value, pgUpDnVals[i], "Test VK_PAGE_DOWN");
+    // TODO: this condition is there because the todo_is() below would pass otherwise.
+    if (stepVals[i] == 0) { continue; }
+    todo_is(elem.value, pgUpDnVals[i], "Test VK_PAGE_DOWN");
     is(elem.validity.valid, true, "Check element is valid for value " + pgUpDnVals[i]);
   }
 
   for (var i = 1; i < stepVals.length; ++i) {
     synthesizeKey("VK_UP", {});
-    is(elem.value, stepVals[i], "Test VK_UP");
+    todo_is(elem.value, stepVals[i], "Test VK_UP");
     is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
   }
 
   for (var i = stepVals.length - 2; i >= 0; --i) {
     synthesizeKey("VK_DOWN", {});
-    is(elem.value, stepVals[i], "Test VK_DOWN");
+    // TODO: this condition is there because the todo_is() below would pass otherwise.
+    if (stepVals[i] == 0) { continue; }
+    todo_is(elem.value, stepVals[i], "Test VK_DOWN");
     is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
   }
 
   for (var i = 1; i < stepVals.length; ++i) {
     elem.stepUp();
     is(elem.value, stepVals[i], "Test stepUp()");
     is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
   }
--- a/content/html/content/test/forms/test_step_attribute.html
+++ b/content/html/content/test/forms/test_step_attribute.html
@@ -401,16 +401,23 @@ for (var test of data) {
       checkValidity(input, true, apply);
 
       input.value = 3;
       checkValidity(input, true, apply);
 
       input.value = 2;
       checkValidity(input, false, apply, {low: 1, high: 3});
 
+      // Rounding issues.
+      input = getFreshElement(test.type);
+      input.min = 0.1;
+      input.step = 0.2;
+      input.value = 0.3;
+      checkValidity(input, true, apply);
+
       // Check that when the higher value is higher than max, we don't show it.
       input = getFreshElement(test.type);
       input.step = '2';
       input.min = '1';
       input.max = '10.9';
       input.value = '10';
 
       is(input.validationMessage, "Please select a valid value. " +
--- a/content/media/webrtc/MediaEngineWebRTC.cpp
+++ b/content/media/webrtc/MediaEngineWebRTC.cpp
@@ -92,17 +92,20 @@ MediaEngineWebRTC::EnumerateVideoDevices
   jobject context = mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
 
   // get the JVM
   JavaVM *jvm = mozilla::AndroidBridge::Bridge()->GetVM();
 
   JNIEnv *env;
   jint res = jvm->AttachCurrentThread(&env, NULL);
 
-  webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context);
+  if (webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
+    LOG(("VieCapture:SetAndroidObjects Failed"));
+    return;
+  }
 
   env->DeleteGlobalRef(context);
 #endif
 
   if (!mVideoEngine) {
     if (!(mVideoEngine = webrtc::VideoEngine::Create())) {
       return;
     }
@@ -225,17 +228,20 @@ MediaEngineWebRTC::EnumerateAudioDevices
   jobject context = mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
 
   // get the JVM
   JavaVM *jvm = mozilla::AndroidBridge::Bridge()->GetVM();
 
   JNIEnv *env;
   jvm->AttachCurrentThread(&env, NULL);
 
-  webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
+  if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
+    LOG(("VoiceEngine:SetAndroidObjects Failed"));
+    return;
+  }
 
   env->DeleteGlobalRef(context);
 #endif
 
   if (!mVoiceEngine) {
     mVoiceEngine = webrtc::VoiceEngine::Create();
     if (!mVoiceEngine) {
       return;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4592,18 +4592,20 @@ nsDocShell::Stop(uint32_t aStopFlags)
         }
 
         mFailedChannel = nullptr;
         mFailedURI = nullptr;
     }
 
     if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
         // Stop the document loading
-        if (mContentViewer)
-            mContentViewer->Stop();
+        if (mContentViewer) {
+            nsCOMPtr<nsIContentViewer> cv = mContentViewer;
+            cv->Stop();
+        }
     }
 
     if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
         // Suspend any timers that were set for this loader.  We'll clear
         // them out for good in CreateContentViewer.
         if (mRefreshURIList) {
             SuspendRefreshURIs();
             mSavedRefreshURIList.swap(mRefreshURIList);
@@ -10520,16 +10522,17 @@ nsDocShell::AddToSessionHistory(nsIURI *
             int32_t childCount = 0;
             shContainer->GetChildCount(&childCount);
             // Remove all children of this entry 
             for (int32_t i = childCount - 1; i >= 0; i--) {
                 nsCOMPtr<nsISHEntry> child;
                 shContainer->GetChildAt(i, getter_AddRefs(child));
                 shContainer->RemoveChild(child);
             }  // for
+            entry->AbandonBFCacheEntry();
         }  // shContainer
     }
 
     // Create a new entry if necessary.
     if (!entry) {
         entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);
 
         if (!entry) {
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3083,16 +3083,18 @@ nsDOMWindowUtils::SelectAtPoint(float aX
       amount = eSelectEndLine;
     break;
     case nsIDOMWindowUtils::SELECT_PARAGRAPH:
       amount = eSelectParagraph;
     break;
     case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
       amount = eSelectWordNoSpace;
     break;
+    default:
+      return NS_ERROR_INVALID_ARG;
   }
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_UNEXPECTED;
   }
 
   // The root frame for this content window
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7420,19 +7420,20 @@ nsGlobalWindow::NotifyDOMWindowThawed(ns
                         DOM_WINDOW_THAWED_TOPIC, nullptr);
     }
   }
 }
 
 JSObject*
 nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
 {
-  JSObject* handler = nullptr;
+  AutoSafeJSContext cx;
+  JS::Rooted<JSObject*> handler(cx);
   if (mCachedXBLPrototypeHandlers.IsInitialized()) {
-    mCachedXBLPrototypeHandlers.Get(aKey, &handler);
+    mCachedXBLPrototypeHandlers.Get(aKey, handler.address());
   }
   return handler;
 }
 
 void
 nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                                          JS::Handle<JSObject*> aHandler)
 {
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -103,17 +103,17 @@ class CGNativePropertyHooks(CGThing):
             constructorID += "_ID_Count"
         prototypeID = "prototypes::id::"
         if self.descriptor.interface.hasInterfacePrototypeObject():
             prototypeID += self.descriptor.name
         else:
             prototypeID += "_ID_Count"
         parent = self.descriptor.interface.parent
         parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
-                       if parent else 'NULL')
+                       if parent else 'nullptr')
 
         return CGWrapper(CGIndenter(CGList([CGGeneric(resolveOwnProperty),
                                             CGGeneric(enumerateOwnProperties),
                                             CGWrapper(CGList([CGGeneric(regular),
                                                               CGGeneric(chrome)],
                                                              ", "),
                                                       pre="{ ", post=" }"),
                                             CGGeneric(prototypeID),
@@ -178,20 +178,20 @@ DOMJSClass Class = {
     %s, /* addProperty */
     JS_DeletePropertyStub, /* delProperty */
     JS_PropertyStub,       /* getProperty */
     JS_StrictPropertyStub, /* setProperty */
     JS_EnumerateStub,
     %s,
     JS_ConvertStub,
     %s, /* finalize */
-    NULL,                  /* checkAccess */
+    nullptr,               /* checkAccess */
     %s, /* call */
-    NULL,                  /* hasInstance */
-    NULL,                  /* construct */
+    nullptr,               /* hasInstance */
+    nullptr,               /* construct */
     %s, /* trace */
     JSCLASS_NO_INTERNAL_MEMBERS
   },
 %s
 };
 """ % (self.descriptor.interface.identifier.name,
        classFlags,
        ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'JS_PropertyStub',
@@ -1388,17 +1388,17 @@ class PropertyDefiner:
                 # Terminate previous list
                 specs.append(specTerminator)
                 # And switch to our new pref
                 switchToCondition(self, curCondition)
                 lastCondition = curCondition
             # And the actual spec
             specs.append(specTemplate % getDataTuple(member))
         specs.append(specTerminator)
-        prefableSpecs.append("  { false, NULL }");
+        prefableSpecs.append("  { false, nullptr }");
 
         specType = "const " + specType
         arrays = (("static %s %s_specs[] = {\n" +
                    ',\n'.join(specs) + "\n" +
                    "};\n\n" +
                    "// Can't be const because the pref-enabled boolean needs to be writable\n"
                    "static Prefable<%s> %s[] = {\n" +
                    ',\n'.join(prefableSpecs) + "\n" +
@@ -1842,17 +1842,17 @@ if (!unforgeableHolder) {
                 "                            %s);" % (
             protoClass, protoCache,
             interfaceClass, constructHookHolder, constructArgs,
             namedConstructors,
             interfaceCache,
             domClass,
             properties,
             chromeProperties,
-            '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL"))
+            '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr"))
         if UseHolderForUnforgeable(self.descriptor):
             assert needInterfacePrototypeObject
             setUnforgeableHolder = CGGeneric(
                 "JSObject* proto = protoAndIfaceArray[prototypes::id::%s];\n"
                 "if (proto) {\n"
                 "  js::SetReservedSlot(proto, DOM_INTERFACE_PROTO_SLOTS_BASE,\n"
                 "                      JS::ObjectValue(*unforgeableHolder));\n"
                 "}" % self.descriptor.name)
@@ -2004,29 +2004,29 @@ def CreateBindingJSObject(descriptor, pr
     if needRoot:
         objDecl = "  JS::Rooted<JSObject*> obj(aCx);\n"
     else:
         objDecl = "  JSObject *obj;\n"
     if descriptor.proxy:
         create = """  obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
                        JS::PrivateValue(aObject), proto, %s);
   if (!obj) {
-    return NULL;
+    return nullptr;
   }
 
 """
         if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
             create += """  js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
                     JS::PrivateValue(&aObject->mExpandoAndGeneration));
 
 """
     else:
         create = """  obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
   if (!obj) {
-    return NULL;
+    return nullptr;
   }
 
   js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
 """
     create = objDecl + create
 
     if descriptor.nativeOwnership in ['refcounted', 'nsisupports']:
         create += """  NS_ADDREF(aObject);
@@ -2143,34 +2143,34 @@ class CGWrapWithCacheMethod(CGAbstractMe
         else:
             assertISupportsInheritance = ""
         return """%s
 %s
   JS::Rooted<JSObject*> parent(aCx,
     GetRealParentObject(aObject,
                         WrapNativeParent(aCx, aScope, aObject->GetParentObject())));
   if (!parent) {
-    return NULL;
+    return nullptr;
   }
 
   // That might have ended up wrapping us already, due to the wonders
   // of XBL.  Check for that, and bail out as needed.  Scope so we don't
   // collide with the "obj" we declare in CreateBindingJSObject.
   {
     JSObject* obj = aCache->GetWrapper();
     if (obj) {
       return obj;
     }
   }
 
   JSAutoCompartment ac(aCx, parent);
   JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent));
   JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
   if (!proto) {
-    return NULL;
+    return nullptr;
   }
 
 %s
 %s
   aCache->SetWrapper(obj);
 
   return obj;""" % (AssertInheritanceChain(self.descriptor),
                     assertISupportsInheritance,
@@ -2208,17 +2208,17 @@ class CGWrapNonWrapperCacheMethod(CGAbst
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
         return """%s
   JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aScope));
   JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
   if (!proto) {
-    return NULL;
+    return nullptr;
   }
 
 %s
 %s
   return obj;""" % (AssertInheritanceChain(self.descriptor),
                     CreateBindingJSObject(self.descriptor, self.properties,
                                           "global"),
                     InitUnforgeableProperties(self.descriptor, self.properties))
@@ -3006,17 +3006,17 @@ for (uint32_t i = 0; i < length; ++i) {
                     "  // some random object that might get GCed\n"
                     "  ${holderName} = tmp;\n"
                     "}\n")
 
             # And store our tmp, before it goes out of scope.
             templateBody += "${declName} = tmp;"
 
         templateBody = wrapObjectTemplate(templateBody, type,
-                                          "${declName} = NULL",
+                                          "${declName} = nullptr",
                                           failureCode)
 
         declType = CGGeneric(declType)
         if holderType is not None:
             holderType = CGGeneric(holderType)
         return (templateBody, declType, holderType, isOptional)
 
     if type.isSpiderMonkeyInterface():
@@ -3061,17 +3061,17 @@ for (uint32_t i = 0; i < length; ++i) {
                 template += "${declName}.Construct();\n"
                 nullableTarget = "${declName}.Value()"
             else:
                 nullableTarget = "${declName}"
             template += "%s = ${holderName}.addr();" % nullableTarget
         elif not isOptional:
             template += "${declName} = ${holderName}.addr();"
         template = wrapObjectTemplate(template, type,
-                                      "%s = NULL" % nullableTarget,
+                                      "%s = nullptr" % nullableTarget,
                                       failureCode)
 
         if holderType is not None:
             holderType = CGGeneric(holderType)
         # We handle all the optional stuff ourselves; no need for caller to do it.
         return (template, CGGeneric(declType), holderType, False)
 
     if type.isString():
@@ -5398,17 +5398,17 @@ MOZ_END_ENUM_CLASS(%s)
 
 """ % (enumName, ",\n  ".join(map(getEnumValueName, self.enum.values())),
        enumName) + strings.declare()
 
     def define(self):
         strings = """
   const EnumEntry %s[%d] = {
     %s,
-    { NULL, 0 }
+    { nullptr, 0 }
   };
 """ % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings(),
        ",\n    ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
         return CGNamespace(self.stringsNamespace(), CGGeneric(define=strings)).define()
 
     def deps(self):
         return self.enum.getDeps()
 
@@ -6645,17 +6645,17 @@ if (!isXray && (expando = GetExpandoObje
   }
   if (desc->obj) {
     // Pretend the property lives on the wrapper.
     desc->obj = proxy;
     return true;
   }
 }
 """ + namedGet + """
-desc->obj = NULL;
+desc->obj = nullptr;
 return true;"""
 
 class CGDOMJSProxyHandler_defineProperty(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JSPropertyDescriptor*', 'desc')]
         ClassMethod.__init__(self, "defineProperty", "bool", args)
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -1320,35 +1320,30 @@ nsDOMDeviceStorage::SetRootDirectoryForT
   mRootDirectory = f;
   mStorageType = aStorageType;
   mStorageName = aStorageName;
 }
 
 JS::Value
 InterfaceToJsval(nsPIDOMWindow* aWindow, nsISupports* aObject, const nsIID* aIID)
 {
+  AutoJSContext cx;
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
   if (!sgo) {
     return JSVAL_NULL;
   }
 
-  nsIScriptContext *scriptContext = sgo->GetScriptContext();
-  if (!scriptContext) {
-    return JSVAL_NULL;
-  }
-
-  AutoPushJSContext cx(scriptContext->GetNativeContext());
-  if (!cx) {
-    return JSVAL_NULL;
-  }
+  JS::RootedObject scopeObj(cx, sgo->GetGlobalJSObject());
+  NS_ENSURE_TRUE(scopeObj, JSVAL_NULL);
+  JSAutoCompartment ac(cx, scopeObj);
+
 
   JS::Rooted<JS::Value> someJsVal(cx);
-  JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
   nsresult rv = nsContentUtils::WrapNative(cx,
-                                           global,
+                                           scopeObj,
                                            aObject,
                                            aIID,
                                            someJsVal.address());
   if (NS_FAILED(rv)) {
     return JSVAL_NULL;
   }
 
   return someJsVal;
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -137,17 +137,17 @@ NPObjWrapper_Finalize(JSFreeOp *fop, JSO
 static JSBool
 NPObjWrapper_Call(JSContext *cx, unsigned argc, JS::Value *vp);
 
 static JSBool
 NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
 
 static JSBool
 CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
-                     jsid id, NPVariant* getPropertyResult, JS::Value *vp);
+                     JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp);
 
 JSClass sNPObjectJSWrapperClass =
   {
     NPRUNTIME_JSCLASS_NAME,
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE,
     NPObjWrapper_AddProperty,
     NPObjWrapper_DelProperty,
     NPObjWrapper_GetProperty,
@@ -955,17 +955,17 @@ JSObjWrapperHashMatchEntry(PLDHashTable 
           e->mJSObjWrapper->mNpp == objWrapperKey->mNpp);
 }
 
 
 // Look up or create an NPObject that wraps the JSObject obj.
 
 // static
 NPObject *
-nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
+nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
 {
   if (!npp) {
     NS_ERROR("Null NPP passed to nsJSObjWrapper::GetNewOrUsed()!");
 
     return nullptr;
   }
 
   if (!cx) {
@@ -1079,26 +1079,27 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
 
 // Climb the prototype chain, unwrapping as necessary until we find an NP object
 // wrapper.
 //
 // Because this function unwraps, its return value must be wrapped for the cx
 // compartment for callers that plan to hold onto the result or do anything
 // substantial with it.
 static JSObject *
-GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true)
+GetNPObjectWrapper(JSContext *cx, JSObject *aObj, bool wrapResult = true)
 {
+  JS::Rooted<JSObject*> obj(cx, aObj);
   while (obj && (obj = js::CheckedUnwrap(obj))) {
     if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
-      if (wrapResult && !JS_WrapObject(cx, &obj)) {
+      if (wrapResult && !JS_WrapObject(cx, obj.address())) {
         return NULL;
       }
       return obj;
     }
-    if (!::JS_GetPrototype(cx, obj, &obj)) {
+    if (!::JS_GetPrototype(cx, obj, obj.address())) {
       return NULL;
     }
   }
   return NULL;
 }
 
 static NPObject *
 GetNPObject(JSContext *cx, JSObject *obj)
@@ -1331,17 +1332,17 @@ NPObjWrapper_GetProperty(JSContext *cx, 
     if (!ReportExceptionIfPending(cx))
       return JS_FALSE;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
-CallNPMethodInternal(JSContext *cx, JSObject *obj, unsigned argc,
+CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
                      JS::Value *argv, JS::Value *rval, bool ctorCall)
 {
   NPObject *npobj = GetNPObject(cx, obj);
 
   if (!npobj || !npobj->_class) {
     ThrowJSException(cx, "Bad NPObject as private data!");
 
     return JS_FALSE;
@@ -1460,17 +1461,17 @@ CallNPMethodInternal(JSContext *cx, JSOb
   _releasevariantvalue(&v);
 
   return ReportExceptionIfPending(cx);
 }
 
 static JSBool
 CallNPMethod(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-  JSObject *obj = JS_THIS_OBJECT(cx, vp);
+  JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
   if (!obj)
       return JS_FALSE;
 
   return CallNPMethodInternal(cx, obj, argc, JS_ARGV(cx, vp), vp, false);
 }
 
 struct NPObjectEnumerateState {
   uint32_t     index;
@@ -1661,24 +1662,26 @@ NPObjWrapper_Finalize(JSFreeOp *fop, JSO
   if (!sDelayedReleases)
     sDelayedReleases = new nsTArray<NPObject*>;
   sDelayedReleases->AppendElement(npobj);
 }
 
 static JSBool
 NPObjWrapper_Call(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-  return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
+  JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
+  return CallNPMethodInternal(cx, obj, argc,
                               JS_ARGV(cx, vp), vp, false);
 }
 
 static JSBool
 NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-  return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
+  JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
+  return CallNPMethodInternal(cx, obj, argc,
                               JS_ARGV(cx, vp), vp, true);
 }
 
 class NPObjWrapperHashEntry : public PLDHashEntryHdr
 {
 public:
   NPObject *mNPObj; // Must be the first member for the PLDHash stubs to work
   JSObject *mJSObj;
@@ -1955,17 +1958,17 @@ LookupNPP(NPObject *npobj)
 
   NS_ASSERTION(entry->mNpp, "Live NPObject entry w/o an NPP!");
 
   return entry->mNpp;
 }
 
 JSBool
 CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
-                     jsid id,  NPVariant* getPropertyResult, JS::Value *vp)
+                     JS::Handle<jsid> id,  NPVariant* getPropertyResult, JS::Value *vp)
 {
   NS_ENSURE_TRUE(vp, JS_FALSE);
 
   if (!npobj || !npobj->_class || !npobj->_class->getProperty ||
       !npobj->_class->invoke) {
     ThrowJSException(cx, "Bad NPObject");
 
     return JS_FALSE;
--- a/dom/plugins/base/nsJSNPRuntime.h
+++ b/dom/plugins/base/nsJSNPRuntime.h
@@ -32,17 +32,18 @@ public:
 };
 
 extern JSClass sNPObjectJSWrapperClass;
 
 class nsJSObjWrapper : public NPObject,
                        public nsJSObjWrapperKey
 {
 public:
-  static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj);
+  static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
+                                JS::Handle<JSObject*> obj);
 
 protected:
   nsJSObjWrapper(NPP npp);
   ~nsJSObjWrapper();
 
   static NPObject * NP_Allocate(NPP npp, NPClass *aClass);
   static void NP_Deallocate(NPObject *obj);
   static void NP_Invalidate(NPObject *obj);
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1206,17 +1206,18 @@ NPObject* NP_CALLBACK
     return nullptr;
   }
   AutoPushJSContext cx(GetJSContextFromNPP(npp));
   NS_ENSURE_TRUE(cx, nullptr);
 
   // Using ::JS_GetGlobalObject(cx) is ok here since the window we
   // want to return here is the outer window, *not* the inner (since
   // we don't know what the plugin will do with it).
-  return nsJSObjWrapper::GetNewOrUsed(npp, cx, ::JS_GetGlobalObject(cx));
+  JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalObject(cx));
+  return nsJSObjWrapper::GetNewOrUsed(npp, cx, global);
 }
 
 NPObject* NP_CALLBACK
 _getpluginelement(NPP npp)
 {
   if (!NS_IsMainThread()) {
     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getpluginelement called from the wrong thread\n"));
     return nullptr;
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -149,17 +149,17 @@ PostToRIL(JSContext *cx, unsigned argc, 
 
 bool
 ConnectWorkerToRIL::RunTask(JSContext *aCx)
 {
   // Set up the postRILMessage on the function for worker -> RIL thread
   // communication.
   NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
   NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
-  JSObject *workerGlobal = JS_GetGlobalObject(aCx);
+  JSObject *workerGlobal = JS_GetGlobalForScopeChain(aCx);
 
   if (!JS_DefineProperty(aCx, workerGlobal, "CLIENT_ID",
                          INT_TO_JSVAL(mClientId), nullptr, nullptr, 0)) {
     return false;
   }
 
   return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage", PostToRIL, 1,
                              0);
@@ -255,17 +255,17 @@ public:
 
 bool
 ConnectWorkerToNetd::RunTask(JSContext *aCx)
 {
   // Set up the DoNetdCommand on the function for worker <--> Netd process
   // communication.
   NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
   NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
-  JSObject *workerGlobal = JS_GetGlobalObject(aCx);
+  JSObject *workerGlobal = JS_GetGlobalForScopeChain(aCx);
   return !!JS_DefineFunction(aCx, workerGlobal, "postNetdCommand",
                              DoNetdCommand, 1, 0);
 }
 
 class NetdReceiver : public NetdConsumer
 {
   class DispatchNetdEvent : public WorkerTask
   {
@@ -294,17 +294,17 @@ public:
 
 private:
   nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
 };
 
 bool
 NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx)
 {
-  JSObject *obj = JS_GetGlobalObject(aCx);
+  JSObject *obj = JS_GetGlobalForScopeChain(aCx);
 
   JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
   if (!array) {
     return false;
   }
 
   memcpy(JS_GetUint8ArrayData(array), mMessage->mData, mMessage->mSize);
   JS::Value argv[] = { OBJECT_TO_JSVAL(array) };
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -36,17 +36,17 @@ class nsIChannel;
 class nsIDocument;
 class nsIMemoryMultiReporter;
 class nsIPrincipal;
 class nsIScriptContext;
 class nsIURI;
 class nsPIDOMWindow;
 class nsITimer;
 class nsIXPCScriptNotify;
-namespace JS { class RuntimeStats; }
+namespace JS { struct RuntimeStats; }
 
 BEGIN_WORKERS_NAMESPACE
 
 class WorkerPrivate;
 
 class WorkerRunnable : public nsIRunnable
 {
 public:
--- a/editor/libeditor/base/tests/test_selection_move_commands.xul
+++ b/editor/libeditor/base/tests/test_selection_move_commands.xul
@@ -118,18 +118,20 @@ function execTests() {
     while (i > 0) {
       n = n.nextSibling;
       --i;
     }
     return n;
   }
 
   doCommand("cmd_scrollBottom");
+  yield;
   testScrollCommand("cmd_scrollBottom", root.scrollHeight - 100);
   doCommand("cmd_scrollTop");
+  yield;
   testScrollCommand("cmd_scrollTop", 0);
 
   doCommand("cmd_scrollPageDown");
   yield;
   var pageHeight = -root.getBoundingClientRect().top;
   ok(pageHeight > 0, "cmd_scrollPageDown works");
   ok(pageHeight <= 100, "cmd_scrollPageDown doesn't scroll too much");
   doCommand("cmd_scrollBottom");
--- a/editor/libeditor/html/nsHTMLCSSUtils.cpp
+++ b/editor/libeditor/html/nsHTMLCSSUtils.cpp
@@ -584,17 +584,16 @@ already_AddRefed<nsComputedDOMStyle>
 nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
 {
   MOZ_ASSERT(aElement);
 
   nsIDocument* doc = aElement->GetCurrentDoc();
   NS_ENSURE_TRUE(doc, nullptr);
 
   nsIPresShell* presShell = doc->GetShell();
-  NS_ASSERTION(presShell, "Trying to compute style without PresShell");
   NS_ENSURE_TRUE(presShell, nullptr);
 
   nsRefPtr<nsComputedDOMStyle> style =
     NS_NewComputedDOMStyle(aElement, EmptyString(), presShell);
 
   return style.forget();
 }
 
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -919,16 +919,21 @@ public:
 
   static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);
 
 #ifdef USE_SKIA_GPU
   static TemporaryRef<DrawTarget>
     CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aContext, const IntSize &aSize, SurfaceFormat aFormat);
 #endif
 
+#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
+  static TemporaryRef<GlyphRenderingOptions>
+    CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
+#endif
+
 #ifdef WIN32
   static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   static TemporaryRef<DrawTarget>
     CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
                                          ID3D10Texture2D *aTextureB,
                                          SurfaceFormat aFormat);
 
   static void SetDirect3D10Device(ID3D10Device1 *aDevice);
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; 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/. */
 
 #include "DrawTargetSkia.h"
 #include "SourceSurfaceSkia.h"
 #include "ScaledFontBase.h"
+#include "ScaledFontCairo.h"
 #include "skia/SkDevice.h"
 
 #ifdef USE_SKIA_GPU
 #include "skia/SkGpuDevice.h"
 #endif
 
 #include "skia/SkTypeface.h"
 #include "skia/SkGradientShader.h"
@@ -440,33 +441,56 @@ DrawTargetSkia::Fill(const Path *aPath,
   mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
 }
 
 void
 DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
                            const GlyphBuffer &aBuffer,
                            const Pattern &aPattern,
                            const DrawOptions &aOptions,
-                           const GlyphRenderingOptions*)
+                           const GlyphRenderingOptions *aRenderingOptions)
 {
   if (aFont->GetType() != FONT_MAC &&
       aFont->GetType() != FONT_SKIA &&
       aFont->GetType() != FONT_GDI) {
     return;
   }
 
   MarkChanged();
 
   ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont);
 
   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
   paint.mPaint.setTypeface(skiaFont->GetSkTypeface());
   paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
   paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-  
+
+  if (aRenderingOptions && aRenderingOptions->GetType() == FONT_CAIRO) {
+    switch (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetHinting()) {
+      case FONT_HINTING_NONE:
+        paint.mPaint.setHinting(SkPaint::kNo_Hinting);
+        break;
+      case FONT_HINTING_LIGHT:
+        paint.mPaint.setHinting(SkPaint::kSlight_Hinting);
+        break;
+      case FONT_HINTING_NORMAL:
+        paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
+        break;
+      case FONT_HINTING_FULL:
+        paint.mPaint.setHinting(SkPaint::kFull_Hinting);
+        break;
+    }
+
+    if (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetAutoHinting()) {
+      paint.mPaint.setAutohinted(true);
+    }
+  } else {
+    paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
+  }
+
   std::vector<uint16_t> indices;
   std::vector<SkPoint> offsets;
   indices.resize(aBuffer.mNumGlyphs);
   offsets.resize(aBuffer.mNumGlyphs);
 
   for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
     indices[i] = aBuffer.mGlyphs[i].mIndex;
     offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x);
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -2,24 +2,25 @@
  * 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 "2D.h"
 
 #ifdef USE_CAIRO
 #include "DrawTargetCairo.h"
-#include "ScaledFontBase.h"
+#include "ScaledFontCairo.h"
 #endif
 
 #ifdef USE_SKIA
 #include "DrawTargetSkia.h"
 #include "ScaledFontBase.h"
 #ifdef MOZ_ENABLE_FREETYPE
-#include "ScaledFontFreetype.h"
+#define USE_SKIA_FREETYPE
+#include "ScaledFontCairo.h"
 #endif
 #endif
 
 #if defined(WIN32) && defined(USE_SKIA)
 #include "ScaledFontWin.h"
 #endif
 
 #ifdef XP_MACOSX
@@ -292,30 +293,20 @@ Factory::CreateScaledFontForNativeFont(c
 #endif
 #endif
 #ifdef XP_MACOSX
   case NATIVE_FONT_MAC_FONT_FACE:
     {
       return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
     }
 #endif
-#ifdef USE_SKIA
-#ifdef MOZ_ENABLE_FREETYPE
-  case NATIVE_FONT_SKIA_FONT_FACE:
-    {
-      return new ScaledFontFreetype(static_cast<FontOptions*>(aNativeFont.mFont), aSize);
-    }
-#endif
-#endif
-#ifdef USE_CAIRO
+#if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE)
   case NATIVE_FONT_CAIRO_FONT_FACE:
     {
-      ScaledFontBase* fontBase = new ScaledFontBase(aSize);
-      fontBase->SetCairoScaledFont(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont));
-      return fontBase;
+      return new ScaledFontCairo(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aSize);
     }
 #endif
   default:
     gfxWarning() << "Invalid native font type specified.";
     return nullptr;
   }
 }
 
@@ -454,16 +445,29 @@ TemporaryRef<DrawTarget>
 Factory::CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aGrContext, const IntSize &aSize, SurfaceFormat aFormat)
 {
   RefPtr<DrawTargetSkia> newTarget = new DrawTargetSkia();
   newTarget->InitWithFBO(aFBOID, aGrContext, aSize, aFormat);
   return newTarget;
 }
 #endif // USE_SKIA_GPU
 
+#ifdef USE_SKIA_FREETYPE
+TemporaryRef<GlyphRenderingOptions>
+Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting)
+{
+  RefPtr<GlyphRenderingOptionsCairo> options =
+    new GlyphRenderingOptionsCairo();
+
+  options->SetHinting(aHinting);
+  options->SetAutoHinting(aAutoHinting);
+  return options;
+}
+#endif
+
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize)
 {
   RefPtr<DrawTarget> retVal;
 
 #ifdef USE_CAIRO
   RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
 
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -23,16 +23,17 @@ CPPSRCS	= \
         PathCairo.cpp \
         DrawTargetRecording.cpp \
         PathRecording.cpp \
         RecordedEvent.cpp \
         DrawEventRecorder.cpp \
         Blur.cpp \
         Scale.cpp \
         ScaledFontBase.cpp \
+        ScaledFontCairo.cpp \
         DrawTargetDual.cpp \
         ImageScaling.cpp \
         SourceSurfaceRawData.cpp \
         $(NULL)
 
 GTEST_CPPSRCS = \
         GTestMain.cpp \
         TestBase.cpp \
@@ -68,20 +69,18 @@ endif
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
         ScaledFontMac.cpp \
         $(NULL)
 
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
-CPPSRCS	+= \
-        ScaledFontFreetype.cpp \
-        $(NULL)
 DEFINES += -DMOZ_ENABLE_FREETYPE
+OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
 
 DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0
 
 ifdef MOZ_DEBUG
 DEFINES += -DGFX_LOG_DEBUG -DGFX_LOG_WARNING
 endif
 
--- a/gfx/2d/ScaledFontBase.cpp
+++ b/gfx/2d/ScaledFontBase.cpp
@@ -23,28 +23,28 @@ using namespace std;
 namespace mozilla {
 namespace gfx {
 
 ScaledFontBase::~ScaledFontBase()
 {
 #ifdef USE_SKIA
   SkSafeUnref(mTypeface);
 #endif
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
   cairo_scaled_font_destroy(mScaledFont);
 #endif
 }
 
 ScaledFontBase::ScaledFontBase(Float aSize)
   : mSize(aSize)
 {
 #ifdef USE_SKIA
   mTypeface = nullptr;
 #endif
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
   mScaledFont = nullptr;
 #endif
 }
 
 TemporaryRef<Path>
 ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
 {
 #ifdef USE_SKIA
@@ -101,17 +101,17 @@ ScaledFontBase::GetPathForGlyphs(const G
 void
 ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder)
 {
   // XXX - implement me
   MOZ_ASSERT(false);
   return;
 }
 
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
 void
 ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
 {
   MOZ_ASSERT(!mScaledFont);
 
   mScaledFont = font;
   cairo_scaled_font_reference(mScaledFont);
 }
--- a/gfx/2d/ScaledFontBase.h
+++ b/gfx/2d/ScaledFontBase.h
@@ -3,20 +3,25 @@
  * 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 MOZILLA_GFX_SCALEDFONTBASE_H_
 #define MOZILLA_GFX_SCALEDFONTBASE_H_
 
 #include "2D.h"
 
+// Skia uses cairo_scaled_font_t as the internal font type in ScaledFont
+#if defined(USE_SKIA) || defined(USE_CAIRO)
+#define USE_CAIRO_SCALED_FONT
+#endif
+
 #ifdef USE_SKIA
 #include "skia/SkTypeface.h"
 #endif
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
 #include "cairo.h"
 #endif
 
 class gfxFont;
 
 namespace mozilla {
 namespace gfx {
 
@@ -34,27 +39,27 @@ public:
 
 #ifdef USE_SKIA
   virtual SkTypeface* GetSkTypeface() { return mTypeface; }
 #endif
 
   // Not true, but required to instantiate a ScaledFontBase.
   virtual FontType GetType() const { return FONT_SKIA; }
 
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
   cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; }
   void SetCairoScaledFont(cairo_scaled_font_t* font);
 #endif
 
 protected:
   friend class DrawTargetSkia;
 #ifdef USE_SKIA
   SkTypeface* mTypeface;
 #endif
-#ifdef USE_CAIRO
+#ifdef USE_CAIRO_SCALED_FONT
   cairo_scaled_font_t* mScaledFont;
 #endif
   Float mSize;
 };
 
 }
 }
 
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontCairo.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#include "ScaledFontCairo.h"
+#include "Logging.h"
+
+#include "gfxFont.h"
+
+#ifdef MOZ_ENABLE_FREETYPE
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "cairo-ft.h"
+#endif
+
+#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
+#include "skia/SkTypeface.h"
+#include "skia/SkTypeface_cairo.h"
+#endif
+
+#include <string>
+
+typedef struct FT_FaceRec_* FT_Face;
+
+using namespace std;
+
+namespace mozilla {
+namespace gfx {
+
+// On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
+// an SkFontHost implementation that allows Skia to render using this.
+// This is mainly because FT_Face is not good for sharing between libraries, which
+// is a requirement when we consider runtime switchable backends and so on
+ScaledFontCairo::ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize)
+  : ScaledFontBase(aSize)
+{
+  mScaledFont = aScaledFont;
+#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
+  cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(aScaledFont);
+  FT_Face face = cairo_ft_scaled_font_lock_face(aScaledFont);
+
+  int style = SkTypeface::kNormal;
+
+  if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+    style |= SkTypeface::kItalic;
+
+  if (face->style_flags & FT_STYLE_FLAG_BOLD)
+    style |= SkTypeface::kBold;
+
+  bool isFixedWidth = face->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
+  cairo_ft_scaled_font_unlock_face(aScaledFont);
+
+  mTypeface = SkCreateTypefaceFromCairoFont(fontFace, (SkTypeface::Style)style, isFixedWidth);
+#endif
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontCairo.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#ifndef MOZILLA_GFX_SCALEDFONTCAIRO_H_
+#define MOZILLA_GFX_SCALEDFONTCAIRO_H_
+
+#include "ScaledFontBase.h"
+
+#include "cairo.h"
+
+namespace mozilla {
+namespace gfx {
+
+class ScaledFontCairo : public ScaledFontBase
+{
+public:
+
+  ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize);
+};
+
+// We need to be able to tell Skia whether or not to use
+// hinting when rendering text, so that the glyphs it renders
+// are the same as what layout is expecting. At the moment, only
+// Skia uses this class when rendering with FreeType, as gfxFT2Font
+// is the only gfxFont that honours gfxPlatform::FontHintingEnabled().
+class GlyphRenderingOptionsCairo : public GlyphRenderingOptions
+{
+public:
+  GlyphRenderingOptionsCairo()
+    : mHinting(FONT_HINTING_NORMAL)
+    , mAutoHinting(false)
+  {
+  }
+
+  void SetHinting(FontHinting aHinting) { mHinting = aHinting; }
+  void SetAutoHinting(bool aAutoHinting) { mAutoHinting = aAutoHinting; }
+  FontHinting GetHinting() const { return mHinting; }
+  bool GetAutoHinting() const { return mAutoHinting; }
+  virtual FontType GetType() const { return FONT_CAIRO; }
+private:
+  FontHinting mHinting;
+  bool mAutoHinting;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */
deleted file mode 100644
--- a/gfx/2d/ScaledFontFreetype.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; 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/. */
-
-#include "ScaledFontFreetype.h"
-#include "Logging.h"
-
-#include "gfxFont.h"
-
-#ifdef USE_SKIA
-#include "skia/SkTypeface.h"
-#endif
-
-#include <string>
-
-using namespace std;
-
-namespace mozilla {
-namespace gfx {
-
-#ifdef USE_SKIA
-static SkTypeface::Style
-fontStyleToSkia(FontStyle aStyle)
-{
-  switch (aStyle) {
-  case FONT_STYLE_NORMAL:
-    return SkTypeface::kNormal;
-  case FONT_STYLE_ITALIC:
-    return SkTypeface::kItalic;
-  case FONT_STYLE_BOLD:
-    return SkTypeface::kBold;
-  case FONT_STYLE_BOLD_ITALIC:
-    return SkTypeface::kBoldItalic;
-   }
-
-  gfxWarning() << "Unknown font style";
-  return SkTypeface::kNormal;
-}
-#endif
-
-// Ideally we want to use FT_Face here but as there is currently no way to get
-// an SkTypeface from an FT_Face we do this.
-ScaledFontFreetype::ScaledFontFreetype(FontOptions* aFont, Float aSize)
-  : ScaledFontBase(aSize)
-{
-#ifdef USE_SKIA
-  mTypeface = SkTypeface::CreateFromName(aFont->mName.c_str(), fontStyleToSkia(aFont->mStyle));
-#endif
-}
-
-}
-}
deleted file mode 100644
--- a/gfx/2d/ScaledFontFreetype.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; 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/. */
-
-#ifndef MOZILLA_GFX_SCALEDFONTFREETYPE_H_
-#define MOZILLA_GFX_SCALEDFONTFREETYPE_H_
-
-#include "ScaledFontBase.h"
-
-namespace mozilla {
-namespace gfx {
-
-class ScaledFontFreetype : public ScaledFontBase
-{
-public:
-
-  ScaledFontFreetype(FontOptions* aFont, Float aSize);
-};
-
-}
-}
-
-#endif /* MOZILLA_GFX_SCALEDFONTFREETYPE_H_ */
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -83,16 +83,24 @@ enum NativeFontType
 enum FontStyle
 {
   FONT_STYLE_NORMAL,
   FONT_STYLE_ITALIC,
   FONT_STYLE_BOLD,
   FONT_STYLE_BOLD_ITALIC
 };
 
+enum FontHinting
+{
+  FONT_HINTING_NONE,
+  FONT_HINTING_LIGHT,
+  FONT_HINTING_NORMAL,
+  FONT_HINTING_FULL
+};
+
 enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, 
   OP_MULTIPLY, OP_SCREEN, OP_OVERLAY, OP_DARKEN, OP_LIGHTEN, OP_COLOR_DODGE, OP_COLOR_BURN, OP_HARD_LIGHT, OP_SOFT_LIGHT,  OP_DIFFERENCE, OP_EXCLUSION, OP_HUE, OP_SATURATION, OP_COLOR, OP_LUMINOSITY, OP_COUNT };
 enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
 enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
 enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
 enum Snapping { SNAP_NONE, SNAP_ALIGNED };
 enum Filter { FILTER_LINEAR, FILTER_POINT };
 enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
--- a/gfx/harfbuzz/src/hb-set-private.hh
+++ b/gfx/harfbuzz/src/hb-set-private.hh
@@ -290,17 +290,17 @@ struct hb_set_t
     for (unsigned int i = 0; i < ELTS; i++)
       count += _hb_popcount32 (elts[i]);
     return count;
   }
   inline hb_codepoint_t get_min (void) const
   {
     for (unsigned int i = 0; i < ELTS; i++)
       if (elts[i])
-	for (unsigned int j = 0; i < BITS; j++)
+	for (unsigned int j = 0; j < BITS; j++)
 	  if (elts[i] & (1 << j))
 	    return i * BITS + j;
     return SENTINEL;
   }
   inline hb_codepoint_t get_max (void) const
   {
     for (unsigned int i = ELTS; i; i--)
       if (elts[i - 1])
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -63,17 +63,17 @@ CanvasClient2D::Update(gfx::IntSize aSiz
   mTextureClient->EnsureAllocated(aSize, contentType);
 
   gfxASurface* surface = mTextureClient->LockSurface();
   aLayer->UpdateSurface(surface);
   mTextureClient->Unlock();
 }
 
 void
-CanvasClient2D::Updated()
+CanvasClientWebGL::Updated()
 {
   mForwarder->UpdateTextureNoSwap(this, 1, mTextureClient->GetDescriptor());
 }
 
 
 CanvasClientWebGL::CanvasClientWebGL(CompositableForwarder* aFwd,
                                      TextureFlags aFlags)
 : CanvasClient(aFwd, aFlags)
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -60,32 +60,31 @@ public:
                  TextureFlags aFlags);
 
   TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
-
-  virtual void Updated() MOZ_OVERRIDE;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
 class CanvasClientWebGL : public CanvasClient
 {
 public:
   CanvasClientWebGL(CompositableForwarder* aFwd,
                     TextureFlags aFlags);
 
   TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
+  virtual void Updated() MOZ_OVERRIDE;
 };
 
 }
 }
 
 #endif
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -294,52 +294,59 @@ CPPSRCS += \
 	$(NULL)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkFontHost_mac_coretext.cpp \
 	SkStream_mac.cpp \
 	SkTime_Unix.cpp \
+	SkThread_pthread.cpp \
 	$(NULL)
+DEFINES += -DSK_USE_POSIX_THREADS=1
 endif
 
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkDebug_android.cpp \
-	SkFontHost_android_old.cpp \
-	SkFontHost_FreeType.cpp \
+	SkFontHost_cairo.cpp \
 	SkFontHost_FreeType_common.cpp \
 	SkFontHost_tables.cpp \
 	SkMMapStream.cpp \
 	SkTime_Unix.cpp \
 	SkThread_pthread.cpp \
 	$(NULL)
 
-OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
 DEFINES += -DSK_USE_POSIX_THREADS=1
+EXPORTS_skia += \
+	include/ports/SkTypeface_cairo.h \
+	$(NULL)
+
+OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
 else
 CPPSRCS += \
 	SkDebug_stdio.cpp \
-	SkThread_none.cpp \
 	$(NULL)
 endif
 
 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
-	SkFontHost_FreeType.cpp \
+	SkFontHost_cairo.cpp \
 	SkFontHost_FreeType_common.cpp \
-	SkFontHost_linux.cpp \
 	SkFontHost_tables.cpp \
 	SkTime_Unix.cpp \
 	SkMMapStream.cpp \
 	SkOSFile.cpp \
 	$(NULL)
 
-OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
+EXPORTS_skia += \
+	include/ports/SkTypeface_cairo.h \
+	$(NULL)
+
+OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
 endif
 
 ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkFontHost_FreeType.cpp \
 	SkFontHost_FreeType_common.cpp \
 	SkFontHost_tables.cpp \
 	SkMMapStream.cpp \
@@ -352,24 +359,28 @@ CPPSRCS += \
 	SkTime_Unix.cpp \
 	$(NULL)
 endif
 OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
 ifeq (Linux,$(OS_TARGET))
 DEFINES += -DSK_USE_POSIX_THREADS=1
+CPPSRCS += \
+	SkThread_pthread.cpp \
+	$(NULL)
 endif
 
 ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkFontHost_win.cpp \
 	SkFontHost_tables.cpp \
 	SkFontHost_sandbox_none.cpp \
 	SkTime_win.cpp \
+	SkThread_win.cpp \
 	$(NULL)
 DEFINES += -DSKIA_IMPLEMENTATION=1 -DGR_IMPLEMENTATION=1
 endif
 
 ifneq (,$(INTEL_ARCHITECTURE))
 CPPSRCS += \
 	SkBitmapProcState_opts_SSE2.cpp \
 	SkBlitRect_opts_SSE2.cpp \
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/ports/SkTypeface_cairo.h
@@ -0,0 +1,11 @@
+#ifndef SkTypeface_cairo_DEFINED
+#define SkTypeface_cairo_DEFINED
+
+#include <cairo.h>
+
+#include "SkTypeface.h"
+
+SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth);
+
+#endif
+
new file mode 100644
--- /dev/null
+++ b/gfx/skia/src/ports/SkFontHost_cairo.cpp
@@ -0,0 +1,382 @@
+
+/*
+ * Copyright 2012 Mozilla Foundation
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "cairo.h"
+#include "cairo-ft.h"
+
+#include "SkFontHost_FreeType_common.h"
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkFontHost.h"
+#include "SkPath.h"
+#include "SkScalerContext.h"
+#include "SkTypefaceCache.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+static cairo_user_data_key_t kSkTypefaceKey;
+
+class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
+public:
+    SkScalerContext_CairoFT(const SkDescriptor* desc);
+    virtual ~SkScalerContext_CairoFT();
+
+protected:
+    virtual unsigned generateGlyphCount() SK_OVERRIDE;
+    virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
+    virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
+    virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
+    virtual void generateImage(const SkGlyph& glyph, SkMaskGamma::PreBlend* maskPreBlend) SK_OVERRIDE;
+    virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
+    virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
+                                     SkPaint::FontMetrics* my) SK_OVERRIDE;
+    virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
+private:
+    cairo_scaled_font_t* fScaledFont;
+    uint32_t fLoadGlyphFlags;
+};
+
+class CairoLockedFTFace {
+public:
+    CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
+        : fScaledFont(scaledFont)
+        , fFace(cairo_ft_scaled_font_lock_face(scaledFont))
+    {}
+
+    ~CairoLockedFTFace()
+    {
+        cairo_ft_scaled_font_unlock_face(fScaledFont);
+    }
+
+    FT_Face getFace()
+    {
+        return fFace;
+    }
+
+private:
+    cairo_scaled_font_t* fScaledFont;
+    FT_Face fFace;
+};
+
+class SkCairoFTTypeface : public SkTypeface {
+public:
+    static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
+        SkASSERT(fontFace != NULL);
+        SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
+
+        SkFontID newId = SkTypefaceCache::NewFontID();
+
+        return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
+    }
+
+    cairo_font_face_t* getFontFace() {
+        return fFontFace;
+    }
+
+private:
+
+    SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
+        : SkTypeface(style, id, isFixedWidth)
+        , fFontFace(fontFace)
+    {
+        cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
+        cairo_font_face_reference(fFontFace);
+    }
+
+    ~SkCairoFTTypeface()
+    {
+        cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
+        cairo_font_face_destroy(fFontFace);
+    }
+
+    cairo_font_face_t* fFontFace;
+};
+
+SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
+{
+    SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
+
+    if (typeface) {
+        typeface->ref();
+    } else {
+        typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
+        SkTypefaceCache::Add(typeface, style);
+    }
+
+    return typeface;
+}
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                                     const char famillyName[],
+                                     SkTypeface::Style style)
+{
+    SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
+    return NULL;
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
+{
+    SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
+    return NULL;
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
+{
+    SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
+    return NULL;
+}
+
+// static
+SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
+        uint32_t fontID,
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount)
+{
+    return NULL;
+}
+
+void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkStream* SkFontHost::OpenStream(uint32_t uniqueID)
+{
+    SkDEBUGFAIL("SkFontHost::OpenStream unimplemented");
+    return NULL;
+}
+
+size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
+                               int32_t* index) {
+    SkDebugf("SkFontHost::GetFileName unimplemented\n");
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream)
+{
+    SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
+}
+
+SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
+    SkDEBUGFAIL("SkFontHost::Deserialize unimplemented");
+    return NULL;
+}
+
+static bool isLCD(const SkScalerContext::Rec& rec) {
+    switch (rec.fMaskFormat) {
+        case SkMask::kLCD16_Format:
+        case SkMask::kLCD32_Format:
+            return true;
+        default:
+            return false;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+SkScalerContext_CairoFT::SkScalerContext_CairoFT(const SkDescriptor* desc)
+    : SkScalerContext_FreeType_Base(desc)
+{
+    SkCairoFTTypeface* typeface = static_cast<SkCairoFTTypeface*>(SkTypefaceCache::FindByID(fRec.fFontID));
+
+    SkMatrix matrix;
+    fRec.getSingleMatrix(&matrix);
+
+    cairo_font_face_t* fontFace = typeface->getFontFace();
+
+    cairo_matrix_t fontMatrix, ctMatrix;
+    cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
+    cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
+
+    // We need to ensure that the font options match for hinting, as generateMetrics()
+    // uses the fScaledFont which uses these font options
+    cairo_font_options_t *fontOptions = cairo_font_options_create();
+
+    FT_Int32 loadFlags = FT_LOAD_DEFAULT;
+
+    if (SkMask::kBW_Format == fRec.fMaskFormat) {
+        // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
+        loadFlags = FT_LOAD_TARGET_MONO;
+        if (fRec.getHinting() == SkPaint::kNo_Hinting) {
+            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
+            loadFlags = FT_LOAD_NO_HINTING;
+        }
+    } else {
+        switch (fRec.getHinting()) {
+        case SkPaint::kNo_Hinting:
+            loadFlags = FT_LOAD_NO_HINTING;
+            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
+            break;
+        case SkPaint::kSlight_Hinting:
+            loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
+            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
+            break;
+        case SkPaint::kNormal_Hinting:
+            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
+            if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
+                loadFlags = FT_LOAD_FORCE_AUTOHINT;
+            }
+            break;
+        case SkPaint::kFull_Hinting:
+            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
+            if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
+                loadFlags = FT_LOAD_FORCE_AUTOHINT;
+            }
+            if (isLCD(fRec)) {
+                if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
+                    loadFlags = FT_LOAD_TARGET_LCD_V;
+                } else {
+                    loadFlags = FT_LOAD_TARGET_LCD;
+                }
+            }
+            break;
+        default:
+            SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
+            break;
+        }
+    }
+
+    fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
+
+    if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
+        loadFlags |= FT_LOAD_NO_BITMAP;
+    }
+
+    // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
+    // advances, as fontconfig and cairo do.
+    // See http://code.google.com/p/skia/issues/detail?id=222.
+    loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
+
+    fLoadGlyphFlags = loadFlags;
+}
+
+SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
+{
+    cairo_scaled_font_destroy(fScaledFont);
+}
+
+SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
+{
+    return SkNEW_ARGS(SkScalerContext_CairoFT, (desc));
+}
+
+SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID)
+{
+    return 0;
+}
+
+#ifdef SK_BUILD_FOR_ANDROID
+uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
+    return 0;
+}
+#endif
+
+unsigned SkScalerContext_CairoFT::generateGlyphCount()
+{
+    CairoLockedFTFace faceLock(fScaledFont);
+    return faceLock.getFace()->num_glyphs;
+}
+
+uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
+{
+    CairoLockedFTFace faceLock(fScaledFont);
+    return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
+}
+
+void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
+{
+    generateMetrics(glyph);
+}
+
+void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
+{
+    SkASSERT(fScaledFont != NULL);
+    cairo_text_extents_t extents;
+    cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
+    cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
+
+    glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
+    glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
+    glyph->fWidth = SkToU16(SkScalarCeil(extents.width));
+    glyph->fHeight = SkToU16(SkScalarCeil(extents.height));
+    glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing));
+    glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing));
+    glyph->fLsbDelta = 0;
+    glyph->fRsbDelta = 0;
+}
+
+void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph, SkMaskGamma::PreBlend* maskPreBlend)
+{
+    SkASSERT(fScaledFont != NULL);
+    CairoLockedFTFace faceLock(fScaledFont);
+    FT_Face face = faceLock.getFace();
+
+    FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
+
+    if (err != 0) {
+        memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
+        return;
+    }
+
+    generateGlyphImage(face, glyph, maskPreBlend);
+}
+
+void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
+{
+    SkASSERT(fScaledFont != NULL);
+    CairoLockedFTFace faceLock(fScaledFont);
+    FT_Face face = faceLock.getFace();
+
+    SkASSERT(&glyph && path);
+
+    uint32_t flags = fLoadGlyphFlags;
+    flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
+    flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
+
+    FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
+
+    if (err != 0) {
+        path->reset();
+        return;
+    }
+
+    generateGlyphPath(face, glyph, path);
+}
+
+void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
+                                                  SkPaint::FontMetrics* my)
+{
+}
+
+SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
+{
+    SkASSERT(fScaledFont != NULL);
+    CairoLockedFTFace faceLock(fScaledFont);
+    FT_Face face = faceLock.getFace();
+
+    FT_UInt glyphIndex;
+    SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
+    while (glyphIndex != 0) {
+        if (glyphIndex == glyph) {
+            return charCode;
+        }
+        charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
+    }
+
+    return 0;
+}
+
+#ifdef SK_BUILD_FOR_ANDROID
+SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
+                                         SkFontID origFontID) {
+    return NULL;
+}
+#endif
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -317,26 +317,23 @@ gfxAndroidPlatform::MakePlatformFont(con
                                                                      aFontData,
                                                                      aLength);
 }
 
 TemporaryRef<ScaledFont>
 gfxAndroidPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
 {
     NativeFont nativeFont;
-    if (aTarget->GetType() == BACKEND_CAIRO) {
+    if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
         nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
-        nativeFont.mFont = NULL;
-        return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont());
+        nativeFont.mFont = aFont->GetCairoScaledFont();
+        return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
     }
- 
-    NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_FT2, "Expecting Freetype font");
-    nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
-    nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
-    return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
+
+    return nullptr;
 }
 
 bool
 gfxAndroidPlatform::FontHintingEnabled()
 {
     // In "mobile" builds, we sometimes use non-reflow-zoom, so we
     // might not want hinting.  Let's see.
 
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -31,16 +31,17 @@
 #include "nsUnicodeRange.h"
 #include "nsCRT.h"
 #include "nsXULAppAPI.h"
 
 #include "prlog.h"
 #include "prinit.h"
 
 #include "mozilla/Preferences.h"
+#include "mozilla/gfx/2D.h"
 
 // rounding and truncation functions for a Freetype floating point number
 // (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
 // part and low 6 bits for the fractional part.
 #define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
 #define MOZ_FT_TRUNC(x) ((x) >> 6)
 #define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
         MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
@@ -654,8 +655,26 @@ gfxFT2Font::SizeOfExcludingThis(nsMalloc
 
 void
 gfxFT2Font::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                 FontCacheSizes*   aSizes) const
 {
     aSizes->mFontInstances += aMallocSizeOf(this);
     SizeOfExcludingThis(aMallocSizeOf, aSizes);
 }
+
+#ifdef USE_SKIA
+mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
+gfxFT2Font::GetGlyphRenderingOptions()
+{
+  mozilla::gfx::FontHinting hinting;
+
+  if (gfxPlatform::GetPlatform()->FontHintingEnabled()) {
+    hinting = mozilla::gfx::FONT_HINTING_NORMAL;
+  } else {
+    hinting = mozilla::gfx::FONT_HINTING_NONE;
+  }
+
+  // We don't want to force the use of the autohinter over the font's built in hints
+  return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
+}
+#endif
+
--- a/gfx/thebes/gfxFT2Fonts.h
+++ b/gfx/thebes/gfxFT2Fonts.h
@@ -63,16 +63,20 @@ public: // new functions
         return &entry->mData;
     }
 
     virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                      FontCacheSizes*   aSizes) const;
     virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                      FontCacheSizes*   aSizes) const;
 
+#ifdef USE_SKIA
+    virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
+#endif
+
 protected:
     virtual bool ShapeText(gfxContext      *aContext,
                            const PRUnichar *aText,
                            uint32_t         aOffset,
                            uint32_t         aLength,
                            int32_t          aScript,
                            gfxShapedText   *aShapedText,
                            bool             aPreferPlatformShaping);
--- a/gfx/thebes/gfxPangoFonts.cpp
+++ b/gfx/thebes/gfxPangoFonts.cpp
@@ -772,16 +772,20 @@ public:
     // The PangoFont returned is owned by the gfxFcFont
     PangoFont *GetPangoFont() {
         if (!mPangoFont) {
             MakePangoFont();
         }
         return mPangoFont;
     }
 
+#ifdef USE_SKIA
+    virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
+#endif
+
 protected:
     virtual bool ShapeText(gfxContext      *aContext,
                            const PRUnichar *aText,
                            uint32_t         aOffset,
                            uint32_t         aLength,
                            int32_t          aScript,
                            gfxShapedText   *aShapedText,
                            bool             aPreferPlatformShaping);
@@ -3226,8 +3230,41 @@ ApplyGdkScreenFontOptions(FcPattern *aPa
 {
     const cairo_font_options_t *options =
         gdk_screen_get_font_options(gdk_screen_get_default());
 
     cairo_ft_font_options_substitute(options, aPattern);
 }
 
 #endif // MOZ_WIDGET_GTK2
+
+#ifdef USE_SKIA
+mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
+gfxFcFont::GetGlyphRenderingOptions()
+{
+  cairo_scaled_font_t *scaled_font = CairoScaledFont();
+  cairo_font_options_t *options = cairo_font_options_create();
+  cairo_scaled_font_get_font_options(scaled_font, options);
+  cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);     
+  cairo_font_options_destroy(options);
+
+  mozilla::gfx::FontHinting hinting;
+
+  switch (hint_style) {
+    case CAIRO_HINT_STYLE_NONE:
+      hinting = mozilla::gfx::FONT_HINTING_NONE;
+      break;
+    case CAIRO_HINT_STYLE_SLIGHT:
+      hinting = mozilla::gfx::FONT_HINTING_LIGHT;
+      break;
+    case CAIRO_HINT_STYLE_FULL:
+      hinting = mozilla::gfx::FONT_HINTING_FULL;
+      break;
+    default:
+      hinting = mozilla::gfx::FONT_HINTING_NORMAL;
+      break;
+  }
+
+  // We don't want to force the use of the autohinter over the font's built in hints
+  return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
+}
+#endif
+
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -753,18 +753,18 @@ gfxPlatformGtk::GetGdkDrawable(gfxASurfa
     return NULL;
 }
 #endif
 
 TemporaryRef<ScaledFont>
 gfxPlatformGtk::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
 {
     NativeFont nativeFont;
-    if (aTarget->GetType() == BACKEND_CAIRO) {
+
+    if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
         nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
-        nativeFont.mFont = NULL;
-        return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont());
+        nativeFont.mFont = aFont->GetCairoScaledFont();
+        return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
     }
-    NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_FT2, "Expecting Freetype font");
-    nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
-    nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
-    return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
+
+    return NULL;
+
 }
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -43,17 +43,17 @@ public:
 
 private:
     nsAutoPtr<UnixSocketRawData> mMessage;
 };
 
 bool
 DispatchRILEvent::RunTask(JSContext *aCx)
 {
-    JSObject *obj = JS_GetGlobalObject(aCx);
+    JSObject *obj = JS_GetGlobalForScopeChain(aCx);
 
     JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
     if (!array) {
         return false;
     }
 
     memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
     JS::Value argv[] = { OBJECT_TO_JSVAL(array) };
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -23,17 +23,17 @@ namespace {
     // Only need one reserved slot because the ObjectWrapperParent* is
     // stored in the private slot.
     static const unsigned sFlagsSlot = 0;
     static const unsigned sNumSlots = 1;
     static const unsigned CPOW_FLAG_RESOLVING = 1 << 0;
 
     class AutoResolveFlag
     {
-        JSObject* mObj;
+        Rooted<JSObject*> mObj;
         unsigned mOldFlags;
         MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
         static unsigned GetFlags(JSObject* obj) {
             jsval v = JS_GetReservedSlot(obj, sFlagsSlot);
             return JSVAL_TO_INT(v);
         }
 
@@ -41,19 +41,19 @@ namespace {
             unsigned oldFlags = GetFlags(obj);
             if (oldFlags != flags)
                 JS_SetReservedSlot(obj, sFlagsSlot, INT_TO_JSVAL(flags));
             return oldFlags;
         }
 
     public:
 
-        AutoResolveFlag(JSObject* obj
+        AutoResolveFlag(JSContext *cx, JSObject* obj
                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-            : mObj(obj)
+            : mObj(cx, obj)
             , mOldFlags(SetFlags(obj, GetFlags(obj) | CPOW_FLAG_RESOLVING))
         {
             MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         }
 
         ~AutoResolveFlag() {
             SetFlags(mObj, mOldFlags);
         }
@@ -96,17 +96,17 @@ ObjectWrapperParent::CheckOperation(JSCo
                                     OperationStatus* status)
 {
     NS_PRECONDITION(status->type() != OperationStatus::T__None,
                     "Checking an uninitialized operation.");
 
     switch (status->type()) {
     case OperationStatus::TJSVariant:
         {
-            JS::RootedValue thrown(cx);
+            Rooted<Value> thrown(cx);
             if (jsval_from_JSVariant(cx, status->get_JSVariant(), thrown.address()))
                 JS_SetPendingException(cx, thrown);
             *status = JS_FALSE;
         }
         break;
     case OperationStatus::TJSBool:
         if (!status->get_JSBool() && !JS_IsExceptionPending(cx)) {
             NS_WARNING("CPOW operation failed without setting an exception.");
@@ -176,17 +176,17 @@ ObjectWrapperParent::GetJSObject(JSConte
         }
     }
     return mObj;
 }
 
 static ObjectWrapperParent*
 Unwrap(JSContext* cx, JSObject* objArg)
 {
-    RootedObject obj(cx, objArg), proto(cx);
+    Rooted<JSObject*> obj(cx, objArg), proto(cx);
     while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass) {
         if (!js::GetObjectProto(cx, obj, &proto) || !proto)
             return NULL;
         obj = proto;
     }
 
     ObjectWrapperParent* self =
         static_cast<ObjectWrapperParent*>(JS_GetPrivate(obj));
@@ -280,17 +280,17 @@ ObjectWrapperParent::jsval_from_JSVarian
 ObjectWrapperParent::boolean_from_JSVariant(JSContext* cx, const JSVariant& from,
                                             JSBool* to)
 {
     switch (from.type()) {
     case JSVariant::Tvoid_t:
         *to = false;
         return true;
     case JSVariant::TPObjectWrapperParent: {
-        JS::Rooted<JS::Value> v(cx);
+        Rooted<Value> v(cx);
         if (!jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), v.address()))
             return false;
         *to = JS::ToBoolean(v);
         return true;
     }
     case JSVariant::TnsString:
         {
             JSString* str = JS_NewUCStringCopyZ(cx, from.get_nsString().BeginReading());
@@ -327,33 +327,33 @@ JSObject_to_PObjectWrapperParent(JSConte
     *to = owp;
     return true;
 }
 
 /*static*/ bool
 ObjectWrapperParent::
 JSObject_from_PObjectWrapperParent(JSContext* cx,
                                    const PObjectWrapperParent* from,
-                                   JS::MutableHandleObject to)
+                                   MutableHandleObject to)
 {
     const ObjectWrapperParent* owp =
         static_cast<const ObjectWrapperParent*>(from);
     to.set(owp
            ? owp->GetJSObject(cx)
            : JSVAL_TO_OBJECT(JSVAL_NULL));
     return true;
 }
 
 /*static*/ bool
 ObjectWrapperParent::
 jsval_from_PObjectWrapperParent(JSContext* cx,
                                 const PObjectWrapperParent* from,
                                 jsval* to)
 {
-    JS::RootedObject obj(cx);
+    Rooted<JSObject*> obj(cx);
     if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
         return false;
     *to = OBJECT_TO_JSVAL(obj);
     return true;
 }
     
 static bool
 jsid_from_int(JSContext* cx, int from, jsid* to)
@@ -525,17 +525,17 @@ ObjectWrapperParent::NewEnumerateNext(JS
 
     if (CallNewEnumerateNext(in_state,
                              aco.StatusPtr(), &out_state, &out_id) &&
         aco.Ok() &&
         jsval_from_JSVariant(cx, out_state, statep) &&
         jsid_from_nsString(cx, out_id, idp))
     {
         JSObject* obj = GetJSObject(cx);
-        JS::Rooted<AutoResolveFlag> arf(cx, obj);
+        AutoResolveFlag arf(cx, obj);
         return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
                                      JSPROP_ENUMERATE);
     }
     return JS_FALSE;
 }
 
 JSBool
 ObjectWrapperParent::NewEnumerateDestroy(JSContext* cx, jsval state)
@@ -573,17 +573,17 @@ ObjectWrapperParent::CPOW_NewEnumerate(J
     }
 
     NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
     return JS_FALSE;
 }
 
 /*static*/ JSBool
 ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                     unsigned flags, JS::MutableHandleObject objp)
+                                     unsigned flags, MutableHandleObject objp)
 {
     CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
               JSVAL_TO_CSTR(cx, id)));
 
     ObjectWrapperParent* self = Unwrap(cx, obj);
     if (!self)
         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
 
@@ -599,18 +599,18 @@ ObjectWrapperParent::CPOW_NewResolve(JSC
     if (!self->Manager()->RequestRunToCompletion() ||
         !self->CallNewResolve(in_id, flags,
                               aco.StatusPtr(), &out_pobj) ||
         !aco.Ok() ||
         !JSObject_from_PObjectWrapperParent(cx, out_pobj, objp))
         return JS_FALSE;
 
     if (objp) {
-        JS::Rooted<AutoResolveFlag> arf(cx, objp.get());
-        JS::RootedObject obj2(cx, objp);
+        AutoResolveFlag arf(cx, objp.get());
+        Rooted<JSObject*> obj2(cx, objp);
         JS_DefinePropertyById(cx, obj2, id, JSVAL_VOID, NULL, NULL,
                               JSPROP_ENUMERATE);
     }
     return JS_TRUE;
 }
 
 /*static*/ JSBool
 ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSHandleObject obj, JSType type,
@@ -642,17 +642,17 @@ ObjectWrapperParent::CPOW_Finalize(js::F
     }
 }
 
 /*static*/ JSBool
 ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp)
 {
     CPOW_LOG(("Calling CPOW_Call..."));
 
-    JS::RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
+    Rooted<JSObject*> thisobj(cx, JS_THIS_OBJECT(cx, vp));
     if (!thisobj)
         return JS_FALSE;
 
     ObjectWrapperParent* function =
         Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
     if (!function)
         return with_error(cx, JS_FALSE, "Could not unwrap CPOW function");
 
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -179,40 +179,16 @@ ifdef ENABLE_TRACE_LOGGING
 
 ###############################################
 # BEGIN include sources for trace logging
 #
 CPPSRCS += 	TraceLogging.cpp
 
 endif
 
-ifdef ENABLE_METHODJIT
-
-###############################################
-# BEGIN include sources for the method JIT
-#
-VPATH += 	$(srcdir)/methodjit
-
-CPPSRCS += 	MethodJIT.cpp \
-		StubCalls.cpp \
-		Compiler.cpp \
-		FrameState.cpp \
-		FastArithmetic.cpp \
-		FastBuiltins.cpp \
-		FastOps.cpp \
-		LoopState.cpp \
-		StubCompiler.cpp \
-		MonoIC.cpp \
-		PolyIC.cpp \
-		ImmutableSync.cpp \
-		InvokeHelpers.cpp \
-		Retcon.cpp \
-		TrampolineCompiler.cpp \
-		$(NULL)
-
 # Ion
 ifdef ENABLE_ION
 VPATH +=	$(srcdir)/ion
 VPATH +=	$(srcdir)/ion/shared
 
 CPPSRCS +=	MIR.cpp \
 		BytecodeAnalysis.cpp \
 		BaselineCompiler.cpp \
@@ -331,27 +307,16 @@ CPPSRCS +=	Lowering-arm.cpp \
 		Architecture-arm.cpp \
 		MacroAssembler-arm.cpp \
 		BaselineCompiler-arm.cpp \
 		BaselineIC-arm.cpp \
 		$(NULL)
 endif #ENABLE_ION
 endif
 endif #ENABLE_ION
-ifeq (sparc, $(findstring sparc,$(TARGET_CPU)))
-ASFILES +=	TrampolineSparc.s
-endif
-ifeq (mips, $(findstring mips,$(TARGET_CPU)))
-CPPSRCS +=	TrampolineMIPS.cpp
-endif
-#
-# END enclude sources for the method JIT
-#############################################
-
-endif
 
 ###############################################
 # BEGIN include sources for the Nitro assembler
 #
 
 VPATH += 	$(srcdir)/assembler \
 		$(srcdir)/assembler/wtf \
 		$(srcdir)/assembler/jit \
@@ -361,39 +326,34 @@ VPATH += 	$(srcdir)/assembler \
 CPPSRCS += 	ExecutableAllocator.cpp \
 		PageBlock.cpp \
 		YarrInterpreter.cpp \
 		YarrPattern.cpp \
 		YarrSyntaxChecker.cpp \
 		YarrCanonicalizeUCS2.cpp \
 		$(NONE)
 
-ifdef ENABLE_METHODJIT_SPEW
-CPPSRCS += Logging.cpp
-endif
-
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 CPPSRCS += ExecutableAllocatorPosix.cpp \
            OSAllocatorPosix.cpp \
            $(NONE)
 endif
 ifeq ($(OS_ARCH),WINNT)
 CPPSRCS += ExecutableAllocatorWin.cpp \
            OSAllocatorWin.cpp \
            $(NONE)
 endif
 ifeq ($(OS_ARCH),OS2)
 CPPSRCS += ExecutableAllocatorOS2.cpp \
            OSAllocatorOS2.cpp \
            $(NONE)
 endif
 
-ifneq (,$(ENABLE_METHODJIT)$(ENABLE_ION)$(ENABLE_YARR_JIT))
+ifneq (,$(ENABLE_ION)$(ENABLE_YARR_JIT))
 VPATH += 	$(srcdir)/assembler/assembler \
-		$(srcdir)/methodjit \
 		$(NONE)
 
 CPPSRCS +=	ARMAssembler.cpp \
 		MacroAssemblerARM.cpp \
 		MacroAssemblerX86Common.cpp \
 		$(NONE)
 
 ifdef ENABLE_YARR_JIT
@@ -995,39 +955,17 @@ selfhosted.out.h: $(selfhosted_out_h_dep
 # BEGIN kludges for the Nitro assembler
 #
 
 # Needed to "configure" it correctly.  Unfortunately these
 # flags wind up being applied to all code in js/src, not just
 # the code in js/src/assembler.
 CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1
 
-ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_METHODJIT))
+ifneq (,$(ENABLE_YARR_JIT))
 CXXFLAGS +=  -DENABLE_JIT=1
 endif
 
 INCLUDES +=	-I$(srcdir)/assembler -I$(srcdir)/yarr
 
-ifdef ENABLE_METHODJIT
-# Build a standalone test program that exercises the assembler
-# sources a bit.
-TESTMAIN_OBJS = \
-		Assertions.$(OBJ_SUFFIX) \
-		ExecutableAllocator.$(OBJ_SUFFIX) \
-		ARMAssembler.$(OBJ_SUFFIX) \
-		MacroAssemblerARM.$(OBJ_SUFFIX) \
-		TestMain.$(OBJ_SUFFIX) \
-		jsutil.$(OBJ_SUFFIX) \
-		jslog2.$(OBJ_SUFFIX)
-
-ifeq ($(OS_ARCH),WINNT)
-TESTMAIN_OBJS += ExecutableAllocatorWin.$(OBJ_SUFFIX)
-else
-TESTMAIN_OBJS += ExecutableAllocatorPosix.$(OBJ_SUFFIX)
-endif
-
-TestMain$(HOST_BIN_SUFFIX): $(TESTMAIN_OBJS)
-	$(CXX) -o TestMain$(HOST_BIN_SUFFIX) $(TESTMAIN_OBJS)
-endif
-
 #
 # END kludges for the Nitro assembler
 ###############################################
--- a/js/src/assembler/assembler/AssemblerBuffer.h
+++ b/js/src/assembler/assembler/AssemblerBuffer.h
@@ -40,17 +40,16 @@
 #include "assembler/wtf/Assertions.h"
 
 #include <stdarg.h>
 #include "jsfriendapi.h"
 #include "jsopcode.h"
 
 #include "ion/IonSpewer.h"
 #include "js/RootingAPI.h"
-#include "methodjit/Logging.h"
 
 #define PRETTY_PRINT_OFFSET(os) (((os)<0)?"-":""), (((os)<0)?-(os):(os))
 
 #define FIXME_INSN_PRINTING                                 \
     do {                                                    \
         spew("FIXME insn printing %s:%d",                   \
              __FILE__, __LINE__);                           \
     } while (0)
@@ -281,18 +280,17 @@ namespace JSC {
             printer = sp;
         }
 
         void spew(const char *fmt, ...)
 #ifdef __GNUC__
             __attribute__ ((format (printf, 2, 3)))
 #endif
         {
-            if (printer ||
-                js::IsJaegerSpewChannelActive(js::JSpew_Insns)
+            if (printer
 #ifdef JS_ION
                 || js::ion::IonSpewEnabled(js::ion::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];
@@ -301,56 +299,41 @@ namespace JSC {
                 va_start(va, fmt);
                 int i = vsnprintf(buf, sizeof(buf), fmt, va);
                 va_end(va);
 
                 if (i > -1) {
                     if (printer)
                         printer->printf("%s\n", buf);
 
-                    // The assembler doesn't know which compiler it is for, so if
-                    // both JM and Ion spew are on, just print via one channel
-                    // (Use JM to pick up isOOLPath).
-                    if (js::IsJaegerSpewChannelActive(js::JSpew_Insns))
-                        js::JaegerSpew(js::JSpew_Insns, "%s       %s\n", isOOLPath ? ">" : " ", buf);
 #ifdef JS_ION
-                    else
-                        js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
+                    js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
 #endif
                 }
             }
         }
 
         static void staticSpew(const char *fmt, ...)
 #ifdef __GNUC__
             __attribute__ ((format (printf, 1, 2)))
 #endif
         {
-            if (js::IsJaegerSpewChannelActive(js::JSpew_Insns)
 #ifdef JS_ION
-                || js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
-#endif
-                )
-            {
+            if (js::ion::IonSpewEnabled(js::ion::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) {
-                    if (js::IsJaegerSpewChannelActive(js::JSpew_Insns))
-                        js::JaegerSpew(js::JSpew_Insns, "        %s\n", buf);
-#ifdef JS_ION
-                    else
-                        js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
+                if (i > -1)
+                    js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
+            }
 #endif
-                }
-            }
         }
     };
 
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
 
 #endif // AssemblerBuffer_h
--- a/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h
+++ b/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h
@@ -34,17 +34,16 @@
 #include "assembler/wtf/Platform.h"
 
 #if ENABLE_ASSEMBLER
 
 #include "AssemblerBuffer.h"
 #include "assembler/wtf/SegmentedVector.h"
 #include "assembler/wtf/Assertions.h"
 
-#include "methodjit/Logging.h"
 #include "jsnum.h"
 #define ASSEMBLER_HAS_CONSTANT_POOL 1
 
 namespace JSC {
 
 /*
     On a constant pool 4 or 8 bytes data can be stored. The values can be
     constants or addresses. The addresses should be 32 or 64 bits. The constants
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -11,17 +11,16 @@
 #include "jsfriendapi.h"
 #include "jsgc.h"
 #include "jsobj.h"
 #include "jsobjinlines.h"
 #include "jsprf.h"
 #include "jswrapper.h"
 
 #include "builtin/TestingFunctions.h"
-#include "methodjit/MethodJIT.h"
 #include "vm/ForkJoin.h"
 
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace JS;
 
 using mozilla::ArrayLength;
@@ -165,24 +164,16 @@ GetBuildConfiguration(JSContext *cx, uns
 #ifdef JS_OOM_DO_BACKTRACES
     value = BooleanValue(true);
 #else
     value = BooleanValue(false);
 #endif
     if (!JS_SetProperty(cx, info, "oom-backtraces", &value))
         return false;
 
-#ifdef JS_METHODJIT
-    value = BooleanValue(true);
-#else
-    value = BooleanValue(false);
-#endif
-    if (!JS_SetProperty(cx, info, "methodjit", &value))
-        return false;
-
 #ifdef ENABLE_PARALLEL_JS
     value = BooleanValue(true);
 #else
     value = BooleanValue(false);
 #endif
     if (!JS_SetProperty(cx, info, "parallelJS", &value))
         return false;
 
@@ -811,55 +802,16 @@ DumpHeapComplete(JSContext *cx, unsigned
     js::DumpHeapComplete(JS_GetRuntime(cx), dumpFile);
 
     fclose(dumpFile);
 
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
-JSBool
-MJitChunkLimit(JSContext *cx, unsigned argc, jsval *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (argc != 1) {
-        RootedObject callee(cx, &args.callee());
-        ReportUsageError(cx, callee, "Wrong number of arguments");
-        return JS_FALSE;
-    }
-
-    if (cx->runtime->alwaysPreserveCode) {
-        JS_ReportError(cx, "Can't change chunk limit after gcPreserveCode()");
-        return JS_FALSE;
-    }
-
-    for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) {
-        if (c->lastAnimationTime != 0) {
-            JS_ReportError(cx, "Can't change chunk limit if code may be preserved");
-            return JS_FALSE;
-        }
-    }
-
-    double t;
-    if (!JS_ValueToNumber(cx, args[0], &t))
-        return JS_FALSE;
-
-#ifdef JS_METHODJIT
-    mjit::SetChunkLimit((uint32_t) t);
-#endif
-
-    // Clear out analysis information which might refer to code compiled with
-    // the previous chunk limit.
-    JS_GC(cx->runtime);
-
-    vp->setUndefined();
-    return true;
-}
-
 static JSBool
 Terminate(JSContext *cx, unsigned arg, jsval *vp)
 {
     JS_ClearPendingException(cx);
     return JS_FALSE;
 }
 
 static JSBool
@@ -1051,20 +1003,16 @@ static JSFunctionSpecWithHelp TestingFun
     JS_FN_HELP("isProxy", IsProxy, 1, 0,
 "isProxy(obj)",
 "  If true, obj is a proxy of some sort"),
 
     JS_FN_HELP("dumpHeapComplete", DumpHeapComplete, 1, 0,
 "dumpHeapComplete([filename])",
 "  Dump reachable and unreachable objects to a file."),
 
-    JS_FN_HELP("mjitChunkLimit", MJitChunkLimit, 1, 0,
-"mjitChunkLimit(N)",
-"  Specify limit on compiled chunk size during mjit compilation."),
-
     JS_FN_HELP("terminate", Terminate, 0, 0,
 "terminate()",
 "  Terminate JavaScript execution, as if we had run out of\n"
 "  memory or been terminated by the slow script dialog."),
 
     JS_FN_HELP("enableSPSProfilingAssertions", EnableSPSProfilingAssertions, 1, 0,
 "enableSPSProfilingAssertions(slow)",
 "  Enables SPS instrumentation and corresponding assertions. If 'slow' is\n"
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -479,32 +479,17 @@ case "$target" in
 
         CXX_VERSION=`"${CXX}" -v 2>&1 | sed -nre "$_MSVC_VER_FILTER"`
         _CXX_MAJOR_VERSION=`echo ${CXX_VERSION} | $AWK -F\. '{ print $1 }'`
 
         if test "$_CC_MAJOR_VERSION" != "$_CXX_MAJOR_VERSION"; then
             AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
         fi
 
-        if test "$_CC_MAJOR_VERSION" = "14"; then
-            dnl Require VC8SP1 or newer.
-            dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762.
-            if test "$_CC_RELEASE" -lt 50727 -o \
-                    \( "$_CC_RELEASE" -eq 50727 -a "$_CC_BUILD" -lt 762 \); then
-              AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. You probably need to install Service Pack 1 of Visual Studio 2005. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
-            fi
-
-            _CC_SUITE=8
-            AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
-            AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
-        elif test "$_CC_MAJOR_VERSION" = "15"; then
-            _CC_SUITE=9
-            AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
-            AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
-        elif test "$_CC_MAJOR_VERSION" = "16"; then
+        if test "$_CC_MAJOR_VERSION" = "16"; then
             _CC_SUITE=10
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
             AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
         elif test "$_CC_MAJOR_VERSION" = "17"; then
             _CC_SUITE=11
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
             AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
         else
@@ -2163,33 +2148,16 @@ mips*-*)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 esac
 
 MOZ_ARG_DISABLE_BOOL(ion,
 [  --disable-ion      Disable use of the IonMonkey JIT],
   ENABLE_ION= )
 
-MOZ_ARG_DISABLE_BOOL(methodjit,
-[  --disable-methodjit           Disable method JIT support],
-  ENABLE_METHODJIT= )
-
-MOZ_ARG_DISABLE_BOOL(monoic,
-[  --disable-monoic      Disable use of MICs by JIT compiler],
-  ENABLE_MONOIC= )
-
-MOZ_ARG_DISABLE_BOOL(polyic,
-[  --disable-polyic      Disable use of PICs by JIT compiler],
-  ENABLE_POLYIC= )
-
-MOZ_ARG_ENABLE_BOOL(methodjit-spew,
-[  --enable-methodjit-spew      Enable method JIT spew support],
-  ENABLE_METHODJIT_SPEW=1,
-  ENABLE_METHODJIT_SPEW= )
-
 MOZ_ARG_DISABLE_BOOL(yarr-jit,
 [  --disable-yarr-jit    Disable YARR JIT support],
   ENABLE_YARR_JIT= )
 
 AC_SUBST(ENABLE_METHODJIT)
 AC_SUBST(ENABLE_METHODJIT_SPEW)
 
 if test "$ENABLE_METHODJIT"; then
--- a/js/src/devtools/rootAnalysis/annotations.js
+++ b/js/src/devtools/rootAnalysis/annotations.js
@@ -58,16 +58,17 @@ var ignoreCallees = {
     "JSRuntime.destroyPrincipals" : true,
     "nsISupports.AddRef" : true,
     "nsISupports.Release" : true, // makes me a bit nervous; this is a bug but can happen
     "nsAXPCNativeCallContext.GetJSContext" : true,
     "js::ion::MDefinition.op" : true, // macro generated virtuals just return a constant
     "js::ion::MDefinition.opName" : true, // macro generated virtuals just return a constant
     "js::ion::LInstruction.getDef" : true, // virtual but no implementation can GC
     "js::ion::IonCache.kind" : true, // macro generated virtuals just return a constant
+    "icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC
 };
 
 function fieldCallCannotGC(csu, fullfield)
 {
     if (csu in ignoreClasses)
         return true;
     if (fullfield in ignoreCallees)
         return true;
@@ -128,17 +129,18 @@ function ignoreGCFunction(fun)
         return true;
     return false;
 }
 
 function isRootedTypeName(name)
 {
     if (name == "mozilla::ErrorResult" ||
         name == "js::frontend::TokenStream" ||
-        name == "js::frontend::TokenStream::Position")
+        name == "js::frontend::TokenStream::Position" ||
+        name == "ModuleCompiler")
     {
         return true;
     }
     return false;
 }
 
 function isRootedPointerTypeName(name)
 {
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -431,17 +431,17 @@ class StrictModeGetter {
 // However, they will be ignored unless |lookahead == 0| holds.
 // Due to constraints of the grammar, this turns out not to be a problem in
 // practice. See the mozilla.dev.tech.js-engine.internals thread entitled 'Bug
 // in the scanner?' for more details (https://groups.google.com/forum/?
 // fromgroups=#!topic/mozilla.dev.tech.js-engine.internals/2JLH5jRcr7E).
 //
 // The methods seek() and tell() allow to rescan from a previous visited
 // location of the buffer.
-class TokenStream
+class MOZ_STACK_CLASS TokenStream
 {
     /* Unicode separators that are treated as line terminators, in addition to \n, \r */
     enum {
         LINE_SEPARATOR = 0x2028,
         PARA_SEPARATOR = 0x2029
     };
 
     static const size_t ntokens = 4;                /* 1 current + 2 lookahead, rounded
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -6,17 +6,16 @@
 
 #include "mozilla/DebugOnly.h"
 
 #include "jsprf.h"
 #include "jsstr.h"
 
 #include "gc/Marking.h"
 #include "gc/Nursery-inl.h"
-#include "methodjit/MethodJIT.h"
 #include "vm/Shape.h"
 
 #include "jsobjinlines.h"
 
 #include "ion/IonCode.h"
 #include "vm/Shape-inl.h"
 #include "vm/String-inl.h"
 
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -764,22 +764,16 @@ js::gc::MarkRuntime(JSTracer *trc, bool 
                 c->watchpointMap->markAll(trc);
         }
 
         /* Mark debug scopes, if present */
         if (c->debugScopes)
             c->debugScopes->mark(trc);
     }
 
-#ifdef JS_METHODJIT
-    /* We need to expand inline frames before stack scanning. */
-    for (ZonesIter zone(rt); !zone.done(); zone.next())
-        mjit::ExpandInlineFrames(zone);
-#endif
-
     rt->stackSpace.mark(trc);
 
 #ifdef JS_ION
     ion::MarkIonActivations(rt, trc);
 #endif
 
     for (CompartmentsIter c(rt); !c.done(); c.next())
         c->mark(trc);
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -61,23 +61,16 @@ Zone::init(JSContext *cx)
 {
     types.init(cx);
     return true;
 }
 
 void
 Zone::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon)
 {
-#ifdef JS_METHODJIT
-    /* ClearAllFrames calls compileBarriers() and needs the old value. */
-    bool old = compileBarriers();
-    if (compileBarriers(needs) != old)
-        mjit::ClearAllFrames(this);
-#endif
-
 #ifdef JS_ION
     if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
         ion::ToggleBarriers(this, needs);
         ionUsingBarriers_ = needs;
     }
 #endif
 
     needsBarrier_ = needs;
@@ -151,72 +144,55 @@ Zone::sweep(FreeOp *fop, bool releaseTyp
     }
 
     active = false;
 }
 
 void
 Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
 {
-#ifdef JS_METHODJIT
-    /*
-     * Kick all frames on the stack into the interpreter, and release all JIT
-     * code in the compartment unless code is being preserved, in which case
-     * purge all caches in the JIT scripts. Even if we are not releasing all
-     * JIT code, we still need to release code for scripts which are in the
-     * middle of a native or getter stub call, as these stubs will have been
-     * redirected to the interpoline.
-     */
-    mjit::ClearAllFrames(this);
-
+#ifdef JS_ION
     if (isPreservingCode()) {
         PurgeJITCaches(this);
     } else {
-# ifdef JS_ION
 
-#  ifdef DEBUG
+# ifdef DEBUG
         /* 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
+# endif
 
         /* Mark baseline scripts on the stack as active. */
         ion::MarkActiveBaselineScripts(this);
 
         /* Only mark OSI points if code is being discarded. */
         ion::InvalidateAll(fop, this);
-# endif
+
         for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
-
-            mjit::ReleaseScriptCode(fop, script);
-# ifdef JS_ION
             ion::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);
-# endif
 
             /*
              * 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();
         }
 
         for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) {
-#ifdef JS_ION
             /* Free optimized baseline stubs. */
             if (comp->ionCompartment())
                 comp->ionCompartment()->optimizedStubSpace()->free();
-#endif
 
             comp->types.sweepCompilerOutputs(fop, discardConstraints);
         }
     }
-#endif /* JS_METHODJIT */
+#endif
 }
--- a/js/src/ion/AsmJS.cpp
+++ b/js/src/ion/AsmJS.cpp
@@ -889,17 +889,26 @@ typedef Vector<MBasicBlock*,16> CaseVect
 //      bar(1)|0;    // Exit #3: (int) -> int
 //      bar(2)|0;    // Exit #3: (int) -> int
 //    }
 //
 // The ModuleCompiler maintains a hash table (ExitMap) which allows a call site
 // to add a new exit or reuse an existing one. The key is an ExitDescriptor
 // (which holds the exit pairing) and the value is an index into the
 // Vector<Exit> stored in the AsmJSModule.
-class ModuleCompiler
+//
+// Rooting note: ModuleCompiler is a stack class that contains unrooted
+// PropertyName (JSAtom) pointers.  This is safe because it cannot be
+// constructed without a TokenStream reference.  TokenStream is itself a stack
+// class that cannot be constructed without an AutoKeepAtoms being live on the
+// stack, which prevents collection of atoms.
+//
+// ModuleCompiler is marked as rooted in the rooting analysis.  Don't add
+// non-JSAtom pointers, or this will break!
+class MOZ_STACK_CLASS ModuleCompiler
 {
   public:
     class Func
     {
         ParseNode *fn_;
         ParseNode *body_;
         MIRTypeVector argTypes_;
         RetType returnType_;
--- a/js/src/ion/AsmJSSignalHandlers.cpp
+++ b/js/src/ion/AsmJSSignalHandlers.cpp
@@ -895,38 +895,47 @@ HandleSignal(int signum, siginfo_t *info
         SetRegisterToCoercedUndefined(context, heapAccess->isFloat32Load(), heapAccess->loadedReg());
     *ppc += heapAccess->opLength();
     return true;
 #  else
     return false;
 #  endif
 }
 
-static struct sigaction sPrevHandler;
+static struct sigaction sPrevSegvHandler;
+static struct sigaction sPrevBusHandler;
 
 static void
 AsmJSFaultHandler(int signum, siginfo_t *info, void *context)
 {
     if (HandleSignal(signum, info, context))
         return;
 
     // This signal is not for any asm.js code we expect, so we need to forward
     // the signal to the next handler. If there is no next handler (SIG_IGN or
     // SIG_DFL), then it's time to crash. To do this, we set the signal back to
     // it's previous disposition and return. This will cause the faulting op to
     // be re-executed which will crash in the normal way. The advantage to
     // doing this is that we remove ourselves from the crash stack which
     // simplifies crash reports. Note: the order of these tests matter.
-    if (sPrevHandler.sa_flags & SA_SIGINFO) {
-        sPrevHandler.sa_sigaction(signum, info, context);
+    struct sigaction* prevHandler = NULL;
+    if (signum == SIGSEGV)
+        prevHandler = &sPrevSegvHandler;
+    else {
+	JS_ASSERT(signum == SIGBUS);
+        prevHandler = &sPrevBusHandler;
+    }
+
+    if (prevHandler->sa_flags & SA_SIGINFO) {
+        prevHandler->sa_sigaction(signum, info, context);
         exit(signum);  // backstop
-    } else if (sPrevHandler.sa_handler == SIG_DFL || sPrevHandler.sa_handler == SIG_IGN) {
-        sigaction(signum, &sPrevHandler, NULL);
+    } else if (prevHandler->sa_handler == SIG_DFL || prevHandler->sa_handler == SIG_IGN) {
+        sigaction(signum, prevHandler, NULL);
     } else {
-        sPrevHandler.sa_handler(signum);
+        prevHandler->sa_handler(signum);
         exit(signum);  // backstop
     }
 }
 # endif
 #endif // JS_ASMJS
 
 bool
 EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
@@ -945,19 +954,19 @@ EnsureAsmJSSignalHandlersInstalled(JSRun
 #  if defined(XP_WIN)
     if (!AddVectoredExceptionHandler(/* FirstHandler = */true, AsmJSExceptionHandler))
         return false;
 #  else  // assume Unix
     struct sigaction sigAction;
     sigAction.sa_sigaction = &AsmJSFaultHandler;
     sigemptyset(&sigAction.sa_mask);
     sigAction.sa_flags = SA_SIGINFO;
-    if (sigaction(SIGSEGV, &sigAction, &sPrevHandler))
+    if (sigaction(SIGSEGV, &sigAction, &sPrevSegvHandler))
         return false;
-    if (sigaction(SIGBUS, &sigAction, &sPrevHandler))
+    if (sigaction(SIGBUS, &sigAction, &sPrevBusHandler))
         return false;
 #  endif
 
     lock.setHandlersInstalled();
 # endif
 #endif
     return true;
 }
@@ -989,8 +998,19 @@ js::TriggerOperationCallbackForAsmJSCode
     if (!VirtualProtect(module.functionCode(), module.functionBytes(), PAGE_NOACCESS, &oldProtect))
         MOZ_CRASH();
 # else  // assume Unix
     if (mprotect(module.functionCode(), module.functionBytes(), PROT_NONE))
         MOZ_CRASH();
 # endif
 #endif
 }
+
+#ifdef MOZ_ASAN
+// When running with asm.js under AddressSanitizer, we need to explicitely
+// tell AddressSanitizer to allow custom signal handlers because it will 
+// otherwise trigger ASan's SIGSEGV handler for the internal SIGSEGVs that 
+// asm.js would otherwise handle.
+extern "C" MOZ_ASAN_BLACKLIST
+const char* __asan_default_options() {
+    return "allow_user_segv_handler=1";
+}
+#endif
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -567,21 +567,16 @@ ion::CachedShapeGuardFailure()
 {
     JSContext *cx = GetIonContext()->cx;
     JSScript *script = GetBailedJSScript(cx);
 
     JS_ASSERT(!script->ionScript()->invalidated());
 
     script->failedShapeGuard = true;
 
-    // Purge JM caches in the script and all inlined script, to avoid baking in
-    // the same shape guard next time.
-    for (size_t i = 0; i < script->ionScript()->scriptEntries(); i++)
-        mjit::PurgeCaches(script->ionScript()->getScript(i));
-
     IonSpew(IonSpew_Invalidate, "Invalidating due to shape guard failure");
 
     return Invalidate(cx, script);
 }
 
 uint32_t
 ion::ThunkToInterpreter(Value *vp)
 {
--- a/js/src/ion/BaselineCompiler.cpp
+++ b/js/src/ion/BaselineCompiler.cpp
@@ -185,33 +185,16 @@ BaselineCompiler::compile()
 
     // All SPS instrumentation is emitted toggled off.  Toggle them on if needed.
     if (cx->runtime->spsProfiler.enabled())
         baselineScript->toggleSPS(true);
 
     return Method_Compiled;
 }
 
-#ifdef DEBUG
-#define SPEW_OPCODE()                                                         \
-    JS_BEGIN_MACRO                                                            \
-        if (IsJaegerSpewChannelActive(JSpew_JSOps)) {                         \
-            Sprinter sprinter(cx);                                            \
-            sprinter.init();                                                  \
-            RootedScript script_(cx, script);                                 \
-            js_Disassemble1(cx, script_, pc, pc - script_->code,              \
-                            JS_TRUE, &sprinter);                              \
-            JaegerSpew(JSpew_JSOps, "    %2u %s",                             \
-                       (unsigned)frame.stackDepth(), sprinter.string());      \
-        }                                                                     \
-    JS_END_MACRO;
-#else
-#define SPEW_OPCODE()
-#endif /* DEBUG */
-
 bool
 BaselineCompiler::emitPrologue()
 {
     masm.push(BaselineFrameReg);
     masm.mov(BaselineStackReg, BaselineFrameReg);
 
     masm.subPtr(Imm32(BaselineFrame::Size()), BaselineStackReg);
     masm.checkStackAlignment();
@@ -534,17 +517,16 @@ MethodStatus
 BaselineCompiler::emitBody()
 {
     JS_ASSERT(pc == script->code);
 
     bool lastOpUnreachable = false;
     uint32_t emittedOps = 0;
 
     while (true) {
-        SPEW_OPCODE();
         JSOp op = JSOp(*pc);
         IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s",
                 int(pc - script->code), js_CodeName[op]);
 
         BytecodeInfo *info = analysis_.maybeInfo(pc);
 
         // Skip unreachable ops.
         if (!info) {
--- a/js/src/ion/BaselineIC.cpp
+++ b/js/src/ion/BaselineIC.cpp
@@ -7173,18 +7173,33 @@ ICCallScriptedCompiler::generateStubCode
     masm.callIon(code);
 
     // If this is a constructing call, and the callee returns a non-object, replace it with
     // the |this| object passed in.
     if (isConstructing_) {
         Label skipThisReplace;
         masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
 
+        Register scratchReg = JSReturnOperand.scratchReg();
+
         // Current stack: [ ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
-        masm.loadValue(Address(BaselineStackReg, 3*sizeof(size_t)), JSReturnOperand);
+        // However, we can't use this ThisVal, because it hasn't been traced.  We need to use
+        // The ThisVal higher up the stack:
+        // Current stack: [ ThisVal, ARGVALS..., ...STUB FRAME...,
+        //                  ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
+        masm.loadPtr(Address(BaselineStackReg, 2*sizeof(size_t)), scratchReg);
+
+        // scratchReg now contains actualArgCount.  Double it to account for skipping past two
+        // pushed copies of argument values.  Additionally, we need to add:
+        // STUB_FRAME_SIZE + sizeof(ThisVal) + sizeof(size_t) + sizeof(void *) + sizoef(size_t)
+        // for: stub frame, this value, actual argc, callee, and descriptor
+        masm.lshiftPtr(Imm32(1), scratchReg);
+        BaseIndex reloadThisSlot(BaselineStackReg, scratchReg, TimesEight,
+                                 STUB_FRAME_SIZE + sizeof(Value) + 3*sizeof(size_t));
+        masm.loadValue(reloadThisSlot, JSReturnOperand);
 #ifdef DEBUG
         masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
         masm.breakpoint();
 #endif
         masm.bind(&skipThisReplace);
     }
 
     leaveStubFrame(masm, true);
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -40,17 +40,16 @@
 #endif
 #include "gc/Marking.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 #include "vm/Stack-inl.h"
 #include "ion/IonFrames-inl.h"
 #include "ion/CompilerRoot.h"
-#include "methodjit/Retcon.h"
 #include "ExecutionModeInlines.h"
 
 #if JS_TRACE_LOGGING
 #include "TraceLogging.h"
 #endif
 
 using namespace js;
 using namespace js::ion;
@@ -1289,20 +1288,17 @@ AttachFinishedCompilations(JSContext *cx
             {
                 // Release the worker thread lock and root the compiler for GC.
                 AutoTempAllocatorRooter root(cx, &builder->temp());
                 AutoUnlockWorkerThreadState unlock(cx->runtime);
                 AutoFlushCache afc("AttachFinishedCompilations");
                 success = codegen->link();
             }
 
-            if (success) {
-                if (script->hasIonScript())
-                    mjit::DisableScriptCodeForIon(script, script->ionScript()->osrPc());
-            } else {
+            if (!success) {
                 // Silently ignore OOM during code generation, we're at an
                 // operation callback and can't propagate failures.
                 cx->clearPendingException();
             }
         }
 
         FinishOffThreadBuilder(builder);
     }
@@ -1585,18 +1581,18 @@ Compile(JSContext *cx, HandleScript scri
     IonScript *scriptIon = GetIonScript(script, executionMode);
     if (scriptIon) {
         if (!scriptIon->method())
             return Method_CantCompile;
         return Method_Compiled;
     }
 
     if (executionMode == SequentialExecution) {
-        if (cx->methodJitEnabled || IsBaselineEnabled(cx)) {
-            // If JM is enabled we use getUseCount instead of incUseCount to avoid
+        if (IsBaselineEnabled(cx)) {
+            // If Baseline is enabled we use getUseCount instead of incUseCount to avoid
             // bumping the use count twice.
             if (script->getUseCount() < js_IonOptions.usesBeforeCompile)
                 return Method_Skipped;
         } else {
             if (script->incUseCount() < js_IonOptions.usesBeforeCompileNoJaeger)
                 return Method_Skipped;
         }
     }
@@ -2292,18 +2288,16 @@ ion::Invalidate(types::TypeCompartment &
     AutoFlushCache afc ("Invalidate");
 
     // Add an invalidation reference to all invalidated IonScripts to indicate
     // to the traversal which frames have been invalidated.
     bool anyInvalidation = false;
     for (size_t i = 0; i < invalid.length(); i++) {
         const types::CompilerOutput &co = *invalid[i].compilerOutput(types);
         switch (co.kind()) {
-          case types::CompilerOutput::MethodJIT:
-            break;
           case types::CompilerOutput::Ion:
           case types::CompilerOutput::ParallelIon:
             JS_ASSERT(co.isValid());
             IonSpew(IonSpew_Invalidate, " Invalidate %s:%u, IonScript %p",
                     co.script->filename(), co.script->lineno, co.ion());
 
             // Keep the ion script alive during the invalidation and flag this
             // ionScript as being invalidated.  This increment is removed by the
@@ -2323,18 +2317,16 @@ ion::Invalidate(types::TypeCompartment &
 
     // Drop the references added above. If a script was never active, its
     // IonScript will be immediately destroyed. Otherwise, it will be held live
     // until its last invalidated frame is destroyed.
     for (size_t i = 0; i < invalid.length(); i++) {
         types::CompilerOutput &co = *invalid[i].compilerOutput(types);
         ExecutionMode executionMode = SequentialExecution;
         switch (co.kind()) {
-          case types::CompilerOutput::MethodJIT:
-            continue;
           case types::CompilerOutput::Ion:
             break;
           case types::CompilerOutput::ParallelIon:
             executionMode = ParallelExecution;
             break;
         }
         JS_ASSERT(co.isValid());
         JSScript *script = co.script;
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -7475,23 +7475,18 @@ bool
 IonBuilder::getPropTryInlineAccess(bool *emitted, HandlePropertyName name, HandleId id,
                                    bool barrier, types::StackTypeSet *types)
 {
     JS_ASSERT(*emitted == false);
     if (current->peek(-1)->type() != MIRType_Object)
         return true;
 
     Vector<Shape *> shapes(cx);
-    if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) {
-        if (!shapes.append(objShape))
-            return false;
-    } else {
-        if (!inspector->maybeShapesForPropertyOp(pc, shapes))
-            return false;
-    }
+    if (!inspector->maybeShapesForPropertyOp(pc, shapes))
+        return false;
 
     if (shapes.empty() || !CanInlinePropertyOpShapes(shapes))
         return true;
 
     MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
     if (barrier || IsNullOrUndefined(rvalType))
         rvalType = MIRType_Value;
 
@@ -7677,23 +7672,18 @@ IonBuilder::jsop_setprop(HandlePropertyN
         current->add(fixed);
         current->push(value);
         if (propTypes->needsBarrier(cx))
             fixed->setNeedsBarrier();
         return resumeAfter(fixed);
     }
 
     Vector<Shape *> shapes(cx);
-    if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) {
-        if (!shapes.append(objShape))
-            return false;
-    } else {
-        if (!inspector->maybeShapesForPropertyOp(pc, shapes))
-            return false;
-    }
+    if (!inspector->maybeShapesForPropertyOp(pc, shapes))
+        return false;
 
     if (!shapes.empty() && CanInlinePropertyOpShapes(shapes)) {
         if (shapes.length() == 1) {
             spew("Inlining monomorphic SETPROP");
 
             // The JM IC was monomorphic, so we inline the property access as
             // long as the shape is not in dictionary mode. We cannot be sure
             // that the shape is still a lastProperty, and calling Shape::search
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -2381,29 +2381,32 @@ GetElementIC::update(JSContext *cx, size
             !cache.index().constant() &&
             (cache.index().reg().hasValue() ||
              cache.index().reg().type() == MIRType_Int32) &&
             (cache.output().hasValue() || !cache.output().typedReg().isFloat()))
         {
             if (!cache.attachArgumentsElement(cx, ion, obj))
                 return false;
             attachedStub = true;
-        } else if (obj->isNative() && cache.monitoredResult()) {
+        }
+        if (!attachedStub && obj->isNative() && cache.monitoredResult()) {
             uint32_t dummy;
             if (idval.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) {
                 RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
                 if (!cache.attachGetProp(cx, ion, obj, idval, name))
                     return false;
                 attachedStub = true;
             }
-        } else if (!cache.hasDenseStub() && obj->isNative() && idval.isInt32()) {
+        }
+        if (!attachedStub && !cache.hasDenseStub() && obj->isNative() && idval.isInt32()) {
             if (!cache.attachDenseElement(cx, ion, obj, idval))
                 return false;
             attachedStub = true;
-        } else if (obj->isTypedArray()) {
+        }
+        if (!attachedStub && obj->isTypedArray()) {
             if ((idval.isInt32()) ||
                 (idval.isString() && GetIndexFromString(idval.toString()) != UINT32_MAX))
             {
                 int arrayType = TypedArray::type(obj);
                 bool floatOutput = arrayType == TypedArray::TYPE_FLOAT32 ||
                                    arrayType == TypedArray::TYPE_FLOAT64;
                 if (!floatOutput || cache.output().hasValue()) {
                     if (!cache.attachTypedArrayElement(cx, ion, obj, idval))
--- a/js/src/ion/Lowering.cpp
+++ b/js/src/ion/Lowering.cpp
@@ -421,18 +421,16 @@ LIRGenerator::visitCall(MCall *call)
     return (assignSnapshot(lir) && defineReturn(lir, call) && assignSafepoint(lir, call));
 }
 
 bool
 LIRGenerator::visitApplyArgs(MApplyArgs *apply)
 {
     JS_ASSERT(apply->getFunction()->type() == MIRType_Object);
 
-    JSFunction *target = apply->getSingleTarget();
-
     // Assert if we cannot build a rectifier frame.
     JS_ASSERT(CallTempReg0 != ArgumentsRectifierReg);
     JS_ASSERT(CallTempReg1 != ArgumentsRectifierReg);
 
     // Assert if the return value is already erased.
     JS_ASSERT(CallTempReg2 != JSReturnReg_Type);
     JS_ASSERT(CallTempReg2 != JSReturnReg_Data);
 
@@ -442,17 +440,17 @@ LIRGenerator::visitApplyArgs(MApplyArgs 
         tempFixed(CallTempReg1),  // object register
         tempFixed(CallTempReg2)); // copy register
 
     MDefinition *self = apply->getThis();
     if (!useBoxFixed(lir, LApplyArgsGeneric::ThisIndex, self, CallTempReg4, CallTempReg5))
         return false;
 
     // Bailout is only needed in the case of possible non-JSFunction callee.
-    if (!target && !assignSnapshot(lir))
+    if (!apply->getSingleTarget() && !assignSnapshot(lir))
         return false;
 
     if (!defineReturn(lir, apply))
         return false;
     if (!assignSafepoint(lir, apply))
         return false;
     return true;
 }
--- a/js/src/ion/x64/MacroAssembler-x64.cpp
+++ b/js/src/ion/x64/MacroAssembler-x64.cpp
@@ -115,18 +115,17 @@ MacroAssemblerX64::callWithABIPre(uint32
         MoveEmitter emitter(*this);
         emitter.emit(moveResolver_);
         emitter.finish();
     }
 
 #ifdef DEBUG
     {
         Label good;
-        movl(rsp, rax);
-        testq(rax, Imm32(StackAlignment - 1));
+        testq(rsp, Imm32(StackAlignment - 1));
         j(Equal, &good);
         breakpoint();
         bind(&good);
     }
 #endif
 }
 
 void
--- a/js/src/ion/x86/MacroAssembler-x86.cpp
+++ b/js/src/ion/x86/MacroAssembler-x86.cpp
@@ -144,18 +144,17 @@ MacroAssemblerX86::callWithABIPre(uint32
         emitter.emit(moveResolver_);
         emitter.finish();
     }
 
 #ifdef DEBUG
     {
         // Check call alignment.
         Label good;
-        movl(esp, eax);
-        testl(eax, Imm32(StackAlignment - 1));
+        testl(esp, Imm32(StackAlignment - 1));
         j(Equal, &good);
         breakpoint();
         bind(&good);
     }
 #endif
 }
 
 void
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -137,31 +137,23 @@ def main(argv):
     if not options.run_slow:
         test_list = [ _ for _ in test_list if not _.slow ]
 
     # The full test list is ready. Now create copies for each JIT configuration.
     job_list = []
     if options.tbpl:
         # Running all bits would take forever. Instead, we test a few interesting combinations.
         flags = [
-                      ['--no-baseline', '--no-jm'],
                       ['--ion-eager'], # implies --baseline-eager
-                      ['--no-baseline'],
-                      ['--no-baseline', '--ion-eager'],
                       ['--baseline-eager'],
                       ['--baseline-eager', '--no-ti', '--no-fpu'],
-                      # Below, equivalents the old shell flags: ,m,am,amd,n,mn,amn,amdn,mdn
-                      ['--no-baseline', '--no-ion', '--no-jm', '--no-ti'],
+                      ['--no-baseline'],
+                      ['--no-baseline', '--ion-eager'],
+                      ['--no-baseline', '--no-ion'],
                       ['--no-baseline', '--no-ion', '--no-ti'],
-                      ['--no-baseline', '--no-ion', '--no-ti', '--always-mjit', '--debugjit'],
-                      ['--no-baseline', '--no-ion', '--no-jm'],
-                      ['--no-baseline', '--no-ion'],
-                      ['--no-baseline', '--no-ion', '--always-mjit'],
-                      ['--no-baseline', '--no-ion', '--always-mjit', '--debugjit'],
-                      ['--no-baseline', '--no-ion', '--debugjit']
                     ]
         for test in test_list:
             for variant in flags:
                 new_test = test.copy()
                 new_test.jitflags.extend(variant)
                 job_list.append(new_test)
     elif options.ion:
         flags = [['--no-jm'], ['--ion-eager']]
--- a/js/src/jit-test/tests/auto-regress/bug726799.js
+++ b/js/src/jit-test/tests/auto-regress/bug726799.js
@@ -1,16 +1,15 @@
 // Binary: cache/js-dbg-32-ebafee0cea36-linux
 // Flags: -m -n
 //
 function tryItOut(code) {
     f = eval("(function(){" + code + "})")
     for (e in f()) {}
 }
-mjitChunkLimit(25)
 tryItOut("\
     for each(x in[0,0,0,0,0,0,0]) {\
         function f(b) {\
             Object.defineProperty(b,\"\",({t:f}))\
         }\
         for each(d in[(1),String,String,String,String,(0),String,(1),String]) {\
             try{\
                 f(d);\
--- a/js/src/jit-test/tests/auto-regress/bug728509.js
+++ b/js/src/jit-test/tests/auto-regress/bug728509.js
@@ -5,10 +5,10 @@ function g(code) {
     try {
         f = eval("(function(){" + code + "})")
     } catch (r) {}
     f()
     try {
         evalcx("(function(){return" + code + "})()")
     } catch (e) {}
 }
-g("mjitChunkLimit(8)")
+g("")
 g(" function(x,[]){NaN.x::c}()")
--- a/js/src/jit-test/tests/auto-regress/bug740654.js
+++ b/js/src/jit-test/tests/auto-regress/bug740654.js
@@ -1,14 +1,13 @@
 // |jit-test| error:InternalError
 
 // Binary: cache/js-dbg-32-92fe907ddac8-linux
 // Flags: -m -n
 //
-mjitChunkLimit(31)
 o = {}
 o.valueOf = function() {
     for (var p in undefined) {
         a = new Function;
     }
     +o;
 };
 +o;
--- a/js/src/jit-test/tests/auto-regress/bug743876.js
+++ b/js/src/jit-test/tests/auto-regress/bug743876.js
@@ -1,16 +1,16 @@
 // Binary: cache/js-dbg-64-434f50e70815-linux
 // Flags: -m -n -a
 //
 
 var lfcode = new Array();
 lfcode.push("3");
 lfcode.push("\
-evaluate(\"mjitChunkLimit(5)\");\
+evaluate(\"\");\
 function slice(a, b) {\
     return slice(index, ++(ArrayBuffer));\
 }\
 ");
 lfcode.push("0");
 lfcode.push("var arr = [0, 1, 2, 3, 4];\
 function replacer() {\
   assertEq(arguments.length, 2);\
--- a/js/src/jit-test/tests/basic/testBug755916.js
+++ b/js/src/jit-test/tests/basic/testBug755916.js
@@ -3,11 +3,10 @@
 Object.defineProperty(this, "t2", {
     get: function() {
         for (p in h2) {
             t2
         }
     }
 })
 h2 = {}
-mjitChunkLimit(8)
 h2.a = function() {}
 Object(t2)
--- a/js/src/jit-test/tests/jaeger/bug719918.js
+++ b/js/src/jit-test/tests/jaeger/bug719918.js
@@ -2,18 +2,16 @@ function test(m) {
   do {
     if (m = arr[0]) break;
     m = 0;
   }
   while (0);
   arr[1] = m;
 }
 
-mjitChunkLimit(10);
-
 arr = new Float64Array(2);
 
 // run function a lot to trigger methodjit compile
 for(var i=0; i<200; i++)
   test(0);
 
 // should return 0, not NaN
 assertEq(arr[1], 0)
--- a/js/src/jit-test/tests/jaeger/bug781859-2.js
+++ b/js/src/jit-test/tests/jaeger/bug781859-2.js
@@ -1,9 +1,8 @@
-mjitChunkLimit(42);
 Function("\
     switch (/x/) {\
         case 8:\
         break;\
         t(function(){})\
     }\
     while (false)(function(){})\
 ")()
--- a/js/src/jit-test/tests/jaeger/bug781859-3.js
+++ b/js/src/jit-test/tests/jaeger/bug781859-3.js
@@ -1,9 +1,8 @@
-mjitChunkLimit(10);
 function e() {
     try {
         var t = undefined;
     } catch (e) { }
     while (t)
         continue;
 }
 for (var i = 0; i < 20; i++)
--- a/js/src/jit-test/tests/jaeger/chunk/bug712267.js
+++ b/js/src/jit-test/tests/jaeger/chunk/bug712267.js
@@ -1,10 +1,8 @@
-
-evaluate("mjitChunkLimit(5)");
 expected = 100;
 function slice(a, b) {
   return expected--;
 }
 function f() {
   var length = 8.724e02 ;
   var index = 0;
   function get3() {
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -591,35 +591,16 @@ ScriptAnalysis::analyzeBytecode(JSContex
 
     /*
      * Always ensure that a script's arguments usage has been analyzed before
      * entering the script. This allows the functionPrologue to ensure that
      * arguments are always created eagerly which simplifies interp logic.
      */
     if (!script_->analyzedArgsUsage())
         analyzeSSA(cx);
-
-    /*
-     * If the script has JIT information (we are reanalyzing the script after
-     * a purge), add safepoints for the targets of any cross chunk edges in
-     * the script. These safepoints are normally added when the JITScript is
-     * constructed, but will have been lost during the purge.
-     */
-#ifdef JS_METHODJIT
-    mjit::JITScript *jit = NULL;
-    for (int constructing = 0; constructing <= 1 && !jit; constructing++) {
-        for (int barriers = 0; barriers <= 1 && !jit; barriers++)
-            jit = script_->getJIT((bool) constructing, (bool) barriers);
-    }
-    if (jit) {
-        mjit::CrossChunkEdge *edges = jit->edges();
-        for (size_t i = 0; i < jit->nedges; i++)
-            getCode(edges[i].target).safePoint = true;
-    }
-#endif
 }
 
 /////////////////////////////////////////////////////////////////////
 // Lifetime Analysis
 /////////////////////////////////////////////////////////////////////
 
 void
 ScriptAnalysis::analyzeLifetimes(JSContext *cx)
@@ -885,17 +866,17 @@ ScriptAnalysis::analyzeLifetimes(JSConte
         offset--;
     }
 
     js_free(saved);
 
     ranLifetimes_ = true;
 }
 
-#ifdef JS_METHODJIT_SPEW
+#ifdef DEBUG
 void
 LifetimeVariable::print() const
 {
     Lifetime *segment = lifetime ? lifetime : saved;
     while (segment) {
         printf(" (%u,%u%s)", segment->start, segment->end, segment->loopTail ? ",tail" : "");
         segment = segment->next;
     }
@@ -1101,31 +1082,16 @@ ScriptAnalysis::ensureVariable(LifetimeV
         return;
     }
 
     JS_ASSERT(until < var.lifetime->start);
     var.lifetime->start = until;
     var.ensured = true;
 }
 
-void
-ScriptAnalysis::clearAllocations()
-{
-    /*
-     * Clear out storage used for register allocations in a compilation once
-     * that compilation has finished. Register allocations are only used for
-     * a single compilation.
-     */
-    for (unsigned i = 0; i < script_->length; i++) {
-        Bytecode *code = maybeCode(i);
-        if (code)
-            code->allocation = NULL;
-    }
-}
-
 /////////////////////////////////////////////////////////////////////
 // SSA Analysis
 /////////////////////////////////////////////////////////////////////
 
 void
 ScriptAnalysis::analyzeSSA(JSContext *cx)
 {
     JS_ASSERT(cx->compartment->activeAnalysis && !ranSSA() && !failed());
@@ -1836,23 +1802,19 @@ ScriptAnalysis::needsArgsObj(JSContext *
         return needsArgsObj(cx, seen, SSAValue::PhiValue(use->offset, use->u.phi));
 
     jsbytecode *pc = script_->code + use->offset;
     JSOp op = JSOp(*pc);
 
     if (op == JSOP_POP || op == JSOP_POPN)
         return false;
 
-    /* SplatApplyArgs can read fp->canonicalActualArg(i) directly. */
-    if (op == JSOP_FUNAPPLY && GET_ARGC(pc) == 2 && use->u.which == 0) {
-#ifdef JS_METHODJIT
-        JS_ASSERT(mjit::IsLowerableFunCallOrApply(pc));
-#endif
+    /* We can read the frame's arguments directly for f.apply(x, arguments). */
+    if (op == JSOP_FUNAPPLY && GET_ARGC(pc) == 2 && use->u.which == 0)
         return false;
-    }
 
     /* arguments[i] can read fp->canonicalActualArg(i) directly. */
     if (op == JSOP_GETELEM && use->u.which == 1)
         return false;
 
     /* arguments.length length can read fp->numActualArgs() directly. */
     if (op == JSOP_LENGTH)
         return false;
--- a/js/src/jsanalyze.h
+++ b/js/src/jsanalyze.h
@@ -20,19 +20,16 @@
 #include "jsopcodeinlines.h"
 
 #include "ds/LifoAlloc.h"
 #include "js/TemplateLib.h"
 #include "vm/ScopeObject.h"
 
 class JSScript;
 
-/* Forward declaration of downstream register allocations computed for join points. */
-namespace js { namespace mjit { struct RegisterAllocation; } }
-
 namespace js {
 namespace analyze {
 
 /*
  * There are three analyses we can perform on a JSScript, outlined below.
  * The results of all three are stored in ScriptAnalysis, but the analyses
  * themselves can be performed separately. Along with type inference results,
  * per-script analysis results are tied to the per-compartment analysis pool
@@ -120,21 +117,16 @@ class Bytecode
     /* Stack depth before this opcode. */
     uint32_t stackDepth;
 
   private:
 
     /* If this is a JSOP_LOOPHEAD or JSOP_LOOPENTRY, information about the loop. */
     LoopAnalysis *loop;
 
-    /* --------- Lifetime analysis --------- */
-
-    /* Any allocation computed downstream for this bytecode. */
-    mjit::RegisterAllocation *allocation;
-
     /* --------- SSA analysis --------- */
 
     /* Generated location of each value popped by this bytecode. */
     SSAValue *poppedValues;
 
     /* Points where values pushed or written by this bytecode are popped. */
     SSAUseChain **pushedUses;
 
@@ -508,17 +500,17 @@ struct LifetimeVariable
                     return UINT32_MAX;
                 offset = segment->start;
             }
             segment = segment->next;
         }
         return offset;
     }
 
-#ifdef JS_METHODJIT_SPEW
+#ifdef DEBUG
     void print() const;
 #endif
 };
 
 struct SSAPhiNode;
 
 /*
  * Representation of values on stack or in slots at each point in the script.
@@ -990,24 +982,16 @@ class ScriptAnalysis
         JS_ASSERT(trackUseChain(v));
         if (v.kind() == SSAValue::PUSHED)
             return getCode(v.pushedOffset()).pushedUses[v.pushedIndex()];
         if (v.kind() == SSAValue::VAR)
             return getCode(v.varOffset()).pushedUses[GetDefCount(script_, v.varOffset())];
         return v.phiNode()->uses;
     }
 
-    mjit::RegisterAllocation *&getAllocation(uint32_t offset) {
-        JS_ASSERT(offset < script_->length);
-        return getCode(offset).allocation;
-    }
-    mjit::RegisterAllocation *&getAllocation(const jsbytecode *pc) {
-        return getAllocation(pc - script_->code);
-    }
-
     LoopAnalysis *getLoop(uint32_t offset) {
         JS_ASSERT(offset < script_->length);
         return getCode(offset).loop;
     }
     LoopAnalysis *getLoop(const jsbytecode *pc) { return getLoop(pc - script_->code); }
 
     /* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
     jsbytecode *getCallPC(jsbytecode *pc)
@@ -1046,18 +1030,16 @@ class ScriptAnalysis
         JS_ASSERT(script_->compartment()->activeAnalysis);
         JS_ASSERT(!slotEscapes(slot));
         return lifetimes[slot];
     }
 
     void printSSA(JSContext *cx);
     void printTypes(JSContext *cx);
 
-    void clearAllocations();
-
   private:
     void setOOM(JSContext *cx) {
         if (!outOfMemory)
             js_ReportOutOfMemory(cx);
         outOfMemory = true;
         hadFailure = true;
     }
 
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -126,31 +126,27 @@ ThrowHook(JSContext *cx, JSScript *, jsb
     jsval _;
     JS_EvaluateScript(cx, global, text, strlen(text), "", 0, &_);
 
     return JSTRAP_CONTINUE;
 }
 
 BEGIN_TEST(testDebugger_throwHook)
 {
-    uint32_t newopts =
-        JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS;
-    uint32_t oldopts = JS_SetOptions(cx, newopts);
-
+    CHECK(JS_SetDebugMode(cx, true));
     CHECK(JS_SetThrowHook(rt, ThrowHook, NULL));
     EXEC("function foo() { throw 3 };\n"
          "for (var i = 0; i < 10; ++i) { \n"
          "  var x = {}\n"
          "  try {\n"
          "    foo(); \n"
          "  } catch(e) {}\n"
          "}\n");
     CHECK(called);
     CHECK(JS_SetThrowHook(rt, NULL, NULL));
-    JS_SetOptions(cx, oldopts);
     return true;
 }
 END_TEST(testDebugger_throwHook)
 
 BEGIN_TEST(testDebugger_debuggerObjectVsDebugMode)
 {
     CHECK(JS_DefineDebuggerObject(cx, global));
     JS::RootedObject debuggee(cx, JS_NewGlobalObject(cx, getGlobalClass(), NULL));
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -82,20 +82,19 @@
 #include "vm/ObjectImpl-inl.h"
 #include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 #include "vm/Shape-inl.h"
 #include "vm/String-inl.h"
 
 #if ENABLE_YARR_JIT
 #include "assembler/jit/ExecutableAllocator.h"
-#include "methodjit/Logging.h"
 #endif
 
-#ifdef JS_METHODJIT
+#ifdef JS_ION
 #include "ion/Ion.h"
 #endif
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
 using mozilla::Maybe;
@@ -687,17 +686,17 @@ JS::isGCEnabled()
 JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
 #endif
 
 static const JSSecurityCallbacks NullSecurityCallbacks = { };
 
 static bool
 JitSupportsFloatingPoint()
 {
-#if defined(JS_METHODJIT) || defined(JS_ION)
+#if defined(JS_ION)
     if (!JSC::MacroAssembler().supportsFloatingPoint())
         return false;
 
 #if defined(JS_ION) && WTF_ARM_ARCH_VERSION == 6
     if (!js::ion::hasVFP())
         return false;
 #endif
 
@@ -734,19 +733,16 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     defaultLocale(NULL),
 #ifdef JS_THREADSAFE
     ownerThread_(NULL),
 #endif
     tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     execAlloc_(NULL),
     bumpAlloc_(NULL),
-#ifdef JS_METHODJIT
-    jaegerRuntime_(NULL),
-#endif
     ionRuntime_(NULL),
     selfHostingGlobal_(NULL),
     nativeStackBase(0),
     nativeStackQuota(0),
     interpreterFrames(NULL),
     cxCallback(NULL),
     destroyCompartmentCallback(NULL),
     compartmentNameCallback(NULL),
@@ -922,20 +918,16 @@ JSRuntime::init(uint32_t maxbytes)
 
     operationCallbackLock = PR_NewLock();
     if (!operationCallbackLock)
         return false;
 #endif
 
     js::TlsPerThreadData.set(&mainThread);
 
-#ifdef JS_METHODJIT_SPEW
-    JMCheckLogging();
-#endif
-
     if (!js_InitGC(this, maxbytes))
         return false;
 
     if (!gcMarker.init())
         return false;
 
     const char *size = getenv("JSGC_MARK_STACK_LIMIT");
     if (size)
@@ -1045,23 +1037,20 @@ JSRuntime::~JSRuntime()
     js_FinishGC(this);
 #ifdef JS_THREADSAFE
     if (gcLock)
         PR_DestroyLock(gcLock);
 #endif
 
     js_delete(bumpAlloc_);
     js_delete(mathCache_);
-#ifdef JS_METHODJIT
-    js_delete(jaegerRuntime_);
-#endif
 #ifdef JS_ION
     js_delete(ionRuntime_);
 #endif
-    js_delete(execAlloc_);  /* Delete after jaegerRuntime_. */
+    js_delete(execAlloc_);  /* Delete after ionRuntime_. */
 
     if (ionPcScriptCache)
         js_delete(ionPcScriptCache);
 
 #ifdef JSGC_GENERATIONAL
     gcStoreBuffer.disable();
     gcNursery.disable();
 #endif
@@ -1161,17 +1150,17 @@ JS_NewRuntime(uint32_t maxbytes, JSUseHe
 
         js_NewRuntimeWasCalled = JS_TRUE;
     }
 
     JSRuntime *rt = js_new<JSRuntime>(useHelperThreads);
     if (!rt)
         return NULL;
 
-#if defined(JS_METHODJIT) && defined(JS_ION)
+#if defined(JS_ION)
     if (!ion::InitializeIon())
         return NULL;
 #endif
 
     if (!ForkJoinSlice::InitializeTLS())
         return NULL;
 
     if (!rt->init(maxbytes)) {
@@ -2238,16 +2227,24 @@ JS_PUBLIC_API(JSObject *)
 JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
     return forObj->global().getOrCreateFunctionPrototype(cx);
 }
 
 JS_PUBLIC_API(JSObject *)
+JS_GetArrayPrototype(JSContext *cx, JSObject *forObj)
+{
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, forObj);
+    return forObj->global().getOrCreateArrayPrototype(cx);
+}
+
+JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
 {
     AssertHeapIsIdle(cx);
     assertSameCompartment(cx, obj);
     return &obj->global();
 }
 
 extern JS_PUBLIC_API(JSBool)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2154,16 +2154,23 @@ JS_GetFunctionPrototype(JSContext *cx, J
 
 /*
  * Returns the original value of |Object.prototype| from the global object in
  * which |forObj| was created.
  */
 extern JS_PUBLIC_API(JSObject *)
 JS_GetObjectPrototype(JSContext *cx, JSObject *forObj);
 
+/*
+ * Returns the original value of |Array.prototype| from the global object in
+ * which |forObj| was created.
+ */
+extern JS_PUBLIC_API(JSObject *)
+JS_GetArrayPrototype(JSContext *cx, JSObject *forObj);
+
 extern JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
 JS_IsGlobalObject(JSObject *obj);
 
 /*
  * May return NULL, if |c| never had a global (e.g. the atoms compartment), or
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -19,18 +19,16 @@
 #include "jsfun.h"
 #include "jsinterp.h"
 #include "jsiter.h"
 #include "jsnum.h"
 #include "jsobj.h"
 #include "jstypes.h"
 #include "jsutil.h"
 #include "ds/Sort.h"
-#include "methodjit/MethodJIT.h"
-#include "methodjit/StubCalls-inl.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/ForkJoin.h"
 #include "vm/NumericConversions.h"
 #include "vm/Shape.h"
 #include "vm/StringBuffer.h"
 
 #include "jsatominlines.h"
 #include "jscntxtinlines.h"
@@ -2001,25 +1999,16 @@ js::ArrayShiftMoveElements(JSObject *obj
      * At this point the length and initialized length have already been
      * decremented and the result fetched, so just shift the array elements
      * themselves.
      */
     uint32_t initlen = obj->getDenseInitializedLength();
     obj->moveDenseElementsUnbarriered(0, 1, initlen);
 }
 
-#ifdef JS_METHODJIT
-void JS_FASTCALL
-mjit::stubs::ArrayShift(VMFrame &f)
-{
-    JSObject *obj = &f.regs.sp[-1].toObject();
-    ArrayShiftMoveElements(obj);
-}
-#endif /* JS_METHODJIT */
-
 /* ES5 15.4.4.9 */
 JSBool
 js::array_shift(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     /* Step 1. */
     RootedObject obj(cx, ToObject(cx, args.thisv()));
@@ -2432,17 +2421,17 @@ array_splice(JSContext *cx, unsigned arg
     if (!SetLengthProperty(cx, obj, finalLength))
         return false;
 
     /* Step 17. */
     args.rval().setObject(*arr);
     return true;
 }
 
-#ifdef JS_METHODJIT
+#ifdef JS_ION
 bool
 js::array_concat_dense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject result)
 {
     JS_ASSERT(result->isArray() && obj1->isArray() && obj2->isArray());
 
     uint32_t initlen1 = obj1->getDenseInitializedLength();
     JS_ASSERT(initlen1 == obj1->getArrayLength());
 
@@ -2455,32 +2444,20 @@ js::array_concat_dense(JSContext *cx, Ha
     if (!result->ensureElements(cx, len))
         return false;
 
     JS_ASSERT(!result->getDenseInitializedLength());
     result->setDenseInitializedLength(len);
 
     result->initDenseElements(0, obj1->getDenseElements(), initlen1);
     result->initDenseElements(initlen1, obj2->getDenseElements(), initlen2);
-
     result->setArrayLengthInt32(len);
     return true;
 }
-
-void JS_FASTCALL
-mjit::stubs::ArrayConcatTwoArrays(VMFrame &f)
-{
-    RootedObject result(f.cx, &f.regs.sp[-3].toObject());
-    RootedObject obj1(f.cx, &f.regs.sp[-2].toObject());
-    RootedObject obj2(f.cx, &f.regs.sp[-1].toObject());
-
-    if (!array_concat_dense(f.cx, obj1, obj2, result))
-        THROW();
-}
-#endif /* JS_METHODJIT */
+#endif /* JS_ION */
 
 /*
  * Python-esque sequence operations.
  */
 JSBool
 js::array_concat(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -2987,28 +2964,16 @@ js::NewDenseAllocatedArray(JSContext *cx
 
 JSObject * JS_FASTCALL
 js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, JSObject *proto /* = NULL */,
                              NewObjectKind newKind /* = GenericObject */)
 {
     return NewArray<false>(cx, length, proto, newKind);
 }
 
-#ifdef JS_METHODJIT
-JSObject * JS_FASTCALL
-mjit::stubs::NewDenseUnallocatedArray(VMFrame &f, uint32_t length)
-{
-    JSObject *obj = NewArray<false>(f.cx, length, (JSObject *)f.scratch);
-    if (!obj)
-        THROWV(NULL);
-
-    return obj;
-}
-#endif
-
 JSObject *
 js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset,
                         JSObject *proto /* = NULL */)
 {
     JS_ASSERT(!src->isIndexed());
 
     JSObject* obj = NewArray<true>(cx, length, proto);
     if (!obj)
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -39,19 +39,16 @@
 #include "jspubtd.h"
 #include "jsscript.h"
 #include "jsstr.h"
 #include "jsworkers.h"
 #ifdef JS_ION
 #include "ion/Ion.h"
 #endif
 
-#ifdef JS_METHODJIT
-# include "methodjit/MethodJIT.h"
-#endif
 #include "gc/Marking.h"
 #include "js/CharacterEncoding.h"
 #include "js/MemoryMetrics.h"
 #include "frontend/ParseMaps.h"
 #include "vm/Shape.h"
 #include "yarr/BumpPointerAllocator.h"
 
 #include "jscntxtinlines.h"
@@ -203,35 +200,16 @@ JSRuntime::createMathCache(JSContext *cx
         js_ReportOutOfMemory(cx);
         return NULL;
     }
 
     mathCache_ = newMathCache;
     return mathCache_;
 }
 
-#ifdef JS_METHODJIT
-mjit::JaegerRuntime *
-JSRuntime::createJaegerRuntime(JSContext *cx)
-{
-    JS_ASSERT(!jaegerRuntime_);
-    JS_ASSERT(cx->runtime == this);
-
-    mjit::JaegerRuntime *jr = js_new<mjit::JaegerRuntime>();
-    if (!jr || !jr->init(cx)) {
-        js_ReportOutOfMemory(cx);
-        js_delete(jr);
-        return NULL;
-    }
-
-    jaegerRuntime_ = jr;
-    return jaegerRuntime_;
-}
-#endif
-
 void
 JSCompartment::sweepCallsiteClones()
 {
     if (callsiteClones.initialized()) {
         for (CallsiteCloneTable::Enum e(callsiteClones); !e.empty(); e.popFront()) {
             CallsiteCloneKey key = e.front().key;
             JSFunction *fun = e.front().value;
             if (!IsScriptMarked(&key.script) || !IsObjectMarked(&fun))
@@ -1160,20 +1138,17 @@ JSContext::JSContext(JSRuntime *rt)
     operationCallback(NULL),
     data(NULL),
     data2(NULL),
 #ifdef JS_THREADSAFE
     outstandingRequests(0),
 #endif
     resolveFlags(0),
     iterValue(MagicValue(JS_NO_ITER_VALUE)),
-#ifdef JS_METHODJIT
-    methodJitEnabled(false),
     jitIsBroken(false),
-#endif
 #ifdef MOZ_TRACE_JSCALLS
     functionCallback(NULL),
 #endif
     innermostGenerator_(NULL),
 #ifdef DEBUG
     stackIterAssertionEnabled(true),
 #endif
     activeCompilations(0)
@@ -1387,17 +1362,16 @@ void
 JSContext::purge()
 {
     if (!activeCompilations) {
         js_delete(parseMapPool_);
         parseMapPool_ = NULL;
     }
 }
 
-#if defined(JS_METHODJIT)
 static bool
 ComputeIsJITBroken()
 {
 #if !defined(ANDROID) || defined(GONK)
     return false;
 #else  // ANDROID
     if (getenv("JS_IGNORE_JIT_BROKENNESS")) {
         return false;
@@ -1458,25 +1432,21 @@ IsJITBrokenHere()
     static bool computedIsBroken = false;
     static bool isBroken = false;
     if (!computedIsBroken) {
         isBroken = ComputeIsJITBroken();
         computedIsBroken = true;
     }
     return isBroken;
 }
-#endif
 
 void
 JSContext::updateJITEnabled()
 {
-#ifdef JS_METHODJIT
     jitIsBroken = IsJITBrokenHere();
-    methodJitEnabled = (options_ & JSOPTION_METHODJIT) && !jitIsBroken;
-#endif
 }
 
 size_t
 JSContext::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const
 {
     /*
      * There are other JSContext members that could be measured; the following
      * ones have been found by DMD to be worth measuring.  More stuff may be
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -119,20 +119,16 @@ class AutoCycleDetector
 
     bool foundCycle() { return cyclic; }
 };
 
 /* Updates references in the cycle detection set if the GC moves them. */
 extern void
 TraceCycleDetectionSet(JSTracer *trc, ObjectSet &set);
 
-namespace mjit {
-class JaegerRuntime;
-}
-
 class MathCache;
 
 namespace ion {
 class IonRuntime;
 class IonActivation;
 }
 
 class WeakMapBase;
@@ -742,54 +738,38 @@ struct JSRuntime : public JS::shadow::Ru
 
   private:
     /*
      * Both of these allocators are used for regular expression code which is shared at the
      * thread-data level.
      */
     JSC::ExecutableAllocator *execAlloc_;
     WTF::BumpPointerAllocator *bumpAlloc_;
-#ifdef JS_METHODJIT
-    js::mjit::JaegerRuntime *jaegerRuntime_;
-#endif
     js::ion::IonRuntime *ionRuntime_;
 
     JSObject *selfHostingGlobal_;
 
     JSC::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
     WTF::BumpPointerAllocator *createBumpPointerAllocator(JSContext *cx);
-    js::mjit::JaegerRuntime *createJaegerRuntime(JSContext *cx);
     js::ion::IonRuntime *createIonRuntime(JSContext *cx);
 
   public:
     JSC::ExecutableAllocator *getExecAlloc(JSContext *cx) {
         return execAlloc_ ? execAlloc_ : createExecutableAllocator(cx);
     }
     JSC::ExecutableAllocator &execAlloc() {
         JS_ASSERT(execAlloc_);
         return *execAlloc_;
     }
     JSC::ExecutableAllocator *maybeExecAlloc() {
         return execAlloc_;
     }
     WTF::BumpPointerAllocator *getBumpPointerAllocator(JSContext *cx) {
         return bumpAlloc_ ? bumpAlloc_ : createBumpPointerAllocator(cx);
     }
-#ifdef JS_METHODJIT
-    js::mjit::JaegerRuntime *getJaegerRuntime(JSContext *cx) {
-        return jaegerRuntime_ ? jaegerRuntime_ : createJaegerRuntime(cx);
-    }
-    bool hasJaegerRuntime() const {
-        return jaegerRuntime_;
-    }
-    js::mjit::JaegerRuntime &jaegerRuntime() {
-        JS_ASSERT(hasJaegerRuntime());
-        return *jaegerRuntime_;
-    }
-#endif
     js::ion::IonRuntime *getIonRuntime(JSContext *cx) {
         return ionRuntime_ ? ionRuntime_ : createIonRuntime(cx);
     }
     js::ion::IonRuntime *ionRuntime() {
         return ionRuntime_;
     }
     bool hasIonRuntime() const {
         return !!ionRuntime_;
@@ -1739,25 +1719,19 @@ struct JSContext : js::ContextFriendFiel
 #endif
 
     /* Stored here to avoid passing it around as a parameter. */
     unsigned               resolveFlags;
 
     /* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
     js::Value           iterValue;
 
-#ifdef JS_METHODJIT
-    bool methodJitEnabled;
     bool jitIsBroken;
 
-    js::mjit::JaegerRuntime &jaegerRuntime() { return runtime->jaegerRuntime(); }
-#endif
-
     inline bool typeInferenceEnabled() const;
-    inline bool jaegerCompilationAllowed() const;
 
     void updateJITEnabled();
 
 #ifdef MOZ_TRACE_JSCALLS
     /* Function entry/exit debugging callback. */
     JSFunctionCallback    functionCallback;
 
     void doFunctionCallback(const JSFunction *fun,
@@ -2152,26 +2126,16 @@ static MOZ_ALWAYS_INLINE bool
 JS_CHECK_OPERATION_LIMIT(JSContext *cx)
 {
     JS_ASSERT_REQUEST_DEPTH(cx);
     return !cx->runtime->interrupt || js_InvokeOperationCallback(cx);
 }
 
 namespace js {
 
-#ifdef JS_METHODJIT
-namespace mjit {
-void ExpandInlineFrames(JS::Zone *zone);
-}
-#endif
-
-} /* namespace js */
-
-namespace js {
-
 /************************************************************************/
 
 static JS_ALWAYS_INLINE void
 MakeRangeGCSafe(Value *vec, size_t len)
 {
     mozilla::PodZero(vec, len);
 }
 
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -655,26 +655,18 @@ JSCompartment::setDebugModeFromC(JSConte
 void
 JSCompartment::updateForDebugMode(FreeOp *fop, AutoDebugModeGC &dmgc)
 {
     for (ContextIter acx(rt); !acx.done(); acx.next()) {
         if (acx->compartment == this)
             acx->updateJITEnabled();
     }
 
-#ifdef JS_METHODJIT
-    bool enabled = debugMode();
-
-    JS_ASSERT_IF(enabled, !hasScriptsOnStack());
-
-    for (gc::CellIter i(zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
-        JSScript *script = i.get<JSScript>();
-        if (script->compartment() == this)
-            script->debugMode = enabled;
-    }
+#ifdef JS_ION
+    JS_ASSERT_IF(debugMode(), !hasScriptsOnStack());
 
     // When we change a compartment's debug mode, whether we're turning it
     // on or off, we must always throw away all analyses: debug mode
     // affects various aspects of the analysis, which then get baked into
     // SSA results, which affects code generation in complicated ways. We
     // must also throw away all JIT code, as its soundness depends on the
     // analyses.
     //
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -406,22 +406,16 @@ class js::AutoDebugModeGC
 };
 
 inline bool
 JSContext::typeInferenceEnabled() const
 {
     return compartment->zone()->types.inferenceEnabled;
 }
 
-inline bool
-JSContext::jaegerCompilationAllowed() const
-{
-    return compartment->zone()->types.jaegerCompilationAllowed;
-}
-
 inline js::Handle<js::GlobalObject*>
 JSContext::global() const
 {
     /*
      * It's safe to use |unsafeGet()| here because any compartment that is
      * on-stack will be marked automatically, so there's no need for a read
      * barrier on it. Once the compartment is popped, the handle is no longer
      * safe to use.
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -28,20 +28,16 @@
 #include "builtin/Eval.h"
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/TokenStream.h"
 #include "gc/Marking.h"
 #include "vm/Shape.h"
 #include "vm/StringBuffer.h"
 #include "vm/Xdr.h"
 
-#ifdef JS_METHODJIT
-#include "methodjit/MethodJIT.h"
-#endif
-
 #include "jsfuninlines.h"
 #include "jsinferinlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Stack-inl.h"
 
@@ -128,38 +124,16 @@ fun_getProperty(JSContext *cx, HandleObj
         JSScript *script = iter.script();
         ion::ForbidCompilation(cx, script);
 #endif
 
         vp.setObject(*argsobj);
         return true;
     }
 
-#ifdef JS_METHODJIT
-    StackFrame *fp = NULL;
-    if (!iter.isIon())
-        fp = iter.interpFrame();
-
-    if (JSID_IS_ATOM(id, cx->names().caller) && fp && fp->prev()) {
-        /*
-         * If the frame was called from within an inlined frame, mark the
-         * innermost function as uninlineable to expand its frame and allow us
-         * to recover its callee object.
-         */
-        InlinedSite *inlined;
-        jsbytecode *prevpc = fp->prevpc(&inlined);
-        if (inlined) {
-            mjit::JITChunk *chunk = fp->prev()->jit()->chunk(prevpc);
-            JSFunction *fun = chunk->inlineFrames()[inlined->inlineIndex].fun;
-            fun->nonLazyScript()->uninlineable = true;
-            MarkTypeObjectFlags(cx, fun, OBJECT_FLAG_UNINLINEABLE);
-        }
-    }
-#endif
-
     if (JSID_IS_ATOM(id, cx->names().caller)) {
         ++iter;
         if (iter.done() || !iter.isFunctionFrame()) {
             JS_ASSERT(vp.isNull());
             return true;
         }
 
         /* Callsite clones should never escape to script. */
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -53,17 +53,16 @@
 #include "jsscript.h"
 #include "jswatchpoint.h"
 #include "jsweakmap.h"
 
 #include "gc/FindSCCs.h"
 #include "gc/GCInternals.h"
 #include "gc/Marking.h"
 #include "gc/Memory.h"
-#include "methodjit/MethodJIT.h"
 #include "vm/Debugger.h"
 #include "vm/Shape.h"
 #include "vm/String.h"
 #include "vm/ForkJoin.h"
 #include "ion/IonCode.h"
 #ifdef JS_ION
 # include "ion/BaselineJIT.h"
 #endif
@@ -854,22 +853,16 @@ js::SetGCZeal(JSRuntime *rt, uint8_t zea
 {
     if (zeal == 0) {
         if (rt->gcVerifyPreData)
             VerifyBarriers(rt, PreBarrierVerifier);
         if (rt->gcVerifyPostData)
             VerifyBarriers(rt, PostBarrierVerifier);
     }
 
-#ifdef JS_METHODJIT
-    /* In case Zone::compileBarriers() changed... */
-    for (ZonesIter zone(rt); !zone.done(); zone.next())
-        mjit::ClearAllFrames(zone);
-#endif
-
     bool schedule = zeal >= js::gc::ZealAllocValue;
     rt->gcZeal_ = zeal;
     rt->gcZealFrequency = frequency;
     rt->gcNextScheduled = schedule ? frequency : 0;
 }
 
 static bool
 InitGCZeal(JSRuntime *rt)
@@ -4829,47 +4822,41 @@ void PreventGCDuringInteractiveDebug()
     TlsPerThreadData.get()->suppressGC++;
 }
 
 #endif
 
 void
 js::ReleaseAllJITCode(FreeOp *fop)
 {
-#ifdef JS_METHODJIT
+#ifdef JS_ION
     for (ZonesIter zone(fop->runtime()); !zone.done(); zone.next()) {
-        mjit::ClearAllFrames(zone);
-# ifdef JS_ION
-
-#  ifdef DEBUG
+
+# ifdef DEBUG
         /* Assert no baseline scripts are marked as active. */
         for (CellIter i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
             JS_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
         }
-#  endif
+# endif
 
         /* Mark baseline scripts on the stack as active. */
         ion::MarkActiveBaselineScripts(zone);
 
         ion::InvalidateAll(fop, zone);
-# endif
 
         for (CellIter i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
-            mjit::ReleaseScriptCode(fop, script);
-# ifdef JS_ION
             ion::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);
-# endif
         }
     }
 #endif
 }
 
 /*
  * There are three possible PCCount profiling states:
  *
@@ -4967,29 +4954,22 @@ js::PurgePCCounts(JSContext *cx)
     JS_ASSERT(!rt->profilingScripts);
 
     ReleaseScriptCounts(rt->defaultFreeOp());
 }
 
 void
 js::PurgeJITCaches(Zone *zone)
 {
-#ifdef JS_METHODJIT
-    mjit::ClearAllFrames(zone);
-
+#ifdef JS_ION
     for (CellIterUnderGC i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
 
-        /* Discard JM caches. */
-        mjit::PurgeCaches(script);
-
-#ifdef JS_ION
         /* Discard Ion caches. */
         ion::PurgeCaches(script, zone);
-#endif
     }
 #endif
 }
 
 
 void
 ArenaLists::adoptArenas(JSRuntime *rt, ArenaLists *fromArenaLists)
 {
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -21,18 +21,16 @@
 
 #ifdef JS_ION
 #include "ion/BaselineJIT.h"
 #include "ion/Ion.h"
 #include "ion/IonCompartment.h"
 #endif
 #include "gc/Marking.h"
 #include "js/MemoryMetrics.h"
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Retcon.h"
 #include "vm/Shape.h"
 
 #include "jsatominlines.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
@@ -2338,42 +2336,16 @@ enum RecompileKind {
  * compilation.
  */
 static inline bool
 JITCodeHasCheck(JSScript *script, jsbytecode *pc, RecompileKind kind)
 {
     if (kind == RECOMPILE_NONE)
         return false;
 
-#ifdef JS_METHODJIT
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            mjit::JITScript *jit = script->getJIT((bool) constructing, (bool) barriers);
-            if (!jit)
-                continue;
-            mjit::JITChunk *chunk = jit->chunk(pc);
-            if (!chunk)
-                continue;
-            bool found = false;
-            uint32_t count = (kind == RECOMPILE_CHECK_MONITORED)
-                             ? chunk->nMonitoredBytecodes
-                             : chunk->nTypeBarrierBytecodes;
-            uint32_t *bytecodes = (kind == RECOMPILE_CHECK_MONITORED)
-                                  ? chunk->monitoredBytecodes()
-                                  : chunk->typeBarrierBytecodes();
-            for (size_t i = 0; i < count; i++) {
-                if (bytecodes[i] == uint32_t(pc - script->code))
-                    found = true;
-            }
-            if (!found)
-                return false;
-        }
-    }
-#endif
-
     if (script->hasAnyIonScript() || script->isIonCompilingOffThread())
         return false;
 
     return true;
 }
 
 /*
  * Force recompilation of any jitcode for script at pc, or of any other script
@@ -2399,18 +2371,16 @@ AddPendingRecompile(JSContext *cx, JSScr
     if (info.outputIndex != RecompileInfo::NoCompilerRunning) {
         CompilerOutput *co = info.compilerOutput(cx);
         if (!co) {
             if (script->compartment() != cx->compartment)
                 MOZ_CRASH();
             return;
         }
         switch (co->kind()) {
-          case CompilerOutput::MethodJIT:
-            break;
           case CompilerOutput::Ion:
           case CompilerOutput::ParallelIon:
             if (co->script == script)
                 co->invalidate();
             break;
         }
     }
 
@@ -2813,29 +2783,20 @@ TypeCompartment::processPendingRecompile
         return;
 
     /* Steal the list of scripts to recompile, else we will try to recursively recompile them. */
     Vector<RecompileInfo> *pending = pendingRecompiles;
     pendingRecompiles = NULL;
 
     JS_ASSERT(!pending->empty());
 
-#ifdef JS_METHODJIT
-
-    mjit::ExpandInlineFrames(compartment()->zone());
-
+#ifdef JS_ION
     for (unsigned i = 0; i < pending->length(); i++) {
         CompilerOutput &co = *(*pending)[i].compilerOutput(*this);
         switch (co.kind()) {
-          case CompilerOutput::MethodJIT:
-            JS_ASSERT(co.isValid());
-            mjit::Recompiler::clearStackReferences(fop, co.script);
-            co.mjit()->destroyChunk(fop, co.chunkIndex);
-            JS_ASSERT(co.script == NULL);
-            break;
           case CompilerOutput::Ion:
           case CompilerOutput::ParallelIon:
 # ifdef JS_THREADSAFE
             /*
              * If we are inside transitive compilation, which is a worklist
              * fixpoint algorithm, we need to be re-add invalidated scripts to
              * the worklist.
              */
@@ -2843,20 +2804,18 @@ TypeCompartment::processPendingRecompile
                 transitiveCompilationWorklist->insert(transitiveCompilationWorklist->begin(),
                                                       co.script);
             }
 # endif
             break;
         }
     }
 
-# ifdef JS_ION
     ion::Invalidate(*this, fop, *pending);
-# endif
-#endif /* JS_METHODJIT */
+#endif /* JS_ION */
 
     fop->delete_(pending);
 }
 
 void
 TypeCompartment::setPendingNukeTypes(JSContext *cx)
 {
     TypeZone *zone = &compartment()->zone()->types;
@@ -2893,33 +2852,26 @@ TypeZone::nukeTypes(FreeOp *fop)
         if (comp->types.pendingRecompiles) {
             fop->free_(comp->types.pendingRecompiles);
             comp->types.pendingRecompiles = NULL;
         }
     }
 
     inferenceEnabled = false;
 
-#ifdef JS_METHODJIT
-    mjit::ExpandInlineFrames(zone());
-    mjit::ClearAllFrames(zone());
-# ifdef JS_ION
+#ifdef JS_ION
     ion::InvalidateAll(fop, zone());
-# endif
 
     /* Throw away all JIT code in the compartment, but leave everything else alone. */
 
     for (gc::CellIter i(zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
-        mjit::ReleaseScriptCode(fop, script);
-# ifdef JS_ION
         ion::FinishInvalidation(fop, script);
-# endif
-    }
-#endif /* JS_METHODJIT */
+    }
+#endif /* JS_ION */
 
     pendingNukeTypes = false;
 }
 
 void
 TypeCompartment::addPendingRecompile(JSContext *cx, const RecompileInfo &info)
 {
     CompilerOutput *co = info.compilerOutput(cx);
@@ -2932,25 +2884,18 @@ TypeCompartment::addPendingRecompile(JSC
     if (co->isValid())
         CancelOffThreadIonCompile(cx->compartment, co->script);
 
     if (!co->isValid()) {
         JS_ASSERT(co->script == NULL);
         return;
     }
 
-#ifdef JS_METHODJIT
-    mjit::JITScript *jit = co->script->getJIT(co->constructing, co->barriers);
-    bool hasJITCode = jit && jit->chunkDescriptor(co->chunkIndex).chunk;
-
-# if defined(JS_ION)
-    hasJITCode |= !!co->script->hasAnyIonScript();
-# endif
-
-    if (!hasJITCode) {
+#if defined(JS_ION)
+    if (!co->script->hasAnyIonScript()) {
         /* Scripts which haven't been compiled yet don't need to be recompiled. */
         return;
     }
 #endif
 
     if (!pendingRecompiles) {
         pendingRecompiles = cx->new_< Vector<RecompileInfo> >(cx);
         if (!pendingRecompiles) {
@@ -2976,51 +2921,28 @@ TypeCompartment::addPendingRecompile(JSC
 
 void
 TypeCompartment::addPendingRecompile(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(script);
     if (!constrainedOutputs)
         return;
 
-#ifdef JS_METHODJIT
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            mjit::JITScript *jit = script->getJIT((bool) constructing, (bool) barriers);
-            if (!jit)
-                continue;
-
-            if (pc) {
-                unsigned int chunkIndex = jit->chunkIndex(pc);
-                mjit::JITChunk *chunk = jit->chunkDescriptor(chunkIndex).chunk;
-                if (chunk)
-                    addPendingRecompile(cx, chunk->recompileInfo);
-            } else {
-                for (size_t chunkIndex = 0; chunkIndex < jit->nchunks; chunkIndex++) {
-                    mjit::JITChunk *chunk = jit->chunkDescriptor(chunkIndex).chunk;
-                    if (chunk)
-                        addPendingRecompile(cx, chunk->recompileInfo);
-                }
-            }
-        }
-    }
-
-# ifdef JS_ION
+#ifdef JS_ION
     CancelOffThreadIonCompile(cx->compartment, script);
 
     // Let the script warm up again before attempting another compile.
     if (ion::IsBaselineEnabled(cx))
         script->resetUseCount();
 
     if (script->hasIonScript())
         addPendingRecompile(cx, script->ionScript()->recompileInfo());
 
     if (script->hasParallelIonScript())
         addPendingRecompile(cx, script->parallelIonScript()->recompileInfo());
-# endif
 #endif
 }
 
 void
 TypeCompartment::monitorBytecode(JSContext *cx, JSScript *script, uint32_t offset,
                                  bool returnOnly)
 {
     if (!script->ensureRanInference(cx))
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -96,20 +96,16 @@ class RootedBase<TaggedProto> : public T
     friend class TaggedProtoOperations<Rooted<TaggedProto> >;
     const TaggedProto *extract() const {
         return static_cast<const Rooted<TaggedProto> *>(this)->address();
     }
 };
 
 class CallObject;
 
-namespace mjit {
-    struct JITScript;
-}
-
 namespace ion {
     struct IonScript;
 }
 
 namespace types {
 
 /* Type set entry for either a JSObject with singleton type or a non-singleton TypeObject. */
 struct TypeObjectKey {
@@ -1275,17 +1271,16 @@ typedef HashMap<AllocationSiteKey,ReadBa
  * Information about the result of the compilation of a script.  This structure
  * stored in the TypeCompartment is indexed by the RecompileInfo. This
  * indirection enable the invalidation of all constraints related to the same
  * compilation. The compiler output is build by the AutoEnterCompilation.
  */
 struct CompilerOutput
 {
     enum Kind {
-        MethodJIT,
         Ion,
         ParallelIon
     };
 
     JSScript *script;
 
     // This integer will always be a member of CompilerOutput::Kind,
     // but, for portability, bitfields are limited to bool, int, and
@@ -1296,17 +1291,16 @@ struct CompilerOutput
     bool pendingRecompilation : 1;
     uint32_t chunkIndex:27;
 
     CompilerOutput();
 
     Kind kind() const { return static_cast<Kind>(kindInt); }
     void setKind(Kind k) { kindInt = k; }
 
-    mjit::JITScript *mjit() const;
     ion::IonScript *ion() const;
 
     bool isValid() const;
 
     void setPendingRecompilation() {
         pendingRecompilation = true;
     }
     void invalidate() {
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -86,73 +86,48 @@ namespace types {
 
 /////////////////////////////////////////////////////////////////////
 // CompilerOutput & RecompileInfo
 /////////////////////////////////////////////////////////////////////
 
 inline
 CompilerOutput::CompilerOutput()
   : script(NULL),
-    kindInt(MethodJIT),
+    kindInt(Ion),
     constructing(false),
     barriers(false),
     chunkIndex(false)
 {
 }
 
-inline mjit::JITScript *
-CompilerOutput::mjit() const
-{
-#ifdef JS_METHODJIT
-    JS_ASSERT(kind() == MethodJIT && isValid());
-    return script->getJIT(constructing, barriers);
-#else
-    return NULL;
-#endif
-}
-
 inline ion::IonScript *
 CompilerOutput::ion() const
 {
 #ifdef JS_ION
-    JS_ASSERT(kind() != MethodJIT && isValid());
+    JS_ASSERT(isValid());
     switch (kind()) {
-      case MethodJIT: break;
       case Ion: return script->ionScript();
       case ParallelIon: return script->parallelIonScript();
     }
 #endif
     JS_NOT_REACHED("Invalid kind of CompilerOutput");
     return NULL;
 }
 
 inline bool
 CompilerOutput::isValid() const
 {
     if (!script)
         return false;
 
-#if defined(DEBUG) && (defined(JS_METHODJIT) || defined(JS_ION))
+#if defined(DEBUG) && defined(JS_ION)
     TypeCompartment &types = script->compartment()->types;
 #endif
 
     switch (kind()) {
-      case MethodJIT: {
-#ifdef JS_METHODJIT
-        mjit::JITScript *jit = script->getJIT(constructing, barriers);
-        if (!jit)
-            return false;
-        mjit::JITChunk *chunk = jit->chunkDescriptor(chunkIndex).chunk;
-        if (!chunk)
-            return false;
-        JS_ASSERT(this == chunk->recompileInfo.compilerOutput(types));
-        return true;
-#endif
-      }
-
       case Ion:
 #ifdef JS_ION
         if (script->hasIonScript()) {
             JS_ASSERT(this == script->ionScript()->recompileInfo().compilerOutput(types));
             return true;
         }
         if (script->isIonCompilingOffThread())
             return true;
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -33,20 +33,16 @@
 #include "jspropertycache.h"
 #include "jsscript.h"
 #include "jsstr.h"
 
 #include "builtin/Eval.h"
 #include "vm/Debugger.h"
 #include "vm/Shape.h"
 
-#ifdef JS_METHODJIT
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Logging.h"
-#endif
 #include "ion/Ion.h"
 #include "ion/BaselineJIT.h"
 
 #ifdef JS_ION
 #include "ion/IonFrames-inl.h"
 #endif
 
 #include "jsatominlines.h"
@@ -293,19 +289,16 @@ js::ValueToCallable(JSContext *cx, const
 bool
 js::RunScript(JSContext *cx, StackFrame *fp)
 {
     JS_ASSERT(fp == cx->fp());
     RootedScript script(cx, fp->script());
 
     JS_ASSERT_IF(!fp->isGeneratorFrame(), cx->regs().pc == script->code);
     JS_ASSERT_IF(fp->isEvalFrame(), script->isActiveEval);
-#ifdef JS_METHODJIT_SPEW
-    JMCheckLogging();
-#endif
 
     JS_CHECK_RECURSION(cx, return false);
 
     // Check to see if useNewType flag should be set for this frame.
     if (fp->isFunctionFrame() && fp->isConstructing() && !fp->isGeneratorFrame() &&
         cx->typeInferenceEnabled())
     {
         ScriptFrameIter iter(cx);
@@ -364,27 +357,16 @@ js::RunScript(JSContext *cx, StackFrame 
             // from baseline.
             JS_ASSERT(status != ion::IonExec_Bailout);
 
             return !IsErrorStatus(status);
         }
     }
 #endif
 
-#ifdef JS_METHODJIT
-    mjit::CompileStatus status;
-    status = mjit::CanMethodJIT(cx, script, script->code, fp->isConstructing(),
-                                mjit::CompileRequest_Interpreter, fp);
-    if (status == mjit::Compile_Error)
-        return false;
-
-    if (status == mjit::Compile_Okay)
-        return mjit::JaegerStatusToSuccess(mjit::JaegerShot(cx, false));
-#endif
-
     return Interpret(cx, fp) != Interpret_Error;
 }
 
 /*
  * Find a function reference and its 'this' value implicit first parameter
  * under argc arguments on cx's stack, and call the function.  Push missing
  * required arguments, allocate declared local variables, and pop everything
  * when done.  Then push the return value.
@@ -1077,35 +1059,16 @@ js::Interpret(JSContext *cx, StackFrame 
 # define END_CASE_LEN12     len = 12; goto advance_pc;
 # define END_VARLEN_CASE    goto advance_pc;
 # define ADD_EMPTY_CASE(OP) BEGIN_CASE(OP)
 # define END_EMPTY_CASES    goto advance_pc_by_one;
 
 #define LOAD_DOUBLE(PCOFF, dbl)                                               \
     (dbl = script->getConst(GET_UINT32_INDEX(regs.pc + (PCOFF))).toDouble())
 
-#ifdef JS_METHODJIT
-
-#define CHECK_PARTIAL_METHODJIT(status)                                       \
-    JS_BEGIN_MACRO                                                            \
-        switch (status) {                                                     \
-          case mjit::Jaeger_UnfinishedAtTrap:                                 \
-            interpMode = JSINTERP_SKIP_TRAP;                                  \
-            /* FALLTHROUGH */                                                 \
-          case mjit::Jaeger_Unfinished:                                       \
-            op = (JSOp) *regs.pc;                                             \
-            SET_SCRIPT(regs.fp()->script());                                  \
-            if (cx->isExceptionPending())                                     \
-                goto error;                                                   \
-            DO_OP();                                                          \
-          default:;                                                           \
-        }                                                                     \
-    JS_END_MACRO
-#endif
-
     /*
      * Prepare to call a user-supplied branch handler, and abort the script
      * if it returns false.
      */
 #define CHECK_BRANCH()                                                        \
     JS_BEGIN_MACRO                                                            \
         if (cx->runtime->interrupt && !js_HandleExecutionInterrupt(cx))       \
             goto error;                                                       \
@@ -1379,45 +1342,16 @@ BEGIN_CASE(JSOP_LOOPHEAD)
 END_CASE(JSOP_LOOPHEAD)
 
 BEGIN_CASE(JSOP_LABEL)
 END_CASE(JSOP_LABEL)
 
 check_backedge:
 {
     CHECK_BRANCH();
-    if (op != JSOP_LOOPHEAD)
-        DO_OP();
-
-#ifdef JS_METHODJIT
-    // Attempt on-stack replacement with JaegerMonkey code, which is keyed to
-    // the interpreter state at the JSOP_LOOPHEAD at the start of the loop.
-    // Unlike IonMonkey, this requires two different code fragments to perform
-    // hoisting.
-    mjit::CompileStatus status =
-        mjit::CanMethodJIT(cx, script, regs.pc, regs.fp()->isConstructing(),
-                           mjit::CompileRequest_Interpreter, regs.fp());
-    if (status == mjit::Compile_Error)
-        goto error;
-    if (status == mjit::Compile_Okay) {
-        void *ncode =
-            script->nativeCodeForPC(regs.fp()->isConstructing(), regs.pc);
-        JS_ASSERT(ncode);
-        mjit::JaegerStatus status = mjit::JaegerShotAtSafePoint(cx, ncode, true);
-        if (status == mjit::Jaeger_ThrowBeforeEnter)
-            goto error;
-        CHECK_PARTIAL_METHODJIT(status);
-        interpReturnOK = (status == mjit::Jaeger_Returned);
-        if (entryFrame != regs.fp())
-            goto jit_return;
-        regs.fp()->setFinishedInInterpreter();
-        goto leave_on_safe_point;
-    }
-#endif /* JS_METHODJIT */
-
     DO_OP();
 }
 
 BEGIN_CASE(JSOP_LOOPENTRY)
 
 #ifdef JS_ION
     // Attempt on-stack replacement with Ion code. IonMonkey OSR takes place at
     // the point of the initial loop entry, to consolidate hoisted code between
@@ -1551,37 +1485,30 @@ BEGIN_CASE(JSOP_STOP)
             interpReturnOK = ScriptDebugEpilogue(cx, regs.fp(), interpReturnOK);
 
         if (!regs.fp()->isYielding())
             regs.fp()->epilogue(cx);
         else
             Probes::exitScript(cx, script, script->function(), regs.fp());
 
         /* The JIT inlines the epilogue. */
-#if defined(JS_METHODJIT) || defined(JS_ION)
+#if defined(JS_ION)
   jit_return:
 #endif
 
         /* The results of lowered call/apply frames need to be shifted. */
-        bool shiftResult = regs.fp()->loweredCallOrApply();
-
         cx->stack.popInlineFrame(regs);
         SET_SCRIPT(regs.fp()->script());
 
         JS_ASSERT(js_CodeSpec[*regs.pc].format & JOF_INVOKE);
 
         /* Resume execution in the calling frame. */
         if (JS_LIKELY(interpReturnOK)) {
             TypeScript::Monitor(cx, script, regs.pc, regs.sp[-1]);
 
-            if (shiftResult) {
-                regs.sp[-2] = regs.sp[-1];
-                regs.sp--;
-            }
-
             len = JSOP_CALL_LENGTH;
             DO_NEXT_OP(len);
         }
 
         /* Increment pc so that |sp - fp->slots == ReconstructStackDepth(pc)|. */
         regs.pc += JSOP_CALL_LENGTH;
         goto error;
     } else {
@@ -2448,34 +2375,16 @@ BEGIN_CASE(JSOP_FUNCALL)
             JS_ASSERT(exec != ion::IonExec_Bailout);
 
             interpReturnOK = !IsErrorStatus(exec);
             goto jit_return;
         }
     }
 #endif
 
-#ifdef JS_METHODJIT
-    if (!newType && cx->methodJitEnabled) {
-        /* Try to ensure methods are method JIT'd.  */
-        mjit::CompileStatus status = mjit::CanMethodJIT(cx, script, script->code,
-                                                        construct,
-                                                        mjit::CompileRequest_Interpreter,
-                                                        regs.fp());
-        if (status == mjit::Compile_Error)
-            goto error;
-        if (status == mjit::Compile_Okay) {
-            mjit::JaegerStatus status = mjit::JaegerShot(cx, true);
-            CHECK_PARTIAL_METHODJIT(status);
-            interpReturnOK = mjit::JaegerStatusToSuccess(status);
-            goto jit_return;
-        }
-    }
-#endif
-
     if (!regs.fp()->prologue(cx))
         goto error;
     if (cx->compartment->debugMode()) {
         switch (ScriptDebugPrologue(cx, regs.fp())) {
           case JSTRAP_CONTINUE:
             break;
           case JSTRAP_RETURN:
             interpReturnOK = true;
@@ -3391,17 +3300,17 @@ END_CASE(JSOP_ARRAYPUSH)
     if (!regs.fp()->isYielding())
         regs.fp()->epilogue(cx);
     else
         Probes::exitScript(cx, script, script->function(), regs.fp());
     regs.fp()->setFinishedInInterpreter();
 
     gc::MaybeVerifyBarriers(cx, true);
 
-#ifdef JS_METHODJIT
+#ifdef JS_ION
     /*
      * This path is used when it's guaranteed the method can be finished
      * inside the JIT.
      */
   leave_on_safe_point:
 #endif
 
     return interpReturnOK ? Interpret_Ok : Interpret_Error;
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -12,17 +12,16 @@
 #include "jscompartment.h"
 #include "jsinfer.h"
 #include "jsinterp.h"
 #include "jslibmath.h"
 #include "jsnum.h"
 #include "jsprobes.h"
 #include "jsstr.h"
 
-#include "methodjit/MethodJIT.h"
 #include "vm/ForkJoin.h"
 
 #include "jsatominlines.h"
 #include "jsfuninlines.h"
 #include "jsinferinlines.h"
 #include "jsopcodeinlines.h"
 #include "jspropertycacheinlines.h"
 #include "jstypedarrayinlines.h"
--- a/js/src/jsmemorymetrics.cpp
+++ b/js/src/jsmemorymetrics.cpp
@@ -248,43 +248,38 @@ StatsCellCallback(JSRuntime *rt, void *d
         break;
       }
 
       case JSTRACE_SCRIPT: {
         JSScript *script = static_cast<JSScript *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(script->compartment());
         cStats->gcHeapScripts += thingSize;
         cStats->scriptData += script->sizeOfData(rtStats->mallocSizeOf_);
-#ifdef JS_METHODJIT
-        cStats->jaegerData += script->sizeOfJitScripts(rtStats->mallocSizeOf_);
-# ifdef JS_ION
+#ifdef JS_ION
         size_t baselineData = 0, baselineStubsFallback = 0;
         ion::SizeOfBaselineData(script, rtStats->mallocSizeOf_, &baselineData,
                                 &baselineStubsFallback);
         cStats->baselineData += baselineData;
         cStats->baselineStubsFallback += baselineStubsFallback;
         cStats->ionData += ion::SizeOfIonData(script, rtStats->mallocSizeOf_);
-# endif
 #endif
 
         ScriptSource *ss = script->scriptSource();
         SourceSet::AddPtr entry = closure->seenSources.lookupForAdd(ss);
         if (!entry) {
             closure->seenSources.add(entry, ss); // Not much to be done on failure.
             rtStats->runtime.scriptSources += ss->sizeOfIncludingThis(rtStats->mallocSizeOf_);
         }
         break;
       }
 
       case JSTRACE_IONCODE: {
-#ifdef JS_METHODJIT
-# ifdef JS_ION
+#ifdef JS_ION
         zStats->gcHeapIonCodes += thingSize;
         // The code for a script is counted in ExecutableAllocator::sizeOfCode().
-# endif
 #endif
         break;
       }
 
       case JSTRACE_TYPE_OBJECT: {
         types::TypeObject *obj = static_cast<types::TypeObject *>(thing);
         zStats->gcHeapTypeObjects += thingSize;
         zStats->typeObjects += obj->sizeOfExcludingThis(rtStats->mallocSizeOf_);
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1487,19 +1487,16 @@ FindStartPC(JSContext *cx, ScriptFrameIt
      * would compute.
      *
      * FIXME: also fall back if iter.isIonOptimizedJS(), since the stack snapshot
      * may be for the previous pc (see bug 831120).
      */
     if (iter.isIonOptimizedJS())
         return true;
 
-    if (!iter.isIonBaselineJS() && iter.interpFrame()->jitRevisedStack())
-        return true;
-
     *valuepc = NULL;
 
     PCStack pcstack;
     if (!pcstack.init(cx, iter.script(), current))
         return false;
 
     if (spindex < 0 && spindex + pcstack.depth() < 0)
         spindex = JSDVG_SEARCH_STACK;
--- a/js/src/jsprobes.cpp
+++ b/js/src/jsprobes.cpp
@@ -27,53 +27,16 @@ bool Probes::ProfilingActive = true;
 Probes::JITReportGranularity
 Probes::JITGranularityRequested(JSContext *cx)
 {
     if (cx->runtime->spsProfiler.enabled())
         return JITREPORT_GRANULARITY_LINE;
     return JITREPORT_GRANULARITY_NONE;
 }
 
-#ifdef JS_METHODJIT
-
-bool
-Probes::registerMJITCode(JSContext *cx, js::mjit::JITChunk *chunk,
-                         js::mjit::JSActiveFrame *outerFrame,
-                         js::mjit::JSActiveFrame **inlineFrames)
-{
-    if (cx->runtime->spsProfiler.enabled() &&
-        !cx->runtime->spsProfiler.registerMJITCode(chunk, outerFrame, inlineFrames))
-    {
-        return false;
-    }
-
-    return true;
-}
-
-void
-Probes::discardMJITCode(FreeOp *fop, mjit::JITScript *jscr, mjit::JITChunk *chunk, void* address)
-{
-    if (fop->runtime()->spsProfiler.enabled())
-        fop->runtime()->spsProfiler.discardMJITCode(jscr, chunk, address);
-}
-
-bool
-Probes::registerICCode(JSContext *cx,
-                       mjit::JITChunk *chunk, JSScript *script, jsbytecode* pc,
-                       void *start, size_t size)
-{
-    if (cx->runtime->spsProfiler.enabled() &&
-        !cx->runtime->spsProfiler.registerICCode(chunk, script, pc, start, size))
-    {
-        return false;
-    }
-    return true;
-}
-#endif
-
 /* ICs are unregistered in a batch */
 void
 Probes::discardExecutableRegion(void *start, size_t size)
 {
     /*
      * Not needed for SPS because ICs are disposed of when the normal JITChunk
      * is disposed of
      */
--- a/js/src/jsprobes.h
+++ b/js/src/jsprobes.h
@@ -13,22 +13,16 @@
 #include "jspubtd.h"
 #include "jsprvtd.h"
 #include "jscntxt.h"
 #include "jsobj.h"
 #include "jsscript.h"
 
 namespace js {
 
-namespace mjit {
-struct NativeAddressInfo;
-struct JSActiveFrame;
-struct JITChunk;
-}
-
 namespace Probes {
 
 /*
  * Static probes
  *
  * The probe points defined in this file are scattered around the SpiderMonkey
  * source tree. The presence of Probes::someEvent() means that someEvent is
  * about to happen or has happened. To the extent possible, probes should be
@@ -108,40 +102,16 @@ enum JITReportGranularity {
 };
 
 /*
  * Finest granularity of JIT information desired by all watchers.
  */
 JITReportGranularity
 JITGranularityRequested(JSContext *cx);
 
-#ifdef JS_METHODJIT
-/*
- * New method JIT code has been created
- */
-bool
-registerMJITCode(JSContext *cx, js::mjit::JITChunk *chunk,
-                 mjit::JSActiveFrame *outerFrame,
-                 mjit::JSActiveFrame **inlineFrames);
-
-/*
- * Method JIT code is about to be discarded
- */
-void
-discardMJITCode(FreeOp *fop, mjit::JITScript *jscr, mjit::JITChunk *chunk, void* address);
-
-/*
- * IC code has been allocated within the given JITChunk
- */
-bool
-registerICCode(JSContext *cx,
-               mjit::JITChunk *chunk, JSScript *script, jsbytecode* pc,
-               void *start, size_t size);
-#endif /* JS_METHODJIT */
-
 /*
  * A whole region of code has been deallocated, containing any number of ICs.
  * (ICs are unregistered in a batch, so individual ICs are not registered.)
  */
 void
 discardExecutableRegion(void *start, size_t size);
 
 /*
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -22,20 +22,18 @@
 #include "jsdbgapi.h"
 #include "jsfun.h"
 #include "jsgc.h"
 #include "jsinterp.h"
 #include "jsopcode.h"
 
 #include "gc/Marking.h"
 #include "frontend/BytecodeEmitter.h"
-#include "methodjit/MethodJIT.h"
 #include "ion/IonCode.h"
 #include "ion/BaselineJIT.h"
-#include "methodjit/Retcon.h"
 #include "vm/Debugger.h"
 #include "vm/Shape.h"
 #include "vm/Xdr.h"
 
 #include "jsinferinlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
@@ -1837,20 +1835,16 @@ JSScript::fullyInitFromEmitter(JSContext
         bce->regexpList.finish(script->regexps());
     if (bce->constList.length() != 0)
         bce->constList.finish(script->consts());
     script->strict = bce->sc->strict;
     script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
     script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
     script->funHasExtensibleScope = funbox ? funbox->hasExtensibleScope() : false;
     script->hasSingletons = bce->hasSingletons;
-#ifdef JS_METHODJIT
-    if (cx->compartment->debugMode())
-        script->debugMode = true;
-#endif
 
     if (funbox) {
         if (funbox->argumentsHasLocalBinding()) {
             // This must precede the script->bindings.transfer() call below
             script->setArgumentsHasVarBinding();
             if (funbox->definitelyNeedsArgsObj())
                 script->setNeedsArgsObj(true);
         } else {
@@ -1981,21 +1975,18 @@ JSScript::finalize(FreeOp *fop)
     fop->runtime()->spsProfiler.onScriptFinalized(this);
 
     if (originPrincipals)
         JS_DropPrincipals(fop->runtime(), originPrincipals);
 
     if (types)
         types->destroy();
 
-#ifdef JS_METHODJIT
-    mjit::ReleaseScriptCode(fop, this);
-# ifdef JS_ION
+#ifdef JS_ION
     ion::DestroyIonScripts(fop, this);
-# endif
 #endif
 
     destroyScriptCounts(fop);
     destroyDebugScript(fop);
     scriptSource_->decref();
 
     if (data) {
         JS_POISON(data, 0xdb, computedSizeOfData());
@@ -2505,23 +2496,16 @@ JSScript::ensureHasDebugScript(JSContext
         frames->enableInterruptsIfRunning(this);
 
     return true;
 }
 
 void
 JSScript::recompileForStepMode(FreeOp *fop)
 {
-#ifdef JS_METHODJIT
-    if (hasMJITInfo()) {
-        mjit::Recompiler::clearStackReferences(fop, this);
-        mjit::ReleaseScriptCode(fop, this);
-    }
-#endif
-
 #ifdef JS_ION
     if (hasBaselineScript())
         baseline->toggleDebugTraps(this, NULL);
 #endif
 }
 
 bool
 JSScript::tryNewStepMode(JSContext *cx, uint32_t newValue)
@@ -2693,26 +2677,16 @@ JSScript::markChildren(JSTracer *trc)
         compartment()->mark();
 
         if (code)
             MarkScriptBytecode(trc->runtime, code);
     }
 
     bindings.trace(trc);
 
-#ifdef JS_METHODJIT
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            mjit::JITScript *jit = getJIT((bool) constructing, (bool) barriers);
-            if (jit)
-                jit->trace(trc);
-        }
-    }
-#endif
-
     if (hasAnyBreakpointsOrStepMode()) {
         for (unsigned i = 0; i < length; i++) {
             BreakpointSite *site = debugScript()->breakpoints[i];
             if (site && site->trapHandler)
                 MarkValue(trc, &site->trapClosure, "trap closure");
         }
     }
 
@@ -2836,24 +2810,16 @@ JSScript::argumentsOptimizationFailed(JS
                 script->needsArgsObj_ = false;
                 return false;
             }
 
             SetFrameArgumentsObject(cx, frame, script, argsobj);
         }
     }
 
-#ifdef JS_METHODJIT
-    if (script->hasMJITInfo()) {
-        mjit::ExpandInlineFrames(cx->zone());
-        mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
-        mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
-    }
-#endif
-
     if (script->hasAnalysis() && script->analysis()->ranInference()) {
         types::AutoEnterAnalysis enter(cx);
         types::TypeScript::MonitorUnknown(cx, script, script->argumentsBytecode());
     }
 
     return true;
 }
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -283,80 +283,16 @@ struct ScriptSource;
 } /* namespace js */
 
 class JSScript : public js::gc::Cell
 {
     static const uint32_t stepFlagMask = 0x80000000U;
     static const uint32_t stepCountMask = 0x7fffffffU;
 
   public:
-#ifdef JS_METHODJIT
-    // This type wraps JITScript.  It has three possible states.
-    // - "Empty": no compilation has been attempted and there is no JITScript.
-    // - "Unjittable": compilation failed and there is no JITScript.
-    // - "Valid": compilation succeeded and there is a JITScript.
-    class JITScriptHandle
-    {
-        // CallCompiler must be a friend because it generates code that uses
-        // UNJITTABLE.
-        friend class js::mjit::CallCompiler;
-
-        // The exact representation:
-        // - NULL means "empty".
-        // - UNJITTABLE means "unjittable".
-        // - Any other value means "valid".
-        // UNJITTABLE = 1 so that we can check that a JITScript is valid
-        // with a single |> 1| test.  It's defined outside the class because
-        // non-integral static const fields can't be defined in the class.
-        static const js::mjit::JITScript *UNJITTABLE;   // = (JITScript *)1;
-        js::mjit::JITScript *value;
-
-      public:
-        JITScriptHandle()       { value = NULL; }
-
-        bool isEmpty()          { return value == NULL; }
-        bool isUnjittable()     { return value == UNJITTABLE; }
-        bool isValid()          { return value  > UNJITTABLE; }
-
-        js::mjit::JITScript *getValid() {
-            JS_ASSERT(isValid());
-            return value;
-        }
-
-        void setEmpty()         { value = NULL; }
-        void setUnjittable()    { value = const_cast<js::mjit::JITScript *>(UNJITTABLE); }
-        void setValid(js::mjit::JITScript *jit) {
-            value = jit;
-            JS_ASSERT(isValid());
-        }
-
-        static void staticAsserts();
-    };
-
-    // All the possible JITScripts that can simultaneously exist for a script.
-    struct JITScriptSet
-    {
-        JITScriptHandle jitHandleNormal;          // JIT info for normal scripts
-        JITScriptHandle jitHandleNormalBarriered; // barriered JIT info for normal scripts
-        JITScriptHandle jitHandleCtor;            // JIT info for constructors
-        JITScriptHandle jitHandleCtorBarriered;   // barriered JIT info for constructors
-
-        static size_t jitHandleOffset(bool constructing, bool barriers) {
-            return constructing
-                ? (barriers
-                   ? offsetof(JITScriptSet, jitHandleCtorBarriered)
-                   : offsetof(JITScriptSet, jitHandleCtor))
-                : (barriers
-                   ? offsetof(JITScriptSet, jitHandleNormalBarriered)
-                   : offsetof(JITScriptSet, jitHandleNormal));
-        }
-    };
-
-#endif  // JS_METHODJIT
-
     //
     // We order fields according to their size in order to avoid wasting space
     // for alignment.
     //
 
     // Larger-than-word-sized fields.
 
   public:
@@ -375,21 +311,16 @@ class JSScript : public js::gc::Cell
     JSCompartment   *compartment_;
     JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
 
     /* Persistent type information retained across GCs. */
     js::types::TypeScript *types;
 
   private:
     js::ScriptSource *scriptSource_; /* source code */
-#ifdef JS_METHODJIT
-    JITScriptSet *mJITInfo;
-#else
-    void         *mJITInfoPad;
-#endif
     js::HeapPtrFunction function_;
 
     // For callsite clones, which cannot have enclosing scopes, the original
     // function; otherwise the enclosing scope
     js::HeapPtrObject   enclosingScopeOrOriginalFunction_;
 
     // 32-bit fields.
 
@@ -487,27 +418,22 @@ class JSScript : public js::gc::Cell
 
     /* script is attempted to be cloned anew at each callsite. This is
        temporarily needed for ParallelArray selfhosted code until type
        information can be made context sensitive. See discussion in
        bug 826148. */
     bool            shouldCloneAtCallsite:1;
 
     bool            isCallsiteClone:1; /* is a callsite clone; has a link to the original function */
-#ifdef JS_METHODJIT
-    bool            debugMode:1;      /* script was compiled in debug mode */
+#ifdef JS_ION
     bool            failedBoundsCheck:1; /* script has had hoisted bounds checks fail */
-#else
-    bool            debugModePad:1;
-    bool            failedBoundsCheckPad:1;
-#endif
-#ifdef JS_ION
     bool            failedShapeGuard:1; /* script has had hoisted shape guard fail */
     bool            hadFrequentBailouts:1;
 #else
+    bool            failedBoundsCheckPad:1;
     bool            failedShapeGuardPad:1;
     bool            hadFrequentBailoutsPad:1;
 #endif
     bool            invalidatedIdempotentCache:1; /* idempotent cache has triggered invalidation */
     bool            isGenerator:1;    /* is a generator */
     bool            isGeneratorExp:1; /* is a generator expression */
     bool            hasScriptCounts:1;/* script has an entry in
                                          JSCompartment::scriptCountsMap */
@@ -589,16 +515,20 @@ class JSScript : public js::gc::Cell
   private:
     /* Information attached by Baseline/Ion for sequential mode execution. */
     js::ion::IonScript *ion;
     js::ion::BaselineScript *baseline;
 
     /* Information attached by Ion for parallel mode execution */
     js::ion::IonScript *parallelIon;
 
+#if JS_BITS_PER_WORD == 32
+    uint32_t padding0;
+#endif
+
     /*
      * Pointer to either baseline->method()->raw() or ion->method()->raw(), or NULL
      * if there's no Baseline or Ion script.
      */
     uint8_t *baselineOrIonRaw;
     uint8_t *baselineOrIonSkipArgCheck;
 
   public:
@@ -762,66 +692,23 @@ class JSScript : public js::gc::Cell
      */
     bool enclosingScriptsCompiledSuccessfully() const;
 
   private:
     bool makeTypes(JSContext *cx);
     bool makeBytecodeTypeMap(JSContext *cx);
     bool makeAnalysis(JSContext *cx);
 
-#ifdef JS_METHODJIT
-  private:
-    // CallCompiler must be a friend because it generates code that directly
-    // accesses jitHandleNormal/jitHandleCtor, via jitHandleOffset().
-    friend class js::mjit::CallCompiler;
-
   public:
-    bool hasMJITInfo() {
-        return mJITInfo != NULL;
-    }
-
-    static size_t offsetOfMJITInfo() { return offsetof(JSScript, mJITInfo); }
-
-    inline bool ensureHasMJITInfo(JSContext *cx);
-    inline void destroyMJITInfo(js::FreeOp *fop);
-
-    JITScriptHandle *jitHandle(bool constructing, bool barriers) {
-        JS_ASSERT(mJITInfo);
-        return constructing
-               ? (barriers ? &mJITInfo->jitHandleCtorBarriered : &mJITInfo->jitHandleCtor)
-               : (barriers ? &mJITInfo->jitHandleNormalBarriered : &mJITInfo->jitHandleNormal);
-    }
-
-    js::mjit::JITScript *getJIT(bool constructing, bool barriers) {
-        if (!mJITInfo)
-            return NULL;
-        JITScriptHandle *jith = jitHandle(constructing, barriers);
-        return jith->isValid() ? jith->getValid() : NULL;
-    }
-
-    static void ReleaseCode(js::FreeOp *fop, JITScriptHandle *jith);
-
-    // These methods are implemented in MethodJIT.h.
-    inline void **nativeMap(bool constructing);
-    inline void *nativeCodeForPC(bool constructing, jsbytecode *pc);
-
     uint32_t getUseCount() const  { return useCount; }
     uint32_t incUseCount(uint32_t amount = 1) { return useCount += amount; }
     uint32_t *addressOfUseCount() { return &useCount; }
     static size_t offsetOfUseCount() { return offsetof(JSScript, useCount); }
     void resetUseCount() { useCount = 0; }
 
-    /*
-     * Size of the JITScript and all sections.  If |mallocSizeOf| is NULL, the
-     * size is computed analytically.  (This method is implemented in
-     * MethodJIT.cpp.)
-     */
-    size_t sizeOfJitScripts(JSMallocSizeOfFun mallocSizeOf);
-#endif
-
   public:
     bool initScriptCounts(JSContext *cx);
     js::PCCounts getPCCounts(jsbytecode *pc);
     void addIonCounts(js::ion::IonScriptCounts *ionCounts);
     js::ion::IonScriptCounts *getIonCounts();
     js::ScriptCounts releaseScriptCounts();
     void destroyScriptCounts(js::FreeOp *fop);
 
--- a/js/src/jsscriptinlines.h
+++ b/js/src/jsscriptinlines.h
@@ -152,34 +152,16 @@ JSScript::global() const
 {
     /*
      * A JSScript always marks its compartment's global (via bindings) so we
      * can assert that maybeGlobal is non-null here.
      */
     return *compartment()->maybeGlobal();
 }
 
-#ifdef JS_METHODJIT
-inline bool
-JSScript::ensureHasMJITInfo(JSContext *cx)
-{
-    if (mJITInfo)
-        return true;
-    mJITInfo = cx->new_<JITScriptSet>();
-    return mJITInfo != NULL;
-}
-
-inline void
-JSScript::destroyMJITInfo(js::FreeOp *fop)
-{
-    fop->delete_(mJITInfo);
-    mJITInfo = NULL;
-}
-#endif /* JS_METHODJIT */
-
 inline void
 JSScript::writeBarrierPre(JSScript *script)
 {
 #ifdef JSGC_INCREMENTAL
     if (!script || !script->runtime()->needsBarrier())
         return;
 
     JS::Zone *zone = script->zone();
deleted file mode 100644
--- a/js/src/methodjit/BaseAssembler.h
+++ /dev/null
@@ -1,1560 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_baseassembler_h__ && defined JS_METHODJIT
-#define jsjaeger_baseassembler_h__
-
-#include "mozilla/DebugOnly.h"
-
-#include "jscntxt.h"
-#include "assembler/assembler/MacroAssemblerCodeRef.h"
-#include "assembler/assembler/MacroAssembler.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "assembler/moco/MocoStubs.h"
-#include "methodjit/MethodJIT.h"
-#include "methodjit/MachineRegs.h"
-#include "CodeGenIncludes.h"
-#include "jsobjinlines.h"
-#include "jstypedarrayinlines.h"
-
-#include "vm/Shape-inl.h"
-
-using mozilla::DebugOnly;
-
-namespace js {
-namespace mjit {
-
-class Assembler;
-
-// Represents an int32_t property name in generated code, which must be either
-// a RegisterID or a constant value.
-struct Int32Key {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    MaybeRegisterID reg_;
-    int32_t index_;
-
-    Int32Key() : index_(0) { }
-
-    static Int32Key FromRegister(RegisterID reg) {
-        Int32Key key;
-        key.reg_ = reg;
-        return key;
-    }
-    static Int32Key FromConstant(int32_t index) {
-        Int32Key key;
-        key.index_ = index;
-        return key;
-    }
-
-    int32_t index() const {
-        JS_ASSERT(!reg_.isSet());
-        return index_;
-    }
-
-    RegisterID reg() const { return reg_.reg(); }
-    bool isConstant() const { return !reg_.isSet(); }
-};
-
-struct FrameAddress : JSC::MacroAssembler::Address
-{
-    FrameAddress(int32_t offset)
-      : Address(JSC::MacroAssembler::stackPointerRegister, offset)
-    { }
-};
-
-struct ImmIntPtr : public JSC::MacroAssembler::ImmPtr
-{
-    ImmIntPtr(intptr_t val)
-      : ImmPtr(reinterpret_cast<void*>(val))
-    { }
-};
-
-struct StackMarker {
-    uint32_t base;
-    uint32_t bytes;
-
-    StackMarker(uint32_t base, uint32_t bytes)
-      : base(base), bytes(bytes)
-    { }
-};
-
-typedef SPSInstrumentation<Assembler, JSC::MacroAssembler::RegisterID>
-        MJITInstrumentation;
-
-class Assembler : public ValueAssembler
-{
-    struct CallPatch {
-        CallPatch(Call cl, void *fun)
-          : call(cl), fun(fun)
-        { }
-
-        Call call;
-        JSC::FunctionPtr fun;
-    };
-
-    struct DoublePatch {
-        double d;
-        DataLabelPtr label;
-    };
-
-    /* :TODO: OOM */
-    Label startLabel;
-    Vector<CallPatch, 64, SystemAllocPolicy> callPatches;
-    Vector<DoublePatch, 16, SystemAllocPolicy> doublePatches;
-
-    // Registers that can be clobbered during a call sequence.
-    Registers   availInCall;
-
-    // Extra number of bytes that can be used for storing structs/references
-    // across calls.
-    uint32_t    extraStackSpace;
-
-    // Calling convention used by the currently in-progress call.
-    Registers::CallConvention callConvention;
-
-    // Amount of stack space reserved for the currently in-progress call. This
-    // includes alignment and parameters.
-    uint32_t    stackAdjust;
-
-    // Debug flag to make sure calls do not nest.
-#ifdef DEBUG
-    bool        callIsAligned;
-#endif
-
-    // When instrumentation is enabled, these fields are used to manage the
-    // instrumentation which occurs at call() locations. Each call() has to know
-    // the pc of where the call was invoked from, and this can be changing all
-    // the time in the case of masm from Compiler, or never changing in the case
-    // of ICs.
-    MJITInstrumentation *sps;
-    VMFrame *vmframe; // pc tracker from ICs
-    jsbytecode **pc;  // pc tracker for compilers
-
-  public:
-    Assembler(MJITInstrumentation *sps = NULL, VMFrame *vmframe = NULL)
-      : callPatches(SystemAllocPolicy()),
-        availInCall(0),
-        extraStackSpace(0),
-        stackAdjust(0),
-#ifdef DEBUG
-        callIsAligned(false),
-#endif
-        sps(sps),
-        vmframe(vmframe),
-        pc(NULL)
-    {
-        startLabel = label();
-        if (vmframe)
-            sps->setPushed(vmframe->script());
-    }
-
-    Assembler(MJITInstrumentation *sps, jsbytecode **pc)
-      : callPatches(SystemAllocPolicy()),
-        availInCall(0),
-        extraStackSpace(0),
-        stackAdjust(0),
-#ifdef DEBUG
-        callIsAligned(false),
-#endif
-        sps(sps),
-        vmframe(NULL),
-        pc(pc)
-    {
-        startLabel = label();
-    }
-
-    /* Register pair storing returned type/data for calls. */
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Type  = JSC::X86Registers::edi;
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Data  = JSC::X86Registers::esi;
-static const JSC::MacroAssembler::RegisterID JSParamReg_Argc   = JSC::X86Registers::ecx;
-#elif defined(JS_CPU_ARM)
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Type  = JSC::ARMRegisters::r5;
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Data  = JSC::ARMRegisters::r4;
-static const JSC::MacroAssembler::RegisterID JSParamReg_Argc   = JSC::ARMRegisters::r1;
-#elif defined(JS_CPU_SPARC)
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::SparcRegisters::l2;
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::SparcRegisters::l3;
-static const JSC::MacroAssembler::RegisterID JSParamReg_Argc  = JSC::SparcRegisters::l4;
-#elif defined(JS_CPU_MIPS)
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::MIPSRegisters::a0;
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::MIPSRegisters::a2;
-static const JSC::MacroAssembler::RegisterID JSParamReg_Argc  = JSC::MIPSRegisters::a1;
-#endif
-
-    size_t distanceOf(Label l) {
-        return differenceBetween(startLabel, l);
-    }
-
-    void loadPtrFromImm(void *ptr, RegisterID reg) {
-        loadPtr(ptr, reg);
-    }
-
-    void loadShape(RegisterID obj, RegisterID shape) {
-        loadPtr(Address(obj, JSObject::offsetOfShape()), shape);
-    }
-
-    Jump guardShape(RegisterID objReg, Shape *shape) {
-        return branchPtr(NotEqual, Address(objReg, JSObject::offsetOfShape()), ImmPtr(shape));
-    }
-
-    Jump guardShape(RegisterID objReg, JSObject *obj) {
-        return guardShape(objReg, obj->lastProperty());
-    }
-
-    /*
-     * Finds and returns the address of a known object and slot.
-     */
-    Address objSlotRef(JSObject *obj, RegisterID reg, uint32_t slot) {
-        move(ImmPtr(obj), reg);
-        if (obj->isFixedSlot(slot)) {
-            return Address(reg, JSObject::getFixedSlotOffset(slot));
-        } else {
-            loadPtr(Address(reg, JSObject::offsetOfSlots()), reg);
-            return Address(reg, obj->dynamicSlotIndex(slot) * sizeof(Value));
-        }
-    }
-
-#ifdef JS_CPU_X86
-    void idiv(RegisterID reg) {
-        m_assembler.cdq();
-        m_assembler.idivl_r(reg);
-    }
-
-    void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg) {
-        JS_ASSERT(fpReg != Registers::FPConversionTemp);
-        if (MacroAssemblerX86Common::getSSEState() >= HasSSE4_1) {
-            m_assembler.movd_rr(lo, fpReg);
-            m_assembler.pinsrd_rr(hi, fpReg);
-        } else {
-            m_assembler.movd_rr(lo, fpReg);
-            m_assembler.movd_rr(hi, Registers::FPConversionTemp);
-            m_assembler.unpcklps_rr(Registers::FPConversionTemp, fpReg);
-        }
-    }
-#endif
-
-    /*
-     * Move a register pair which may indicate either an int32_t or double into fpreg,
-     * converting to double in the int32_t case.
-     */
-    void moveInt32OrDouble(RegisterID data, RegisterID type, Address address, FPRegisterID fpreg)
-    {
-#ifdef JS_CPU_X86
-        fastLoadDouble(data, type, fpreg);
-        Jump notInteger = testInt32(Assembler::NotEqual, type);
-        convertInt32ToDouble(data, fpreg);
-        notInteger.linkTo(label(), this);
-#else
-        Jump notInteger = testInt32(Assembler::NotEqual, type);
-        convertInt32ToDouble(data, fpreg);
-        Jump fallthrough = jump();
-        notInteger.linkTo(label(), this);
-
-        /* Store the components, then read it back out as a double. */
-        storeValueFromComponents(type, data, address);
-        loadDouble(address, fpreg);
-
-        fallthrough.linkTo(label(), this);
-#endif
-    }
-
-    /*
-     * Move a memory address which contains either an int32_t or double into fpreg,
-     * converting to double in the int32_t case.
-     */
-    template <typename T>
-    void moveInt32OrDouble(T address, FPRegisterID fpreg)
-    {
-        Jump notInteger = testInt32(Assembler::NotEqual, address);
-        convertInt32ToDouble(payloadOf(address), fpreg);
-        Jump fallthrough = jump();
-        notInteger.linkTo(label(), this);
-        loadDouble(address, fpreg);
-        fallthrough.linkTo(label(), this);
-    }
-
-    /* Ensure that an in-memory address is definitely a double. */
-    void ensureInMemoryDouble(Address address)
-    {
-        Jump notInteger = testInt32(Assembler::NotEqual, address);
-        convertInt32ToDouble(payloadOf(address), Registers::FPConversionTemp);
-        storeDouble(Registers::FPConversionTemp, address);
-        notInteger.linkTo(label(), this);
-    }
-
-    void negateDouble(FPRegisterID fpreg)
-    {
-#if defined JS_CPU_X86 || defined JS_CPU_X64
-        static const uint64_t DoubleNegMask = 0x8000000000000000ULL;
-        loadDouble(&DoubleNegMask, Registers::FPConversionTemp);
-        xorDouble(Registers::FPConversionTemp, fpreg);
-#elif defined JS_CPU_ARM || defined JS_CPU_SPARC || defined JS_CPU_MIPS
-        negDouble(fpreg, fpreg);
-#endif
-    }
-
-    /* Prepare for a call that might THROW. */
-    void *getFallibleCallTarget(void *fun) {
-#ifdef JS_CPU_ARM
-        /*
-         * Insert a veneer for ARM to allow it to catch exceptions. There is no
-         * reliable way to determine the location of the return address on the
-         * stack, so a typical C(++) return address cannot be hijacked.
-         *
-         * We put the real target address into IP, as this won't conflict with
-         * the EABI argument-passing mechanism. JaegerStubVeneer is responsible
-         * for calling 'fun' (in IP) and catching exceptions.
-         *
-         * Note that we must use 'moveWithPatch' here, rather than 'move',
-         * because 'move' might try to optimize the constant load, and we need a
-         * consistent code sequence for patching.
-         */
-        moveWithPatch(Imm32(intptr_t(fun)), JSC::ARMRegisters::ip);
-
-        return JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer);
-#elif defined(JS_CPU_SPARC)
-        /*
-         * We can simulate the situation in jited code to let call return to a
-         * target address located on stack without veneer. We record the return
-         * address and jump to that address after call return to jited code. The
-         * reason we take veneer back is jited code maybe released when
-         * exceptions happened. That will make the call have no chance to return
-         * back to jited code.
-         */
-        moveWithPatch(Imm32(intptr_t(fun)), JSC::SparcRegisters::i0);
-        return JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer);
-#elif defined(JS_CPU_MIPS)
-        /*
-         * For MIPS, we need to call JaegerStubVeneer by passing
-         * the real target address in v0.
-         */
-        moveWithPatch(Imm32(intptr_t(fun)), JSC::MIPSRegisters::v0);
-        return JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer);
-#else
-        /*
-         * Architectures that push the return address to an easily-determined
-         * location on the stack can hijack C++'s return mechanism by overwriting
-         * that address, so a veneer is not required.
-         */
-        return fun;
-#endif
-    }
-
-    static inline uint32_t align(uint32_t bytes, uint32_t alignment) {
-        return (alignment - (bytes % alignment)) % alignment;
-    }
-
-    // Specifies extra stack space that is available across a call, for storing
-    // large parameters (structs) or returning values via references. All extra
-    // stack space must be reserved up-front, and is aligned on an 8-byte
-    // boundary.
-    //
-    // Returns an offset that can be used to index into this stack
-    StackMarker allocStack(uint32_t bytes, uint32_t alignment = 4) {
-        bytes += align(bytes + extraStackSpace, alignment);
-        subPtr(Imm32(bytes), stackPointerRegister);
-        extraStackSpace += bytes;
-        return StackMarker(extraStackSpace, bytes);
-    }
-
-    // Similar to allocStack(), but combines it with a push().
-    void saveReg(RegisterID reg) {
-        push(reg);
-        extraStackSpace += sizeof(void *);
-    }
-
-    // Similar to freeStack(), but combines it with a pop().
-    void restoreReg(RegisterID reg) {
-        JS_ASSERT(extraStackSpace >= sizeof(void *));
-        extraStackSpace -= sizeof(void *);
-        pop(reg);
-    }
-
-#if defined JS_CPU_MIPS
-    static const uint32_t StackAlignment = 8;
-#else
-    static const uint32_t StackAlignment = 16;
-#endif
-
-    static inline uint32_t alignForCall(uint32_t stackBytes) {
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64) || defined(JS_CPU_MIPS)
-        // If StackAlignment is a power of two, % is just two shifts.
-        // 16 - (x % 16) gives alignment, extra % 16 handles total == 0.
-        return align(stackBytes, StackAlignment);
-#else
-        return 0;
-#endif
-    }
-
-    // Some platforms require stack manipulation before making stub calls.
-    // When using THROW/V, the return address is replaced, meaning the
-    // stack de-adjustment will not have occured. JaegerThrowpoline accounts
-    // for this. For stub calls, which are always invoked as if they use
-    // two parameters, the stack adjustment is constant.
-    //
-    // When using callWithABI() manually, for example via an IC, it might
-    // be necessary to jump directly to JaegerThrowpoline. In this case,
-    // the constant is provided here in order to appropriately adjust the
-    // stack.
-#ifdef _WIN64
-    static const uint32_t ReturnStackAdjustment = 32;
-#elif defined(JS_CPU_X86) && defined(JS_NO_FASTCALL)
-    static const uint32_t ReturnStackAdjustment = 16;
-#else
-    static const uint32_t ReturnStackAdjustment = 0;
-#endif
-
-    void throwInJIT() {
-        if (ReturnStackAdjustment)
-            subPtr(Imm32(ReturnStackAdjustment), stackPointerRegister);
-        move(ImmPtr(JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline)), Registers::ReturnReg);
-        jump(Registers::ReturnReg);
-    }
-
-    // Windows x64 requires extra space in between calls.
-#ifdef _WIN64
-    static const uint32_t ShadowStackSpace = 32;
-#elif defined(JS_CPU_SPARC)
-    static const uint32_t ShadowStackSpace = 92;
-#else
-    static const uint32_t ShadowStackSpace = 0;
-#endif
-
-#if defined(JS_CPU_SPARC)
-    static const uint32_t BaseStackSpace = 104;
-#else
-    static const uint32_t BaseStackSpace = 0;
-#endif
-
-    // Prepare the stack for a call sequence. This must be called AFTER all
-    // volatile regs have been saved, and BEFORE pushArg() is used. The stack
-    // is assumed to be aligned to 16-bytes plus any pushes that occured via
-    // saveRegs().
-    //
-    // During a call sequence all registers are "owned" by the Assembler.
-    // Attempts to perform loads, nested calls, or anything that can clobber
-    // a register, is asking for breaking on some platform or some situation.
-    // Be careful to limit to storeArg() during setupABICall.
-    void setupABICall(Registers::CallConvention convention, uint32_t generalArgs) {
-        if (sps && sps->enabled())
-            leaveBeforeCall();
-
-        JS_ASSERT(!callIsAligned);
-
-        uint32_t numArgRegs = Registers::numArgRegs(convention);
-        uint32_t pushCount = (generalArgs > numArgRegs)
-                           ? generalArgs - numArgRegs
-                           : 0;
-
-        // Assume all temporary regs are available to clobber.
-        availInCall = Registers::TempRegs;
-
-        // Find the total number of bytes the stack will have been adjusted by,
-        // in order to compute alignment.
-        uint32_t total = (pushCount * sizeof(void *)) +
-                       extraStackSpace;
-
-        stackAdjust = (pushCount * sizeof(void *)) +
-                      alignForCall(total);
-
-#ifdef _WIN64
-        // Windows x64 ABI requires 32 bytes of "shadow space" for the callee
-        // to spill its parameters.
-        stackAdjust += ShadowStackSpace;
-#endif
-
-        if (stackAdjust)
-            subPtr(Imm32(stackAdjust), stackPointerRegister);
-
-        callConvention = convention;
-#ifdef DEBUG
-        callIsAligned = true;
-#endif
-    }
-
-    // Computes an interior pointer into VMFrame during a call.
-    Address vmFrameOffset(uint32_t offs) {
-        return Address(stackPointerRegister, stackAdjust + extraStackSpace + offs);
-    }
-
-    // Get an Address to the extra space already allocated before the call.
-    Address addressOfExtra(const StackMarker &marker) {
-        // Stack looks like this:
-        //   extraStackSpace
-        //   stackAdjust
-        // To get to the requested offset into extraStackSpace, we can walk
-        // up to the top of the extra stack space, then subtract |offs|.
-        //
-        // Note that it's not required we're in a call - stackAdjust can be 0.
-        JS_ASSERT(marker.base <= extraStackSpace);
-        return Address(stackPointerRegister, BaseStackSpace + stackAdjust + extraStackSpace - marker.base);
-    }
-
-    // This is an internal function only for use inside a setupABICall(),
-    // callWithABI() sequence, and only for arguments known to fit in
-    // registers.
-    Address addressOfArg(uint32_t i) {
-        uint32_t numArgRegs = Registers::numArgRegs(callConvention);
-        JS_ASSERT(i >= numArgRegs);
-
-        // Note that shadow space is for the callee to spill, and thus it must
-        // be skipped when writing its arguments.
-        int32_t spOffset = ((i - numArgRegs) * sizeof(void *)) + ShadowStackSpace;
-        return Address(stackPointerRegister, spOffset);
-    }
-
-    // Push an argument for a call.
-    void storeArg(uint32_t i, RegisterID reg) {
-        JS_ASSERT(callIsAligned);
-        RegisterID to;
-        if (Registers::regForArg(callConvention, i, &to)) {
-            if (reg != to)
-                move(reg, to);
-            availInCall.takeRegUnchecked(to);
-        } else {
-            storePtr(reg, addressOfArg(i));
-        }
-    }
-
-    // This variant can clobber temporary registers. However, it will NOT
-    // clobber any registers that have already been set via storeArg().
-    void storeArg(uint32_t i, Address address) {
-        JS_ASSERT(callIsAligned);
-        RegisterID to;
-        if (Registers::regForArg(callConvention, i, &to)) {
-            loadPtr(address, to);
-            availInCall.takeRegUnchecked(to);
-        } else if (!availInCall.empty()) {
-            // Memory-to-memory, and there is a temporary register free.
-            RegisterID reg = availInCall.takeAnyReg().reg();
-            loadPtr(address, reg);
-            storeArg(i, reg);
-            availInCall.putReg(reg);
-        } else {
-            // Memory-to-memory, but no temporary registers are free.
-            // This shouldn't happen on any platforms, because
-            // (TempRegs) Union (ArgRegs) != 0
-            JS_NOT_REACHED("too much reg pressure");
-        }
-    }
-
-    // This variant can clobber temporary registers. However, it will NOT
-    // clobber any registers that have already been set via storeArg().
-    void storeArgAddr(uint32_t i, Address address) {
-        JS_ASSERT(callIsAligned);
-        RegisterID to;
-        if (Registers::regForArg(callConvention, i, &to)) {
-            lea(address, to);
-            availInCall.takeRegUnchecked(to);
-        } else if (!availInCall.empty()) {
-            // Memory-to-memory, and there is a temporary register free.
-            RegisterID reg = availInCall.takeAnyReg().reg();
-            lea(address, reg);
-            storeArg(i, reg);
-            availInCall.putReg(reg);
-        } else {
-            // Memory-to-memory, but no temporary registers are free.
-            // This shouldn't happen on any platforms, because
-            // (TempRegs) Union (ArgRegs) != 0
-            JS_NOT_REACHED("too much reg pressure");
-        }
-    }
-
-    void storeArg(uint32_t i, ImmPtr imm) {
-        JS_ASSERT(callIsAligned);
-        RegisterID to;
-        if (Registers::regForArg(callConvention, i, &to)) {
-            move(imm, to);
-            availInCall.takeRegUnchecked(to);
-        } else {
-            storePtr(imm, addressOfArg(i));
-        }
-    }
-
-    void storeArg(uint32_t i, Imm32 imm) {
-        JS_ASSERT(callIsAligned);
-        RegisterID to;
-        if (Registers::regForArg(callConvention, i, &to)) {
-            move(imm, to);
-            availInCall.takeRegUnchecked(to);
-        } else {
-            store32(imm, addressOfArg(i));
-        }
-    }
-
-  private:
-    // When profiling is enabled, we need to run an epilogue and a prologue to
-    // every call. These two functions manage this code generation and are
-    // called from callWithABI below.
-    void leaveBeforeCall() {
-        jsbytecode *pc = vmframe == NULL ? *this->pc : vmframe->pc();
-        if (availInCall.empty()) {
-            RegisterID reg = Registers(Registers::TempRegs).peekReg().reg();
-            saveReg(reg);
-            sps->leave(pc, *this, reg);
-            restoreReg(reg);
-        } else {
-            sps->leave(pc, *this, availInCall.peekReg().reg());
-        }
-    }
-
-    void reenterAfterCall() {
-        if (availInCall.empty()) {
-            RegisterID reg = Registers(Registers::TempRegs).peekReg().reg();
-            saveReg(reg);
-            sps->reenter(*this, reg);
-            restoreReg(reg);
-        } else {
-            sps->reenter(*this, availInCall.peekReg().reg());
-        }
-    }
-
-  public:
-    // High-level call helper, given an optional function pointer and a
-    // calling convention. setupABICall() must have been called beforehand,
-    // as well as each numbered argument stored with storeArg().
-    //
-    // After callWithABI(), the call state is reset, so a new call may begin.
-    Call callWithABI(void *fun, bool canThrow) {
-#ifdef JS_CPU_ARM
-        // the repatcher requires that these instructions are adjacent in
-        // memory, make sure that they are in fact adjacent.
-        // Theoretically, this requires only 12 bytes of space, however
-        // there are at least a couple of off-by-one errors that I've noticed
-        // that make 12 insufficent.  In case 16 is also insufficent, I've bumped
-        // it to 20.
-        ensureSpace(20);
-        DebugOnly<int> initFlushCount = flushCount();
-#endif
-        // [Bug 614953]: This can only be made conditional once the ARM back-end
-        // is able to distinguish and patch both call sequences. Other
-        // architecutres are unaffected regardless.
-        //if (canThrow) {
-            // Some platforms (such as ARM) require a call veneer if the target
-            // might THROW. For other platforms, getFallibleCallTarget does
-            // nothing.
-            fun = getFallibleCallTarget(fun);
-        //}
-
-        JS_ASSERT(callIsAligned);
-
-        Call cl = callAddress(fun);
-
-#ifdef JS_CPU_ARM
-        JS_ASSERT(initFlushCount == flushCount());
-#endif
-        if (sps && sps->enabled())
-            reenterAfterCall();
-        if (stackAdjust)
-            addPtr(Imm32(stackAdjust), stackPointerRegister);
-
-        stackAdjust = 0;
-
-#ifdef DEBUG
-        callIsAligned = false;
-#endif
-        return cl;
-    }
-
-    Call callAddress(void *ptr) {
-        Call cl = call();
-        callPatches.append(CallPatch(cl, ptr));
-        return cl;
-    }
-
-    // Frees stack space allocated by allocStack().
-    void freeStack(const StackMarker &mark) {
-        JS_ASSERT(!callIsAligned);
-        JS_ASSERT(mark.bytes <= extraStackSpace);
-
-        extraStackSpace -= mark.bytes;
-        addPtr(Imm32(mark.bytes), stackPointerRegister);
-    }
-
-    // Wrap AbstractMacroAssembler::getLinkerCallReturnOffset which is protected.
-    unsigned callReturnOffset(Call call) {
-        return getLinkerCallReturnOffset(call);
-    }
-
-
-#define STUB_CALL_TYPE(type)                                                  \
-    Call callWithVMFrame(bool inlining, type stub, jsbytecode *pc,            \
-                         DataLabelPtr *pinlined, uint32_t fd) {               \
-        return fallibleVMCall(inlining, JS_FUNC_TO_DATA_PTR(void *, stub),    \
-                              pc, pinlined, fd);                              \
-    }
-
-    STUB_CALL_TYPE(JSObjStub)
-    STUB_CALL_TYPE(VoidPtrStubUInt32)
-    STUB_CALL_TYPE(VoidStubUInt32)
-    STUB_CALL_TYPE(VoidStub)
-
-#undef STUB_CALL_TYPE
-
-    void setupFrameDepth(int32_t frameDepth) {
-        // |frameDepth < 0| implies ic::SplatApplyArgs has been called which
-        // means regs.sp has already been set in the VMFrame.
-        if (frameDepth >= 0) {
-            // sp = fp->slots() + frameDepth
-            // regs->sp = sp
-            addPtr(Imm32(sizeof(StackFrame) + frameDepth * sizeof(jsval)),
-                   JSFrameReg,
-                   Registers::ClobberInCall);
-            storePtr(Registers::ClobberInCall, FrameAddress(VMFrame::offsetOfRegsSp()));
-        }
-    }
-
-    void setupInfallibleVMFrame(int32_t frameDepth) {
-        setupFrameDepth(frameDepth);
-
-        // The JIT has moved Arg1 already, and we've guaranteed to not clobber
-        // it. Move ArgReg0 into place now. setupFallibleVMFrame will not
-        // clobber it either.
-        move(MacroAssembler::stackPointerRegister, Registers::ArgReg0);
-    }
-
-    void setupFallibleVMFrame(bool inlining, jsbytecode *pc,
-                              DataLabelPtr *pinlined, int32_t frameDepth) {
-        setupInfallibleVMFrame(frameDepth);
-
-        // regs->fp = fp
-        storePtr(JSFrameReg, FrameAddress(VMFrame::offsetOfFp));
-
-        // PC -> regs->pc :(  Note: If pc is null, we are emitting a trampoline,
-        // so regs->pc is already correct.
-        if (pc)
-            storePtr(ImmPtr(pc), FrameAddress(VMFrame::offsetOfRegsPc()));
-
-        if (inlining) {
-            // inlined -> regs->inlined :(
-            DataLabelPtr ptr = storePtrWithPatch(ImmPtr(NULL),
-                                                 FrameAddress(VMFrame::offsetOfInlined));
-            if (pinlined)
-                *pinlined = ptr;
-        }
-
-        restoreStackBase();
-    }
-
-    void setupFallibleABICall(bool inlining, jsbytecode *pc, int32_t frameDepth) {
-        setupFrameDepth(frameDepth);
-
-        /* Store fp and pc */
-        storePtr(JSFrameReg, FrameAddress(VMFrame::offsetOfFp));
-        storePtr(ImmPtr(pc), FrameAddress(VMFrame::offsetOfRegsPc()));
-
-        if (inlining) {
-            /* ABI calls cannot be made from inlined frames. */
-            storePtr(ImmPtr(NULL), FrameAddress(VMFrame::offsetOfInlined));
-        }
-    }
-
-    void restoreStackBase() {
-#if defined(JS_CPU_X86)
-        /*
-         * We use the %ebp base stack pointer on x86 to store the JSStackFrame.
-         * Restore this before calling so that debuggers can construct a
-         * coherent stack if we crash outside of JIT code.
-         */
-        JS_STATIC_ASSERT(JSFrameReg == JSC::X86Registers::ebp);
-        move(JSC::X86Registers::esp, JSFrameReg);
-        addPtr(Imm32(VMFrame::STACK_BASE_DIFFERENCE), JSFrameReg);
-#endif
-    }
-
-    // An infallible VM call is a stub call (taking a VMFrame & and one
-    // optional parameter) that does not need |pc| and |fp| updated, since
-    // the call is guaranteed to not fail. However, |sp| is always coherent.
-    Call infallibleVMCall(void *ptr, int32_t frameDepth) {
-        setupInfallibleVMFrame(frameDepth);
-        return wrapVMCall(ptr);
-    }
-
-    // A fallible VM call is a stub call (taking a VMFrame & and one optional
-    // parameter) that needs the entire VMFrame to be coherent, meaning that
-    // |pc|, |inlined| and |fp| are guaranteed to be up-to-date.
-    //
-    // If |pc| is null, the caller guarantees that the current regs->pc may be
-    // trusted. This is the case for a single debug-only path; see
-    // generateForceReturn.
-    Call fallibleVMCall(bool inlining, void *ptr, jsbytecode *pc,
-                        DataLabelPtr *pinlined, int32_t frameDepth) {
-        setupFallibleVMFrame(inlining, pc, pinlined, frameDepth);
-        Call call = wrapVMCall(ptr);
-
-        // Restore the frame pointer from the VM.
-        loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
-
-        return call;
-    }
-
-    Call wrapVMCall(void *ptr) {
-        JS_ASSERT(!callIsAligned);
-
-        // Every stub call has at most two arguments.
-        setupABICall(Registers::FastCall, 2);
-
-        // On x86, if JS_NO_FASTCALL is present, these will result in actual
-        // pushes to the stack, which the caller will clean up. Otherwise,
-        // they'll be ignored because the registers fit into the calling
-        // sequence.
-        storeArg(0, Registers::ArgReg0);
-        storeArg(1, Registers::ArgReg1);
-
-        // [Bug 614953]: The second argument, 'canThrow', can be set to 'false'
-        // for infallibleVMCall invocations. However, this changes the call
-        // sequence on ARM, and the ARM repatcher cannot currently distinguish
-        // between the two sequences. The argument does not affect the code
-        // generated by x86 or amd64.
-        return callWithABI(ptr, true);
-    }
-
-    // Constant doubles can't be directly moved into a register, we need to put
-    // them in memory and load them back with.
-    void slowLoadConstantDouble(double d, FPRegisterID fpreg) {
-        DoublePatch patch;
-        patch.d = d;
-        patch.label = loadDouble(NULL, fpreg);
-        doublePatches.append(patch);
-    }
-
-    size_t numDoubles() { return doublePatches.length(); }
-
-    void finalize(JSC::LinkBuffer &linker, double *doubleVec = NULL) {
-        for (size_t i = 0; i < callPatches.length(); i++) {
-            CallPatch &patch = callPatches[i];
-            linker.link(patch.call, JSC::FunctionPtr(patch.fun));
-        }
-        for (size_t i = 0; i < doublePatches.length(); i++) {
-            DoublePatch &patch = doublePatches[i];
-            doubleVec[i] = patch.d;
-            linker.patch(patch.label, &doubleVec[i]);
-        }
-    }
-
-    struct FastArrayLoadFails {
-        Jump rangeCheck;
-        Jump holeCheck;
-    };
-
-    // Guard an extent (capacity, length or initialized length) on an array or typed array.
-    Jump guardArrayExtent(int offset, RegisterID reg,
-                          const Int32Key &key, Condition cond) {
-        Address extent(reg, offset);
-        if (key.isConstant())
-            return branch32(cond, extent, Imm32(key.index()));
-        return branch32(cond, extent, key.reg());
-    }
-
-    Jump guardElementNotHole(RegisterID elements, const Int32Key &key) {
-        Jump jmp;
-
-        if (key.isConstant()) {
-            Address slot(elements, key.index() * sizeof(Value));
-            jmp = guardNotHole(slot);
-        } else {
-            BaseIndex slot(elements, key.reg(), JSVAL_SCALE);
-            jmp = guardNotHole(slot);
-        }
-
-        return jmp;
-    }
-
-    // Load a jsval from an array slot, given a key. |objReg| is clobbered.
-    FastArrayLoadFails fastArrayLoad(RegisterID objReg, const Int32Key &key,
-                                     RegisterID typeReg, RegisterID dataReg) {
-        JS_ASSERT(objReg != typeReg);
-
-        RegisterID elementsReg = objReg;
-        loadPtr(Address(objReg, JSObject::offsetOfElements()), elementsReg);
-
-        FastArrayLoadFails fails;
-        fails.rangeCheck = guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                            objReg, key, BelowOrEqual);
-
-        // Load the slot out of the array.
-        if (key.isConstant()) {
-            Address slot(elementsReg, key.index() * sizeof(Value));
-            fails.holeCheck = fastArrayLoadSlot(slot, true, typeReg, dataReg);
-        } else {
-            BaseIndex slot(elementsReg, key.reg(), JSVAL_SCALE);
-            fails.holeCheck = fastArrayLoadSlot(slot, true, typeReg, dataReg);
-        }
-
-        return fails;
-    }
-
-    void storeKey(const Int32Key &key, Address address) {
-        if (key.isConstant())
-            store32(Imm32(key.index()), address);
-        else
-            store32(key.reg(), address);
-    }
-
-    void bumpKey(Int32Key &key, int32_t delta) {
-        if (key.isConstant())
-            key.index_ += delta;
-        else
-            add32(Imm32(delta), key.reg());
-    }
-
-    void loadFrameActuals(JSFunction *fun, RegisterID reg) {
-        /* Bias for the case where there was an arguments overflow. */
-        load32(Address(JSFrameReg, StackFrame::offsetOfNumActual()), reg);
-        add32(Imm32(fun->nargs + 2), reg);
-        Jump overflowArgs = branchTest32(Assembler::NonZero,
-                                         Address(JSFrameReg, StackFrame::offsetOfFlags()),
-                                         Imm32(StackFrame::OVERFLOW_ARGS));
-        move(Imm32(fun->nargs), reg);
-        overflowArgs.linkTo(label(), this);
-        lshiftPtr(Imm32(3), reg);
-        negPtr(reg);
-        addPtr(JSFrameReg, reg);
-    }
-
-    void loadBaseShape(RegisterID obj, RegisterID dest) {
-        loadPtr(Address(obj, JSObject::offsetOfShape()), dest);
-        loadPtr(Address(dest, Shape::offsetOfBase()), dest);
-    }
-
-    void loadObjClass(RegisterID obj, RegisterID dest) {
-        loadPtr(Address(obj, JSObject::offsetOfType()), dest);
-        loadPtr(Address(dest, offsetof(types::TypeObject, clasp)), dest);
-    }
-
-    Jump testClass(Condition cond, RegisterID claspReg, js::Class *clasp) {
-        return branchPtr(cond, claspReg, ImmPtr(clasp));
-    }
-
-    Jump testObjClass(Condition cond, RegisterID obj, RegisterID temp, js::Class *clasp) {
-        loadPtr(Address(obj, JSObject::offsetOfType()), temp);
-        return branchPtr(cond, Address(temp, offsetof(types::TypeObject, clasp)), ImmPtr(clasp));
-    }
-
-    Jump testFunction(Condition cond, RegisterID fun, RegisterID temp) {
-        return testObjClass(cond, fun, temp, &js::FunctionClass);
-    }
-
-    void branchValue(Condition cond, RegisterID reg, int32_t value, RegisterID result)
-    {
-        if (Registers::maskReg(result) & Registers::SingleByteRegs) {
-            set32(cond, reg, Imm32(value), result);
-        } else {
-            Jump j = branch32(cond, reg, Imm32(value));
-            move(Imm32(0), result);
-            Jump skip = jump();
-            j.linkTo(label(), this);
-            move(Imm32(1), result);
-            skip.linkTo(label(), this);
-        }
-    }
-
-    void branchValue(Condition cond, RegisterID lreg, RegisterID rreg, RegisterID result)
-    {
-        if (Registers::maskReg(result) & Registers::SingleByteRegs) {
-            set32(cond, lreg, rreg, result);
-        } else {
-            Jump j = branch32(cond, lreg, rreg);
-            move(Imm32(0), result);
-            Jump skip = jump();
-            j.linkTo(label(), this);
-            move(Imm32(1), result);
-            skip.linkTo(label(), this);
-        }
-    }
-
-    void rematPayload(const StateRemat &remat, RegisterID reg) {
-        if (remat.inMemory())
-            loadPayload(remat.address(), reg);
-        else
-            move(remat.reg(), reg);
-    }
-
-    void loadDynamicSlot(RegisterID objReg, uint32_t index,
-                         RegisterID typeReg, RegisterID dataReg) {
-        loadPtr(Address(objReg, JSObject::offsetOfSlots()), dataReg);
-        loadValueAsComponents(Address(dataReg, index * sizeof(Value)), typeReg, dataReg);
-    }
-
-    void loadObjProp(JSObject *obj, RegisterID objReg,
-                     js::Shape *shape,
-                     RegisterID typeReg, RegisterID dataReg)
-    {
-        if (obj->isFixedSlot(shape->slot()))
-            loadInlineSlot(objReg, shape->slot(), typeReg, dataReg);
-        else
-            loadDynamicSlot(objReg, obj->dynamicSlotIndex(shape->slot()), typeReg, dataReg);
-    }
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-    // Load a value from a typed array's packed data vector into dataReg.
-    // This function expects the following combinations of typeReg, dataReg and tempReg:
-    // 1) for all INT arrays other than UINT32:
-    //    - dataReg is a GP-register
-    //    - typeReg is optional
-    //    - tempReg is not set
-    // 2) for UINT32:
-    //    - dataReg is either a FP-register or a GP-register
-    //    - typeReg is set if dataReg is a GP-register
-    //    - tempReg is set if dataReg is a FP-register
-    // 3) for FLOAT32 and FLOAT64:
-    //    - dataReg is either a FP-register or a GP-register
-    //    - typeReg is set if dataReg is a GP-register
-    //    - tempReg is not set
-    template <typename T>
-    void loadFromTypedArray(int atype, T address, MaybeRegisterID typeReg,
-                            AnyRegisterID dataReg, MaybeRegisterID tempReg)
-    {
-        // If dataReg is an FP-register we don't use typeReg.
-        JS_ASSERT_IF(dataReg.isFPReg(), !typeReg.isSet());
-
-        // We only need tempReg for Uint32Array and only if dataReg is an FP-register.
-        JS_ASSERT_IF(atype != js::TypedArray::TYPE_UINT32 || dataReg.isReg(), !tempReg.isSet());
-
-        switch (atype) {
-          case js::TypedArray::TYPE_INT8:
-            load8SignExtend(address, dataReg.reg());
-            if (typeReg.isSet())
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-            break;
-          case js::TypedArray::TYPE_UINT8:
-          case js::TypedArray::TYPE_UINT8_CLAMPED:
-            load8ZeroExtend(address, dataReg.reg());
-            if (typeReg.isSet())
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-            break;
-          case js::TypedArray::TYPE_INT16:
-            load16SignExtend(address, dataReg.reg());
-            if (typeReg.isSet())
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-            break;
-          case js::TypedArray::TYPE_UINT16:
-            load16(address, dataReg.reg());
-            if (typeReg.isSet())
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-            break;
-          case js::TypedArray::TYPE_INT32:
-            load32(address, dataReg.reg());
-            if (typeReg.isSet())
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-            break;
-          case js::TypedArray::TYPE_UINT32:
-          {
-            // For Uint32Array the result is either int32_t or double.
-            // If dataReg is a GP-register, load a double or int32_t into dataReg/typeReg.
-            // If dataReg is a FP-register, load the value as double.
-            if (dataReg.isReg()) {
-                load32(address, dataReg.reg());
-                move(ImmType(JSVAL_TYPE_INT32), typeReg.reg());
-                Jump safeInt = branch32(Assembler::Below, dataReg.reg(), Imm32(0x80000000));
-                convertUInt32ToDouble(dataReg.reg(), Registers::FPConversionTemp);
-                breakDouble(Registers::FPConversionTemp, typeReg.reg(), dataReg.reg());
-                safeInt.linkTo(label(), this);
-            } else {
-                load32(address, tempReg.reg());
-                convertUInt32ToDouble(tempReg.reg(), dataReg.fpreg());
-            }
-            break;
-          }
-          case js::TypedArray::TYPE_FLOAT32:
-          case js::TypedArray::TYPE_FLOAT64:
-          {
-            FPRegisterID fpreg = dataReg.isReg()
-                               ? Registers::FPConversionTemp
-                               : dataReg.fpreg();
-            if (atype == js::TypedArray::TYPE_FLOAT32)
-                loadFloat(address, fpreg);
-            else
-                loadDouble(address, fpreg);
-            // Make sure NaN gets canonicalized. If dataReg is not an FP-register
-            // we have to use loadStaticDouble as we were probably called from an
-            // IC and we can't use slowLoadConstantDouble.
-            Jump notNaN = branchDouble(Assembler::DoubleEqual, fpreg, fpreg);
-            if (dataReg.isReg())
-                loadStaticDouble(&js_NaN, Registers::FPConversionTemp, dataReg.reg());
-            else
-                slowLoadConstantDouble(js_NaN, fpreg);
-            notNaN.linkTo(label(), this);
-            if (dataReg.isReg())
-                breakDouble(Registers::FPConversionTemp, typeReg.reg(), dataReg.reg());
-            break;
-          }
-        }
-    }
-
-    void loadFromTypedArray(int atype, RegisterID objReg, Int32Key key,
-                            MaybeRegisterID typeReg, AnyRegisterID dataReg,
-                            MaybeRegisterID tempReg)
-    {
-        int shift = TypedArray::slotWidth(atype);
-
-        if (key.isConstant()) {
-            Address addr(objReg, key.index() * shift);
-            loadFromTypedArray(atype, addr, typeReg, dataReg, tempReg);
-        } else {
-            Assembler::Scale scale = Assembler::TimesOne;
-            switch (shift) {
-              case 2:
-                scale = Assembler::TimesTwo;
-                break;
-              case 4:
-                scale = Assembler::TimesFour;
-                break;
-              case 8:
-                scale = Assembler::TimesEight;
-                break;
-            }
-            BaseIndex addr(objReg, key.reg(), scale);
-            loadFromTypedArray(atype, addr, typeReg, dataReg, tempReg);
-        }
-    }
-
-    template <typename S, typename T>
-    void storeToTypedIntArray(int atype, S src, T address)
-    {
-        switch (atype) {
-          case js::TypedArray::TYPE_INT8:
-          case js::TypedArray::TYPE_UINT8:
-          case js::TypedArray::TYPE_UINT8_CLAMPED:
-            store8(src, address);
-            break;
-          case js::TypedArray::TYPE_INT16:
-          case js::TypedArray::TYPE_UINT16:
-            store16(src, address);
-            break;
-          case js::TypedArray::TYPE_INT32:
-          case js::TypedArray::TYPE_UINT32:
-            store32(src, address);
-            break;
-          default:
-            JS_NOT_REACHED("unknown int array type");
-        }
-    }
-
-    template <typename S, typename T>
-    void storeToTypedFloatArray(int atype, S src, T address)
-    {
-        if (atype == js::TypedArray::TYPE_FLOAT32)
-            storeFloat(src, address);
-        else
-            storeDouble(src, address);
-    }
-
-    template <typename T>
-#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 7 && defined(JS_CPU_ARM)
-    __attribute__((optimize("-O1")))
-#endif
-    void storeToTypedArray(int atype, ValueRemat vr, T address)
-    {
-        if (atype == js::TypedArray::TYPE_FLOAT32 || atype == js::TypedArray::TYPE_FLOAT64) {
-            if (vr.isConstant())
-                storeToTypedFloatArray(atype, ImmDouble(vr.value().toDouble()), address);
-            else
-                storeToTypedFloatArray(atype, vr.fpReg(), address);
-        } else {
-            if (vr.isConstant())
-                storeToTypedIntArray(atype, Imm32(vr.value().toInt32()), address);
-            else
-                storeToTypedIntArray(atype, vr.dataReg(), address);
-        }
-    }
-
-    void storeToTypedArray(int atype, RegisterID objReg, Int32Key key, ValueRemat vr)
-    {
-        int shift = TypedArray::slotWidth(atype);
-        if (key.isConstant()) {
-            Address addr(objReg, key.index() * shift);
-            storeToTypedArray(atype, vr, addr);
-        } else {
-            Assembler::Scale scale = Assembler::TimesOne;
-            switch (shift) {
-            case 2:
-                scale = Assembler::TimesTwo;
-                break;
-            case 4:
-                scale = Assembler::TimesFour;
-                break;
-            case 8:
-                scale = Assembler::TimesEight;
-                break;
-            }
-            BaseIndex addr(objReg, key.reg(), scale);
-            storeToTypedArray(atype, vr, addr);
-        }
-    }
-
-    void clampInt32ToUint8(RegisterID reg)
-    {
-        Jump j = branch32(Assembler::GreaterThanOrEqual, reg, Imm32(0));
-        move(Imm32(0), reg);
-        Jump done = jump();
-        j.linkTo(label(), this);
-        j = branch32(Assembler::LessThanOrEqual, reg, Imm32(255));
-        move(Imm32(255), reg);
-        j.linkTo(label(), this);
-        done.linkTo(label(), this);
-    }
-
-    // Inline version of js::ClampDoubleToUint8.
-    void clampDoubleToUint8(FPRegisterID fpReg, FPRegisterID fpTemp, RegisterID reg)
-    {
-        JS_ASSERT(fpTemp != Registers::FPConversionTemp);
-
-        // <= 0 or NaN ==> 0
-        zeroDouble(fpTemp);
-        Jump positive = branchDouble(Assembler::DoubleGreaterThan, fpReg, fpTemp);
-        move(Imm32(0), reg);
-        Jump done1 = jump();
-
-        // Add 0.5 and truncate.
-        positive.linkTo(label(), this);
-        slowLoadConstantDouble(0.5, fpTemp);
-        addDouble(fpReg, fpTemp);
-        Jump notInt = branchTruncateDoubleToInt32(fpTemp, reg);
-
-        // > 255 ==> 255
-        Jump inRange = branch32(Assembler::BelowOrEqual, reg, Imm32(255));
-        notInt.linkTo(label(), this);
-        move(Imm32(255), reg);
-        Jump done2 = jump();
-
-        // Check if we had a tie.
-        inRange.linkTo(label(), this);
-        convertInt32ToDouble(reg, Registers::FPConversionTemp);
-        Jump done3 = branchDouble(Assembler::DoubleNotEqual, fpTemp, Registers::FPConversionTemp);
-
-        // It was a tie. Mask out the ones bit to get an even value.
-        // See js::ClampDoubleToUint8 for the reasoning behind this.
-        and32(Imm32(~1), reg);
-
-        done1.linkTo(label(), this);
-        done2.linkTo(label(), this);
-        done3.linkTo(label(), this);
-    }
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-    Address objPropAddress(JSObject *obj, RegisterID objReg, uint32_t slot)
-    {
-        if (obj->isFixedSlot(slot))
-            return Address(objReg, JSObject::getFixedSlotOffset(slot));
-        loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
-        return Address(objReg, obj->dynamicSlotIndex(slot) * sizeof(Value));
-    }
-
-    static uint32_t maskAddress(Address address) {
-        return Registers::maskReg(address.base);
-    }
-
-    static uint32_t maskAddress(BaseIndex address) {
-        return Registers::maskReg(address.base) |
-               Registers::maskReg(address.index);
-    }
-
-    /*
-     * Generate code testing whether an in memory value at address has a type
-     * in the specified set. Updates mismatches with any failure jumps. Assumes
-     * that no temporary (caller save) registers are live.
-     */
-    bool generateTypeCheck(JSContext *cx, Address address,
-                           types::TypeSet *types, Vector<Jump> *mismatches)
-    {
-        if (types->unknown())
-            return true;
-
-        Vector<Jump> matches(cx);
-
-        if (types->hasType(types::Type::DoubleType())) {
-            /* Type sets containing double also contain int. */
-            if (!matches.append(testNumber(Assembler::Equal, address)))
-                return false;
-        } else if (types->hasType(types::Type::Int32Type())) {
-            if (!matches.append(testInt32(Assembler::Equal, address)))
-                return false;
-        }
-
-        if (types->hasType(types::Type::UndefinedType())) {
-            if (!matches.append(testUndefined(Assembler::Equal, address)))
-                return false;
-        }
-
-        if (types->hasType(types::Type::BooleanType())) {
-            if (!matches.append(testBoolean(Assembler::Equal, address)))
-                return false;
-        }
-
-        if (types->hasType(types::Type::StringType())) {
-            if (!matches.append(testString(Assembler::Equal, address)))
-                return false;
-        }
-
-        if (types->hasType(types::Type::NullType())) {
-            if (!matches.append(testNull(Assembler::Equal, address)))
-                return false;
-        }
-
-        unsigned count = 0;
-        if (types->hasType(types::Type::AnyObjectType())) {
-            if (!matches.append(testObject(Assembler::Equal, address)))
-                return false;
-        } else {
-            count = types->getObjectCount();
-        }
-
-        if (count != 0) {
-            if (!mismatches->append(testObject(Assembler::NotEqual, address)))
-                return false;
-            RegisterID reg = Registers::ArgReg1;
-
-            loadPayload(address, reg);
-
-            for (unsigned i = 0; i < count; i++) {
-                if (JSObject *object = types->getSingleObject(i)) {
-                    if (!matches.append(branchPtr(Assembler::Equal, reg, ImmPtr(object))))
-                        return false;
-                }
-            }
-
-            loadPtr(Address(reg, JSObject::offsetOfType()), reg);
-
-            for (unsigned i = 0; i < count; i++) {
-                if (types::TypeObject *object = types->getTypeObject(i)) {
-                    if (!matches.append(branchPtr(Assembler::Equal, reg, ImmPtr(object))))
-                        return false;
-                }
-            }
-        }
-
-        if (!mismatches->append(jump()))
-            return false;
-
-        for (unsigned i = 0; i < matches.length(); i++)
-            matches[i].linkTo(label(), this);
-
-        return true;
-    }
-
-    /*
-     * Get a free object for the specified GC kind in compartment, writing it
-     * to result and filling it in according to templateObject. Returns a jump
-     * taken if a free thing was not retrieved. Note: don't call this directly,
-     * use Compiler::getNewObject instead.
-     */
-    Jump getNewObject(JSContext *cx, RegisterID result, JSObject *templateObject)
-    {
-        gc::AllocKind allocKind = templateObject->tenuredGetAllocKind();
-
-        JS_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST);
-        int thingSize = (int)gc::Arena::thingSize(allocKind);
-
-        JS_ASSERT(cx->typeInferenceEnabled());
-        JS_ASSERT(!templateObject->hasDynamicSlots());
-        JS_ASSERT(!templateObject->hasDynamicElements());
-
-#ifdef JS_GC_ZEAL
-        if (cx->runtime->needZealousGC())
-            return jump();
-#endif
-
-        /*
-         * Inline FreeSpan::allocate. Only the case where the current freelist
-         * span is not empty is handled.
-         */
-        gc::FreeSpan *list = const_cast<gc::FreeSpan *>
-                             (cx->zone()->allocator.arenas.getFreeList(allocKind));
-        loadPtr(&list->first, result);
-
-        Jump jump = branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(&list->last), result);
-
-        addPtr(Imm32(thingSize), result);
-        storePtr(result, &list->first);
-
-        /*
-         * Fill in the blank object. Order doesn't matter here, from here
-         * everything is infallible. Note that this bakes GC thing pointers
-         * into the code without explicitly pinning them. With type inference
-         * enabled, JIT code is collected on GC except when analysis or
-         * compilation is active, in which case type objects won't be collected
-         * but other things may be. The shape held by templateObject *must* be
-         * pinned against GC either by the script or by some type object.
-         */
-
-        int elementsOffset = JSObject::offsetOfFixedElements();
-
-        /*
-         * Write out the elements pointer before readjusting the result register,
-         * as for dense arrays we will need to get the address of the fixed
-         * elements first.
-         */
-        if (templateObject->isArray()) {
-            JS_ASSERT(!templateObject->getDenseInitializedLength());
-            addPtr(Imm32(-thingSize + elementsOffset), result);
-            storePtr(result, Address(result, -elementsOffset + JSObject::offsetOfElements()));
-            addPtr(Imm32(-elementsOffset), result);
-        } else {
-            addPtr(Imm32(-thingSize), result);
-            storePtr(ImmPtr(emptyObjectElements), Address(result, JSObject::offsetOfElements()));
-        }
-
-        storePtr(ImmPtr(templateObject->lastProperty()), Address(result, JSObject::offsetOfShape()));
-        storePtr(ImmPtr(templateObject->type()), Address(result, JSObject::offsetOfType()));
-        storePtr(ImmPtr(NULL), Address(result, JSObject::offsetOfSlots()));
-
-        if (templateObject->isArray()) {
-            /* Fill in the elements header. */
-            store32(Imm32(templateObject->getDenseCapacity()),
-                    Address(result, elementsOffset + ObjectElements::offsetOfCapacity()));
-            store32(Imm32(templateObject->getDenseInitializedLength()),
-                    Address(result, elementsOffset + ObjectElements::offsetOfInitializedLength()));
-            store32(Imm32(templateObject->getArrayLength()),
-                    Address(result, elementsOffset + ObjectElements::offsetOfLength()));
-            store32(Imm32(templateObject->shouldConvertDoubleElements()
-                          ? ObjectElements::CONVERT_DOUBLE_ELEMENTS
-                          : 0),
-                    Address(result, elementsOffset + ObjectElements::offsetOfFlags()));
-        } else {
-            /*
-             * Fixed slots of non-array objects are required to be initialized;
-             * Use the values currently in the template object.
-             */
-            for (unsigned i = 0; i < templateObject->slotSpan(); i++) {
-                storeValue(templateObject->getFixedSlot(i),
-                           Address(result, JSObject::getFixedSlotOffset(i)));
-            }
-        }
-
-        if (templateObject->hasPrivate()) {
-            uint32_t nfixed = templateObject->numFixedSlots();
-            storePtr(ImmPtr(templateObject->getPrivate()),
-                     Address(result, JSObject::getPrivateDataOffset(nfixed)));
-        }
-
-        return jump;
-    }
-
-    /* Add the value stored in 'value' to the accumulator 'count'. */
-    void addCount(const double *value, double *count, RegisterID scratch)
-    {
-        loadDouble(value, Registers::FPConversionTemp);
-        move(ImmPtr(count), scratch);
-        addDouble(Address(scratch), Registers::FPConversionTemp);
-        storeDouble(Registers::FPConversionTemp, Address(scratch));
-    }
-
-    /* Add one to the accumulator |count|. */
-    void bumpCount(double *count, RegisterID scratch)
-    {
-        addCount(&oneDouble, count, scratch);
-    }
-
-    /* Bump the stub call count for script/pc if they are being counted. */
-    void bumpStubCount(JSScript *script, jsbytecode *pc, RegisterID scratch)
-    {
-        if (script->hasScriptCounts) {
-            PCCounts counts = script->getPCCounts(pc);
-            double *count = &counts.get(PCCounts::BASE_METHODJIT_STUBS);
-            bumpCount(count, scratch);
-        }
-    }
-
-  private:
-    /*
-     * Performs address arithmetic to return the base of the ProfileEntry into
-     * the register provided. The Jump returned is taken if the SPS stack is
-     * overflowing and no data should be written to it.
-     */
-    Jump spsProfileEntryAddress(SPSProfiler *p, int offset, RegisterID reg)
-    {
-        load32(p->sizePointer(), reg);
-        if (offset != 0)
-            add32(Imm32(offset), reg);
-        Jump j = branch32(Assembler::GreaterThanOrEqual, reg, Imm32(p->maxSize()));
-        JS_STATIC_ASSERT(sizeof(ProfileEntry) == 4 * sizeof(void*));
-        // 4 * sizeof(void*) * idx = idx << (2 + log(sizeof(void*)))
-        lshift32(Imm32(2 + (sizeof(void*) == 4 ? 2 : 3)), reg);
-        addPtr(ImmPtr(p->stack()), reg);
-        return j;
-    }
-
-  public:
-    void spsUpdatePCIdx(SPSProfiler *p, int32_t idx, RegisterID reg) {
-        Jump j = spsProfileEntryAddress(p, -1, reg);
-        store32(Imm32(idx), Address(reg, ProfileEntry::offsetOfPCIdx()));
-        j.linkTo(label(), this);
-    }
-
-    void spsPushFrame(SPSProfiler *p, const char *str, JSScript *s, RegisterID reg) {
-        Jump j = spsProfileEntryAddress(p, 0, reg);
-
-        storePtr(ImmPtr(str),  Address(reg, ProfileEntry::offsetOfString()));
-        storePtr(ImmPtr(s),    Address(reg, ProfileEntry::offsetOfScript()));
-        storePtr(ImmPtr(NULL), Address(reg, ProfileEntry::offsetOfStackAddress()));
-        store32(Imm32(ProfileEntry::NullPCIndex),
-                Address(reg, ProfileEntry::offsetOfPCIdx()));
-
-        /* Always increment the stack size, regardless if we actually pushed */
-        j.linkTo(label(), this);
-        add32(Imm32(1), AbsoluteAddress(p->sizePointer()));
-    }
-
-    void spsPopFrame(SPSProfiler *p, RegisterID reg) {
-        move(ImmPtr(p->sizePointer()), reg);
-        sub32(Imm32(1), Address(reg, 0));
-    }
-
-    static const double oneDouble;
-};
-
-/* Return f<true> if the script is strict mode code, f<false> otherwise. */
-#define STRICT_VARIANT(script, f)                                             \
-    (FunctionTemplateConditional(script->strict,                              \
-                                 f<true>, f<false>))
-
-/* Save some typing. */
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = Assembler::JSReturnReg_Type;
-static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = Assembler::JSReturnReg_Data;
-static const JSC::MacroAssembler::RegisterID JSParamReg_Argc  = Assembler::JSParamReg_Argc;
-
-struct FrameFlagsAddress : JSC::MacroAssembler::Address
-{
-    FrameFlagsAddress()
-      : Address(JSFrameReg, StackFrame::offsetOfFlags())
-    {}
-};
-
-class PreserveRegisters {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    Assembler   &masm;
-    uint32_t    count;
-    RegisterID  regs[JSC::MacroAssembler::TotalRegisters];
-
-  public:
-    PreserveRegisters(Assembler &masm) : masm(masm), count(0) { }
-    ~PreserveRegisters() { JS_ASSERT(!count); }
-
-    void preserve(Registers mask) {
-        JS_ASSERT(!count);
-
-        while (!mask.empty()) {
-            RegisterID reg = mask.takeAnyReg().reg();
-            regs[count++] = reg;
-            masm.saveReg(reg);
-        }
-    }
-
-    void restore() {
-        while (count)
-            masm.restoreReg(regs[--count]);
-    }
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/BaseCompiler.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-#if !defined jsjaeger_compilerbase_h__ && defined JS_METHODJIT
-#define jsjaeger_compilerbase_h__
-
-#include "jscntxt.h"
-#include "assembler/assembler/MacroAssembler.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "assembler/assembler/RepatchBuffer.h"
-#include "assembler/jit/ExecutableAllocator.h"
-#include <limits.h>
-
-#if defined JS_CPU_ARM
-# define POST_INST_OFFSET(__expr) ((__expr) - sizeof(ARMWord))
-#else
-# define POST_INST_OFFSET(__expr) (__expr)
-#endif
-
-namespace js {
-namespace mjit {
-
-struct MacroAssemblerTypedefs {
-    typedef JSC::MacroAssembler::Label Label;
-    typedef JSC::MacroAssembler::Imm32 Imm32;
-    typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-    typedef JSC::MacroAssembler::Address Address;
-    typedef JSC::MacroAssembler::BaseIndex BaseIndex;
-    typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
-    typedef JSC::MacroAssembler MacroAssembler;
-    typedef JSC::MacroAssembler::Jump Jump;
-    typedef JSC::MacroAssembler::JumpList JumpList;
-    typedef JSC::MacroAssembler::Call Call;
-    typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
-    typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
-    typedef JSC::FunctionPtr FunctionPtr;
-    typedef JSC::RepatchBuffer RepatchBuffer;
-    typedef JSC::CodeLocationLabel CodeLocationLabel;
-    typedef JSC::CodeLocationDataLabel32 CodeLocationDataLabel32;
-    typedef JSC::CodeLocationDataLabelPtr CodeLocationDataLabelPtr;
-    typedef JSC::CodeLocationJump CodeLocationJump;
-    typedef JSC::CodeLocationCall CodeLocationCall;
-    typedef JSC::CodeLocationInstruction CodeLocationInstruction;
-    typedef JSC::ReturnAddressPtr ReturnAddressPtr;
-    typedef JSC::MacroAssemblerCodePtr MacroAssemblerCodePtr;
-    typedef JSC::JITCode JITCode;
-#if defined JS_CPU_ARM
-    typedef JSC::ARMWord ARMWord;
-#endif
-};
-
-class BaseCompiler : public MacroAssemblerTypedefs
-{
-  protected:
-    JSContext *cx;
-
-  public:
-    BaseCompiler() : cx(NULL)
-    { }
-
-    BaseCompiler(JSContext *cx) : cx(cx)
-    { }
-};
-
-#ifdef JS_CPU_X64
-inline bool
-VerifyRange(void *start1, size_t size1, void *start2, size_t size2)
-{
-    uintptr_t end1 = uintptr_t(start1) + size1;
-    uintptr_t end2 = uintptr_t(start2) + size2;
-
-    uintptr_t lowest = Min(uintptr_t(start1), uintptr_t(start2));
-    uintptr_t highest = Max(end1, end2);
-
-    return (highest - lowest < INT_MAX);
-}
-#endif
-
-// This class wraps JSC::LinkBuffer for Mozilla-specific memory handling.
-// Every return |false| guarantees an OOM that has been correctly propagated,
-// and should continue to propagate.
-class LinkerHelper : public JSC::LinkBuffer
-{
-  protected:
-    Assembler &masm;
-#ifdef DEBUG
-    bool verifiedRange;
-#endif
-
-  public:
-    LinkerHelper(Assembler &masm, JSC::CodeKind kind) : JSC::LinkBuffer(kind)
-        , masm(masm)
-#ifdef DEBUG
-        , verifiedRange(false)
-#endif
-    { }
-
-    ~LinkerHelper() {
-        JS_ASSERT(verifiedRange);
-    }
-
-    bool verifyRange(const JSC::JITCode &other) {
-        markVerified();
-#ifdef JS_CPU_X64
-        return VerifyRange(m_code, m_size, other.start(), other.size());
-#else
-        return true;
-#endif
-    }
-
-    bool verifyRange(JITChunk *chunk) {
-        return verifyRange(JSC::JITCode(chunk->code.m_code.executableAddress(),
-                                        chunk->code.m_size));
-    }
-
-    JSC::ExecutablePool *init(JSContext *cx) {
-        // The pool is incref'd after this call, so it's necessary to release()
-        // on any failure.
-        JSC::ExecutableAllocator *allocator = &cx->runtime->execAlloc();
-        allocator->setDestroyCallback(Probes::discardExecutableRegion);
-        JSC::ExecutablePool *pool;
-        m_code = executableAllocAndCopy(masm, allocator, &pool);
-        if (!m_code) {
-            markVerified();
-            js_ReportOutOfMemory(cx);
-            return NULL;
-        }
-        m_size = masm.size();   // must come after call to executableAllocAndCopy()!
-        return pool;
-    }
-
-    JSC::CodeLocationLabel finalize(VMFrame &f) {
-        masm.finalize(*this);
-        JSC::CodeLocationLabel label = finalizeCodeAddendum();
-        Probes::registerICCode(f.cx, f.chunk(), f.script(), f.pc(),
-                               label.executableAddress(), masm.size());
-        return label;
-    }
-
-    void maybeLink(MaybeJump jump, JSC::CodeLocationLabel label) {
-        if (!jump.isSet())
-            return;
-        link(jump.get(), label);
-    }
-
-    size_t size() const {
-        return m_size;
-    }
-
-  protected:
-    void markVerified() {
-#ifdef DEBUG
-        verifiedRange = true;
-#endif
-    }
-};
-
-class NativeStubLinker : public LinkerHelper
-{
-  public:
-#ifdef JS_CPU_X64
-    typedef JSC::MacroAssembler::DataLabelPtr FinalJump;
-#else
-    typedef JSC::MacroAssembler::Jump FinalJump;
-#endif
-
-    NativeStubLinker(Assembler &masm, JITChunk *chunk, jsbytecode *pc, FinalJump done)
-        : LinkerHelper(masm, JSC::JAEGER_CODE), chunk(chunk), pc(pc), done(done)
-    {}
-
-    bool init(JSContext *cx);
-
-    void patchJump(JSC::CodeLocationLabel target) {
-#ifdef JS_CPU_X64
-        patch(done, target);
-#else
-        link(done, target);
-#endif
-    }
-
-  private:
-    JITChunk *chunk;
-    jsbytecode *pc;
-    FinalJump done;
-};
-
-bool
-NativeStubEpilogue(VMFrame &f, Assembler &masm, NativeStubLinker::FinalJump *result,
-                   int32_t initialFrameDepth, int32_t vpOffset,
-                   MaybeRegisterID typeReg, MaybeRegisterID dataReg);
-
-/*
- * On ARM, we periodically flush a constant pool into the instruction stream
- * where constants are found using PC-relative addressing. This is necessary
- * because the fixed-width instruction set doesn't support wide immediates.
- *
- * ICs perform repatching on the inline (fast) path by knowing small and
- * generally fixed code location offset values where the patchable instructions
- * live. Dumping a huge constant pool into the middle of an IC's inline path
- * makes the distance between emitted instructions potentially variable and/or
- * large, which makes the IC offsets invalid. We must reserve contiguous space
- * up front to prevent this from happening.
- */
-#ifdef JS_CPU_ARM
-template <size_t reservedSpace>
-class AutoReserveICSpace {
-    typedef Assembler::Label Label;
-
-    Assembler           &masm;
-    bool                didCheck;
-    bool                *overflowSpace;
-    int                 flushCount;
-
-  public:
-    AutoReserveICSpace(Assembler &masm, bool *overflowSpace)
-        : masm(masm), didCheck(false), overflowSpace(overflowSpace)
-    {
-        masm.ensureSpace(reservedSpace);
-        flushCount = masm.flushCount();
-    }
-
-    /* Allow manual IC space checks so that non-patchable code at the end of an IC section can be
-     * free to use constant pools. */
-    void check() {
-        JS_ASSERT(!didCheck);
-        didCheck = true;
-
-        if (masm.flushCount() != flushCount)
-            *overflowSpace = true;
-    }
-
-    ~AutoReserveICSpace() {
-        /* Automatically check the IC space if we didn't already do it manually. */
-        if (!didCheck) {
-            check();
-        }
-    }
-};
-
-# define RESERVE_IC_SPACE(__masm)       AutoReserveICSpace<256> arics(__masm, &this->overflowICSpace)
-# define CHECK_IC_SPACE()               arics.check()
-
-/* The OOL path can need a lot of space because we save and restore a lot of registers. The actual
- * sequene varies. However, dumping the literal pool before an OOL block is probably a good idea
- * anyway, as we branch directly to the start of the block from the fast path. */
-# define RESERVE_OOL_SPACE(__masm)      AutoReserveICSpace<2048> arics_ool(__masm, &this->overflowICSpace)
-
-/* Allow the OOL patch to be checked before object destruction. Often, non-patchable epilogues or
- * rejoining sequences are emitted, and it isn't necessary to protect these from literal pools. */
-# define CHECK_OOL_SPACE()              arics_ool.check()
-#else
-# define RESERVE_IC_SPACE(__masm)       /* Do nothing. */
-# define CHECK_IC_SPACE()               /* Do nothing. */
-# define RESERVE_OOL_SPACE(__masm)      /* Do nothing. */
-# define CHECK_OOL_SPACE()              /* Do nothing. */
-#endif
-
-} /* namespace js */
-} /* namespace mjit */
-
-#endif
deleted file mode 100644
--- a/js/src/methodjit/CodeGenIncludes.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_codegenincs_h__ && defined JS_METHODJIT
-#define jsjaeger_codegenincs_h__
-
-/* Get a label for assertion purposes. Prevent #ifdef clutter. */
-#ifdef DEBUG
-# define DBGLABEL(name) Label name = masm.label();
-# define DBGLABEL_NOMASM(name) Label name = label();
-# define DBGLABEL_ASSIGN(name) name = masm.label();
-#else
-# define DBGLABEL(name)
-# define DBGLABEL_NOMASM(name)
-# define DBGLABEL_ASSIGN(name)
-#endif
-
-#if defined JS_NUNBOX32
-# include "NunboxAssembler.h"
-#elif defined JS_PUNBOX64
-# include "PunboxAssembler.h"
-#else
-# error "Neither JS_NUNBOX32 nor JS_PUNBOX64 is defined."
-#endif
-
-#include "BaseAssembler.h"
-
-#endif /* jsjaeger_codegenincs_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/Compiler.cpp
+++ /dev/null
@@ -1,8223 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/DebugOnly.h"
-
-#include "MethodJIT.h"
-#include "jsnum.h"
-#include "jsbool.h"
-#include "jsiter.h"
-#include "Compiler.h"
-#include "StubCalls.h"
-#include "MonoIC.h"
-#include "PolyIC.h"
-#include "ICChecker.h"
-#include "Retcon.h"
-#include "assembler/jit/ExecutableAllocator.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "FrameState-inl.h"
-#include "jsobjinlines.h"
-#include "jsscriptinlines.h"
-#include "InlineFrameAssembler.h"
-#include "jscompartment.h"
-#include "jsopcodeinlines.h"
-#include "jsworkers.h"
-
-#include "builtin/RegExp.h"
-#include "vm/RegExpStatics.h"
-#include "vm/RegExpObject.h"
-
-#include "jsautooplen.h"
-#include "jstypedarrayinlines.h"
-#include "vm/RegExpObject-inl.h"
-
-#include "ion/BaselineJIT.h"
-#include "ion/Ion.h"
-
-#if JS_TRACE_LOGGING
-#include "TraceLogging.h"
-#endif
-
-using namespace js;
-using namespace js::mjit;
-#if defined(JS_POLYIC) || defined(JS_MONOIC)
-using namespace js::mjit::ic;
-#endif
-using namespace js::analyze;
-
-using mozilla::DebugOnly;
-
-#define RETURN_IF_OOM(retval)                                   \
-    JS_BEGIN_MACRO                                              \
-        if (oomInVector || masm.oom() || stubcc.masm.oom())     \
-            return retval;                                      \
-    JS_END_MACRO
-
-static inline bool IsIonEnabled(JSContext *cx)
-{
-#ifdef JS_ION
-    return ion::IsEnabled(cx);
-#else
-    return false;
-#endif
-}
-
-/*
- * Number of times a script must be called or had a backedge before we try to
- * inline its calls. This is only used if IonMonkey is disabled.
- */
-static const size_t USES_BEFORE_INLINING = 10240;
-
-mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript,
-                         unsigned chunkIndex, bool isConstructing)
-  : BaseCompiler(cx),
-    outerScript(cx, outerScript),
-    chunkIndex(chunkIndex),
-    isConstructing(isConstructing),
-    outerChunk(outerJIT()->chunkDescriptor(chunkIndex)),
-    ssa(cx, outerScript),
-    globalObj(cx, outerScript->compileAndGo ? &outerScript->global() : NULL),
-    globalSlots(globalObj ? globalObj->getRawSlots() : NULL),
-    sps(&cx->runtime->spsProfiler),
-    masm(&sps, &PC),
-    frame(cx, *thisFromCtor(), masm, stubcc),
-    a(NULL), outer(NULL), script_(cx), PC(NULL), loop(NULL),
-    inlineFrames(CompilerAllocPolicy(cx, *thisFromCtor())),
-    branchPatches(CompilerAllocPolicy(cx, *thisFromCtor())),
-#if defined JS_MONOIC
-    getGlobalNames(CompilerAllocPolicy(cx, *thisFromCtor())),
-    setGlobalNames(CompilerAllocPolicy(cx, *thisFromCtor())),
-    callICs(CompilerAllocPolicy(cx, *thisFromCtor())),
-    equalityICs(CompilerAllocPolicy(cx, *thisFromCtor())),
-#endif
-#if defined JS_POLYIC
-    pics(CompilerAllocPolicy(cx, *thisFromCtor())),
-    getElemICs(CompilerAllocPolicy(cx, *thisFromCtor())),
-    setElemICs(CompilerAllocPolicy(cx, *thisFromCtor())),
-#endif
-    callPatches(CompilerAllocPolicy(cx, *thisFromCtor())),
-    callSites(CompilerAllocPolicy(cx, *thisFromCtor())),
-    compileTriggers(CompilerAllocPolicy(cx, *thisFromCtor())),
-    doubleList(CompilerAllocPolicy(cx, *thisFromCtor())),
-    rootedTemplates(CompilerAllocPolicy(cx, *thisFromCtor())),
-    rootedRegExps(CompilerAllocPolicy(cx, *thisFromCtor())),
-    monitoredBytecodes(CompilerAllocPolicy(cx, *thisFromCtor())),
-    typeBarrierBytecodes(CompilerAllocPolicy(cx, *thisFromCtor())),
-    fixedIntToDoubleEntries(CompilerAllocPolicy(cx, *thisFromCtor())),
-    fixedDoubleToAnyEntries(CompilerAllocPolicy(cx, *thisFromCtor())),
-    jumpTables(CompilerAllocPolicy(cx, *thisFromCtor())),
-    jumpTableEdges(CompilerAllocPolicy(cx, *thisFromCtor())),
-    loopEntries(CompilerAllocPolicy(cx, *thisFromCtor())),
-    chunkEdges(CompilerAllocPolicy(cx, *thisFromCtor())),
-    stubcc(cx, *thisFromCtor(), frame),
-    debugMode_(cx->compartment->debugMode()),
-    inlining_(false),
-    hasGlobalReallocation(false),
-    oomInVector(false),
-    overflowICSpace(false),
-    gcNumber(cx->runtime->gcNumber),
-    pcLengths(NULL)
-{
-    JS_ASSERT(cx->jaegerCompilationAllowed());
-
-    if (!IsIonEnabled(cx)) {
-        /* Once a script starts getting really hot we will inline calls in it. */
-        if (!debugMode() && cx->typeInferenceEnabled() && globalObj &&
-            (outerScript->getUseCount() >= USES_BEFORE_INLINING ||
-             cx->hasOption(JSOPTION_METHODJIT_ALWAYS))) {
-            inlining_ = true;
-        }
-    }
-}
-
-CompileStatus
-mjit::Compiler::compile()
-{
-    JS_ASSERT(!outerChunkRef().chunk);
-
-#if JS_TRACE_LOGGING
-    AutoTraceLog logger(TraceLogging::defaultLogger(),
-                        TraceLogging::JM_COMPILE_START,
-                        TraceLogging::JM_COMPILE_STOP,
-                        outerScript);
-#endif
-
-    CompileStatus status = performCompilation();
-    if (status != Compile_Okay && status != Compile_Retry) {
-        mjit::ExpandInlineFrames(cx->zone());
-        mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), outerScript);
-        if (!outerScript->ensureHasMJITInfo(cx))
-            return Compile_Error;
-        JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->zone()->compileBarriers());
-        JSScript::ReleaseCode(cx->runtime->defaultFreeOp(), jith);
-        jith->setUnjittable();
-
-        if (outerScript->function()) {
-            outerScript->uninlineable = true;
-            types::MarkTypeObjectFlags(cx, outerScript->function(),
-                                       types::OBJECT_FLAG_UNINLINEABLE);
-        }
-    }
-
-    return status;
-}
-
-CompileStatus
-mjit::Compiler::checkAnalysis(HandleScript script)
-{
-    if (!script->ensureRanAnalysis(cx))
-        return Compile_Error;
-
-    if (!script->analysis()->jaegerCompileable()) {
-        JaegerSpew(JSpew_Abort, "script has uncompileable opcodes\n");
-        return Compile_Abort;
-    }
-
-    if (cx->typeInferenceEnabled() && !script->ensureRanInference(cx))
-        return Compile_Error;
-
-    ScriptAnalysis *analysis = script->analysis();
-    analysis->assertMatchingDebugMode();
-    if (analysis->failed()) {
-        JaegerSpew(JSpew_Abort, "couldn't analyze bytecode; probably switchX or OOM\n");
-        return Compile_Abort;
-    }
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::addInlineFrame(HandleScript script, uint32_t depth,
-                               uint32_t parent, jsbytecode *parentpc)
-{
-    JS_ASSERT(inlining());
-
-    CompileStatus status = checkAnalysis(script);
-    if (status != Compile_Okay)
-        return status;
-
-    if (!ssa.addInlineFrame(script, depth, parent, parentpc))
-        return Compile_Error;
-
-    uint32_t index = ssa.iterFrame(ssa.numFrames() - 1).index;
-    return scanInlineCalls(index, depth);
-}
-
-CompileStatus
-mjit::Compiler::scanInlineCalls(uint32_t index, uint32_t depth)
-{
-    /* Maximum number of calls we will inline at the same site. */
-    static const uint32_t INLINE_SITE_LIMIT = 5;
-
-    JS_ASSERT(inlining() && globalObj);
-
-    /* Not inlining yet from 'new' scripts. */
-    if (isConstructing)
-        return Compile_Okay;
-
-    JSScript *script = ssa.getFrame(index).script;
-    ScriptAnalysis *analysis = script->analysis();
-
-    /* Don't inline from functions which could have a non-global scope object. */
-    if (!script->compileAndGo ||
-        &script->global() != globalObj ||
-        (script->function() && script->function()->getParent() != globalObj) ||
-        (script->function() && script->function()->isHeavyweight()) ||
-        script->isActiveEval) {
-        return Compile_Okay;
-    }
-
-    uint32_t nextOffset = 0;
-    uint32_t lastOffset = script->length;
-
-    if (index == CrossScriptSSA::OUTER_FRAME) {
-        nextOffset = outerChunk.begin;
-        lastOffset = outerChunk.end;
-    }
-
-    while (nextOffset < lastOffset) {
-        uint32_t offset = nextOffset;
-        jsbytecode *pc = script->code + offset;
-        nextOffset = offset + GetBytecodeLength(pc);
-
-        Bytecode *code = analysis->maybeCode(pc);
-        if (!code)
-            continue;
-
-        /* :XXX: Not yet inlining 'new' calls. */
-        if (JSOp(*pc) != JSOP_CALL)
-            continue;
-
-        /* Not inlining at monitored call sites or those with type barriers. */
-        if (code->monitoredTypes || code->monitoredTypesReturn || analysis->typeBarriers(cx, pc) != NULL)
-            continue;
-
-        uint32_t argc = GET_ARGC(pc);
-        types::StackTypeSet *calleeTypes = analysis->poppedTypes(pc, argc + 1);
-
-        if (calleeTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT)
-            continue;
-
-        if (calleeTypes->getObjectCount() >= INLINE_SITE_LIMIT)
-            continue;
-
-        /*
-         * Compute the maximum height we can grow the stack for inlined frames.
-         * We always reserve space for loop temporaries, for an extra stack
-         * frame pushed when making a call from the deepest inlined frame, and
-         * for the temporary slot used by type barriers.
-         */
-        uint32_t stackLimit = outerScript->nslots + StackSpace::STACK_JIT_EXTRA
-            - VALUES_PER_STACK_FRAME - FrameState::TEMPORARY_LIMIT - 1;
-
-        /* Compute the depth of any frames inlined at this site. */
-        uint32_t nextDepth = depth + VALUES_PER_STACK_FRAME + script->nfixed + code->stackDepth;
-
-        /*
-         * Scan each of the possible callees for other conditions precluding
-         * inlining. We only inline at a call site if all callees are inlineable.
-         */
-        unsigned count = calleeTypes->getObjectCount();
-        bool okay = true;
-        for (unsigned i = 0; i < count; i++) {
-            if (calleeTypes->getTypeObject(i) != NULL) {
-                okay = false;
-                break;
-            }
-
-            JSObject *obj = calleeTypes->getSingleObject(i);
-            if (!obj)
-                continue;
-
-            if (!obj->isFunction()) {
-                okay = false;
-                break;
-            }
-
-            JSFunction *fun = obj->toFunction();
-            if (!fun->isInterpreted()) {
-                okay = false;
-                break;
-            }
-            RootedScript script(cx, fun->nonLazyScript());
-
-            /*
-             * Don't inline calls to scripts which haven't been analyzed.
-             * We need to analyze the inlined scripts to compile them, and
-             * doing so can change type information we have queried already
-             * in making inlining decisions.
-             */
-            if (!script->hasAnalysis() || !script->analysis()->ranInference()) {
-                okay = false;
-                break;
-            }
-
-            /* See bug 768313. */
-            if (script->hasScriptCounts != outerScript->hasScriptCounts) {
-                okay = false;
-                break;
-            }
-
-            /*
-             * The outer and inner scripts must have the same scope. This only
-             * allows us to inline calls between non-inner functions. Also
-             * check for consistent strictness between the functions.
-             */
-            if (!globalObj ||
-                fun->getParent() != globalObj ||
-                outerScript->strict != script->strict) {
-                okay = false;
-                break;
-            }
-
-            /* We can't cope with inlining recursive functions yet. */
-            uint32_t nindex = index;
-            while (nindex != CrossScriptSSA::INVALID_FRAME) {
-                if (ssa.getFrame(nindex).script == script)
-                    okay = false;
-                nindex = ssa.getFrame(nindex).parent;
-            }
-            if (!okay)
-                break;
-
-            /* Watch for excessively deep nesting of inlined frames. */
-            if (nextDepth + script->nslots >= stackLimit) {
-                okay = false;
-                break;
-            }
-
-            if (!script->types) {
-                okay = false;
-                break;
-            }
-
-            CompileStatus status = checkAnalysis(script);
-            if (status != Compile_Okay)
-                return status;
-
-            if (!script->analysis()->jaegerInlineable(argc)) {
-                okay = false;
-                break;
-            }
-
-            types::TypeObject *funType = fun->getType(cx);
-            if (!funType ||
-                types::HeapTypeSet::HasObjectFlags(cx, funType, types::OBJECT_FLAG_UNINLINEABLE))
-            {
-                okay = false;
-                break;
-            }
-
-            /*
-             * Watch for a generic state change in the callee's type, so that
-             * the outer script will be recompiled if any type information
-             * changes in stack values within the callee.
-             */
-            types::HeapTypeSet::WatchObjectStateChange(cx, funType);
-
-            /*
-             * Don't inline scripts which use 'this' if it is possible they
-             * could be called with a 'this' value requiring wrapping. During
-             * inlining we do not want to modify frame entries belonging to the
-             * caller.
-             */
-            if (script->analysis()->usesThisValue() &&
-                types::TypeScript::ThisTypes(script)->getKnownTypeTag() != JSVAL_TYPE_OBJECT) {
-                okay = false;
-                break;
-            }
-        }
-        if (!okay)
-            continue;
-
-        /*
-         * Add the inline frames to the cross script SSA. We will pick these
-         * back up when compiling the call site.
-         */
-        for (unsigned i = 0; i < count; i++) {
-            JSObject *obj = calleeTypes->getSingleObject(i);
-            if (!obj)
-                continue;
-
-            JSFunction *fun = obj->toFunction();
-            RootedScript script(cx, fun->nonLazyScript());
-
-            CompileStatus status = addInlineFrame(script, nextDepth, index, pc);
-            if (status != Compile_Okay)
-                return status;
-        }
-    }
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::pushActiveFrame(JSScript *scriptArg, uint32_t argc)
-{
-    RootedScript script(cx, scriptArg);
-    if (cx->runtime->profilingScripts && !script->hasScriptCounts)
-        script->initScriptCounts(cx);
-
-    ActiveFrame *newa = js_new<ActiveFrame>(cx);
-    if (!newa) {
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-
-    newa->parent = a;
-    if (a)
-        newa->parentPC = PC;
-    newa->script = script;
-    newa->mainCodeStart = masm.size();
-    newa->stubCodeStart = stubcc.size();
-
-    if (outer) {
-        newa->inlineIndex = uint32_t(inlineFrames.length());
-        inlineFrames.append(newa);
-    } else {
-        newa->inlineIndex = CrossScriptSSA::OUTER_FRAME;
-        outer = newa;
-    }
-    JS_ASSERT(ssa.getFrame(newa->inlineIndex).script == script);
-
-    newa->inlinePCOffset = ssa.frameLength(newa->inlineIndex);
-
-    ScriptAnalysis *newAnalysis = script->analysis();
-
-#ifdef JS_METHODJIT_SPEW
-    if (cx->typeInferenceEnabled() && IsJaegerSpewChannelActive(JSpew_Regalloc)) {
-        unsigned nargs = script->function() ? script->function()->nargs : 0;
-        for (unsigned i = 0; i < nargs; i++) {
-            uint32_t slot = ArgSlot(i);
-            if (!newAnalysis->slotEscapes(slot)) {
-                JaegerSpew(JSpew_Regalloc, "Argument %u:", i);
-                newAnalysis->liveness(slot).print();
-            }
-        }
-        for (unsigned i = 0; i < script->nfixed; i++) {
-            uint32_t slot = LocalSlot(script, i);
-            if (!newAnalysis->slotEscapes(slot)) {
-                JaegerSpew(JSpew_Regalloc, "Local %u:", i);
-                newAnalysis->liveness(slot).print();
-            }
-        }
-    }
-#endif
-
-    if (!frame.pushActiveFrame(script, argc)) {
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-
-    newa->jumpMap = js_pod_malloc<Label>(script->length);
-    if (!newa->jumpMap) {
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-#ifdef DEBUG
-    for (uint32_t i = 0; i < script->length; i++)
-        newa->jumpMap[i] = Label();
-#endif
-
-    if (cx->typeInferenceEnabled()) {
-        CompileStatus status = prepareInferenceTypes(script, newa);
-        if (status != Compile_Okay)
-            return status;
-    }
-
-    if (script != outerScript && !sps.enterInlineFrame())
-        return Compile_Error;
-
-    this->script_ = script;
-    this->analysis = newAnalysis;
-    this->PC = script->code;
-    this->a = newa;
-
-    return Compile_Okay;
-}
-
-void
-mjit::Compiler::popActiveFrame()
-{
-    JS_ASSERT(a->parent);
-    a->mainCodeEnd = masm.size();
-    a->stubCodeEnd = stubcc.size();
-    this->PC = a->parentPC;
-    this->a = (ActiveFrame *) a->parent;
-    this->script_ = a->script;
-    this->analysis = this->script_->analysis();
-
-    frame.popActiveFrame();
-    sps.leaveInlineFrame();
-}
-
-#define CHECK_STATUS(expr)                                           \
-    JS_BEGIN_MACRO                                                   \
-        CompileStatus status_ = (expr);                              \
-        if (status_ != Compile_Okay) {                               \
-            if (oomInVector || masm.oom() || stubcc.masm.oom())      \
-                js_ReportOutOfMemory(cx);                            \
-            return status_;                                          \
-        }                                                            \
-    JS_END_MACRO
-
-CompileStatus
-mjit::Compiler::performCompilation()
-{
-    JaegerSpew(JSpew_Scripts,
-               "compiling script (file \"%s\") (line \"%d\") (length \"%d\") (chunk \"%d\") (usecount \"%d\")\n",
-               outerScript->filename(), outerScript->lineno, outerScript->length, chunkIndex, (int) outerScript->getUseCount());
-
-    if (inlining()) {
-        JaegerSpew(JSpew_Inlining,
-                   "inlining calls in script (file \"%s\") (line \"%d\")\n",
-                   outerScript->filename(), outerScript->lineno);
-    }
-
-#ifdef JS_METHODJIT_SPEW
-    Profiler prof;
-    prof.start();
-#endif
-
-#ifdef JS_METHODJIT
-    outerScript->debugMode = debugMode();
-#endif
-
-    JS_ASSERT(cx->compartment->activeAnalysis);
-
-    {
-        types::AutoEnterCompilation enter(cx, types::CompilerOutput::MethodJIT);
-        if (!enter.init(outerScript, isConstructing, chunkIndex)) {
-            js_ReportOutOfMemory(cx);
-            return Compile_Error;
-        }
-
-        CHECK_STATUS(checkAnalysis(outerScript));
-        if (inlining())
-            CHECK_STATUS(scanInlineCalls(CrossScriptSSA::OUTER_FRAME, 0));
-        CHECK_STATUS(pushActiveFrame(outerScript, 0));
-
-        if (outerScript->hasScriptCounts || Probes::wantNativeAddressInfo(cx)) {
-            size_t length = ssa.frameLength(ssa.numFrames() - 1);
-            pcLengths = js_pod_calloc<PCLengthEntry>(length);
-            if (!pcLengths)
-                return Compile_Error;
-        }
-
-        if (chunkIndex == 0)
-            CHECK_STATUS(generatePrologue());
-        else
-            sps.setPushed(script_);
-        CHECK_STATUS(generateMethod());
-        if (outerJIT() && chunkIndex == outerJIT()->nchunks - 1)
-            CHECK_STATUS(generateEpilogue());
-        CHECK_STATUS(finishThisUp());
-    }
-
-#ifdef JS_METHODJIT_SPEW
-    prof.stop();
-    JaegerSpew(JSpew_Prof, "compilation took %d us\n", prof.time_us());
-#endif
-
-    JaegerSpew(JSpew_Scripts, "successfully compiled (code \"%p\") (size \"%u\")\n",
-               outerChunkRef().chunk->code.m_code.executableAddress(),
-               unsigned(outerChunkRef().chunk->code.m_size));
-
-    return Compile_Okay;
-}
-
-#undef CHECK_STATUS
-
-mjit::JSActiveFrame::JSActiveFrame()
-    : parent(NULL), parentPC(NULL), script(NULL), inlineIndex(UINT32_MAX)
-{
-}
-
-mjit::Compiler::ActiveFrame::ActiveFrame(JSContext *cx)
-    : jumpMap(NULL),
-      varTypes(NULL), needReturnValue(false),
-      syncReturnValue(false), returnValueDouble(false), returnSet(false),
-      returnEntry(NULL), returnJumps(NULL), exitState(NULL)
-{}
-
-mjit::Compiler::ActiveFrame::~ActiveFrame()
-{
-    js_free(jumpMap);
-    if (varTypes)
-        js_free(varTypes);
-}
-
-mjit::Compiler::~Compiler()
-{
-    if (outer)
-        js_delete(outer);
-    for (unsigned i = 0; i < inlineFrames.length(); i++)
-        js_delete(inlineFrames[i]);
-    while (loop) {
-        LoopState *nloop = loop->outer;
-        js_delete(loop);
-        loop = nloop;
-    }
-}
-
-CompileStatus
-mjit::Compiler::prepareInferenceTypes(JSScript *script, ActiveFrame *a)
-{
-    /*
-     * During our walk of the script, we need to preserve the invariant that at
-     * join points the in memory type tag is always in sync with the known type
-     * tag of the variable's SSA value at that join point. In particular, SSA
-     * values inferred as (int|double) must in fact be doubles, stored either
-     * in floating point registers or in memory. There is an exception for
-     * locals whose value is currently dead, whose type might not be synced.
-     *
-     * To ensure this, we need to know the SSA values for each variable at each
-     * join point, which the SSA analysis does not store explicitly. These can
-     * be recovered, though. During the forward walk, the SSA value of a var
-     * (and its associated type set) change only when we see an explicit assign
-     * to the var or get to a join point with a phi node for that var. So we
-     * can duplicate the effects of that walk here by watching for writes to
-     * vars (updateVarTypes) and new phi nodes at join points.
-     *
-     * When we get to a branch and need to know a variable's value at the
-     * branch target, we know it will either be a phi node at the target or
-     * the variable's current value, as no phi node is created at the target
-     * only if a variable has the same value on all incoming edges.
-     */
-
-    a->varTypes = js_pod_calloc<VarType>(TotalSlots(script));
-    if (!a->varTypes) {
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-
-    for (uint32_t slot = ArgSlot(0); slot < TotalSlots(script); slot++) {
-        VarType &vt = a->varTypes[slot];
-        vt.setTypes(types::TypeScript::SlotTypes(script, slot));
-    }
-
-    return Compile_Okay;
-}
-
-/*
- * Number of times a script must be called or have back edges taken before we
- * run it in the methodjit. We wait longer if type inference is enabled, to
- * allow more gathering of type information and less recompilation.
- */
-static const size_t USES_BEFORE_COMPILE       = 16;
-static const size_t INFER_USES_BEFORE_COMPILE = 43;
-
-/* Target maximum size, in bytecode length, for a compiled chunk of a script. */
-static uint32_t CHUNK_LIMIT = 1500;
-
-void
-mjit::SetChunkLimit(uint32_t limit)
-{
-    if (limit)
-        CHUNK_LIMIT = limit;
-}
-
-JITScript *
-MakeJITScript(JSContext *cx, JSScript *script)
-{
-    if (!script->ensureRanAnalysis(cx))
-        return NULL;
-
-    ScriptAnalysis *analysis = script->analysis();
-
-    Vector<ChunkDescriptor> chunks(cx);
-    Vector<CrossChunkEdge> edges(cx);
-
-    if (script->length < CHUNK_LIMIT || !cx->typeInferenceEnabled()) {
-        ChunkDescriptor desc;
-        desc.begin = 0;
-        desc.end = script->length;
-        if (!chunks.append(desc))
-            return NULL;
-    } else {
-        if (!script->ensureRanInference(cx))
-            return NULL;
-
-        /* Outgoing edges within the current chunk. */
-        Vector<CrossChunkEdge> currentEdges(cx);
-        uint32_t chunkStart = 0;
-
-        bool preserveNextChunk = false;
-        unsigned offset, nextOffset = 0;
-        while (nextOffset < script->length) {
-            offset = nextOffset;
-
-            jsbytecode *pc = script->code + offset;
-            JSOp op = JSOp(*pc);
-
-            nextOffset = offset + GetBytecodeLength(pc);
-
-            Bytecode *code = analysis->maybeCode(offset);
-            if (!code)
-                op = JSOP_NOP; /* Ignore edges from unreachable opcodes. */
-
-            /* Whether this should be the last opcode in the chunk. */
-            bool finishChunk = false;
-
-            /* Keep going, override finishChunk. */
-            bool preserveChunk = preserveNextChunk;
-            preserveNextChunk = false;
-
-            /*
-             * Add an edge for opcodes which perform a branch. Skip LABEL ops,
-             * which do not actually branch. XXX LABEL should not be JOF_JUMP.
-             */
-            uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
-            if (type == JOF_JUMP && op != JSOP_LABEL) {
-                CrossChunkEdge edge;
-                edge.source = offset;
-                edge.target = FollowBranch(cx, script, pc - script->code);
-                if (edge.target < offset) {
-                    /* Always end chunks after loop back edges. */
-                    finishChunk = true;
-                    if (edge.target < chunkStart) {
-                        analysis->getCode(edge.target).safePoint = true;
-                        if (!edges.append(edge))
-                            return NULL;
-                    }
-                } else if (edge.target == nextOffset) {
-                    /*
-                     * Override finishChunk for bytecodes which directly
-                     * jump to their fallthrough opcode ('if (x) {}'). This
-                     * creates two CFG edges with the same source/target, which
-                     * will confuse the compiler's edge patching code.
-                     */
-                    preserveChunk = true;
-                } else {
-                    if (!currentEdges.append(edge))
-                        return NULL;
-                }
-            }
-
-            if (op == JSOP_TABLESWITCH) {
-                jsbytecode *pc2 = pc;
-                unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
-                pc2 += JUMP_OFFSET_LEN;
-                int32_t low = GET_JUMP_OFFSET(pc2);
-                pc2 += JUMP_OFFSET_LEN;
-                int32_t high = GET_JUMP_OFFSET(pc2);
-                pc2 += JUMP_OFFSET_LEN;
-
-                CrossChunkEdge edge;
-                edge.source = offset;
-                edge.target = defaultOffset;
-                if (!currentEdges.append(edge))
-                    return NULL;
-
-                for (int32_t i = low; i <= high; i++) {
-                    unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
-                    if (targetOffset != offset) {
-                        /*
-                         * This can end up inserting duplicate edges, all but
-                         * the first of which will be ignored.
-                         */
-                        CrossChunkEdge edge;
-                        edge.source = offset;
-                        edge.target = targetOffset;
-                        if (!currentEdges.append(edge))
-                            return NULL;
-                    }
-                    pc2 += JUMP_OFFSET_LEN;
-                }
-            }
-
-            if (unsigned(offset - chunkStart) > CHUNK_LIMIT)
-                finishChunk = true;
-
-            if (nextOffset >= script->length || !analysis->maybeCode(nextOffset)) {
-                /* Ensure that chunks do not start on unreachable opcodes. */
-                preserveChunk = true;
-            } else {
-                /*
-                 * Start new chunks at the opcode before each loop head.
-                 * This ensures that the initial goto for loops is included in
-                 * the same chunk as the loop itself.
-                 */
-                jsbytecode *nextpc = script->code + nextOffset;
-
-                /*
-                 * Don't insert a chunk boundary in the middle of two opcodes
-                 * which may be fused together.
-                 */
-                switch (JSOp(*nextpc)) {
-                  case JSOP_POP:
-                  case JSOP_IFNE:
-                  case JSOP_IFEQ:
-                    preserveChunk = true;
-                    break;
-                  default:
-                    break;
-                }
-
-                uint32_t afterOffset = nextOffset + GetBytecodeLength(nextpc);
-                if (afterOffset < script->length) {
-                    if (analysis->maybeCode(afterOffset) &&
-                        JSOp(script->code[afterOffset]) == JSOP_LOOPHEAD &&
-                        analysis->getLoop(afterOffset))
-                    {
-                        if (preserveChunk)
-                            preserveNextChunk = true;
-                        else
-                            finishChunk = true;
-                    }
-                }
-            }
-
-            if (finishChunk && !preserveChunk) {
-                ChunkDescriptor desc;
-                desc.begin = chunkStart;
-                desc.end = nextOffset;
-                if (!chunks.append(desc))
-                    return NULL;
-
-                /* Add an edge for fallthrough from this chunk to the next one. */
-                if (BytecodeFallsThrough(op)) {
-                    CrossChunkEdge edge;
-                    edge.source = offset;
-                    edge.target = nextOffset;
-                    analysis->getCode(edge.target).safePoint = true;
-                    if (!edges.append(edge))
-                        return NULL;
-                }
-
-                chunkStart = nextOffset;
-                for (unsigned i = 0; i < currentEdges.length(); i++) {
-                    const CrossChunkEdge &edge = currentEdges[i];
-                    if (edge.target >= nextOffset) {
-                        analysis->getCode(edge.target).safePoint = true;
-                        if (!edges.append(edge))
-                            return NULL;
-                    }
-                }
-                currentEdges.clear();
-            }
-        }
-
-        if (chunkStart != script->length) {
-            ChunkDescriptor desc;
-            desc.begin = chunkStart;
-            desc.end = script->length;
-            if (!chunks.append(desc))
-                return NULL;
-        }
-    }
-
-    size_t dataSize = sizeof(JITScript)
-        + (chunks.length() * sizeof(ChunkDescriptor))
-        + (edges.length() * sizeof(CrossChunkEdge));
-    uint8_t *cursor = (uint8_t *) js_calloc(dataSize);
-    if (!cursor)
-        return NULL;
-
-    JITScript *jit = (JITScript *) cursor;
-    cursor += sizeof(JITScript);
-
-    jit->script = script;
-    JS_INIT_CLIST(&jit->callers);
-
-    jit->nchunks = chunks.length();
-    for (unsigned i = 0; i < chunks.length(); i++) {
-        const ChunkDescriptor &a = chunks[i];
-        ChunkDescriptor &b = jit->chunkDescriptor(i);
-        b.begin = a.begin;
-        b.end = a.end;
-
-        if (chunks.length() == 1) {
-            /* Seed the chunk's count so it is immediately compiled. */
-            b.counter = INFER_USES_BEFORE_COMPILE;
-        }
-    }
-
-    if (edges.empty())
-        return jit;
-
-    jit->nedges = edges.length();
-    CrossChunkEdge *jitEdges = jit->edges();
-    for (unsigned i = 0; i < edges.length(); i++) {
-        const CrossChunkEdge &a = edges[i];
-        CrossChunkEdge &b = jitEdges[i];
-        b.source = a.source;
-        b.target = a.target;
-    }
-
-    /* Generate a pool with all cross chunk shims, and set shimLabel for each edge. */
-    jsbytecode *pc;
-    MJITInstrumentation sps(&cx->runtime->spsProfiler);
-    Assembler masm(&sps, &pc);
-    sps.setPushed(script);
-    for (unsigned i = 0; i < jit->nedges; i++) {
-        pc = script->code + jitEdges[i].target;
-        jitEdges[i].shimLabel = (void *) masm.distanceOf(masm.label());
-        masm.move(JSC::MacroAssembler::ImmPtr(&jitEdges[i]), Registers::ArgReg1);
-        masm.fallibleVMCall(true, JS_FUNC_TO_DATA_PTR(void *, stubs::CrossChunkShim),
-                            pc, NULL, script->nfixed + analysis->getCode(pc).stackDepth);
-    }
-    LinkerHelper linker(masm, JSC::JAEGER_CODE);
-    JSC::ExecutablePool *ep = linker.init(cx);
-    if (!ep)
-        return NULL;
-    jit->shimPool = ep;
-
-    masm.finalize(linker);
-    uint8_t *shimCode = (uint8_t *) linker.finalizeCodeAddendum().executableAddress();
-
-    JS_ALWAYS_TRUE(linker.verifyRange(JSC::JITCode(shimCode, masm.size())));
-
-    JaegerSpew(JSpew_PICs, "generated SHIM POOL stub %p (%lu bytes)\n",
-               shimCode, (unsigned long)masm.size());
-
-    for (unsigned i = 0; i < jit->nedges; i++) {
-        CrossChunkEdge &edge = jitEdges[i];
-        edge.shimLabel = shimCode + (size_t) edge.shimLabel;
-    }
-
-    return jit;
-}
-
-static inline bool
-IonGetsFirstChance(JSContext *cx, JSScript *script, jsbytecode *pc, CompileRequest request)
-{
-#ifdef JS_ION
-    if (!ion::IsEnabled(cx))
-        return false;
-
-    // If the script is not hot, use JM. recompileCheckHelper will insert a check
-    // to trigger a recompile when the script becomes hot.
-    if (script->getUseCount() < ion::js_IonOptions.usesBeforeCompile)
-        return false;
-
-    // If we're called from JM, use JM to avoid slow JM -> Ion calls.
-    if (request == CompileRequest_JIT)
-        return false;
-
-    // If there's no way this script is going to be Ion compiled, let JM take over.
-    if (!script->canIonCompile())
-        return false;
-
-    // If we cannot enter Ion because bailouts are expected, let JM take over.
-    if (script->hasIonScript() && script->ionScript()->bailoutExpected())
-        return false;
-
-    // If we cannot enter Ion because it was compiled for OSR at a different PC,
-    // let JM take over until the PC is reached. Don't do this until the script
-    // reaches a high use count, as if we do this prematurely we may get stuck
-    // in JM code.
-    if (OffThreadCompilationEnabled(cx) && script->hasIonScript() &&
-        pc && script->ionScript()->osrPc() && script->ionScript()->osrPc() != pc &&
-        script->getUseCount() >= ion::js_IonOptions.usesBeforeCompile * 2)
-    {
-        return false;
-    }
-
-    // If ion compilation is pending or in progress on another thread, continue
-    // using JM until that compilation finishes.
-    if (script->isIonCompilingOffThread())
-        return false;
-
-    return true;
-#endif
-    return false;
-}
-
-CompileStatus
-mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
-                   bool construct, CompileRequest request, StackFrame *frame)
-{
-    bool compiledOnce = false;
-  checkOutput:
-    if (!cx->methodJitEnabled)
-        return Compile_Abort;
-
-    if (!cx->jaegerCompilationAllowed())
-        return Compile_Abort;
-
-#ifdef JS_ION
-    if (ion::IsBaselineEnabled(cx) || ion::IsEnabled(cx))
-        return Compile_Abort;
-#endif
-
-    /*
-     * If SPS (profiling) is enabled, then the emitted instrumentation has to be
-     * careful to not wildly write to random locations. This is relevant
-     * whenever the status of profiling (on/off) is changed while JS is running.
-     * All pushed frames still need to be popped, but newly emitted code may
-     * have slightly different behavior.
-     *
-     * For a new function, this doesn't matter at all, but if we're compiling
-     * the current function, then the writes start to matter. If an SPS frame
-     * has been pushed and SPS is still enabled, then we're good to go. If an
-     * SPS frame has not been pushed, and SPS is not enabled, then we're still
-     * good to go. If, however, the two are different, then we cannot emit JIT
-     * code because the instrumentation will be wrong one way or another.
-     */
-    if (frame->script() == script && pc != script->code) {
-        if (frame->hasPushedSPSFrame() != cx->runtime->spsProfiler.enabled())
-            return Compile_Skipped;
-    }
-
-    if (IonGetsFirstChance(cx, script, pc, request)) {
-        if (script->hasIonScript())
-            script->incUseCount();
-        return Compile_Skipped;
-    }
-
-    if (script->hasMJITInfo()) {
-        JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->zone()->compileBarriers());
-        if (jith->isUnjittable())
-            return Compile_Abort;
-    }
-
-    if (!cx->hasOption(JSOPTION_METHODJIT_ALWAYS) &&
-        (cx->typeInferenceEnabled()
-         ? script->incUseCount() <= INFER_USES_BEFORE_COMPILE
-         : script->incUseCount() <= USES_BEFORE_COMPILE))
-    {
-        return Compile_Skipped;
-    }
-
-    if (!cx->runtime->getJaegerRuntime(cx))
-        return Compile_Error;
-
-    // Ensure that constructors have at least one slot.
-    if (construct && !script->nslots)
-        script->nslots++;
-
-    uint64_t gcNumber = cx->runtime->gcNumber;
-
-    if (!script->ensureHasMJITInfo(cx))
-        return Compile_Error;
-
-    JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->zone()->compileBarriers());
-
-    JITScript *jit;
-    if (jith->isEmpty()) {
-        jit = MakeJITScript(cx, script);
-        if (!jit)
-            return Compile_Error;
-
-        // Script analysis can trigger GC, watch in case compileBarriers() changed.
-        if (gcNumber != cx->runtime->gcNumber) {
-            FreeOp *fop = cx->runtime->defaultFreeOp();
-            jit->destroy(fop);
-            fop->free_(jit);
-            return Compile_Skipped;
-        }
-
-        jith->setValid(jit);
-    } else {
-        jit = jith->getValid();
-    }
-
-    unsigned chunkIndex = jit->chunkIndex(pc);
-    ChunkDescriptor &desc = jit->chunkDescriptor(chunkIndex);
-
-    if (jit->mustDestroyEntryChunk) {
-        // We kept this chunk around so that Ion can get info from its caches.
-        // If we end up here, we decided not to use Ion so we can destroy the
-        // chunk now.
-        JS_ASSERT(jit->nchunks == 1);
-        jit->mustDestroyEntryChunk = false;
-
-        if (desc.chunk) {
-            jit->destroyChunk(cx->runtime->defaultFreeOp(), chunkIndex, /* resetUses = */ false);
-            return Compile_Skipped;
-        }
-    }
-
-    if (desc.chunk)
-        return Compile_Okay;
-    if (compiledOnce)
-        return Compile_Skipped;
-
-    if (!cx->hasOption(JSOPTION_METHODJIT_ALWAYS) &&
-        ++desc.counter <= INFER_USES_BEFORE_COMPILE)
-    {
-        return Compile_Skipped;
-    }
-
-    CompileStatus status;
-    {
-        types::AutoEnterAnalysis enter(cx);
-
-        Compiler cc(cx, script, chunkIndex, construct);
-        status = cc.compile();
-    }
-
-    /*
-     * Check if we have hit the threshold for purging analysis data. This is
-     * done after compilation, rather than after another analysis stage, to
-     * ensure we don't throw away the work just performed.
-     */
-    cx->compartment->types.maybePurgeAnalysis(cx);
-
-    if (status == Compile_Okay) {
-        /*
-         * Compiling a script can occasionally trigger its own recompilation,
-         * so go back through the compilation logic.
-         */
-        compiledOnce = true;
-        goto checkOutput;
-    }
-
-    /* Non-OOM errors should have an associated exception. */
-    JS_ASSERT_IF(status == Compile_Error,
-                 cx->isExceptionPending() || cx->runtime->hadOutOfMemory);
-
-    return status;
-}
-
-CompileStatus
-mjit::Compiler::generatePrologue()
-{
-    fastEntryLabel = masm.label();
-
-    /*
-     * If there is no function, then this can only be called via JaegerShot(),
-     * which expects an existing frame to be initialized like the interpreter.
-     */
-    if (script_->function()) {
-        Jump j = masm.jump();
-
-        /*
-         * Entry point #2: The caller has partially constructed a frame, and
-         * either argc >= nargs or the arity check has corrected the frame.
-         */
-        fastEntryLabel = masm.label();
-
-        /* Store this early on so slow paths can access it. */
-        masm.storePtr(ImmPtr(script_->function()),
-                      Address(JSFrameReg, StackFrame::offsetOfExec()));
-        if (script_->isCallsiteClone) {
-            masm.storeValue(ObjectValue(*script_->function()),
-                            Address(JSFrameReg, StackFrame::offsetOfCallee(script_->function())));
-        }
-
-        {
-            /*
-             * Entry point #3: The caller has partially constructed a frame,
-             * but argc might be != nargs, so an arity check might be called.
-             *
-             * This loops back to entry point #2.
-             */
-            arityLabel = stubcc.masm.label();
-
-            Jump argMatch = stubcc.masm.branch32(Assembler::Equal, JSParamReg_Argc,
-                                                 Imm32(script_->function()->nargs));
-
-            if (JSParamReg_Argc != Registers::ArgReg1)
-                stubcc.masm.move(JSParamReg_Argc, Registers::ArgReg1);
-
-            /* Slow path - call the arity check function. Returns new fp. */
-            stubcc.masm.storePtr(ImmPtr(script_->function()),
-                                 Address(JSFrameReg, StackFrame::offsetOfExec()));
-            OOL_STUBCALL(stubs::FixupArity, REJOIN_NONE);
-            stubcc.masm.move(Registers::ReturnReg, JSFrameReg);
-            argMatch.linkTo(stubcc.masm.label(), &stubcc.masm);
-
-            argsCheckLabel = stubcc.masm.label();
-
-            /* Type check the arguments as well. */
-            if (cx->typeInferenceEnabled()) {
-#ifdef JS_MONOIC
-                this->argsCheckJump = stubcc.masm.jump();
-                this->argsCheckStub = stubcc.masm.label();
-                this->argsCheckJump.linkTo(this->argsCheckStub, &stubcc.masm);
-#endif
-                stubcc.masm.storePtr(ImmPtr(script_->function()),
-                                     Address(JSFrameReg, StackFrame::offsetOfExec()));
-                OOL_STUBCALL(stubs::CheckArgumentTypes, REJOIN_CHECK_ARGUMENTS);
-#ifdef JS_MONOIC
-                this->argsCheckFallthrough = stubcc.masm.label();
-#endif
-            }
-
-            stubcc.crossJump(stubcc.masm.jump(), fastEntryLabel);
-        }
-
-        /*
-         * Guard that there is enough stack space. Note we reserve space for
-         * any inline frames we end up generating, or a callee's stack frame
-         * we write to before the callee checks the stack.
-         */
-        uint32_t nvals = VALUES_PER_STACK_FRAME + script_->nslots + StackSpace::STACK_JIT_EXTRA;
-        masm.addPtr(Imm32(nvals * sizeof(Value)), JSFrameReg, Registers::ReturnReg);
-        Jump stackCheck = masm.branchPtr(Assembler::AboveOrEqual, Registers::ReturnReg,
-                                         FrameAddress(offsetof(VMFrame, stackLimit)));
-
-        /*
-         * If the stack check fails then we need to either commit more of the
-         * reserved stack space or throw an error. Specify that the number of
-         * local slots is 0 (instead of the default script->nfixed) since the
-         * range [fp->slots(), fp->base()) may not be commited. (The calling
-         * contract requires only that the caller has reserved space for fp.)
-         */
-        {
-            stubcc.linkExitDirect(stackCheck, stubcc.masm.label());
-            OOL_STUBCALL(stubs::HitStackQuota, REJOIN_NONE);
-            stubcc.crossJump(stubcc.masm.jump(), masm.label());
-        }
-
-        markUndefinedLocals();
-
-        /*
-         * Load the scope chain into the frame if it will be needed by NAME
-         * opcodes or by the nesting prologue below. The scope chain is always
-         * set for global and eval frames, and will have been set by
-         * HeavyweightFunctionPrologue for heavyweight function frames.
-         */
-        if (!script_->function()->isHeavyweight() && analysis->usesScopeChain()) {
-            RegisterID t0 = Registers::ReturnReg;
-            Jump hasScope = masm.branchTest32(Assembler::NonZero,
-                                              FrameFlagsAddress(), Imm32(StackFrame::HAS_SCOPECHAIN));
-            masm.loadPayload(Address(JSFrameReg, StackFrame::offsetOfCallee(script_->function())), t0);
-            masm.loadPtr(Address(t0, JSFunction::offsetOfEnvironment()), t0);
-            masm.storePtr(t0, Address(JSFrameReg, StackFrame::offsetOfScopeChain()));
-            hasScope.linkTo(masm.label(), &masm);
-        }
-
-        /*
-         * When 'arguments' is used in the script, it may be optimized away
-         * which involves reading from the stack frame directly, including
-         * fp->u.nactual. fp->u.nactual is only set when numActual != numFormal,
-         * so store 'fp->u.nactual = numFormal' when there is no over/underflow.
-         */
-        if (script_->argumentsHasVarBinding()) {
-            Jump hasArgs = masm.branchTest32(Assembler::NonZero, FrameFlagsAddress(),
-                                             Imm32(StackFrame::UNDERFLOW_ARGS |
-                                                   StackFrame::OVERFLOW_ARGS));
-            masm.storePtr(ImmPtr((void *)(size_t) script_->function()->nargs),
-                          Address(JSFrameReg, StackFrame::offsetOfNumActual()));
-            hasArgs.linkTo(masm.label(), &masm);
-        }
-
-        j.linkTo(masm.label(), &masm);
-    }
-
-    if (cx->typeInferenceEnabled()) {
-#ifdef DEBUG
-        if (script_->function()) {
-            prepareStubCall(Uses(0));
-            INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE);
-        }
-#endif
-        ensureDoubleArguments();
-    }
-
-    /* Inline StackFrame::prologue. */
-    if (script_->isActiveEval && script_->strict) {
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::StrictEvalPrologue, REJOIN_EVAL_PROLOGUE);
-    } else if (script_->function()) {
-        if (script_->function()->isHeavyweight()) {
-            prepareStubCall(Uses(0));
-            INLINE_STUBCALL(stubs::HeavyweightFunctionPrologue, REJOIN_FUNCTION_PROLOGUE);
-        }
-
-        if (isConstructing && !constructThis())
-            return Compile_Error;
-    }
-
-    CompileStatus status = methodEntryHelper();
-    if (status == Compile_Okay) {
-        if (IsIonEnabled(cx))
-            ionCompileHelper();
-        else
-            inliningCompileHelper();
-    }
-
-    return status;
-}
-
-void
-mjit::Compiler::ensureDoubleArguments()
-{
-    /* Convert integer arguments which were inferred as (int|double) to doubles. */
-    for (uint32_t i = 0; script_->function() && i < script_->function()->nargs; i++) {
-        uint32_t slot = ArgSlot(i);
-        if (a->varTypes[slot].getTypeTag() == JSVAL_TYPE_DOUBLE && analysis->trackSlot(slot))
-            frame.ensureDouble(frame.getArg(i));
-    }
-}
-
-void
-mjit::Compiler::markUndefinedLocal(uint32_t offset, uint32_t i)
-{
-    uint32_t depth = ssa.getFrame(a->inlineIndex).depth;
-    Address local(JSFrameReg, sizeof(StackFrame) + (depth + i) * sizeof(Value));
-    masm.storeValue(UndefinedValue(), local);
-}
-
-void
-mjit::Compiler::markUndefinedLocals()
-{
-    /*
-     * Set locals to undefined. Skip locals which aren't closed and are known
-     * to be defined before used,
-     */
-    for (uint32_t i = 0; i < script_->nfixed; i++)
-        markUndefinedLocal(0, i);
-
-#ifdef DEBUG
-    uint32_t depth = ssa.getFrame(a->inlineIndex).depth;
-    for (uint32_t i = script_->nfixed; i < script_->nslots; i++) {
-        Address local(JSFrameReg, sizeof(StackFrame) + (depth + i) * sizeof(Value));
-        masm.storeValue(JS::ObjectValueCrashOnTouch(), local);
-    }
-#endif
-}
-
-CompileStatus
-mjit::Compiler::generateEpilogue()
-{
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::finishThisUp()
-{
-#ifdef JS_CPU_X64
-    /* Generate trampolines to ensure that cross chunk edges are patchable. */
-    for (unsigned i = 0; i < chunkEdges.length(); i++) {
-        chunkEdges[i].sourceTrampoline = stubcc.masm.label();
-        stubcc.masm.move(ImmPtr(NULL), Registers::ScratchReg);
-        stubcc.masm.jump(Registers::ScratchReg);
-    }
-#endif
-
-    RETURN_IF_OOM(Compile_Error);
-
-    /*
-     * Watch for reallocation of the global slots while we were in the middle
-     * of compiling due to, e.g. standard class initialization.
-     */
-    if (globalSlots && globalObj->getRawSlots() != globalSlots)
-        return Compile_Retry;
-
-    /*
-     * Watch for GCs which occurred during compilation. These may have
-     * renumbered shapes baked into the jitcode.
-     */
-    if (cx->runtime->gcNumber != gcNumber)
-        return Compile_Retry;
-
-    /* The JIT will not have been cleared if no GC has occurred. */
-    JITScript *jit = outerJIT();
-    JS_ASSERT(jit != NULL);
-
-    if (overflowICSpace) {
-        JaegerSpew(JSpew_Scripts, "dumped a constant pool while generating an IC\n");
-        return Compile_Abort;
-    }
-
-    a->mainCodeEnd = masm.size();
-    a->stubCodeEnd = stubcc.size();
-
-    for (size_t i = 0; i < branchPatches.length(); i++) {
-        Label label = labelOf(branchPatches[i].pc, branchPatches[i].inlineIndex);
-        branchPatches[i].jump.linkTo(label, &masm);
-    }
-
-#ifdef JS_CPU_ARM
-    masm.forceFlushConstantPool();
-    stubcc.masm.forceFlushConstantPool();
-#endif
-    JaegerSpew(JSpew_Insns, "## Fast code (masm) size = %lu, Slow code (stubcc) size = %lu.\n",
-               (unsigned long) masm.size(), (unsigned long) stubcc.size());
-
-    /* To make inlineDoubles and oolDoubles aligned to sizeof(double) bytes,
-       MIPS adds extra sizeof(double) bytes to codeSize.  */
-    size_t codeSize = masm.size() +
-#if defined(JS_CPU_MIPS)
-                      stubcc.size() + sizeof(double) +
-#else
-                      stubcc.size() +
-#endif
-                      (masm.numDoubles() * sizeof(double)) +
-                      (stubcc.masm.numDoubles() * sizeof(double)) +
-                      jumpTableEdges.length() * sizeof(void *);
-
-    Vector<ChunkJumpTableEdge> chunkJumps(cx);
-    if (!chunkJumps.reserve(jumpTableEdges.length()))
-        return Compile_Error;
-
-    JSC::ExecutableAllocator &execAlloc = cx->runtime->execAlloc();
-    JSC::ExecutablePool *execPool;
-    uint8_t *result = (uint8_t *)execAlloc.alloc(codeSize, &execPool, JSC::JAEGER_CODE);
-    if (!result) {
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-    JS_ASSERT(execPool);
-    JSC::ExecutableAllocator::makeWritable(result, codeSize);
-    masm.executableCopy(result);
-    stubcc.masm.executableCopy(result + masm.size());
-
-    JSC::LinkBuffer fullCode(result, codeSize, JSC::JAEGER_CODE);
-    JSC::LinkBuffer stubCode(result + masm.size(), stubcc.size(), JSC::JAEGER_CODE);
-
-    JS_ASSERT(!loop);
-
-    size_t nNmapLive = loopEntries.length();
-    for (size_t i = outerChunk.begin; i < outerChunk.end; i++) {
-        Bytecode *opinfo = analysis->maybeCode(i);
-        if (opinfo && opinfo->safePoint)
-            nNmapLive++;
-    }
-
-    /* Please keep in sync with JITChunk::sizeOfIncludingThis! */
-    size_t dataSize = sizeof(JITChunk) +
-                      sizeof(NativeMapEntry) * nNmapLive +
-                      sizeof(InlineFrame) * inlineFrames.length() +
-                      sizeof(CallSite) * callSites.length() +
-                      sizeof(CompileTrigger) * compileTriggers.length() +
-                      sizeof(JSObject*) * rootedTemplates.length() +
-                      sizeof(RegExpShared*) * rootedRegExps.length() +
-                      sizeof(uint32_t) * monitoredBytecodes.length() +
-                      sizeof(uint32_t) * typeBarrierBytecodes.length() +
-#if defined JS_MONOIC
-                      sizeof(ic::GetGlobalNameIC) * getGlobalNames.length() +
-                      sizeof(ic::SetGlobalNameIC) * setGlobalNames.length() +
-                      sizeof(ic::CallICInfo) * callICs.length() +
-                      sizeof(ic::EqualityICInfo) * equalityICs.length() +
-#endif
-#if defined JS_POLYIC
-                      sizeof(ic::PICInfo) * pics.length() +
-                      sizeof(ic::GetElementIC) * getElemICs.length() +
-                      sizeof(ic::SetElementIC) * setElemICs.length() +
-#endif
-                      0;
-
-    uint8_t *cursor = (uint8_t *)js_calloc(dataSize);
-    if (!cursor) {
-        execPool->release();
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-
-    JITChunk *chunk = new(cursor) JITChunk;
-    cursor += sizeof(JITChunk);
-
-    JS_ASSERT(outerScript == script_);
-
-    chunk->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size());
-    chunk->pcLengths = pcLengths;
-
-    if (chunkIndex == 0) {
-        jit->invokeEntry = result;
-        if (script_->function()) {
-            jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
-            jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress();
-            jit->fastEntry = fullCode.locationOf(fastEntryLabel).executableAddress();
-        }
-    }
-
-    /*
-     * WARNING: mics(), callICs() et al depend on the ordering of these
-     * variable-length sections.  See JITChunk's declaration for details.
-     */
-
-    /* ICs can only refer to bytecodes in the outermost script, not inlined calls. */
-    Label *jumpMap = a->jumpMap;
-
-    /* Build the pc -> ncode mapping. */
-    NativeMapEntry *jitNmap = (NativeMapEntry *)cursor;
-    chunk->nNmapPairs = nNmapLive;
-    cursor += sizeof(NativeMapEntry) * chunk->nNmapPairs;
-    size_t ix = 0;
-    if (chunk->nNmapPairs > 0) {
-        for (size_t i = outerChunk.begin; i < outerChunk.end; i++) {
-            Bytecode *opinfo = analysis->maybeCode(i);
-            if (opinfo && opinfo->safePoint) {
-                Label L = jumpMap[i];
-                JS_ASSERT(L.isSet());
-                jitNmap[ix].bcOff = i;
-                jitNmap[ix].ncode = (uint8_t *)(result + masm.distanceOf(L));
-                ix++;
-            }
-        }
-        for (size_t i = 0; i < loopEntries.length(); i++) {
-            /* Insert the entry at the right position. */
-            const LoopEntry &entry = loopEntries[i];
-            size_t j;
-            for (j = 0; j < ix; j++) {
-                if (jitNmap[j].bcOff > entry.pcOffset) {
-                    memmove(jitNmap + j + 1, jitNmap + j, (ix - j) * sizeof(NativeMapEntry));
-                    break;
-                }
-            }
-            jitNmap[j].bcOff = entry.pcOffset;
-            jitNmap[j].ncode = (uint8_t *) stubCode.locationOf(entry.label).executableAddress();
-            ix++;
-        }
-    }
-    JS_ASSERT(ix == chunk->nNmapPairs);
-
-    /* Build the table of inlined frames. */
-    InlineFrame *jitInlineFrames = (InlineFrame *)cursor;
-    chunk->nInlineFrames = inlineFrames.length();
-    cursor += sizeof(InlineFrame) * chunk->nInlineFrames;
-    for (size_t i = 0; i < chunk->nInlineFrames; i++) {
-        InlineFrame &to = jitInlineFrames[i];
-        ActiveFrame *from = inlineFrames[i];
-        if (from->parent != outer)
-            to.parent = &jitInlineFrames[from->parent->inlineIndex];
-        else
-            to.parent = NULL;
-        to.parentpc = from->parentPC;
-        to.fun = from->script->function();
-        to.depth = ssa.getFrame(from->inlineIndex).depth;
-    }
-
-    /* Build the table of call sites. */
-    CallSite *jitCallSites = (CallSite *)cursor;
-    chunk->nCallSites = callSites.length();
-    cursor += sizeof(CallSite) * chunk->nCallSites;
-    for (size_t i = 0; i < chunk->nCallSites; i++) {
-        CallSite &to = jitCallSites[i];
-        InternalCallSite &from = callSites[i];
-
-        /* Patch stores of f.regs.inlined for stubs called from within inline frames. */
-        if (cx->typeInferenceEnabled() &&
-            from.rejoin != REJOIN_TRAP &&
-            from.rejoin != REJOIN_SCRIPTED &&
-            from.inlineIndex != UINT32_MAX) {
-            if (from.ool)
-                stubCode.patch(from.inlinePatch, &to);
-            else
-                fullCode.patch(from.inlinePatch, &to);
-        }
-
-        JSScript *script =
-            (from.inlineIndex == UINT32_MAX) ? outerScript.get()
-                                             : inlineFrames[from.inlineIndex]->script;
-        uint32_t codeOffset = from.ool
-                            ? masm.size() + from.returnOffset
-                            : from.returnOffset;
-        to.initialize(codeOffset, from.inlineIndex, from.inlinepc - script->code, from.rejoin);
-
-        /*
-         * Patch stores of the base call's return address for InvariantFailure
-         * calls. InvariantFailure will patch its own return address to this
-         * pointer before triggering recompilation.
-         */
-        if (from.loopPatch.hasPatch)
-            stubCode.patch(from.loopPatch.codePatch, result + codeOffset);
-    }
-
-    CompileTrigger *jitCompileTriggers = (CompileTrigger *)cursor;
-    chunk->nCompileTriggers = compileTriggers.length();
-    cursor += sizeof(CompileTrigger) * chunk->nCompileTriggers;
-    for (size_t i = 0; i < chunk->nCompileTriggers; i++) {
-        const InternalCompileTrigger &trigger = compileTriggers[i];
-        jitCompileTriggers[i].initialize(trigger.pc - outerScript->code,
-                                         fullCode.locationOf(trigger.inlineJump),
-                                         stubCode.locationOf(trigger.stubLabel));
-    }
-
-    JSObject **jitRootedTemplates = (JSObject **)cursor;
-    chunk->nRootedTemplates = rootedTemplates.length();
-    cursor += sizeof(JSObject*) * chunk->nRootedTemplates;
-    for (size_t i = 0; i < chunk->nRootedTemplates; i++)
-        jitRootedTemplates[i] = rootedTemplates[i];
-
-    RegExpShared **jitRootedRegExps = (RegExpShared **)cursor;
-    chunk->nRootedRegExps = rootedRegExps.length();
-    cursor += sizeof(RegExpShared*) * chunk->nRootedRegExps;
-    for (size_t i = 0; i < chunk->nRootedRegExps; i++) {
-        jitRootedRegExps[i] = rootedRegExps[i];
-        jitRootedRegExps[i]->incRef();
-    }
-
-    uint32_t *jitMonitoredBytecodes = (uint32_t *)cursor;
-    chunk->nMonitoredBytecodes = monitoredBytecodes.length();
-    cursor += sizeof(uint32_t) * chunk->nMonitoredBytecodes;
-    for (size_t i = 0; i < chunk->nMonitoredBytecodes; i++)
-        jitMonitoredBytecodes[i] = monitoredBytecodes[i];
-
-    uint32_t *jitTypeBarrierBytecodes = (uint32_t *)cursor;
-    chunk->nTypeBarrierBytecodes = typeBarrierBytecodes.length();
-    cursor += sizeof(uint32_t) * chunk->nTypeBarrierBytecodes;
-    for (size_t i = 0; i < chunk->nTypeBarrierBytecodes; i++)
-        jitTypeBarrierBytecodes[i] = typeBarrierBytecodes[i];
-
-#if defined JS_MONOIC
-    if (chunkIndex == 0 && script_->function()) {
-        JS_ASSERT(jit->argsCheckPool == NULL);
-        if (cx->typeInferenceEnabled()) {
-            jit->argsCheckStub = stubCode.locationOf(argsCheckStub);
-            jit->argsCheckFallthrough = stubCode.locationOf(argsCheckFallthrough);
-            jit->argsCheckJump = stubCode.locationOf(argsCheckJump);
-        }
-    }
-
-    ic::GetGlobalNameIC *getGlobalNames_ = (ic::GetGlobalNameIC *)cursor;
-    chunk->nGetGlobalNames = getGlobalNames.length();
-    cursor += sizeof(ic::GetGlobalNameIC) * chunk->nGetGlobalNames;
-    for (size_t i = 0; i < chunk->nGetGlobalNames; i++) {
-        ic::GetGlobalNameIC &to = getGlobalNames_[i];
-        GetGlobalNameICInfo &from = getGlobalNames[i];
-        from.copyTo(to, fullCode, stubCode);
-
-        int offset = fullCode.locationOf(from.load) - to.fastPathStart;
-        to.loadStoreOffset = offset;
-        JS_ASSERT(to.loadStoreOffset == offset);
-
-        stubCode.patch(from.addrLabel, &to);
-    }
-
-    ic::SetGlobalNameIC *setGlobalNames_ = (ic::SetGlobalNameIC *)cursor;
-    chunk->nSetGlobalNames = setGlobalNames.length();
-    cursor += sizeof(ic::SetGlobalNameIC) * chunk->nSetGlobalNames;
-    for (size_t i = 0; i < chunk->nSetGlobalNames; i++) {
-        ic::SetGlobalNameIC &to = setGlobalNames_[i];
-        SetGlobalNameICInfo &from = setGlobalNames[i];
-        from.copyTo(to, fullCode, stubCode);
-        to.slowPathStart = stubCode.locationOf(from.slowPathStart);
-
-        int offset = fullCode.locationOf(from.store).labelAtOffset(0) -
-                     to.fastPathStart;
-        to.loadStoreOffset = offset;
-        JS_ASSERT(to.loadStoreOffset == offset);
-
-        to.objConst = from.objConst;
-        to.shapeReg = from.shapeReg;
-        to.objReg = from.objReg;
-        to.vr = from.vr;
-
-        offset = fullCode.locationOf(from.shapeGuardJump) -
-                 to.fastPathStart;
-        to.inlineShapeJump = offset;
-        JS_ASSERT(to.inlineShapeJump == offset);
-
-        offset = fullCode.locationOf(from.fastPathRejoin) -
-                 to.fastPathStart;
-        to.fastRejoinOffset = offset;
-        JS_ASSERT(to.fastRejoinOffset == offset);
-
-        stubCode.patch(from.addrLabel, &to);
-    }
-
-    ic::CallICInfo *jitCallICs = (ic::CallICInfo *)cursor;
-    chunk->nCallICs = callICs.length();
-    cursor += sizeof(ic::CallICInfo) * chunk->nCallICs;
-    for (size_t i = 0; i < chunk->nCallICs; i++) {
-        jitCallICs[i].funGuardLabel = fullCode.locationOf(callICs[i].funGuardLabel);
-        jitCallICs[i].funGuard = fullCode.locationOf(callICs[i].funGuard);
-        jitCallICs[i].funJump = fullCode.locationOf(callICs[i].funJump);
-        jitCallICs[i].slowPathStart = stubCode.locationOf(callICs[i].slowPathStart);
-        jitCallICs[i].typeMonitored = callICs[i].typeMonitored;
-
-        /* Compute the hot call offset. */
-        uint32_t offset = fullCode.locationOf(callICs[i].hotJump) -
-                        fullCode.locationOf(callICs[i].funGuard);
-        jitCallICs[i].hotJumpOffset = offset;
-        JS_ASSERT(jitCallICs[i].hotJumpOffset == offset);
-
-        /* Compute the join point offset. */
-        offset = fullCode.locationOf(callICs[i].joinPoint) -
-                 fullCode.locationOf(callICs[i].funGuard);
-        jitCallICs[i].joinPointOffset = offset;
-        JS_ASSERT(jitCallICs[i].joinPointOffset == offset);
-
-        offset = fullCode.locationOf(callICs[i].ionJoinPoint) -
-                 fullCode.locationOf(callICs[i].funGuard);
-        jitCallICs[i].ionJoinOffset = offset;
-        JS_ASSERT(jitCallICs[i].ionJoinOffset == offset);
-
-        /* Compute the OOL call offset. */
-        offset = stubCode.locationOf(callICs[i].oolCall) -
-                 stubCode.locationOf(callICs[i].slowPathStart);
-        jitCallICs[i].oolCallOffset = offset;
-        JS_ASSERT(jitCallICs[i].oolCallOffset == offset);
-
-        /* Compute the OOL jump offset. */
-        offset = stubCode.locationOf(callICs[i].oolJump) -
-                 stubCode.locationOf(callICs[i].slowPathStart);
-        jitCallICs[i].oolJumpOffset = offset;
-        JS_ASSERT(jitCallICs[i].oolJumpOffset == offset);
-
-        /* Compute the start of the OOL IC call. */
-        offset = stubCode.locationOf(callICs[i].icCall) -
-                 stubCode.locationOf(callICs[i].slowPathStart);
-        jitCallICs[i].icCallOffset = offset;
-        JS_ASSERT(jitCallICs[i].icCallOffset == offset);
-
-        /* Compute the slow join point offset. */
-        offset = stubCode.locationOf(callICs[i].slowJoinPoint) -
-                 stubCode.locationOf(callICs[i].slowPathStart);
-        jitCallICs[i].slowJoinOffset = offset;
-        JS_ASSERT(jitCallICs[i].slowJoinOffset == offset);
-
-        /* Compute the join point offset for continuing on the hot path. */
-        offset = stubCode.locationOf(callICs[i].hotPathLabel) -
-                 stubCode.locationOf(callICs[i].funGuard);
-        jitCallICs[i].hotPathOffset = offset;
-        JS_ASSERT(jitCallICs[i].hotPathOffset == offset);
-
-        jitCallICs[i].call = &jitCallSites[callICs[i].callIndex];
-        jitCallICs[i].frameSize = callICs[i].frameSize;
-        jitCallICs[i].funObjReg = callICs[i].funObjReg;
-        stubCode.patch(callICs[i].addrLabel1, &jitCallICs[i]);
-        stubCode.patch(callICs[i].addrLabel2, &jitCallICs[i]);
-    }
-
-    ic::EqualityICInfo *jitEqualityICs = (ic::EqualityICInfo *)cursor;
-    chunk->nEqualityICs = equalityICs.length();
-    cursor += sizeof(ic::EqualityICInfo) * chunk->nEqualityICs;
-    for (size_t i = 0; i < chunk->nEqualityICs; i++) {
-        if (equalityICs[i].trampoline) {
-            jitEqualityICs[i].target = stubCode.locationOf(equalityICs[i].trampolineStart);
-        } else {
-            uint32_t offs = uint32_t(equalityICs[i].jumpTarget - script_->code);
-            JS_ASSERT(jumpMap[offs].isSet());
-            jitEqualityICs[i].target = fullCode.locationOf(jumpMap[offs]);
-        }
-        jitEqualityICs[i].stubEntry = stubCode.locationOf(equalityICs[i].stubEntry);
-        jitEqualityICs[i].stubCall = stubCode.locationOf(equalityICs[i].stubCall);
-        jitEqualityICs[i].stub = equalityICs[i].stub;
-        jitEqualityICs[i].lvr = equalityICs[i].lvr;
-        jitEqualityICs[i].rvr = equalityICs[i].rvr;
-        jitEqualityICs[i].tempReg = equalityICs[i].tempReg;
-        jitEqualityICs[i].cond = equalityICs[i].cond;
-        if (equalityICs[i].jumpToStub.isSet())
-            jitEqualityICs[i].jumpToStub = fullCode.locationOf(equalityICs[i].jumpToStub.get());
-        jitEqualityICs[i].fallThrough = fullCode.locationOf(equalityICs[i].fallThrough);
-
-        stubCode.patch(equalityICs[i].addrLabel, &jitEqualityICs[i]);
-    }
-#endif /* JS_MONOIC */
-
-    for (size_t i = 0; i < callPatches.length(); i++) {
-        CallPatchInfo &patch = callPatches[i];
-
-        CodeLocationLabel joinPoint = patch.joinSlow
-            ? stubCode.locationOf(patch.joinPoint)
-            : fullCode.locationOf(patch.joinPoint);
-
-        if (patch.hasFastNcode)
-            fullCode.patch(patch.fastNcodePatch, joinPoint);
-        if (patch.hasSlowNcode)
-            stubCode.patch(patch.slowNcodePatch, joinPoint);
-    }
-
-#ifdef JS_POLYIC
-    ic::GetElementIC *jitGetElems = (ic::GetElementIC *)cursor;
-    chunk->nGetElems = getElemICs.length();
-    cursor += sizeof(ic::GetElementIC) * chunk->nGetElems;
-    for (size_t i = 0; i < chunk->nGetElems; i++) {
-        ic::GetElementIC &to = jitGetElems[i];
-        GetElementICInfo &from = getElemICs[i];
-
-        new (&to) ic::GetElementIC();
-        from.copyTo(to, fullCode, stubCode);
-
-        to.typeReg = from.typeReg;
-        to.objReg = from.objReg;
-        to.idRemat = from.id;
-
-        if (from.typeGuard.isSet()) {
-            int inlineTypeGuard = fullCode.locationOf(from.typeGuard.get()) -
-                                  fullCode.locationOf(from.fastPathStart);
-            to.inlineTypeGuard = inlineTypeGuard;
-            JS_ASSERT(to.inlineTypeGuard == inlineTypeGuard);
-        }
-        int inlineShapeGuard = fullCode.locationOf(from.shapeGuard) -
-                               fullCode.locationOf(from.fastPathStart);
-        to.inlineShapeGuard = inlineShapeGuard;
-        JS_ASSERT(to.inlineShapeGuard == inlineShapeGuard);
-
-        stubCode.patch(from.paramAddr, &to);
-    }
-
-    ic::SetElementIC *jitSetElems = (ic::SetElementIC *)cursor;
-    chunk->nSetElems = setElemICs.length();
-    cursor += sizeof(ic::SetElementIC) * chunk->nSetElems;
-    for (size_t i = 0; i < chunk->nSetElems; i++) {
-        ic::SetElementIC &to = jitSetElems[i];
-        SetElementICInfo &from = setElemICs[i];
-
-        new (&to) ic::SetElementIC();
-        from.copyTo(to, fullCode, stubCode);
-
-        to.strictMode = script_->strict;
-        to.vr = from.vr;
-        to.objReg = from.objReg;
-        to.objRemat = from.objRemat.toInt32();
-        JS_ASSERT(to.objRemat == from.objRemat.toInt32());
-
-        to.hasConstantKey = from.key.isConstant();
-        if (from.key.isConstant())
-            to.keyValue = from.key.index();
-        else
-            to.keyReg = from.key.reg();
-
-        int inlineShapeGuard = fullCode.locationOf(from.shapeGuard) -
-                               fullCode.locationOf(from.fastPathStart);
-        to.inlineShapeGuard = inlineShapeGuard;
-        JS_ASSERT(to.inlineShapeGuard == inlineShapeGuard);
-
-        int inlineHoleGuard = fullCode.locationOf(from.holeGuard) -
-                               fullCode.locationOf(from.fastPathStart);
-        to.inlineHoleGuard = inlineHoleGuard;
-        JS_ASSERT(to.inlineHoleGuard == inlineHoleGuard);
-
-        CheckIsStubCall(to.slowPathCall.labelAtOffset(0));
-
-        to.volatileMask = from.volatileMask;
-        JS_ASSERT(to.volatileMask == from.volatileMask);
-
-        stubCode.patch(from.paramAddr, &to);
-    }
-
-    ic::PICInfo *jitPics = (ic::PICInfo *)cursor;
-    chunk->nPICs = pics.length();
-    cursor += sizeof(ic::PICInfo) * chunk->nPICs;
-    for (size_t i = 0; i < chunk->nPICs; i++) {
-        new (&jitPics[i]) ic::PICInfo();
-        pics[i].copyTo(jitPics[i], fullCode, stubCode);
-        pics[i].copySimpleMembersTo(jitPics[i]);
-
-        jitPics[i].shapeGuard = masm.distanceOf(pics[i].shapeGuard) -
-                                masm.distanceOf(pics[i].fastPathStart);
-        JS_ASSERT(jitPics[i].shapeGuard == masm.distanceOf(pics[i].shapeGuard) -
-                                           masm.distanceOf(pics[i].fastPathStart));
-        jitPics[i].shapeRegHasBaseShape = true;
-        jitPics[i].pc = pics[i].pc;
-
-        if (pics[i].kind == ic::PICInfo::SET) {
-            jitPics[i].u.vr = pics[i].vr;
-        } else if (pics[i].kind != ic::PICInfo::NAME) {
-            if (pics[i].hasTypeCheck) {
-                int32_t distance = stubcc.masm.distanceOf(pics[i].typeCheck) -
-                                 stubcc.masm.distanceOf(pics[i].slowPathStart);
-                JS_ASSERT(distance <= 0);
-                jitPics[i].u.get.typeCheckOffset = distance;
-            }
-        }
-        stubCode.patch(pics[i].paramAddr, &jitPics[i]);
-    }
-#endif
-
-    JS_ASSERT(size_t(cursor - (uint8_t*)chunk) == dataSize);
-    /* Use the computed size here -- we don't want slop bytes to be counted. */
-    JS_ASSERT(chunk->computedSizeOfIncludingThis() == dataSize);
-
-    /* Link fast and slow paths together. */
-    stubcc.fixCrossJumps(result, masm.size(), masm.size() + stubcc.size());
-
-#if defined(JS_CPU_MIPS)
-    /* Make sure doubleOffset is aligned to sizeof(double) bytes.  */
-    size_t doubleOffset = (((size_t)result + masm.size() + stubcc.size() +
-                            sizeof(double) - 1) & (~(sizeof(double) - 1))) -
-                          (size_t)result;
-    JS_ASSERT((((size_t)result + doubleOffset) & 7) == 0);
-#else
-    size_t doubleOffset = masm.size() + stubcc.size();
-#endif
-
-    double *inlineDoubles = (double *) (result + doubleOffset);
-    double *oolDoubles = (double*) (result + doubleOffset +
-                                    masm.numDoubles() * sizeof(double));
-
-    /* Generate jump tables. */
-    void **jumpVec = (void **)(oolDoubles + stubcc.masm.numDoubles());
-
-    for (size_t i = 0; i < jumpTableEdges.length(); i++) {
-        JumpTableEdge edge = jumpTableEdges[i];
-        if (bytecodeInChunk(script_->code + edge.target)) {
-            JS_ASSERT(jumpMap[edge.target].isSet());
-            jumpVec[i] = (void *)(result + masm.distanceOf(jumpMap[edge.target]));
-        } else {
-            ChunkJumpTableEdge nedge;
-            nedge.edge = edge;
-            nedge.jumpTableEntry = &jumpVec[i];
-            chunkJumps.infallibleAppend(nedge);
-            jumpVec[i] = NULL;
-        }
-    }
-
-    /* Patch jump table references. */
-    for (size_t i = 0; i < jumpTables.length(); i++) {
-        JumpTable &jumpTable = jumpTables[i];
-        fullCode.patch(jumpTable.label, &jumpVec[jumpTable.offsetIndex]);
-    }
-
-    /* Patch all outgoing calls. */
-    masm.finalize(fullCode, inlineDoubles);
-    stubcc.masm.finalize(stubCode, oolDoubles);
-
-    JSC::ExecutableAllocator::makeExecutable(result, masm.size() + stubcc.size());
-    JSC::ExecutableAllocator::cacheFlush(result, masm.size() + stubcc.size());
-
-    a->mainCodeStart = size_t(result);
-    a->mainCodeEnd   = size_t(result + masm.size());
-    a->stubCodeStart = a->mainCodeEnd;
-    a->stubCodeEnd   = a->mainCodeEnd + stubcc.size();
-    if (!Probes::registerMJITCode(cx, chunk,
-                                  a, (JSActiveFrame**) inlineFrames.begin())) {
-        execPool->release();
-        js_free(chunk);
-        js_ReportOutOfMemory(cx);
-        return Compile_Error;
-    }
-
-    outerChunkRef().chunk = chunk;
-
-    /* Patch all incoming and outgoing cross-chunk jumps. */
-    CrossChunkEdge *crossEdges = jit->edges();
-    for (unsigned i = 0; i < jit->nedges; i++) {
-        CrossChunkEdge &edge = crossEdges[i];
-        if (bytecodeInChunk(outerScript->code + edge.source)) {
-            JS_ASSERT(!edge.sourceJump1 && !edge.sourceJump2);
-            void *label = edge.targetLabel ? edge.targetLabel : edge.shimLabel;
-            CodeLocationLabel targetLabel(label);
-            JSOp op = JSOp(script_->code[edge.source]);
-            if (op == JSOP_TABLESWITCH) {
-                if (edge.jumpTableEntries)
-                    js_free(edge.jumpTableEntries);
-                CrossChunkEdge::JumpTableEntryVector *jumpTableEntries = NULL;
-                bool failed = false;
-                for (unsigned j = 0; j < chunkJumps.length(); j++) {
-                    ChunkJumpTableEdge nedge = chunkJumps[j];
-                    if (nedge.edge.source == edge.source && nedge.edge.target == edge.target) {
-                        if (!jumpTableEntries) {
-                            jumpTableEntries = js_new<CrossChunkEdge::JumpTableEntryVector>();
-                            if (!jumpTableEntries)
-                                failed = true;
-                        }
-                        if (!jumpTableEntries->append(nedge.jumpTableEntry))
-                            failed = true;
-                        *nedge.jumpTableEntry = label;
-                    }
-                }
-                if (failed) {
-                    execPool->release();
-                    js_free(chunk);
-                    js_ReportOutOfMemory(cx);
-                    return Compile_Error;
-                }
-                edge.jumpTableEntries = jumpTableEntries;
-            }
-            for (unsigned j = 0; j < chunkEdges.length(); j++) {
-                const OutgoingChunkEdge &oedge = chunkEdges[j];
-                if (oedge.source == edge.source && oedge.target == edge.target) {
-                    /*
-                     * Only a single edge needs to be patched; we ensured while
-                     * generating chunks that no two cross chunk edges can have
-                     * the same source and target. Note that there may not be
-                     * an edge to patch, if constant folding determined the
-                     * jump is never taken.
-                     */
-                    edge.sourceJump1 = fullCode.locationOf(oedge.fastJump).executableAddress();
-                    if (oedge.slowJump.isSet()) {
-                        edge.sourceJump2 =
-                            stubCode.locationOf(oedge.slowJump.get()).executableAddress();
-                    }
-#ifdef JS_CPU_X64
-                    edge.sourceTrampoline =
-                        stubCode.locationOf(oedge.sourceTrampoline).executableAddress();
-#endif
-                    jit->patchEdge(edge, label);
-                    break;
-                }
-            }
-        } else if (bytecodeInChunk(outerScript->code + edge.target)) {
-            JS_ASSERT(!edge.targetLabel);
-            JS_ASSERT(jumpMap[edge.target].isSet());
-            edge.targetLabel = fullCode.locationOf(jumpMap[edge.target]).executableAddress();
-            jit->patchEdge(edge, edge.targetLabel);
-        }
-    }
-
-    chunk->recompileInfo = cx->compartment->types.compiledInfo;
-    return Compile_Okay;
-}
-
-#ifdef DEBUG
-#define SPEW_OPCODE()                                                         \
-    JS_BEGIN_MACRO                                                            \
-        if (IsJaegerSpewChannelActive(JSpew_JSOps)) {                         \
-            Sprinter sprinter(cx);                                            \
-            sprinter.init();                                                  \
-            RootedScript script(cx, script_);                                 \
-            js_Disassemble1(cx, script, PC, PC - script_->code,               \
-                            JS_TRUE, &sprinter);                              \
-            JaegerSpew(JSpew_JSOps, "    %2d %s",                             \
-                       frame.stackDepth(), sprinter.string());                \
-        }                                                                     \
-    JS_END_MACRO;
-#else
-#define SPEW_OPCODE()
-#endif /* DEBUG */
-
-#define BEGIN_CASE(name)        case name:
-#define END_CASE(name)                      \
-    JS_BEGIN_MACRO                          \
-        PC += name##_LENGTH;                \
-    JS_END_MACRO;                           \
-    break;
-
-static inline void
-FixDouble(Value &val)
-{
-    if (val.isInt32())
-        val.setDouble((double)val.toInt32());
-}
-
-inline bool
-mjit::Compiler::shouldStartLoop(jsbytecode *head)
-{
-    /*
-     * Don't do loop based optimizations or register allocation for loops which
-     * span multiple chunks.
-     */
-    if (*head == JSOP_LOOPHEAD && analysis->getLoop(head)) {
-        uint32_t backedge = analysis->getLoop(head)->backedge;
-        if (!bytecodeInChunk(script_->code + backedge))
-            return false;
-        return true;
-    }
-    return false;
-}
-
-CompileStatus
-mjit::Compiler::generateMethod()
-{
-    SrcNoteLineScanner scanner(script_->notes(), script_->lineno);
-
-    /* For join points, whether there was fallthrough from the previous opcode. */
-    bool fallthrough = true;
-
-    /* Last bytecode processed. */
-    jsbytecode *lastPC = NULL;
-
-    if (!outerJIT())
-        return Compile_Retry;
-
-    uint32_t chunkBegin = 0, chunkEnd = script_->length;
-    if (!a->parent) {
-        const ChunkDescriptor &desc =
-            outerJIT()->chunkDescriptor(chunkIndex);
-        chunkBegin = desc.begin;
-        chunkEnd = desc.end;
-
-        while (PC != script_->code + chunkBegin) {
-            Bytecode *opinfo = analysis->maybeCode(PC);
-            if (opinfo) {
-                if (opinfo->jumpTarget) {
-                    /* Update variable types for all new values at this bytecode. */
-                    const SlotValue *newv = analysis->newValues(PC);
-                    if (newv) {
-                        while (newv->slot) {
-                            if (newv->slot < TotalSlots(script_)) {
-                                VarType &vt = a->varTypes[newv->slot];
-                                vt.setTypes(analysis->getValueTypes(newv->value));
-                            }
-                            newv++;
-                        }
-                    }
-                }
-                if (analyze::BytecodeUpdatesSlot(JSOp(*PC))) {
-                    uint32_t slot = GetBytecodeSlot(script_, PC);
-                    if (analysis->trackSlot(slot)) {
-                        VarType &vt = a->varTypes[slot];
-                        vt.setTypes(analysis->pushedTypes(PC, 0));
-                    }
-                }
-            }
-
-            PC += GetBytecodeLength(PC);
-        }
-
-        if (chunkIndex != 0) {
-            uint32_t depth = analysis->getCode(PC).stackDepth;
-            for (uint32_t i = 0; i < depth; i++)
-                frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-        }
-    }
-
-    /* Use a common root to avoid frequent re-rooting. */
-    RootedPropertyName name0(cx);
-
-    for (;;) {
-        JSOp op = JSOp(*PC);
-        int trap = stubs::JSTRAP_NONE;
-
-        if (script_->hasBreakpointsAt(PC))
-            trap |= stubs::JSTRAP_TRAP;
-
-        Bytecode *opinfo = analysis->maybeCode(PC);
-
-        if (!opinfo) {
-            if (op == JSOP_STOP)
-                break;
-            if (js_CodeSpec[op].length != -1)
-                PC += js_CodeSpec[op].length;
-            else
-                PC += js_GetVariableBytecodeLength(PC);
-            continue;
-        }
-
-        if (PC >= script_->code + script_->length)
-            break;
-
-        scanner.advanceTo(PC - script_->code);
-        if (script_->stepModeEnabled() &&
-            (scanner.isLineHeader() || opinfo->jumpTarget))
-        {
-            trap |= stubs::JSTRAP_SINGLESTEP;
-        }
-
-        frame.setPC(PC);
-        frame.setInTryBlock(opinfo->inTryBlock);
-
-        if (fallthrough) {
-            /*
-             * If there is fallthrough from the previous opcode and we changed
-             * any entries into doubles for a branch at that previous op,
-             * revert those entries into integers. Similarly, if we forgot that
-             * an entry is a double then make it a double again, as the frame
-             * may have assigned it a normal register.
-             */
-            for (unsigned i = 0; i < fixedIntToDoubleEntries.length(); i++) {
-                FrameEntry *fe = frame.getSlotEntry(fixedIntToDoubleEntries[i]);
-                frame.ensureInteger(fe);
-            }
-            for (unsigned i = 0; i < fixedDoubleToAnyEntries.length(); i++) {
-                FrameEntry *fe = frame.getSlotEntry(fixedDoubleToAnyEntries[i]);
-                frame.syncAndForgetFe(fe);
-            }
-        }
-        fixedIntToDoubleEntries.clear();
-        fixedDoubleToAnyEntries.clear();
-
-        if (PC >= script_->code + chunkEnd) {
-            if (fallthrough) {
-                if (opinfo->jumpTarget)
-                    fixDoubleTypes(PC);
-                frame.syncAndForgetEverything();
-                jsbytecode *curPC = PC;
-                do {
-                    PC--;
-                } while (!analysis->maybeCode(PC));
-                if (!jumpAndRun(masm.jump(), curPC, NULL, NULL, /* fallthrough = */ true))
-                    return Compile_Error;
-                PC = curPC;
-            }
-            break;
-        }
-
-        if (opinfo->jumpTarget || trap) {
-            if (fallthrough) {
-                fixDoubleTypes(PC);
-                fixedIntToDoubleEntries.clear();
-                fixedDoubleToAnyEntries.clear();
-
-                /*
-                 * Watch for fallthrough to the head of a 'do while' loop.
-                 * We don't know what register state we will be using at the head
-                 * of the loop so sync, branch, and fix it up after the loop
-                 * has been processed.
-                 */
-                if (cx->typeInferenceEnabled() && shouldStartLoop(PC)) {
-                    frame.syncAndForgetEverything();
-                    Jump j = masm.jump();
-                    if (!startLoop(PC, j, PC))
-                        return Compile_Error;
-                } else {
-                    Label start = masm.label();
-                    if (!frame.syncForBranch(PC, Uses(0)))
-                        return Compile_Error;
-                    if (pcLengths && lastPC) {
-                        /* Track this sync code for the previous op. */
-                        size_t length = masm.size() - masm.distanceOf(start);
-                        uint32_t offset = ssa.frameLength(a->inlineIndex) + lastPC - script_->code;
-                        pcLengths[offset].codeLengthAugment += length;
-                    }
-                    JS_ASSERT(frame.consistentRegisters(PC));
-                }
-            }
-
-            if (!frame.discardForJoin(analysis->getAllocation(PC), opinfo->stackDepth))
-                return Compile_Error;
-            updateJoinVarTypes();
-            fallthrough = true;
-
-            if (!cx->typeInferenceEnabled()) {
-                /* All join points have synced state if we aren't doing cross-branch regalloc. */
-                opinfo->safePoint = true;
-            }
-        } else if (opinfo->safePoint) {
-            frame.syncAndForgetEverything();
-        }
-        frame.assertValidRegisterState();
-        a->jumpMap[uint32_t(PC - script_->code)] = masm.label();
-
-        if (cx->typeInferenceEnabled() && opinfo->safePoint) {
-            /*
-             * We may have come in from a table switch, which does not watch
-             * for the new types introduced for variables at each dispatch
-             * target. Make sure that new SSA values at this safe point with
-             * double type have the correct in memory representation.
-             */
-            const SlotValue *newv = analysis->newValues(PC);
-            if (newv) {
-                while (newv->slot) {
-                    if (newv->value.kind() == SSAValue::PHI &&
-                        newv->value.phiOffset() == uint32_t(PC - script_->code) &&
-                        analysis->trackSlot(newv->slot) &&
-                        a->varTypes[newv->slot].getTypeTag() == JSVAL_TYPE_DOUBLE) {
-                        FrameEntry *fe = frame.getSlotEntry(newv->slot);
-                        masm.ensureInMemoryDouble(frame.addressOf(fe));
-                    }
-                    newv++;
-                }
-            }
-        }
-
-        // Now that we have the PC's register allocation, make sure it gets
-        // explicitly updated if this is the loop entry and new loop registers
-        // are allocated later on.
-        if (loop && !a->parent)
-            loop->setOuterPC(PC);
-
-        SPEW_OPCODE();
-        JS_ASSERT(frame.stackDepth() == opinfo->stackDepth);
-
-        if (op == JSOP_LOOPHEAD && analysis->getLoop(PC)) {
-            jsbytecode *backedge = script_->code + analysis->getLoop(PC)->backedge;
-            if (!bytecodeInChunk(backedge)){
-                for (uint32_t slot = ArgSlot(0); slot < TotalSlots(script_); slot++) {
-                    if (a->varTypes[slot].getTypeTag() == JSVAL_TYPE_DOUBLE) {
-                        FrameEntry *fe = frame.getSlotEntry(slot);
-                        masm.ensureInMemoryDouble(frame.addressOf(fe));
-                    }
-                }
-            }
-        }
-
-        // If this is an exception entry point, then jsl_InternalThrow has set
-        // VMFrame::fp to the correct fp for the entry point. We need to copy
-        // that value here to FpReg so that FpReg also has the correct sp.
-        // Otherwise, we would simply be using a stale FpReg value.
-        if (op == JSOP_ENTERBLOCK && analysis->getCode(PC).exceptionEntry)
-            masm.loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
-
-        if (trap) {
-            prepareStubCall(Uses(0));
-            masm.move(Imm32(trap), Registers::ArgReg1);
-            Call cl = emitStubCall(JS_FUNC_TO_DATA_PTR(void *, stubs::Trap), NULL);
-            InternalCallSite site(masm.callReturnOffset(cl), a->inlineIndex, PC,
-                                  REJOIN_TRAP, false);
-            addCallSite(site);
-        }
-
-        /* Don't compile fat opcodes, run the decomposed version instead. */
-        if (js_CodeSpec[op].format & JOF_DECOMPOSE) {
-            PC += js_CodeSpec[op].length;
-            continue;
-        }
-
-        Label inlineStart = masm.label();
-        Label stubStart = stubcc.masm.label();
-        bool countsUpdated = false;
-        bool arithUpdated = false;
-
-        JSValueType arithFirstUseType = JSVAL_TYPE_UNKNOWN;
-        JSValueType arithSecondUseType = JSVAL_TYPE_UNKNOWN;
-        if (script_->hasScriptCounts && !!(js_CodeSpec[op].format & JOF_ARITH)) {
-            if (GetUseCount(script_, PC - script_->code) == 1) {
-                FrameEntry *use = frame.peek(-1);
-                /*
-                 * Pretend it's a binary operation and the second operand has
-                 * the same type as the first one.
-                 */
-                if (use->isTypeKnown())
-                    arithFirstUseType = arithSecondUseType = use->getKnownType();
-            } else {
-                FrameEntry *use = frame.peek(-1);
-                if (use->isTypeKnown())
-                    arithFirstUseType = use->getKnownType();
-                use = frame.peek(-2);
-                if (use->isTypeKnown())
-                    arithSecondUseType = use->getKnownType();
-            }
-        }
-
-        /*
-         * Update PC counts for jump opcodes at their start, so that we don't
-         * miss them when taking the jump. This is delayed for other opcodes,
-         * as we want to skip updating for ops we didn't generate any code for.
-         */
-        if (script_->hasScriptCounts && JOF_OPTYPE(op) == JOF_JUMP)
-            updatePCCounts(PC, &countsUpdated);
-
-    /**********************
-     * BEGIN COMPILER OPS *
-     **********************/
-
-        lastPC = PC;
-
-        switch (op) {
-          BEGIN_CASE(JSOP_NOP)
-          END_CASE(JSOP_NOP)
-
-          BEGIN_CASE(JSOP_NOTEARG)
-          END_CASE(JSOP_NOTEARG)
-
-          BEGIN_CASE(JSOP_UNDEFINED)
-            frame.push(UndefinedValue());
-          END_CASE(JSOP_UNDEFINED)
-
-          BEGIN_CASE(JSOP_POPV)
-          BEGIN_CASE(JSOP_SETRVAL)
-          {
-            RegisterID reg = frame.allocReg();
-            masm.load32(FrameFlagsAddress(), reg);
-            masm.or32(Imm32(StackFrame::HAS_RVAL), reg);
-            masm.store32(reg, FrameFlagsAddress());
-            frame.freeReg(reg);
-
-            /* Scripts which write to the frame's return slot aren't inlined. */
-            JS_ASSERT(a == outer);
-
-            FrameEntry *fe = frame.peek(-1);
-            frame.storeTo(fe, Address(JSFrameReg, StackFrame::offsetOfReturnValue()), true);
-            frame.pop();
-          }
-          END_CASE(JSOP_POPV)
-
-          BEGIN_CASE(JSOP_RETURN)
-            if (script_->hasScriptCounts)
-                updatePCCounts(PC, &countsUpdated);
-            emitReturn(frame.peek(-1));
-            fallthrough = false;
-          END_CASE(JSOP_RETURN)
-
-          BEGIN_CASE(JSOP_GOTO)
-          BEGIN_CASE(JSOP_DEFAULT)
-          {
-            unsigned targetOffset = FollowBranch(cx, script_, PC - script_->code);
-            jsbytecode *target = script_->code + targetOffset;
-
-            fixDoubleTypes(target);
-
-            /*
-             * Watch for gotos which are entering a 'for' or 'while' loop.
-             * These jump to the loop condition test and are immediately
-             * followed by the head of the loop.
-             */
-            jsbytecode *next = PC + js_CodeSpec[op].length;
-            if (cx->typeInferenceEnabled() &&
-                analysis->maybeCode(next) &&
-                shouldStartLoop(next))
-            {
-                frame.syncAndForgetEverything();
-                Jump j = masm.jump();
-                if (!startLoop(next, j, target))
-                    return Compile_Error;
-            } else {
-                if (!frame.syncForBranch(target, Uses(0)))
-                    return Compile_Error;
-                Jump j = masm.jump();
-                if (!jumpAndRun(j, target))
-                    return Compile_Error;
-            }
-            fallthrough = false;
-            PC += js_CodeSpec[op].length;
-            break;
-          }
-          END_CASE(JSOP_GOTO)
-
-          BEGIN_CASE(JSOP_IFEQ)
-          BEGIN_CASE(JSOP_IFNE)
-          {
-            jsbytecode *target = PC + GET_JUMP_OFFSET(PC);
-            fixDoubleTypes(target);
-            if (!jsop_ifneq(op, target))
-                return Compile_Error;
-            PC += js_CodeSpec[op].length;
-            break;
-          }
-          END_CASE(JSOP_IFNE)
-
-          BEGIN_CASE(JSOP_ARGUMENTS)
-            if (script_->needsArgsObj()) {
-                prepareStubCall(Uses(0));
-                INLINE_STUBCALL(stubs::Arguments, REJOIN_FALLTHROUGH);
-                pushSyncedEntry(0);
-            } else {
-                frame.push(MagicValue(JS_OPTIMIZED_ARGUMENTS));
-            }
-          END_CASE(JSOP_ARGUMENTS)
-
-          BEGIN_CASE(JSOP_ITERNEXT)
-            iterNext();
-          END_CASE(JSOP_ITERNEXT)
-
-          BEGIN_CASE(JSOP_DUP)
-            frame.dup();
-          END_CASE(JSOP_DUP)
-
-          BEGIN_CASE(JSOP_DUP2)
-            frame.dup2();
-          END_CASE(JSOP_DUP2)
-
-          BEGIN_CASE(JSOP_SWAP)
-            frame.dup2();
-            frame.shift(-3);
-            frame.shift(-1);
-          END_CASE(JSOP_SWAP)
-
-          BEGIN_CASE(JSOP_PICK)
-          {
-            uint32_t amt = GET_UINT8(PC);
-
-            // Push -(amt + 1), say amt == 2
-            // Stack before: X3 X2 X1
-            // Stack after:  X3 X2 X1 X3
-            frame.dupAt(-int32_t(amt + 1));
-
-            // For each item X[i...1] push it then move it down.
-            // The above would transition like so:
-            //   X3 X2 X1 X3 X2 (dupAt)
-            //   X2 X2 X1 X3    (shift)
-            //   X2 X2 X1 X3 X1 (dupAt)
-            //   X2 X1 X1 X3    (shift)
-            for (int32_t i = -int32_t(amt); i < 0; i++) {
-                frame.dupAt(i - 1);
-                frame.shift(i - 2);
-            }
-
-            // The stack looks like:
-            // Xn ... X1 X1 X{n+1}
-            // So shimmy the last value down.
-            frame.shimmy(1);
-          }
-          END_CASE(JSOP_PICK)
-
-          BEGIN_CASE(JSOP_BITOR)
-          BEGIN_CASE(JSOP_BITXOR)
-          BEGIN_CASE(JSOP_BITAND)
-            jsop_bitop(op);
-          END_CASE(JSOP_BITAND)
-
-          BEGIN_CASE(JSOP_LT)
-          BEGIN_CASE(JSOP_LE)
-          BEGIN_CASE(JSOP_GT)
-          BEGIN_CASE(JSOP_GE)
-          BEGIN_CASE(JSOP_EQ)
-          BEGIN_CASE(JSOP_NE)
-          {
-           if (script_->hasScriptCounts) {
-               updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
-               arithUpdated = true;
-           }
-
-            /* Detect fusions. */
-            jsbytecode *next = &PC[JSOP_GE_LENGTH];
-            JSOp fused = JSOp(*next);
-            if ((fused != JSOP_IFEQ && fused != JSOP_IFNE) || analysis->jumpTarget(next))
-                fused = JSOP_NOP;
-
-            /* Get jump target, if any. */
-            jsbytecode *target = NULL;
-            if (fused != JSOP_NOP) {
-                if (script_->hasScriptCounts)
-                    updatePCCounts(PC, &countsUpdated);
-                target = next + GET_JUMP_OFFSET(next);
-                fixDoubleTypes(target);
-            }
-
-            BoolStub stub = NULL;
-            switch (op) {
-              case JSOP_LT:
-                stub = stubs::LessThan;
-                break;
-              case JSOP_LE:
-                stub = stubs::LessEqual;
-                break;
-              case JSOP_GT:
-                stub = stubs::GreaterThan;
-                break;
-              case JSOP_GE:
-                stub = stubs::GreaterEqual;
-                break;
-              case JSOP_EQ:
-                stub = stubs::Equal;
-                break;
-              case JSOP_NE:
-                stub = stubs::NotEqual;
-                break;
-              default:
-                JS_NOT_REACHED("WAT");
-                break;
-            }
-
-            /*
-             * We need to ensure in the target case that we always rejoin
-             * before the rval test. In the non-target case we will rejoin
-             * correctly after the op finishes.
-             */
-
-            FrameEntry *rhs = frame.peek(-1);
-            FrameEntry *lhs = frame.peek(-2);
-
-            /* Check for easy cases that the parser does not constant fold. */
-            if (lhs->isConstant() && rhs->isConstant()) {
-                /* Primitives can be trivially constant folded. */
-                const Value &lv = lhs->getValue();
-                const Value &rv = rhs->getValue();
-
-                if (lv.isPrimitive() && rv.isPrimitive()) {
-                    bool result = compareTwoValues(cx, op, lv, rv);
-
-                    frame.pop();
-                    frame.pop();
-
-                    if (!target) {
-                        frame.push(Value(BooleanValue(result)));
-                    } else {
-                        if (fused == JSOP_IFEQ)
-                            result = !result;
-                        if (!constantFoldBranch(target, result))
-                            return Compile_Error;
-                    }
-                } else {
-                    if (!emitStubCmpOp(stub, target, fused))
-                        return Compile_Error;
-                }
-            } else {
-                /* Anything else should go through the fast path generator. */
-                if (!jsop_relational(op, stub, target, fused))
-                    return Compile_Error;
-            }
-
-            /* Advance PC manually. */
-            JS_STATIC_ASSERT(JSOP_LT_LENGTH == JSOP_GE_LENGTH);
-            JS_STATIC_ASSERT(JSOP_LE_LENGTH == JSOP_GE_LENGTH);
-            JS_STATIC_ASSERT(JSOP_GT_LENGTH == JSOP_GE_LENGTH);
-            JS_STATIC_ASSERT(JSOP_EQ_LENGTH == JSOP_GE_LENGTH);
-            JS_STATIC_ASSERT(JSOP_NE_LENGTH == JSOP_GE_LENGTH);
-
-            PC += JSOP_GE_LENGTH;
-            if (fused != JSOP_NOP) {
-                SPEW_OPCODE();
-                PC += JSOP_IFNE_LENGTH;
-            }
-            break;
-          }
-          END_CASE(JSOP_GE)
-
-          BEGIN_CASE(JSOP_LSH)
-            jsop_bitop(op);
-          END_CASE(JSOP_LSH)
-
-          BEGIN_CASE(JSOP_RSH)
-            jsop_bitop(op);
-          END_CASE(JSOP_RSH)
-
-          BEGIN_CASE(JSOP_URSH)
-            jsop_bitop(op);
-          END_CASE(JSOP_URSH)
-
-          BEGIN_CASE(JSOP_ADD)
-            if (!jsop_binary(op, stubs::Add, knownPushedType(0), pushedTypeSet(0)))
-                return Compile_Retry;
-          END_CASE(JSOP_ADD)
-
-          BEGIN_CASE(JSOP_SUB)
-            if (!jsop_binary(op, stubs::Sub, knownPushedType(0), pushedTypeSet(0)))
-                return Compile_Retry;
-          END_CASE(JSOP_SUB)
-
-          BEGIN_CASE(JSOP_MUL)
-            if (!jsop_binary(op, stubs::Mul, knownPushedType(0), pushedTypeSet(0)))
-                return Compile_Retry;
-          END_CASE(JSOP_MUL)
-
-          BEGIN_CASE(JSOP_DIV)
-            if (!jsop_binary(op, stubs::Div, knownPushedType(0), pushedTypeSet(0)))
-                return Compile_Retry;
-          END_CASE(JSOP_DIV)
-
-          BEGIN_CASE(JSOP_MOD)
-            if (!jsop_mod())
-                return Compile_Retry;
-          END_CASE(JSOP_MOD)
-
-          BEGIN_CASE(JSOP_NOT)
-            jsop_not();
-          END_CASE(JSOP_NOT)
-
-          BEGIN_CASE(JSOP_BITNOT)
-          {
-            FrameEntry *top = frame.peek(-1);
-            if (top->isConstant() && top->getValue().isPrimitive()) {
-                int32_t i;
-                JS_ALWAYS_TRUE(ToInt32(cx, top->getValue(), &i));
-                i = ~i;
-                frame.pop();
-                frame.push(Int32Value(i));
-            } else {
-                jsop_bitnot();
-            }
-          }
-          END_CASE(JSOP_BITNOT)
-
-          BEGIN_CASE(JSOP_NEG)
-          {
-            FrameEntry *top = frame.peek(-1);
-            if (top->isConstant() && top->getValue().isPrimitive()) {
-                double d;
-                JS_ALWAYS_TRUE(ToNumber(cx, top->getValue(), &d));
-                d = -d;
-                Value v = NumberValue(d);
-
-                /* Watch for overflow in constant propagation. */
-                types::TypeSet *pushed = pushedTypeSet(0);
-                if (!v.isInt32() && pushed && !pushed->hasType(types::Type::DoubleType())) {
-                    RootedScript script(cx, script_);
-                    types::TypeScript::MonitorOverflow(cx, script, PC);
-                    return Compile_Retry;
-                }
-
-                frame.pop();
-                frame.push(v);
-            } else {
-                jsop_neg();
-            }
-          }
-          END_CASE(JSOP_NEG)
-
-          BEGIN_CASE(JSOP_POS)
-            jsop_pos();
-          END_CASE(JSOP_POS)
-
-          BEGIN_CASE(JSOP_DELNAME)
-          {
-            uint32_t index = GET_UINT32_INDEX(PC);
-            name0 = script_->getName(index);
-
-            prepareStubCall(Uses(0));
-            masm.move(ImmPtr(name0), Registers::ArgReg1);
-            INLINE_STUBCALL(stubs::DelName, REJOIN_FALLTHROUGH);
-            pushSyncedEntry(0);
-          }
-          END_CASE(JSOP_DELNAME)
-
-          BEGIN_CASE(JSOP_DELPROP)
-          {
-            uint32_t index = GET_UINT32_INDEX(PC);
-            name0 = script_->getName(index);
-
-            prepareStubCall(Uses(1));
-            masm.move(ImmPtr(name0), Registers::ArgReg1);
-            INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::DelProp), REJOIN_FALLTHROUGH);
-            frame.pop();
-            pushSyncedEntry(0);
-          }
-          END_CASE(JSOP_DELPROP)
-
-          BEGIN_CASE(JSOP_DELELEM)
-          {
-            prepareStubCall(Uses(2));
-            INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::DelElem), REJOIN_FALLTHROUGH);
-            frame.popn(2);
-            pushSyncedEntry(0);
-          }
-          END_CASE(JSOP_DELELEM)
-
-          BEGIN_CASE(JSOP_TYPEOF)
-          BEGIN_CASE(JSOP_TYPEOFEXPR)
-            jsop_typeof();
-          END_CASE(JSOP_TYPEOF)
-
-          BEGIN_CASE(JSOP_VOID)
-            frame.pop();
-            frame.push(UndefinedValue());
-          END_CASE(JSOP_VOID)
-
-          BEGIN_CASE(JSOP_GETPROP)
-          BEGIN_CASE(JSOP_CALLPROP)
-          BEGIN_CASE(JSOP_LENGTH)
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_getprop(name0, knownPushedType(0)))
-                return Compile_Error;
-          END_CASE(JSOP_GETPROP)
-
-          BEGIN_CASE(JSOP_GETELEM)
-          BEGIN_CASE(JSOP_CALLELEM)
-            if (script_->hasScriptCounts)
-                updateElemCounts(PC, frame.peek(-2), frame.peek(-1));
-            if (!jsop_getelem())
-                return Compile_Error;
-          END_CASE(JSOP_GETELEM)
-
-          BEGIN_CASE(JSOP_TOID)
-            jsop_toid();
-          END_CASE(JSOP_TOID)
-
-          BEGIN_CASE(JSOP_SETELEM)
-          {
-            if (script_->hasScriptCounts)
-                updateElemCounts(PC, frame.peek(-3), frame.peek(-2));
-            jsbytecode *next = &PC[JSOP_SETELEM_LENGTH];
-            bool pop = (JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next));
-            if (!jsop_setelem(pop))
-                return Compile_Error;
-          }
-          END_CASE(JSOP_SETELEM);
-
-          BEGIN_CASE(JSOP_EVAL)
-          {
-            JaegerSpew(JSpew_Insns, " --- EVAL --- \n");
-            emitEval(GET_ARGC(PC));
-            JaegerSpew(JSpew_Insns, " --- END EVAL --- \n");
-          }
-          END_CASE(JSOP_EVAL)
-
-          BEGIN_CASE(JSOP_CALL)
-          BEGIN_CASE(JSOP_NEW)
-          BEGIN_CASE(JSOP_FUNAPPLY)
-          BEGIN_CASE(JSOP_FUNCALL)
-          {
-            bool callingNew = (op == JSOP_NEW);
-
-            bool done = false;
-            if ((op == JSOP_CALL || op == JSOP_NEW) && !monitored(PC)) {
-                CompileStatus status = inlineNativeFunction(GET_ARGC(PC), callingNew);
-                if (status == Compile_Okay)
-                    done = true;
-                else if (status != Compile_InlineAbort)
-                    return status;
-            }
-            if (!done && inlining()) {
-                CompileStatus status = inlineScriptedFunction(GET_ARGC(PC), callingNew);
-                if (status == Compile_Okay)
-                    done = true;
-                else if (status != Compile_InlineAbort)
-                    return status;
-                if (script_->hasScriptCounts) {
-                    /* Code generated while inlining has been accounted for. */
-                    countsUpdated = true;
-                }
-            }
-
-            FrameSize frameSize;
-            frameSize.initStatic(frame.totalDepth(), GET_ARGC(PC));
-
-            if (!done) {
-                JaegerSpew(JSpew_Insns, " --- SCRIPTED CALL --- \n");
-                if (!inlineCallHelper(GET_ARGC(PC), callingNew, frameSize))
-                    return Compile_Error;
-                JaegerSpew(JSpew_Insns, " --- END SCRIPTED CALL --- \n");
-            }
-          }
-          END_CASE(JSOP_CALL)
-
-          BEGIN_CASE(JSOP_NAME)
-          BEGIN_CASE(JSOP_CALLNAME)
-          {
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            jsop_name(name0, knownPushedType(0));
-            frame.extra(frame.peek(-1)).name = name0;
-          }
-          END_CASE(JSOP_NAME)
-
-          BEGIN_CASE(JSOP_GETINTRINSIC)
-          BEGIN_CASE(JSOP_CALLINTRINSIC)
-          {
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_intrinsic(name0, knownPushedType(0)))
-                return Compile_Error;
-            frame.extra(frame.peek(-1)).name = name0;
-          }
-          END_CASE(JSOP_GETINTRINSIC)
-
-          BEGIN_CASE(JSOP_IMPLICITTHIS)
-          {
-            prepareStubCall(Uses(0));
-            masm.move(ImmPtr(script_->getName(GET_UINT32_INDEX(PC))), Registers::ArgReg1);
-            INLINE_STUBCALL(stubs::ImplicitThis, REJOIN_FALLTHROUGH);
-            frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-          }
-          END_CASE(JSOP_IMPLICITTHIS)
-
-          BEGIN_CASE(JSOP_DOUBLE)
-          {
-            double d = script_->getConst(GET_UINT32_INDEX(PC)).toDouble();
-            frame.push(Value(DoubleValue(d)));
-          }
-          END_CASE(JSOP_DOUBLE)
-
-          BEGIN_CASE(JSOP_STRING)
-            frame.push(StringValue(script_->getAtom(GET_UINT32_INDEX(PC))));
-          END_CASE(JSOP_STRING)
-
-          BEGIN_CASE(JSOP_ZERO)
-            frame.push(JSVAL_ZERO);
-          END_CASE(JSOP_ZERO)
-
-          BEGIN_CASE(JSOP_ONE)
-            frame.push(JSVAL_ONE);
-          END_CASE(JSOP_ONE)
-
-          BEGIN_CASE(JSOP_NULL)
-            frame.push(NullValue());
-          END_CASE(JSOP_NULL)
-
-          BEGIN_CASE(JSOP_CALLEE)
-            frame.pushCallee();
-          END_CASE(JSOP_CALLEE)
-
-          BEGIN_CASE(JSOP_THIS)
-            jsop_this();
-          END_CASE(JSOP_THIS)
-
-          BEGIN_CASE(JSOP_FALSE)
-            frame.push(Value(BooleanValue(false)));
-          END_CASE(JSOP_FALSE)
-
-          BEGIN_CASE(JSOP_TRUE)
-            frame.push(Value(BooleanValue(true)));
-          END_CASE(JSOP_TRUE)
-
-          BEGIN_CASE(JSOP_OR)
-          BEGIN_CASE(JSOP_AND)
-          {
-            jsbytecode *target = PC + GET_JUMP_OFFSET(PC);
-            fixDoubleTypes(target);
-            if (!jsop_andor(op, target))
-                return Compile_Error;
-          }
-          END_CASE(JSOP_AND)
-
-          BEGIN_CASE(JSOP_TABLESWITCH)
-            /*
-             * Note: there is no need to syncForBranch for the various targets of
-             * switch statement. The liveness analysis has already marked these as
-             * allocated with no registers in use. There is also no need to fix
-             * double types, as we don't track types of slots in scripts with
-             * switch statements (could be fixed).
-             */
-            if (script_->hasScriptCounts)
-                updatePCCounts(PC, &countsUpdated);
-#if defined JS_CPU_ARM /* Need to implement jump(BaseIndex) for ARM */
-            frame.syncAndKillEverything();
-            masm.move(ImmPtr(PC), Registers::ArgReg1);
-
-            /* prepareStubCall() is not needed due to syncAndForgetEverything() */
-            INLINE_STUBCALL(stubs::TableSwitch, REJOIN_NONE);
-            frame.pop();
-
-            masm.jump(Registers::ReturnReg);
-#else
-            if (!jsop_tableswitch(PC))
-                return Compile_Error;
-#endif
-            PC += js_GetVariableBytecodeLength(PC);
-            break;
-          END_CASE(JSOP_TABLESWITCH)
-
-          BEGIN_CASE(JSOP_CASE)
-            // X Y
-
-            frame.dupAt(-2);
-            // X Y X
-
-            jsop_stricteq(JSOP_STRICTEQ);
-            // X cond
-
-            if (!jsop_ifneq(JSOP_IFNE, PC + GET_JUMP_OFFSET(PC)))
-                return Compile_Error;
-          END_CASE(JSOP_CASE)
-
-          BEGIN_CASE(JSOP_STRICTEQ)
-          BEGIN_CASE(JSOP_STRICTNE)
-            if (script_->hasScriptCounts) {
-                updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
-                arithUpdated = true;
-            }
-            jsop_stricteq(op);
-          END_CASE(JSOP_STRICTEQ)
-
-          BEGIN_CASE(JSOP_ITER)
-            if (!iter(GET_UINT8(PC)))
-                return Compile_Error;
-          END_CASE(JSOP_ITER)
-
-          BEGIN_CASE(JSOP_MOREITER)
-          {
-            /* At the byte level, this is always fused with IFNE or IFNEX. */
-            if (script_->hasScriptCounts)
-                updatePCCounts(PC, &countsUpdated);
-            jsbytecode *target = &PC[JSOP_MOREITER_LENGTH];
-            JSOp next = JSOp(*target);
-            JS_ASSERT(next == JSOP_IFNE);
-
-            target += GET_JUMP_OFFSET(target);
-
-            fixDoubleTypes(target);
-            if (!iterMore(target))
-                return Compile_Error;
-            PC += JSOP_MOREITER_LENGTH;
-            PC += js_CodeSpec[next].length;
-            break;
-          }
-          END_CASE(JSOP_MOREITER)
-
-          BEGIN_CASE(JSOP_ENDITER)
-            iterEnd();
-          END_CASE(JSOP_ENDITER)
-
-          BEGIN_CASE(JSOP_POP)
-            frame.pop();
-          END_CASE(JSOP_POP)
-
-          BEGIN_CASE(JSOP_GETARG)
-          BEGIN_CASE(JSOP_CALLARG)
-          {
-            restoreVarType();
-            uint32_t arg = GET_SLOTNO(PC);
-            if (JSObject *singleton = pushedSingleton(0))
-                frame.push(ObjectValue(*singleton));
-            else if (script_->argsObjAliasesFormals())
-                jsop_aliasedArg(arg, /* get = */ true);
-            else
-                frame.pushArg(arg);
-          }
-          END_CASE(JSOP_GETARG)
-
-          BEGIN_CASE(JSOP_BINDGNAME)
-            jsop_bindgname();
-          END_CASE(JSOP_BINDGNAME)
-
-          BEGIN_CASE(JSOP_SETARG)
-          {
-            jsbytecode *next = &PC[JSOP_SETARG_LENGTH];
-            bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-
-            uint32_t arg = GET_SLOTNO(PC);
-            if (script_->argsObjAliasesFormals())
-                jsop_aliasedArg(arg, /* get = */ false, pop);
-            else
-                frame.storeArg(arg, pop);
-
-            updateVarType();
-
-            if (pop) {
-                frame.pop();
-                PC += JSOP_SETARG_LENGTH + JSOP_POP_LENGTH;
-                break;
-            }
-          }
-          END_CASE(JSOP_SETARG)
-
-          BEGIN_CASE(JSOP_GETLOCAL)
-          BEGIN_CASE(JSOP_CALLLOCAL)
-          {
-            /*
-             * Update the var type unless we are about to pop the variable.
-             * Sync is not guaranteed for types of dead locals, and GETLOCAL
-             * followed by POP is not regarded as a use of the variable.
-             */
-            jsbytecode *next = &PC[JSOP_GETLOCAL_LENGTH];
-            if (JSOp(*next) != JSOP_POP || analysis->jumpTarget(next))
-                restoreVarType();
-            if (JSObject *singleton = pushedSingleton(0))
-                frame.push(ObjectValue(*singleton));
-            else
-                frame.pushLocal(GET_SLOTNO(PC));
-          }
-          END_CASE(JSOP_GETLOCAL)
-
-          BEGIN_CASE(JSOP_GETALIASEDVAR)
-          BEGIN_CASE(JSOP_CALLALIASEDVAR)
-            jsop_aliasedVar(ScopeCoordinate(PC), /* get = */ true);
-          END_CASE(JSOP_GETALIASEDVAR);
-
-          BEGIN_CASE(JSOP_SETLOCAL)
-          BEGIN_CASE(JSOP_SETALIASEDVAR)
-          {
-            jsbytecode *next = &PC[GetBytecodeLength(PC)];
-            bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            if (JOF_OPTYPE(*PC) == JOF_SCOPECOORD) {
-                jsop_aliasedVar(ScopeCoordinate(PC), /* get = */ false, pop);
-            } else {
-                frame.storeLocal(GET_SLOTNO(PC), pop);
-                updateVarType();
-            }
-
-            if (pop) {
-                frame.pop();
-                PC = next + JSOP_POP_LENGTH;
-                break;
-            }
-
-            PC = next;
-            break;
-          }
-          END_CASE(JSOP_SETLOCAL)
-
-          BEGIN_CASE(JSOP_UINT16)
-            frame.push(Value(Int32Value((int32_t) GET_UINT16(PC))));
-          END_CASE(JSOP_UINT16)
-
-          BEGIN_CASE(JSOP_NEWINIT)
-            if (!jsop_newinit())
-                return Compile_Error;
-          END_CASE(JSOP_NEWINIT)
-
-          BEGIN_CASE(JSOP_NEWARRAY)
-            if (!jsop_newinit())
-                return Compile_Error;
-          END_CASE(JSOP_NEWARRAY)
-
-          BEGIN_CASE(JSOP_NEWOBJECT)
-            if (!jsop_newinit())
-                return Compile_Error;
-          END_CASE(JSOP_NEWOBJECT)
-
-          BEGIN_CASE(JSOP_ENDINIT)
-          END_CASE(JSOP_ENDINIT)
-
-          BEGIN_CASE(JSOP_INITPROP)
-            jsop_initprop();
-            frame.pop();
-          END_CASE(JSOP_INITPROP)
-
-          BEGIN_CASE(JSOP_INITELEM_ARRAY)
-            jsop_initelem_array();
-          END_CASE(JSOP_INITELEM_ARRAY)
-
-          BEGIN_CASE(JSOP_INITELEM)
-            prepareStubCall(Uses(3));
-            INLINE_STUBCALL(stubs::InitElem, REJOIN_FALLTHROUGH);
-            frame.popn(2);
-          END_CASE(JSOP_INITELEM)
-
-          BEGIN_CASE(JSOP_BINDNAME)
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            jsop_bindname(name0);
-          END_CASE(JSOP_BINDNAME)
-
-          BEGIN_CASE(JSOP_SETPROP)
-          {
-            jsbytecode *next = &PC[JSOP_SETPROP_LENGTH];
-            bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_setprop(name0, pop))
-                return Compile_Error;
-          }
-          END_CASE(JSOP_SETPROP)
-
-          BEGIN_CASE(JSOP_SETNAME)
-          {
-            jsbytecode *next = &PC[JSOP_SETNAME_LENGTH];
-            bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_setprop(name0, pop))
-                return Compile_Error;
-          }
-          END_CASE(JSOP_SETNAME)
-
-          BEGIN_CASE(JSOP_THROW)
-            prepareStubCall(Uses(1));
-            INLINE_STUBCALL(stubs::Throw, REJOIN_NONE);
-            frame.pop();
-            fallthrough = false;
-          END_CASE(JSOP_THROW)
-
-          BEGIN_CASE(JSOP_IN)
-          {
-            jsop_in();
-          }
-          END_CASE(JSOP_IN)
-
-          BEGIN_CASE(JSOP_INSTANCEOF)
-            if (!jsop_instanceof())
-                return Compile_Error;
-          END_CASE(JSOP_INSTANCEOF)
-
-          BEGIN_CASE(JSOP_EXCEPTION)
-          {
-            prepareStubCall(Uses(0));
-            INLINE_STUBCALL(stubs::Exception, REJOIN_FALLTHROUGH);
-            frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-          }
-          END_CASE(JSOP_EXCEPTION)
-
-          BEGIN_CASE(JSOP_LINENO)
-          END_CASE(JSOP_LINENO)
-
-          BEGIN_CASE(JSOP_ENUMELEM)
-            // Normally, SETELEM transforms the stack
-            //  from: OBJ ID VALUE
-            //  to:   VALUE
-            //
-            // Here, the stack transition is
-            //  from: VALUE OBJ ID
-            //  to:
-            // So we make the stack look like a SETELEM, and re-use it.
-
-            // Before: VALUE OBJ ID
-            // After:  VALUE OBJ ID VALUE
-            frame.dupAt(-3);
-
-            // Before: VALUE OBJ ID VALUE
-            // After:  VALUE VALUE
-            if (!jsop_setelem(true))
-                return Compile_Error;
-
-            // Before: VALUE VALUE
-            // After:
-            frame.popn(2);
-          END_CASE(JSOP_ENUMELEM)
-
-          BEGIN_CASE(JSOP_CONDSWITCH)
-            /* No-op for the decompiler. */
-          END_CASE(JSOP_CONDSWITCH)
-
-          BEGIN_CASE(JSOP_LABEL)
-          END_CASE(JSOP_LABEL)
-
-          BEGIN_CASE(JSOP_DEFFUN)
-          {
-            JSFunction *innerFun = script_->getFunction(GET_UINT32_INDEX(PC));
-
-            prepareStubCall(Uses(0));
-            masm.move(ImmPtr(innerFun), Registers::ArgReg1);
-            INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::DefFun), REJOIN_FALLTHROUGH);
-          }
-          END_CASE(JSOP_DEFFUN)
-
-          BEGIN_CASE(JSOP_DEFVAR)
-          BEGIN_CASE(JSOP_DEFCONST)
-          {
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-
-            prepareStubCall(Uses(0));
-            masm.move(ImmPtr(name0), Registers::ArgReg1);
-            INLINE_STUBCALL(stubs::DefVarOrConst, REJOIN_FALLTHROUGH);
-          }
-          END_CASE(JSOP_DEFVAR)
-
-          BEGIN_CASE(JSOP_SETCONST)
-          {
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-
-            prepareStubCall(Uses(1));
-            masm.move(ImmPtr(name0), Registers::ArgReg1);
-            INLINE_STUBCALL(stubs::SetConst, REJOIN_FALLTHROUGH);
-          }
-          END_CASE(JSOP_SETCONST)
-
-          BEGIN_CASE(JSOP_LAMBDA)
-          {
-            JSFunction *fun = script_->getFunction(GET_UINT32_INDEX(PC));
-
-            JSObjStubFun stub = stubs::Lambda;
-            uint32_t uses = 0;
-
-            prepareStubCall(Uses(uses));
-            masm.move(ImmPtr(fun), Registers::ArgReg1);
-
-            INLINE_STUBCALL(stub, REJOIN_PUSH_OBJECT);
-
-            frame.takeReg(Registers::ReturnReg);
-            frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
-          }
-          END_CASE(JSOP_LAMBDA)
-
-          BEGIN_CASE(JSOP_TRY)
-            frame.syncAndForgetEverything();
-          END_CASE(JSOP_TRY)
-
-          BEGIN_CASE(JSOP_RETRVAL)
-            emitReturn(NULL);
-            fallthrough = false;
-          END_CASE(JSOP_RETRVAL)
-
-          BEGIN_CASE(JSOP_GETGNAME)
-          BEGIN_CASE(JSOP_CALLGNAME)
-          {
-            uint32_t index = GET_UINT32_INDEX(PC);
-            if (!jsop_getgname(index))
-                return Compile_Error;
-            frame.extra(frame.peek(-1)).name = script_->getName(index);
-          }
-          END_CASE(JSOP_GETGNAME)
-
-          BEGIN_CASE(JSOP_SETGNAME)
-          {
-            jsbytecode *next = &PC[JSOP_SETGNAME_LENGTH];
-            bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_setgname(name0, pop))
-                return Compile_Error;
-          }
-          END_CASE(JSOP_SETGNAME)
-
-          BEGIN_CASE(JSOP_REGEXP)
-            if (!jsop_regexp())
-                return Compile_Error;
-          END_CASE(JSOP_REGEXP)
-
-          BEGIN_CASE(JSOP_OBJECT)
-          {
-            JSObject *object = script_->getObject(GET_UINT32_INDEX(PC));
-            RegisterID reg = frame.allocReg();
-            masm.move(ImmPtr(object), reg);
-            frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
-          }
-          END_CASE(JSOP_OBJECT)
-
-          BEGIN_CASE(JSOP_UINT24)
-            frame.push(Value(Int32Value((int32_t) GET_UINT24(PC))));
-          END_CASE(JSOP_UINT24)
-
-          BEGIN_CASE(JSOP_STOP)
-            if (script_->hasScriptCounts)
-                updatePCCounts(PC, &countsUpdated);
-            emitReturn(NULL);
-            goto done;
-          END_CASE(JSOP_STOP)
-
-          BEGIN_CASE(JSOP_GETXPROP)
-            name0 = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_xname(name0))
-                return Compile_Error;
-          END_CASE(JSOP_GETXPROP)
-
-          BEGIN_CASE(JSOP_ENTERBLOCK)
-          BEGIN_CASE(JSOP_ENTERLET0)
-          BEGIN_CASE(JSOP_ENTERLET1)
-            enterBlock(&script_->getObject(GET_UINT32_INDEX(PC))->asStaticBlock());
-          END_CASE(JSOP_ENTERBLOCK);
-
-          BEGIN_CASE(JSOP_LEAVEBLOCK)
-            leaveBlock();
-          END_CASE(JSOP_LEAVEBLOCK)
-
-          BEGIN_CASE(JSOP_INT8)
-            frame.push(Value(Int32Value(GET_INT8(PC))));
-          END_CASE(JSOP_INT8)
-
-          BEGIN_CASE(JSOP_INT32)
-            frame.push(Value(Int32Value(GET_INT32(PC))));
-          END_CASE(JSOP_INT32)
-
-          BEGIN_CASE(JSOP_HOLE)
-            frame.push(MagicValue(JS_ELEMENTS_HOLE));
-          END_CASE(JSOP_HOLE)
-
-          BEGIN_CASE(JSOP_LOOPHEAD)
-            if (analysis->jumpTarget(PC))
-                interruptCheckHelper();
-          END_CASE(JSOP_LOOPHEAD)
-
-          BEGIN_CASE(JSOP_LOOPENTRY)
-            // Unlike JM, IonMonkey OSR enters loops at the LOOPENTRY op.
-            // Insert the recompile check here so that we can immediately
-            // enter Ion.
-            if (loop) {
-                if (IsIonEnabled(cx))
-                    ionCompileHelper();
-                else
-                    inliningCompileHelper();
-            }
-          END_CASE(JSOP_LOOPENTRY)
-
-          BEGIN_CASE(JSOP_DEBUGGER)
-          {
-            prepareStubCall(Uses(0));
-            masm.move(ImmPtr(PC), Registers::ArgReg1);
-            INLINE_STUBCALL(stubs::DebuggerStatement, REJOIN_FALLTHROUGH);
-          }
-          END_CASE(JSOP_DEBUGGER)
-
-          default:
-            JS_NOT_REACHED("Opcode not implemented");
-        }
-
-    /**********************
-     *  END COMPILER OPS  *
-     **********************/
-
-        if (cx->typeInferenceEnabled() && PC == lastPC + GetBytecodeLength(lastPC)) {
-            /*
-             * Inform the frame of the type sets for values just pushed. Skip
-             * this if we did any opcode fusions, we don't keep track of the
-             * associated type sets in such cases.
-             */
-            unsigned nuses = GetUseCount(script_, lastPC - script_->code);
-            unsigned ndefs = GetDefCount(script_, lastPC - script_->code);
-            for (unsigned i = 0; i < ndefs; i++) {
-                FrameEntry *fe = frame.getStack(opinfo->stackDepth - nuses + i);
-                if (fe) {
-                    /* fe may be NULL for conditionally pushed entries, e.g. JSOP_AND */
-                    frame.extra(fe).types = analysis->pushedTypes(lastPC - script_->code, i);
-                }
-            }
-        }
-
-        if (script_->hasScriptCounts) {
-            size_t length = masm.size() - masm.distanceOf(inlineStart);
-            bool typesUpdated = false;
-
-            /* Update information about the type of value pushed by arithmetic ops. */
-            if ((js_CodeSpec[op].format & JOF_ARITH) && !arithUpdated) {
-                FrameEntry *pushed = NULL;
-                if (PC == lastPC + GetBytecodeLength(lastPC))
-                    pushed = frame.peek(-1);
-                updateArithCounts(lastPC, pushed, arithFirstUseType, arithSecondUseType);
-                typesUpdated = true;
-            }
-
-            /* Update information about the result type of access operations. */
-            if (PCCounts::accessOp(op) &&
-                op != JSOP_SETPROP && op != JSOP_SETELEM) {
-                FrameEntry *fe = (GetDefCount(script_, lastPC - script_->code) == 1)
-                    ? frame.peek(-1)
-                    : frame.peek(-2);
-                updatePCTypes(lastPC, fe);
-                typesUpdated = true;
-            }
-
-            if (!countsUpdated && (typesUpdated || length != 0))
-                updatePCCounts(lastPC, &countsUpdated);
-        }
-        /* Update how much code we generated for this opcode */
-        if (pcLengths) {
-            size_t length     = masm.size() - masm.distanceOf(inlineStart);
-            size_t stubLength = stubcc.size() - stubcc.masm.distanceOf(stubStart);
-            uint32_t offset   = ssa.frameLength(a->inlineIndex) + lastPC - script_->code;
-            pcLengths[offset].inlineLength += length;
-            pcLengths[offset].stubLength   += stubLength;
-        }
-
-        frame.assertValidRegisterState();
-    }
-
-  done:
-    return Compile_Okay;
-}
-
-#undef END_CASE
-#undef BEGIN_CASE
-
-void
-mjit::Compiler::updatePCCounts(jsbytecode *pc, bool *updated)
-{
-    JS_ASSERT(script_->hasScriptCounts);
-
-    Label start = masm.label();
-
-    /*
-     * Bump the METHODJIT count for the opcode, read the METHODJIT_CODE_LENGTH
-     * and METHODJIT_PICS_LENGTH counts, indicating the amounts of inline path
-     * code and generated code, respectively, and add them to the accumulated
-     * total for the op.
-     */
-    uint32_t offset = ssa.frameLength(a->inlineIndex) + pc - script_->code;
-
-    /*
-     * Base register for addresses, we can't use AbsoluteAddress in all places.
-     * This may hold a live value, so write it out to the top of the stack
-     * first. This cannot overflow the stack, as space is always reserved for
-     * an extra callee frame.
-     */
-    RegisterID reg = Registers::ReturnReg;
-    masm.storePtr(reg, frame.addressOfTop());
-
-    PCCounts counts = script_->getPCCounts(pc);
-
-    /*
-     * The inlineLength represents the actual length of the opcode generated,
-     * but this includes the instrumentation as well as other possibly not
-     * useful bytes. This extra cruft is accumulated in codeLengthAugment and
-     * will be taken out accordingly.
-     */
-    double *code = &counts.get(PCCounts::BASE_METHODJIT_CODE);
-    masm.addCount(&pcLengths[offset].inlineLength, code, reg);
-    masm.addCount(&pcLengths[offset].codeLengthAugment, code, reg);
-
-    double *pics = &counts.get(PCCounts::BASE_METHODJIT_PICS);
-    double *picsLength = &pcLengths[offset].picsLength;
-    masm.addCount(picsLength, pics, reg);
-
-    double *count = &counts.get(PCCounts::BASE_METHODJIT);
-    masm.bumpCount(count, reg);
-
-    /* Reload the base register's original value. */
-    masm.loadPtr(frame.addressOfTop(), reg);
-
-    /* The count of code executed should not reflect instrumentation as well */
-    pcLengths[offset].codeLengthAugment -= masm.size() - masm.distanceOf(start);
-
-    *updated = true;
-}
-
-static inline bool
-HasPayloadType(types::TypeSet *types)
-{
-    if (types->unknown())
-        return false;
-
-    types::TypeFlags flags = types->baseFlags();
-    bool objects = !!(flags & types::TYPE_FLAG_ANYOBJECT) || !!types->getObjectCount();
-
-    if (objects && !!(flags & types::TYPE_FLAG_STRING))
-        return false;
-
-    flags = flags & ~(types::TYPE_FLAG_ANYOBJECT | types::TYPE_FLAG_STRING);
-
-    return (flags == types::TYPE_FLAG_UNDEFINED)
-        || (flags == types::TYPE_FLAG_NULL)
-        || (flags == types::TYPE_FLAG_BOOLEAN);
-}
-
-void
-mjit::Compiler::updatePCTypes(jsbytecode *pc, FrameEntry *fe)
-{
-    JS_ASSERT(script_->hasScriptCounts);
-
-    /*
-     * Get a temporary register, as for updatePCCounts. Don't overlap with
-     * the backing store for the entry's type tag, if there is one.
-     */
-    RegisterID reg = Registers::ReturnReg;
-    if (frame.peekTypeInRegister(fe) && reg == frame.tempRegForType(fe)) {
-        JS_STATIC_ASSERT(Registers::ReturnReg != Registers::ArgReg1);
-        reg = Registers::ArgReg1;
-    }
-    masm.push(reg);
-
-    PCCounts counts = script_->getPCCounts(pc);
-
-    /* Update the counts for pushed type tags and possible access types. */
-    if (fe->isTypeKnown()) {
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_MONOMORPHIC), reg);
-        PCCounts::AccessCounts count = PCCounts::ACCESS_OBJECT;
-        switch (fe->getKnownType()) {
-          case JSVAL_TYPE_UNDEFINED:  count = PCCounts::ACCESS_UNDEFINED;  break;
-          case JSVAL_TYPE_NULL:       count = PCCounts::ACCESS_NULL;       break;
-          case JSVAL_TYPE_BOOLEAN:    count = PCCounts::ACCESS_BOOLEAN;    break;
-          case JSVAL_TYPE_INT32:      count = PCCounts::ACCESS_INT32;      break;
-          case JSVAL_TYPE_DOUBLE:     count = PCCounts::ACCESS_DOUBLE;     break;
-          case JSVAL_TYPE_STRING:     count = PCCounts::ACCESS_STRING;     break;
-          case JSVAL_TYPE_OBJECT:     count = PCCounts::ACCESS_OBJECT;     break;
-          default:;
-        }
-        if (count)
-            masm.bumpCount(&counts.get(count), reg);
-    } else {
-        types::TypeSet *types = frame.extra(fe).types;
-        if (types && HasPayloadType(types))
-            masm.bumpCount(&counts.get(PCCounts::ACCESS_DIMORPHIC), reg);
-        else
-            masm.bumpCount(&counts.get(PCCounts::ACCESS_POLYMORPHIC), reg);
-
-        frame.loadTypeIntoReg(fe, reg);
-
-        Jump j = masm.testUndefined(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_UNDEFINED), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testNull(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_NULL), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testBoolean(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_BOOLEAN), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testInt32(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_INT32), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testDouble(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_DOUBLE), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testString(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_STRING), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-
-        j = masm.testObject(Assembler::NotEqual, reg);
-        masm.bumpCount(&counts.get(PCCounts::ACCESS_OBJECT), reg);
-        frame.loadTypeIntoReg(fe, reg);
-        j.linkTo(masm.label(), &masm);
-    }
-
-    /* Update the count for accesses with type barriers. */
-    if (js_CodeSpec[*pc].format & JOF_TYPESET) {
-        double *count = &counts.get(hasTypeBarriers(pc)
-                                      ? PCCounts::ACCESS_BARRIER
-                                      : PCCounts::ACCESS_NOBARRIER);
-        masm.bumpCount(count, reg);
-    }
-
-    /* Reload the base register's original value. */
-    masm.pop(reg);
-}
-
-void
-mjit::Compiler::updateArithCounts(jsbytecode *pc, FrameEntry *fe,
-                                  JSValueType firstUseType, JSValueType secondUseType)
-{
-    JS_ASSERT(script_->hasScriptCounts);
-
-    RegisterID reg = Registers::ReturnReg;
-    masm.push(reg);
-
-    /*
-     * What count we bump for arithmetic expressions depend on the
-     * known types of its operands.
-     *
-     * ARITH_INT: operands are known ints, result is int
-     * ARITH_OVERFLOW: operands are known ints, result is double
-     * ARITH_DOUBLE: either operand is a known double, result is double
-     * ARITH_OTHER: operands are monomorphic but not int or double
-     * ARITH_UNKNOWN: operands are polymorphic
-     */
-
-    PCCounts::ArithCounts count;
-    if (firstUseType == JSVAL_TYPE_INT32 && secondUseType == JSVAL_TYPE_INT32 &&
-        (!fe || fe->isNotType(JSVAL_TYPE_DOUBLE))) {
-        count = PCCounts::ARITH_INT;
-    } else if (firstUseType == JSVAL_TYPE_INT32 || firstUseType == JSVAL_TYPE_DOUBLE ||
-               secondUseType == JSVAL_TYPE_INT32 || secondUseType == JSVAL_TYPE_DOUBLE) {
-        count = PCCounts::ARITH_DOUBLE;
-    } else if (firstUseType != JSVAL_TYPE_UNKNOWN && secondUseType != JSVAL_TYPE_UNKNOWN &&
-               (!fe || fe->isTypeKnown())) {
-        count = PCCounts::ARITH_OTHER;
-    } else {
-        count = PCCounts::ARITH_UNKNOWN;
-    }
-
-    masm.bumpCount(&script_->getPCCounts(pc).get(count), reg);
-    masm.pop(reg);
-}
-
-void
-mjit::Compiler::updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id)
-{
-    JS_ASSERT(script_->hasScriptCounts);
-
-    RegisterID reg = Registers::ReturnReg;
-    masm.push(reg);
-
-    PCCounts counts = script_->getPCCounts(pc);
-
-    PCCounts::ElementCounts count;
-    if (id->isTypeKnown()) {
-        switch (id->getKnownType()) {
-          case JSVAL_TYPE_INT32:   count = PCCounts::ELEM_ID_INT;     break;
-          case JSVAL_TYPE_DOUBLE:  count = PCCounts::ELEM_ID_DOUBLE;  break;
-          default:                 count = PCCounts::ELEM_ID_OTHER;   break;
-        }
-    } else {
-        count = PCCounts::ELEM_ID_UNKNOWN;
-    }
-    masm.bumpCount(&counts.get(count), reg);
-
-    if (obj->mightBeType(JSVAL_TYPE_OBJECT)) {
-        types::StackTypeSet *types = frame.extra(obj).types;
-        if (types && types->getTypedArrayType() != TypedArray::TYPE_MAX) {
-            count = PCCounts::ELEM_OBJECT_TYPED;
-        } else if (types && types->getKnownClass() == &ArrayClass &&
-                   !types->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                          types::OBJECT_FLAG_LENGTH_OVERFLOW)) {
-            if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED))
-                count = PCCounts::ELEM_OBJECT_PACKED;
-            else
-                count = PCCounts::ELEM_OBJECT_DENSE;
-        } else {
-            count = PCCounts::ELEM_OBJECT_OTHER;
-        }
-        masm.bumpCount(&counts.get(count), reg);
-    } else {
-        masm.bumpCount(&counts.get(PCCounts::ELEM_OBJECT_OTHER), reg);
-    }
-
-    masm.pop(reg);
-}
-
-void
-mjit::Compiler::bumpPropCount(jsbytecode *pc, int count)
-{
-    /* Don't accumulate counts for property ops fused with other ops. */
-    if (!(js_CodeSpec[*pc].format & JOF_PROP))
-        return;
-    RegisterID reg = Registers::ReturnReg;
-    masm.push(reg);
-    masm.bumpCount(&script_->getPCCounts(pc).get(count), reg);
-    masm.pop(reg);
-}
-
-JSC::MacroAssembler::Label
-mjit::Compiler::labelOf(jsbytecode *pc, uint32_t inlineIndex)
-{
-    ActiveFrame *a = (inlineIndex == UINT32_MAX) ? outer : inlineFrames[inlineIndex];
-    JS_ASSERT(uint32_t(pc - a->script->code) < a->script->length);
-
-    uint32_t offs = uint32_t(pc - a->script->code);
-    JS_ASSERT(a->jumpMap[offs].isSet());
-    return a->jumpMap[offs];
-}
-
-bool
-mjit::Compiler::knownJump(jsbytecode *pc)
-{
-    return pc < PC;
-}
-
-bool
-mjit::Compiler::jumpInScript(Jump j, jsbytecode *pc)
-{
-    JS_ASSERT(pc >= script_->code && uint32_t(pc - script_->code) < script_->length);
-
-    if (pc < PC) {
-        j.linkTo(a->jumpMap[uint32_t(pc - script_->code)], &masm);
-        return true;
-    }
-    return branchPatches.append(BranchPatch(j, pc, a->inlineIndex));
-}
-
-void
-mjit::Compiler::emitFinalReturn(Assembler &masm)
-{
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfNcode()), Registers::ReturnReg);
-    masm.jump(Registers::ReturnReg);
-}
-
-// Emits code to load a return value of the frame into the scripted-ABI
-// type & data register pair. If the return value is in fp->rval, then |fe|
-// is NULL. Otherwise, |fe| contains the return value.
-//
-// If reading from fp->rval, |undefined| is loaded optimistically, before
-// checking if fp->rval is set in the frame flags and loading that instead.
-//
-// Otherwise, if |masm| is the inline path, it is loaded as efficiently as
-// the FrameState can manage. If |masm| is the OOL path, the value is simply
-// loaded from its slot in the frame, since the caller has guaranteed it's
-// been synced.
-//
-void
-mjit::Compiler::loadReturnValue(Assembler *masm, FrameEntry *fe)
-{
-    RegisterID typeReg = JSReturnReg_Type;
-    RegisterID dataReg = JSReturnReg_Data;
-
-    if (fe) {
-        // If using the OOL assembler, the caller signifies that the |fe| is
-        // synced, but not to rely on its register state.
-        if (masm != &this->masm) {
-            if (fe->isConstant()) {
-                stubcc.masm.loadValueAsComponents(fe->getValue(), typeReg, dataReg);
-            } else {
-                Address rval(frame.addressOf(fe));
-                if (fe->isTypeKnown() && !fe->isType(JSVAL_TYPE_DOUBLE)) {
-                    stubcc.masm.loadPayload(rval, dataReg);
-                    stubcc.masm.move(ImmType(fe->getKnownType()), typeReg);
-                } else {
-                    stubcc.masm.loadValueAsComponents(rval, typeReg, dataReg);
-                }
-            }
-        } else {
-            frame.loadForReturn(fe, typeReg, dataReg, Registers::ReturnReg);
-        }
-    } else {
-         // Load a return value from POPV or SETRVAL into the return registers,
-         // otherwise return undefined.
-        masm->loadValueAsComponents(UndefinedValue(), typeReg, dataReg);
-        if (analysis->usesReturnValue()) {
-            Jump rvalClear = masm->branchTest32(Assembler::Zero,
-                                               FrameFlagsAddress(),
-                                               Imm32(StackFrame::HAS_RVAL));
-            Address rvalAddress(JSFrameReg, StackFrame::offsetOfReturnValue());
-            masm->loadValueAsComponents(rvalAddress, typeReg, dataReg);
-            rvalClear.linkTo(masm->label(), masm);
-        }
-    }
-}
-
-// This ensures that constructor return values are an object. If a non-object
-// is returned, either explicitly or implicitly, the newly created object is
-// loaded out of the frame. Otherwise, the explicitly returned object is kept.
-//
-void
-mjit::Compiler::fixPrimitiveReturn(Assembler *masm, FrameEntry *fe)
-{
-    JS_ASSERT(isConstructing);
-
-    bool ool = (masm != &this->masm);
-    Address thisv(JSFrameReg, StackFrame::offsetOfThis(script_->function()));
-
-    // We can just load |thisv| if either of the following is true:
-    //  (1) There is no explicit return value, AND fp->rval is not used.
-    //  (2) There is an explicit return value, and it's known to be primitive.
-    if ((!fe && !analysis->usesReturnValue()) ||
-        (fe && fe->isTypeKnown() && fe->getKnownType() != JSVAL_TYPE_OBJECT))
-    {
-        if (ool)
-            masm->loadValueAsComponents(thisv, JSReturnReg_Type, JSReturnReg_Data);
-        else
-            frame.loadThisForReturn(JSReturnReg_Type, JSReturnReg_Data, Registers::ReturnReg);
-        return;
-    }
-
-    // If the type is known to be an object, just load the return value as normal.
-    if (fe && fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT) {
-        loadReturnValue(masm, fe);
-        return;
-    }
-
-    // There's a return value, and its type is unknown. Test the type and load
-    // |thisv| if necessary. Sync the 'this' entry before doing so, as it may
-    // be stored in registers if we constructed it inline.
-    frame.syncThis();
-    loadReturnValue(masm, fe);
-    Jump j = masm->testObject(Assembler::Equal, JSReturnReg_Type);
-    masm->loadValueAsComponents(thisv, JSReturnReg_Type, JSReturnReg_Data);
-    j.linkTo(masm->label(), masm);
-}
-
-// Loads the return value into the scripted ABI register pair, such that JS
-// semantics in constructors are preserved.
-//
-void
-mjit::Compiler::emitReturnValue(Assembler *masm, FrameEntry *fe)
-{
-    if (isConstructing)
-        fixPrimitiveReturn(masm, fe);
-    else
-        loadReturnValue(masm, fe);
-}
-
-void
-mjit::Compiler::emitInlineReturnValue(FrameEntry *fe)
-{
-    JS_ASSERT(!isConstructing && a->needReturnValue);
-
-    if (a->syncReturnValue) {
-        /* Needed return value with unknown type, the caller's entry is synced. */
-        Address address = frame.addressForInlineReturn();
-        if (fe)
-            frame.storeTo(fe, address);
-        else
-            masm.storeValue(UndefinedValue(), address);
-        return;
-    }
-
-    /*
-     * For inlined functions that simply return an entry present in the outer
-     * script (e.g. a loop invariant term), mark the copy and propagate it
-     * after popping the frame.
-     */
-    if (!a->exitState && fe && fe->isCopy() && frame.isOuterSlot(fe->backing())) {
-        a->returnEntry = fe->backing();
-        return;
-    }
-
-    if (a->returnValueDouble) {
-        JS_ASSERT(fe);
-        frame.ensureDouble(fe);
-        Registers mask(a->returnSet
-                       ? Registers::maskReg(a->returnRegister)
-                       : Registers::AvailFPRegs);
-        FPRegisterID fpreg;
-        if (!fe->isConstant()) {
-            fpreg = frame.tempRegInMaskForData(fe, mask.freeMask).fpreg();
-            frame.syncAndForgetFe(fe, true);
-            frame.takeReg(fpreg);
-        } else {
-            fpreg = frame.allocReg(mask.freeMask).fpreg();
-            masm.slowLoadConstantDouble(fe->getValue().toDouble(), fpreg);
-        }
-        JS_ASSERT_IF(a->returnSet, fpreg == a->returnRegister.fpreg());
-        a->returnRegister = fpreg;
-    } else {
-        Registers mask(a->returnSet
-                       ? Registers::maskReg(a->returnRegister)
-                       : Registers::AvailRegs);
-        RegisterID reg;
-        if (fe && !fe->isConstant()) {
-            reg = frame.tempRegInMaskForData(fe, mask.freeMask).reg();
-            frame.syncAndForgetFe(fe, true);
-            frame.takeReg(reg);
-        } else {
-            reg = frame.allocReg(mask.freeMask).reg();
-            Value val = fe ? fe->getValue() : UndefinedValue();
-            masm.loadValuePayload(val, reg);
-        }
-        JS_ASSERT_IF(a->returnSet, reg == a->returnRegister.reg());
-        a->returnRegister = reg;
-    }
-
-    a->returnSet = true;
-    if (a->exitState)
-        a->exitState->setUnassigned(a->returnRegister);
-}
-
-void
-mjit::Compiler::emitReturn(FrameEntry *fe)
-{
-    JS_ASSERT_IF(!script_->function(), JSOp(*PC) == JSOP_STOP);
-
-    /* Only the top of the stack can be returned. */
-    JS_ASSERT_IF(fe, fe == frame.peek(-1));
-
-    if (debugMode()) {
-        /* If the return value isn't in the frame's rval slot, move it there. */
-        if (fe) {
-            frame.storeTo(fe, Address(JSFrameReg, StackFrame::offsetOfReturnValue()), true);
-
-            /* Set the frame flag indicating it's there. */
-            RegisterID reg = frame.allocReg();
-            masm.load32(FrameFlagsAddress(), reg);
-            masm.or32(Imm32(StackFrame::HAS_RVAL), reg);
-            masm.store32(reg, FrameFlagsAddress());
-            frame.freeReg(reg);
-
-            /* Use the frame's return value when generating further code. */
-            fe = NULL;
-        }
-
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::ScriptDebugEpilogue, REJOIN_RESUME);
-    }
-
-    if (a != outer) {
-        JS_ASSERT(!debugMode());
-        profilingPopHelper();
-
-        /*
-         * Returning from an inlined script. The checks we do for inlineability
-         * and recompilation triggered by args object construction ensure that
-         * there can't be an arguments or call object.
-         */
-
-        if (a->needReturnValue)
-            emitInlineReturnValue(fe);
-
-        if (a->exitState) {
-            /*
-             * Restore the register state to reflect that at the original call,
-             * modulo entries which will be popped once the call finishes and any
-             * entry which will be clobbered by the return value register.
-             */
-            frame.syncForAllocation(a->exitState, true, Uses(0));
-        }
-
-        /*
-         * Simple tests to see if we are at the end of the script and will
-         * fallthrough after the script body finishes, thus won't need to jump.
-         */
-        bool endOfScript =
-            (JSOp(*PC) == JSOP_STOP) ||
-            (JSOp(*PC) == JSOP_RETURN &&
-             (JSOp(PC[JSOP_RETURN_LENGTH]) == JSOP_STOP &&
-              !analysis->maybeCode(PC + JSOP_RETURN_LENGTH)));
-        if (!endOfScript)
-            a->returnJumps->append(masm.jump());
-
-        if (a->returnSet)
-            frame.freeReg(a->returnRegister);
-        return;
-    }
-
-    /* Inline StackFrame::epilogue. */
-    if (debugMode()) {
-        sps.skipNextReenter();
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::Epilogue, REJOIN_NONE);
-    } else {
-        profilingPopHelper();
-    }
-
-    emitReturnValue(&masm, fe);
-    emitFinalReturn(masm);
-
-    /*
-     * After we've placed the call object, all tracked state can be
-     * thrown away. This will happen anyway because the next live opcode (if
-     * any) must have an incoming edge. It's an optimization to throw it away
-     * early - the tracker won't be spilled on further exits or join points.
-     */
-    frame.discardFrame();
-}
-
-void
-mjit::Compiler::prepareStubCall(Uses uses)
-{
-    JaegerSpew(JSpew_Insns, " ---- STUB CALL, SYNCING FRAME ---- \n");
-    frame.syncAndKill(Registers(Registers::AvailAnyRegs), uses);
-    JaegerSpew(JSpew_Insns, " ---- FRAME SYNCING DONE ---- \n");
-}
-
-JSC::MacroAssembler::Call
-mjit::Compiler::emitStubCall(void *ptr, DataLabelPtr *pinline)
-{
-    JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n");
-
-    masm.bumpStubCount(script_, PC, Registers::tempCallReg());
-
-    Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
-                                  ptr, outerPC(), pinline, frame.totalDepth());
-    JaegerSpew(JSpew_Insns, " ---- END STUB CALL ---- \n");
-    return cl;
-}
-
-void
-mjit::Compiler::interruptCheckHelper()
-{
-    Jump jump;
-    if (cx->runtime->gcZeal() == js::gc::ZealVerifierPreValue ||
-        cx->runtime->gcZeal() == js::gc::ZealVerifierPostValue)
-    {
-        /* For barrier verification, always take the interrupt so we can verify. */
-        jump = masm.jump();
-    } else {
-        void *interrupt = (void*) &cx->runtime->interrupt;
-#if defined(JS_CPU_X86) || defined(JS_CPU_ARM) || defined(JS_CPU_MIPS)
-        jump = masm.branch32(Assembler::NotEqual, AbsoluteAddress(interrupt), Imm32(0));
-#else
-        /* Handle processors that can't load from absolute addresses. */
-        RegisterID reg = frame.allocReg();
-        masm.move(ImmPtr(interrupt), reg);
-        jump = masm.branchTest32(Assembler::NonZero, Address(reg, 0));
-        frame.freeReg(reg);
-#endif
-    }
-
-    stubcc.linkExitDirect(jump, stubcc.masm.label());
-
-    frame.sync(stubcc.masm, Uses(0));
-    stubcc.masm.move(ImmPtr(PC), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::Interrupt, REJOIN_RESUME);
-    stubcc.rejoin(Changes(0));
-}
-
-static inline bool
-MaybeIonCompileable(JSContext *cx, JSScript *script, bool *recompileCheckForIon)
-{
-#ifdef JS_ION
-    *recompileCheckForIon = true;
-
-    if (!ion::IsEnabled(cx))
-        return false;
-    if (!script->canIonCompile())
-        return false;
-
-    // If this script is small, doesn't have any function calls, and doesn't have
-    // any big loops, then throwing in a recompile check and causing an invalidation
-    // when we otherwise wouldn't have would be wasteful.
-    if (script->isShortRunning())
-        *recompileCheckForIon = false;
-
-    return true;
-#endif
-    return false;
-}
-
-void
-mjit::Compiler::ionCompileHelper()
-{
-    JS_ASSERT(script_ == outerScript);
-
-    JS_ASSERT(IsIonEnabled(cx));
-    JS_ASSERT(!inlining());
-
-#ifdef JS_ION
-    if (debugMode() || !globalObj || !cx->typeInferenceEnabled() || outerScript->hasIonScript())
-        return;
-
-    bool recompileCheckForIon = false;
-    if (!MaybeIonCompileable(cx, outerScript, &recompileCheckForIon))
-        return;
-
-    uint32_t minUses = ion::UsesBeforeIonRecompile(outerScript, PC);
-
-    uint32_t *useCountAddress = script_->addressOfUseCount();
-    masm.add32(Imm32(1), AbsoluteAddress(useCountAddress));
-
-    // We cannot inline a JM -> Ion constructing call.
-    // Compiling this function is pointless and would disable the JM -> JM fastpath.
-    // This function will start running in Ion, when caller runs in Ion/Interpreter.
-    if (isConstructing && outerScript->code == PC)
-        return;
-
-    // If we don't want to do a recompileCheck for Ion, then this just needs to
-    // increment the useCount so that we know when to recompile this function
-    // from an Ion call.  No need to call out to recompiler stub.
-    if (!recompileCheckForIon)
-        return;
-
-    const void *ionScriptAddress = script_->addressOfIonScript();
-
-#ifdef JS_CPU_X64
-    // Allocate a temp register. Note that we have to do this before calling
-    // syncExitAndJump below.
-    RegisterID reg = frame.allocReg();
-#endif
-
-    InternalCompileTrigger trigger;
-    trigger.pc = PC;
-    trigger.stubLabel = stubcc.syncExitAndJump(Uses(0));
-
-    // Trigger ion compilation if (a) the script has been used enough times for
-    // this opcode, and (b) the script does not already have ion information
-    // (whether successful, failed, or in progress off thread compilation)
-    // *OR* off thread compilation is not being used.
-    //
-    // If off thread compilation is in use, we retain the CompileTrigger so
-    // that (b) can be short circuited to force a call to TriggerIonCompile
-    // (see DisableScriptAtPC).
-    //
-    // If off thread compilation is not in use, (b) is unnecessary and
-    // negatively affects tuning on some benchmarks (see bug 774253). Thus,
-    // we immediately short circuit the check for (b).
-
-    Label secondTest = stubcc.masm.label();
-
-#if defined(JS_CPU_X86) || defined(JS_CPU_ARM)
-    trigger.inlineJump = masm.branch32(Assembler::GreaterThanOrEqual,
-                                       AbsoluteAddress(useCountAddress),
-                                       Imm32(minUses));
-    Jump scriptJump = stubcc.masm.branch32(Assembler::Equal,
-                                           AbsoluteAddress((void *)ionScriptAddress),
-                                           Imm32(0));
-#elif defined(JS_CPU_X64)
-    /* Handle processors that can't load from absolute addresses. */
-    masm.move(ImmPtr(useCountAddress), reg);
-    trigger.inlineJump = masm.branch32(Assembler::GreaterThanOrEqual,
-                                       Address(reg),
-                                       Imm32(minUses));
-    stubcc.masm.move(ImmPtr((void *)ionScriptAddress), reg);
-    Jump scriptJump = stubcc.masm.branchPtr(Assembler::Equal, Address(reg), ImmPtr(NULL));
-    frame.freeReg(reg);
-#else
-#error "Unknown platform"
-#endif
-
-    stubcc.linkExitDirect(trigger.inlineJump,
-                          OffThreadCompilationEnabled(cx)
-                          ? secondTest
-                          : trigger.stubLabel);
-
-    scriptJump.linkTo(trigger.stubLabel, &stubcc.masm);
-    stubcc.crossJump(stubcc.masm.jump(), masm.label());
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::TriggerIonCompile, REJOIN_RESUME);
-    stubcc.rejoin(Changes(0));
-
-    compileTriggers.append(trigger);
-#endif /* JS_ION */
-}
-
-void
-mjit::Compiler::inliningCompileHelper()
-{
-    JS_ASSERT(!IsIonEnabled(cx));
-
-    if (inlining() || debugMode() || !globalObj ||
-        !analysis->hasFunctionCalls() || !cx->typeInferenceEnabled()) {
-        return;
-    }
-
-    uint32_t *addr = script_->addressOfUseCount();
-    masm.add32(Imm32(1), AbsoluteAddress(addr));
-#if defined(JS_CPU_X86) || defined(JS_CPU_ARM)
-    Jump jump = masm.branch32(Assembler::GreaterThanOrEqual, AbsoluteAddress(addr),
-                              Imm32(USES_BEFORE_INLINING));
-#else
-    /* Handle processors that can't load from absolute addresses. */
-    RegisterID reg = frame.allocReg();
-    masm.move(ImmPtr(addr), reg);
-    Jump jump = masm.branch32(Assembler::GreaterThanOrEqual, Address(reg, 0),
-                              Imm32(USES_BEFORE_INLINING));
-    frame.freeReg(reg);
-#endif
-    stubcc.linkExit(jump, Uses(0));
-    stubcc.leave();
-
-    OOL_STUBCALL(stubs::RecompileForInline, REJOIN_RESUME);
-    stubcc.rejoin(Changes(0));
-}
-
-CompileStatus
-mjit::Compiler::methodEntryHelper()
-{
-    if (debugMode()) {
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::ScriptDebugPrologue, REJOIN_RESUME);
-
-    /*
-     * If necessary, call the tracking probe to trigger SPS assertions. We can
-     * only do this when not inlining because the same StackFrame instance will
-     * be used to enter a function, triggering an assertion in enterScript
-     */
-    } else if (Probes::callTrackingActive(cx) ||
-               (sps.slowAssertions() && a->inlineIndex == UINT32_MAX)) {
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::ScriptProbeOnlyPrologue, REJOIN_RESUME);
-    } else {
-        return profilingPushHelper();
-    }
-    /* Ensure that we've flagged that the push has happened */
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.pushManual(script_, masm, reg);
-        frame.freeReg(reg);
-    }
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::profilingPushHelper()
-{
-    if (!sps.enabled())
-        return Compile_Okay;
-    RegisterID reg = frame.allocReg();
-    if (!sps.push(cx, script_, masm, reg))
-        return Compile_Error;
-
-    /* Set the flags that we've pushed information onto the SPS stack */
-    masm.load32(FrameFlagsAddress(), reg);
-    masm.or32(Imm32(StackFrame::HAS_PUSHED_SPS_FRAME), reg);
-    masm.store32(reg, FrameFlagsAddress());
-    frame.freeReg(reg);
-
-    return Compile_Okay;
-}
-
-void
-mjit::Compiler::profilingPopHelper()
-{
-    if (Probes::callTrackingActive(cx) || sps.slowAssertions()) {
-        sps.skipNextReenter();
-        prepareStubCall(Uses(0));
-        INLINE_STUBCALL(stubs::ScriptProbeOnlyEpilogue, REJOIN_RESUME);
-    } else if (cx->runtime->spsProfiler.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.pop(masm, reg);
-        frame.freeReg(reg);
-    }
-}
-
-void
-mjit::Compiler::addReturnSite()
-{
-    InternalCallSite site(masm.distanceOf(masm.label()), a->inlineIndex, PC,
-                          REJOIN_SCRIPTED, false);
-    addCallSite(site);
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfPrev()), JSFrameReg);
-}
-
-void
-mjit::Compiler::emitUncachedCall(uint32_t argc, bool callingNew)
-{
-    CallPatchInfo callPatch;
-
-    RegisterID r0 = Registers::ReturnReg;
-    VoidPtrStubUInt32 stub = callingNew ? stubs::UncachedNew : stubs::UncachedCall;
-
-    frame.syncAndKill(Uses(argc + 2));
-    prepareStubCall(Uses(argc + 2));
-    masm.move(Imm32(argc), Registers::ArgReg1);
-    INLINE_STUBCALL(stub, REJOIN_CALL_PROLOGUE);
-
-    Jump notCompiled = masm.branchTestPtr(Assembler::Zero, r0, r0);
-
-    masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), JSFrameReg);
-    callPatch.hasFastNcode = true;
-    callPatch.fastNcodePatch =
-        masm.storePtrWithPatch(ImmPtr(NULL),
-                               Address(JSFrameReg, StackFrame::offsetOfNcode()));
-
-    masm.jump(r0);
-    callPatch.joinPoint = masm.label();
-    addReturnSite();
-
-    frame.popn(argc + 2);
-
-    frame.takeReg(JSReturnReg_Type);
-    frame.takeReg(JSReturnReg_Data);
-    frame.pushRegs(JSReturnReg_Type, JSReturnReg_Data, knownPushedType(0));
-
-    BarrierState barrier = testBarrier(JSReturnReg_Type, JSReturnReg_Data,
-                                       /* testUndefined = */ false,
-                                       /* testReturn = */ true);
-
-    stubcc.linkExitDirect(notCompiled, stubcc.masm.label());
-    stubcc.rejoin(Changes(1));
-    callPatches.append(callPatch);
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.reenter(masm, reg);
-        frame.freeReg(reg);
-    }
-}
-
-void
-mjit::Compiler::checkCallApplySpeculation(uint32_t argc, FrameEntry *origCallee, FrameEntry *origThis,
-                                          MaybeRegisterID origCalleeType, RegisterID origCalleeData,
-                                          MaybeRegisterID origThisType, RegisterID origThisData,
-                                          Jump *uncachedCallSlowRejoin, CallPatchInfo *uncachedCallPatch)
-{
-    JS_ASSERT(IsLowerableFunCallOrApply(PC));
-
-    RegisterID temp;
-    Registers tempRegs(Registers::AvailRegs);
-    if (origCalleeType.isSet())
-        tempRegs.takeReg(origCalleeType.reg());
-    tempRegs.takeReg(origCalleeData);
-    if (origThisType.isSet())
-        tempRegs.takeReg(origThisType.reg());
-    tempRegs.takeReg(origThisData);
-    temp = tempRegs.takeAnyReg().reg();
-
-    /*
-     * if (origCallee.isObject() &&
-     *     origCallee.toObject().isFunction &&
-     *     origCallee.toObject().toFunction() == js_fun_{call,apply})
-     */
-    MaybeJump isObj;
-    if (origCalleeType.isSet())
-        isObj = masm.testObject(Assembler::NotEqual, origCalleeType.reg());
-    Jump isFun = masm.testFunction(Assembler::NotEqual, origCalleeData, temp);
-    Native native = *PC == JSOP_FUNCALL ? js_fun_call : js_fun_apply;
-    Jump isNative = masm.branchPtr(Assembler::NotEqual,
-                                   Address(origCalleeData, JSFunction::offsetOfNativeOrScript()),
-                                   ImmPtr(JS_FUNC_TO_DATA_PTR(void *, native)));
-
-    /*
-     * If speculation fails, we can't use the ic, since it is compiled on the
-     * assumption that speculation succeeds. Instead, just do an uncached call.
-     */
-    {
-        if (isObj.isSet())
-            stubcc.linkExitDirect(isObj.getJump(), stubcc.masm.label());
-        stubcc.linkExitDirect(isFun, stubcc.masm.label());
-        stubcc.linkExitDirect(isNative, stubcc.masm.label());
-
-        stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
-        JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
-        OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-        JaegerSpew(JSpew_Insns, " ---- END SLOW CALL CODE ---- \n");
-
-        /*
-         * inlineCallHelper will link uncachedCallSlowRejoin to the join point
-         * at the end of the ic. At that join point, we'll load the rval into
-         * the return registers.
-         */
-        *uncachedCallSlowRejoin = stubcc.masm.jump();
-    }
-}
-
-/* See MonoIC.cpp, CallCompiler for more information on call ICs. */
-bool
-mjit::Compiler::inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &callFrameSize)
-{
-    /*
-     * Check for interrupts on function call. We don't do this for lazy
-     * arguments objects as the interrupt may kick this frame into the
-     * interpreter, which doesn't know about the apply tricks. Instead, we
-     * do the interrupt check at the start of the JSOP_ARGUMENTS.
-     */
-    interruptCheckHelper();
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.leave(PC, masm, reg);
-        frame.freeReg(reg);
-    }
-
-    FrameEntry *origCallee = frame.peek(-(int(argc) + 2));
-    FrameEntry *origThis = frame.peek(-(int(argc) + 1));
-
-    /*
-     * 'this' does not need to be synced for constructing. :FIXME: is it
-     * possible that one of the arguments is directly copying the 'this'
-     * entry (something like 'new x.f(x)')?
-     */
-    if (callingNew) {
-        frame.discardFe(origThis);
-
-        /*
-         * We store NULL here to ensure that the slot doesn't contain
-         * garbage. Additionally, we need to store a non-object value here for
-         * TI. If a GC gets triggered before the callee can fill in the slot
-         * (i.e. the GC happens on constructing the 'new' object or the call
-         * object for a heavyweight callee), it needs to be able to read the
-         * 'this' value to tell whether newScript constraints will need to be
-         * regenerated afterwards.
-         */
-        masm.storeValue(NullValue(), frame.addressOf(origThis));
-    }
-
-    /*
-     * From the presence of JSOP_FUN{CALL,APPLY}, we speculate that we are
-     * going to call js_fun_{call,apply}. Normally, this call would go through
-     * js::Invoke to ultimately call 'this'. We can do much better by having
-     * the callIC cache and call 'this' directly. However, if it turns out that
-     * we are not actually calling js_fun_call, the callIC must act as normal.
-     *
-     * Note: do *NOT* use type information or inline state in any way when
-     * deciding whether to lower a CALL or APPLY. The stub calls here store
-     * their return values in a different slot, so when recompiling we need
-     * to go down the exact same path.
-     */
-    bool lowerFunCallOrApply = IsLowerableFunCallOrApply(PC);
-
-    RootedScript script(cx, script_);
-    bool newType = callingNew && cx->typeInferenceEnabled() && types::UseNewType(cx, script, PC);
-
-#ifdef JS_MONOIC
-    if (debugMode() || newType) {
-#endif
-        emitUncachedCall(argc, callingNew);
-        return true;
-#ifdef JS_MONOIC
-    }
-
-    frame.forgetMismatchedObject(origCallee);
-    if (lowerFunCallOrApply)
-        frame.forgetMismatchedObject(origThis);
-
-    /* Initialized by both branches below. */
-    CallGenInfo     callIC;
-    CallPatchInfo   callPatch;
-    MaybeRegisterID icCalleeType; /* type to test for function-ness */
-    RegisterID      icCalleeData; /* data to call */
-    Address         icRvalAddr;   /* return slot on slow-path rejoin */
-
-    /*
-     * IC space must be reserved (using RESERVE_IC_SPACE or RESERVE_OOL_SPACE) between the
-     * following labels (as used in finishThisUp):
-     *  - funGuard -> hotJump
-     *  - funGuard -> joinPoint
-     *  - funGuard -> hotPathLabel
-     *  - slowPathStart -> oolCall
-     *  - slowPathStart -> oolJump
-     *  - slowPathStart -> icCall
-     *  - slowPathStart -> slowJoinPoint
-     * Because the call ICs are fairly long (compared to PICs), we don't reserve the space in each
-     * path until the first usage of funGuard (for the in-line path) or slowPathStart (for the
-     * out-of-line path).
-     */
-
-    /* Initialized only on lowerFunCallOrApply branch. */
-    Jump            uncachedCallSlowRejoin;
-    CallPatchInfo   uncachedCallPatch;
-
-    {
-        MaybeRegisterID origCalleeType, maybeOrigCalleeData;
-        RegisterID origCalleeData;
-
-        /* Get the callee in registers. */
-        frame.ensureFullRegs(origCallee, &origCalleeType, &maybeOrigCalleeData);
-        origCalleeData = maybeOrigCalleeData.reg();
-        PinRegAcrossSyncAndKill p1(frame, origCalleeData), p2(frame, origCalleeType);
-
-        if (lowerFunCallOrApply) {
-            MaybeRegisterID origThisType, maybeOrigThisData;
-            RegisterID origThisData;
-            {
-                /* Get thisv in registers. */
-                frame.ensureFullRegs(origThis, &origThisType, &maybeOrigThisData);
-                origThisData = maybeOrigThisData.reg();
-                PinRegAcrossSyncAndKill p3(frame, origThisData), p4(frame, origThisType);
-
-                /* Leaves pinned regs untouched. */
-                frame.syncAndKill(Uses(argc + 2));
-            }
-
-            checkCallApplySpeculation(argc, origCallee, origThis,
-                                      origCalleeType, origCalleeData,
-                                      origThisType, origThisData,
-                                      &uncachedCallSlowRejoin, &uncachedCallPatch);
-
-            icCalleeType = origThisType;
-            icCalleeData = origThisData;
-            icRvalAddr = frame.addressOf(origThis);
-
-            /*
-             * For f.call(), since we compile the ic under the (checked)
-             * assumption that call == js_fun_call, we still have a static
-             * frame size. For f.apply(), the frame size depends on the dynamic
-             * length of the array passed to apply.
-             */
-            if (*PC == JSOP_FUNCALL)
-                callIC.frameSize.initStatic(frame.totalDepth(), argc - 1);
-            else
-                callIC.frameSize.initDynamic();
-        } else {
-            /* Leaves pinned regs untouched. */
-            frame.syncAndKill(Uses(argc + 2));
-
-            icCalleeType = origCalleeType;
-            icCalleeData = origCalleeData;
-            icRvalAddr = frame.addressOf(origCallee);
-            callIC.frameSize.initStatic(frame.totalDepth(), argc);
-        }
-    }
-
-    callFrameSize = callIC.frameSize;
-
-    callIC.typeMonitored = monitored(PC) || hasTypeBarriers(PC);
-
-    if (script_ == outerScript) {
-        if (monitored(PC))
-            monitoredBytecodes.append(PC - script_->code);
-        if (hasTypeBarriers(PC))
-            typeBarrierBytecodes.append(PC - script_->code);
-    }
-
-    /* Test the type if necessary. Failing this always takes a really slow path. */
-    MaybeJump notObjectJump;
-    if (icCalleeType.isSet())
-        notObjectJump = masm.testObject(Assembler::NotEqual, icCalleeType.reg());
-
-    Registers tempRegs(Registers::AvailRegs);
-    tempRegs.takeReg(icCalleeData);
-
-    /* Reserve space just before initialization of funGuard. */
-    RESERVE_IC_SPACE(masm);
-
-    /*
-     * Guard on the callee identity. This misses on the first run. If the
-     * callee is scripted, compiled/compilable, and argc == nargs, then this
-     * guard is patched, and the compiled code address is baked in.
-     */
-    callIC.funGuardLabel = masm.label();
-    Jump j = masm.branchPtrWithPatch(Assembler::NotEqual, icCalleeData, callIC.funGuard);
-    callIC.funJump = j;
-
-    /* Reserve space just before initialization of slowPathStart. */
-    RESERVE_OOL_SPACE(stubcc.masm);
-
-    Jump rejoin1, rejoin2;
-    {
-        RESERVE_OOL_SPACE(stubcc.masm);
-        stubcc.linkExitDirect(j, stubcc.masm.label());
-        callIC.slowPathStart = stubcc.masm.label();
-
-        RegisterID tmp = tempRegs.takeAnyReg().reg();
-
-        /*
-         * Test if the callee is even a function. If this doesn't match, we
-         * take a _really_ slow path later.
-         */
-        Jump notFunction = stubcc.masm.testFunction(Assembler::NotEqual, icCalleeData, tmp);
-
-        /* Test if the function is scripted. */
-        stubcc.masm.load16(Address(icCalleeData, offsetof(JSFunction, flags)), tmp);
-        Jump isNative = stubcc.masm.branchTest32(Assembler::Zero, tmp,
-                                                 Imm32(JSFunction::INTERPRETED));
-        tempRegs.putReg(tmp);
-
-        /*
-         * N.B. After this call, the frame will have a dynamic frame size.
-         * Check after the function is known not to be a native so that the
-         * catch-all/native path has a static depth.
-         */
-        if (callIC.frameSize.isDynamic()) {
-            OOL_STUBCALL(ic::SplatApplyArgs, REJOIN_CALL_SPLAT);
-
-            /*
-             * Restore identity of callee after SplatApplyArgs, which may
-             * have been clobbered (not callee save reg or changed by moving GC).
-             */
-            stubcc.masm.loadPayload(frame.addressOf(origThis), icCalleeData);
-        }
-
-        /*
-         * No-op jump that gets patched by ic::New/Call to the stub generated
-         * by generateFullCallStub.
-         */
-        Jump toPatch = stubcc.masm.jump();
-        toPatch.linkTo(stubcc.masm.label(), &stubcc.masm);
-        callIC.oolJump = toPatch;
-        callIC.icCall = stubcc.masm.label();
-
-        RejoinState rejoinState = callIC.frameSize.rejoinState(PC, false);
-
-        /*
-         * At this point the function is definitely scripted, so we try to
-         * compile it and patch either funGuard/funJump or oolJump. This code
-         * is only executed once.
-         */
-        callIC.addrLabel1 = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
-        void *icFunPtr = JS_FUNC_TO_DATA_PTR(void *, callingNew ? ic::New : ic::Call);
-        if (callIC.frameSize.isStatic()) {
-            callIC.oolCall = OOL_STUBCALL_LOCAL_SLOTS(icFunPtr, rejoinState, frame.totalDepth());
-        } else {
-            callIC.oolCall = OOL_STUBCALL_LOCAL_SLOTS(icFunPtr, rejoinState, -1);
-        }
-
-        callIC.funObjReg = icCalleeData;
-
-        /*
-         * The IC call either returns NULL, meaning call completed, or a
-         * function pointer to jump to.
-         */
-        rejoin1 = stubcc.masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
-                                            Registers::ReturnReg);
-        if (callIC.frameSize.isStatic())
-            stubcc.masm.move(Imm32(callIC.frameSize.staticArgc()), JSParamReg_Argc);
-        else
-            stubcc.masm.load32(FrameAddress(VMFrame::offsetOfDynamicArgc()), JSParamReg_Argc);
-        stubcc.masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), JSFrameReg);
-        callPatch.hasSlowNcode = true;
-        callPatch.slowNcodePatch =
-            stubcc.masm.storePtrWithPatch(ImmPtr(NULL),
-                                          Address(JSFrameReg, StackFrame::offsetOfNcode()));
-        stubcc.masm.jump(Registers::ReturnReg);
-
-
-
-        /*
-         * This ool path is the catch-all for everything but scripted function
-         * callees. For native functions, ic::NativeNew/NativeCall will repatch
-         * funGaurd/funJump with a fast call stub. All other cases
-         * (non-function callable objects and invalid callees) take the slow
-         * path through js::Invoke.
-         */
-        if (notObjectJump.isSet())
-            stubcc.linkExitDirect(notObjectJump.get(), stubcc.masm.label());
-        notFunction.linkTo(stubcc.masm.label(), &stubcc.masm);
-        isNative.linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        callIC.addrLabel2 = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
-        OOL_STUBCALL(callingNew ? ic::NativeNew : ic::NativeCall, rejoinState);
-
-        rejoin2 = stubcc.masm.jump();
-    }
-
-    /*
-     * If the call site goes to a closure over the same function, it will
-     * generate an out-of-line stub that joins back here.
-     */
-    callIC.hotPathLabel = masm.label();
-
-    uint32_t flags = 0;
-    if (callingNew)
-        flags |= StackFrame::CONSTRUCTING;
-
-    InlineFrameAssembler inlFrame(masm, callIC, flags);
-    callPatch.hasFastNcode = true;
-    callPatch.fastNcodePatch = inlFrame.assemble(NULL, PC);
-
-    callIC.hotJump = masm.jump();
-    callIC.joinPoint = callPatch.joinPoint = masm.label();
-    callIC.callIndex = callSites.length();
-    addReturnSite();
-    callIC.ionJoinPoint = masm.label();
-    if (lowerFunCallOrApply)
-        uncachedCallPatch.joinPoint = callIC.joinPoint;
-
-    /*
-     * We've placed hotJump, joinPoint and hotPathLabel, and no other labels are located by offset
-     * in the in-line path so we can check the IC space now.
-     */
-    CHECK_IC_SPACE();
-
-    JSValueType type = knownPushedType(0);
-
-    frame.popn(argc + 2);
-    frame.takeReg(JSReturnReg_Type);
-    frame.takeReg(JSReturnReg_Data);
-    frame.pushRegs(JSReturnReg_Type, JSReturnReg_Data, type);
-
-    BarrierState barrier = testBarrier(JSReturnReg_Type, JSReturnReg_Data,
-                                       /* testUndefined = */ false,
-                                       /* testReturn = */ true);
-
-    /*
-     * Now that the frame state is set, generate the rejoin path. Note that, if
-     * lowerFunCallOrApply, we cannot just call 'stubcc.rejoin' since the return
-     * value has been placed at vp[1] which is not the stack address associated
-     * with frame.peek(-1).
-     */
-    callIC.slowJoinPoint = stubcc.masm.label();
-    rejoin1.linkTo(callIC.slowJoinPoint, &stubcc.masm);
-    rejoin2.linkTo(callIC.slowJoinPoint, &stubcc.masm);
-    JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW RESTORE CODE ---- \n");
-    frame.reloadEntry(stubcc.masm, icRvalAddr, frame.peek(-1));
-    stubcc.crossJump(stubcc.masm.jump(), masm.label());
-    JaegerSpew(JSpew_Insns, " ---- END SLOW RESTORE CODE ---- \n");
-
-    CHECK_OOL_SPACE();
-
-    if (lowerFunCallOrApply) {
-        uncachedCallSlowRejoin.linkTo(stubcc.masm.label(), &stubcc.masm);
-        JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW RESTORE CODE ---- \n");
-        Address uncachedRvalAddr = frame.addressOf(origCallee);
-        if (knownPushedType(0) == JSVAL_TYPE_DOUBLE)
-            stubcc.masm.ensureInMemoryDouble(uncachedRvalAddr);
-        frame.reloadEntry(stubcc.masm, uncachedRvalAddr, frame.peek(-1));
-        stubcc.crossJump(stubcc.masm.jump(), masm.label());
-        JaegerSpew(JSpew_Insns, " ---- END SLOW RESTORE CODE ---- \n");
-    }
-
-    callICs.append(callIC);
-    callPatches.append(callPatch);
-    if (lowerFunCallOrApply)
-        callPatches.append(uncachedCallPatch);
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.reenter(masm, reg);
-        frame.freeReg(reg);
-    }
-    return true;
-#endif
-}
-
-/* Maximum number of calls we will inline at the same site. */
-static const uint32_t INLINE_SITE_LIMIT = 5;
-
-CompileStatus
-mjit::Compiler::inlineScriptedFunction(uint32_t argc, bool callingNew)
-{
-    JS_ASSERT(inlining());
-
-    /* We already know which frames we are inlining at each PC, so scan the list of inline frames. */
-    bool calleeMultipleReturns = false;
-    Vector<JSScript *> inlineCallees(CompilerAllocPolicy(cx, *this));
-    for (unsigned i = 0; i < ssa.numFrames(); i++) {
-        if (ssa.iterFrame(i).parent == a->inlineIndex && ssa.iterFrame(i).parentpc == PC) {
-            JSScript *script_ = ssa.iterFrame(i).script;
-
-            /* Don't inline if any of the callees should be cloned at callsite. */
-            if (script_->shouldCloneAtCallsite)
-                return Compile_InlineAbort;
-
-            inlineCallees.append(script_);
-            if (script_->analysis()->numReturnSites() > 1)
-                calleeMultipleReturns = true;
-        }
-    }
-
-    if (inlineCallees.empty())
-        return Compile_InlineAbort;
-
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.leave(PC, masm, reg);
-        frame.freeReg(reg);
-    }
-
-    JS_ASSERT(!monitored(PC));
-
-    /*
-     * Remove all dead entries from the frame's tracker. We will not recognize
-     * them as dead after pushing the new frame.
-     */
-    frame.pruneDeadEntries();
-
-    RegisterAllocation *exitState = NULL;
-    if (inlineCallees.length() > 1 || calleeMultipleReturns) {
-        /*
-         * Multiple paths through the callees, get a register allocation for
-         * the various incoming edges.
-         */
-        exitState = frame.computeAllocation(PC + JSOP_CALL_LENGTH);
-    }
-
-    /*
-     * If this is a polymorphic callsite, get a register for the callee too.
-     * After this, do not touch the register state in the current frame until
-     * stubs for all callees have been generated.
-     */
-    FrameEntry *origCallee = frame.peek(-((int)argc + 2));
-    FrameEntry *entrySnapshot = NULL;
-    MaybeRegisterID calleeReg;
-    if (inlineCallees.length() > 1) {
-        frame.forgetMismatchedObject(origCallee);
-        calleeReg = frame.tempRegForData(origCallee);
-
-        entrySnapshot = frame.snapshotState();
-        if (!entrySnapshot)
-            return Compile_Error;
-    }
-    MaybeJump calleePrevious;
-
-    JSValueType returnType = knownPushedType(0);
-
-    bool needReturnValue = JSOP_POP != (JSOp)*(PC + JSOP_CALL_LENGTH);
-    bool syncReturnValue = needReturnValue && returnType == JSVAL_TYPE_UNKNOWN;
-
-    /* Track register state after the call. */
-    bool returnSet = false;
-    AnyRegisterID returnRegister;
-    const FrameEntry *returnEntry = NULL;
-
-    Vector<Jump, 4, CompilerAllocPolicy> returnJumps(CompilerAllocPolicy(cx, *this));
-
-    for (unsigned i = 0; i < inlineCallees.length(); i++) {
-        if (entrySnapshot)
-            frame.restoreFromSnapshot(entrySnapshot);
-
-        JSScript *script = inlineCallees[i];
-        CompileStatus status;
-
-        status = pushActiveFrame(script, argc);
-        if (status != Compile_Okay)
-            return status;
-
-        a->exitState = exitState;
-
-        JaegerSpew(JSpew_Inlining, "inlining call to script (file \"%s\") (line \"%d\")\n",
-                   script->filename(), script->lineno);
-
-        if (calleePrevious.isSet()) {
-            calleePrevious.get().linkTo(masm.label(), &masm);
-            calleePrevious = MaybeJump();
-        }
-
-        if (i + 1 != inlineCallees.length()) {
-            /* Guard on the callee, except when this object must be the callee. */
-            JS_ASSERT(calleeReg.isSet());
-            calleePrevious = masm.branchPtr(Assembler::NotEqual, calleeReg.reg(), ImmPtr(script->function()));
-        }
-
-        a->returnJumps = &returnJumps;
-        a->needReturnValue = needReturnValue;
-        a->syncReturnValue = syncReturnValue;
-        a->returnValueDouble = returnType == JSVAL_TYPE_DOUBLE;
-        if (returnSet) {
-            a->returnSet = true;
-            a->returnRegister = returnRegister;
-        }
-
-        /*
-         * Update the argument frame entries in place if the callee has had an
-         * argument inferred as double but we are passing an int.
-         */
-        ensureDoubleArguments();
-
-        markUndefinedLocals();
-
-        status = methodEntryHelper();
-        if (status == Compile_Okay)
-            status = generateMethod();
-
-        if (status != Compile_Okay) {
-            popActiveFrame();
-            if (status == Compile_Abort) {
-                /* The callee is uncompileable, mark it as uninlineable and retry. */
-                script->uninlineable = true;
-                types::MarkTypeObjectFlags(cx, script->function(),
-                                           types::OBJECT_FLAG_UNINLINEABLE);
-                return Compile_Retry;
-            }
-            return status;
-        }
-
-        if (needReturnValue && !returnSet) {
-            if (a->returnSet) {
-                returnSet = true;
-                returnRegister = a->returnRegister;
-            } else {
-                returnEntry = a->returnEntry;
-            }
-        }
-
-        popActiveFrame();
-
-        if (i + 1 != inlineCallees.length())
-            returnJumps.append(masm.jump());
-    }
-
-    for (unsigned i = 0; i < returnJumps.length(); i++)
-        returnJumps[i].linkTo(masm.label(), &masm);
-
-    frame.popn(argc + 2);
-
-    if (entrySnapshot)
-        js_free(entrySnapshot);
-
-    if (exitState)
-        frame.discardForJoin(exitState, analysis->getCode(PC).stackDepth - (argc + 2));
-
-    if (returnSet) {
-        frame.takeReg(returnRegister);
-        if (returnRegister.isReg())
-            frame.pushTypedPayload(returnType, returnRegister.reg());
-        else
-            frame.pushDouble(returnRegister.fpreg());
-    } else if (returnEntry) {
-        frame.pushCopyOf((FrameEntry *) returnEntry);
-    } else {
-        frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-    }
-
-    JaegerSpew(JSpew_Inlining, "finished inlining call to script (file \"%s\") (line \"%d\")\n",
-               script_->filename(), script_->lineno);
-
-    if (sps.enabled()) {
-        RegisterID reg = frame.allocReg();
-        sps.reenter(masm, reg);
-        frame.freeReg(reg);
-    }
-
-    return Compile_Okay;
-}
-
-/*
- * This function must be called immediately after any instruction which could
- * cause a new StackFrame to be pushed and could lead to a new debug trap
- * being set. This includes any API callbacks and any scripted or native call.
- */
-void
-mjit::Compiler::addCallSite(const InternalCallSite &site)
-{
-    callSites.append(site);
-}
-
-void
-mjit::Compiler::inlineStubCall(void *stub, RejoinState rejoin, Uses uses)
-{
-    DataLabelPtr inlinePatch;
-    Call cl = emitStubCall(stub, &inlinePatch);
-    InternalCallSite site(masm.callReturnOffset(cl), a->inlineIndex, PC,
-                          rejoin, false);
-    site.inlinePatch = inlinePatch;
-    if (loop && loop->generatingInvariants()) {
-        Jump j = masm.jump();
-        Label l = masm.label();
-        loop->addInvariantCall(j, l, false, false, callSites.length(), uses);
-    }
-    addCallSite(site);
-}
-
-bool
-mjit::Compiler::compareTwoValues(JSContext *cx, JSOp op, const Value &lhs, const Value &rhs)
-{
-    JS_ASSERT(lhs.isPrimitive());
-    JS_ASSERT(rhs.isPrimitive());
-
-    if (lhs.isString() && rhs.isString()) {
-        int32_t cmp;
-        CompareStrings(cx, lhs.toString(), rhs.toString(), &cmp);
-        switch (op) {
-          case JSOP_LT:
-            return cmp < 0;
-          case JSOP_LE:
-            return cmp <= 0;
-          case JSOP_GT:
-            return cmp > 0;
-          case JSOP_GE:
-            return cmp >= 0;
-          case JSOP_EQ:
-            return cmp == 0;
-          case JSOP_NE:
-            return cmp != 0;
-          default:
-            JS_NOT_REACHED("NYI");
-        }
-    } else {
-        double ld, rd;
-
-        /* These should be infallible w/ primitives. */
-        JS_ALWAYS_TRUE(ToNumber(cx, lhs, &ld));
-        JS_ALWAYS_TRUE(ToNumber(cx, rhs, &rd));
-        switch(op) {
-          case JSOP_LT:
-            return ld < rd;
-          case JSOP_LE:
-            return ld <= rd;
-          case JSOP_GT:
-            return ld > rd;
-          case JSOP_GE:
-            return ld >= rd;
-          case JSOP_EQ: /* fall through */
-          case JSOP_NE:
-            /* Special case null/undefined/void comparisons. */
-            if (lhs.isNullOrUndefined()) {
-                if (rhs.isNullOrUndefined())
-                    return op == JSOP_EQ;
-                return op == JSOP_NE;
-            }
-            if (rhs.isNullOrUndefined())
-                return op == JSOP_NE;
-
-            /* Normal return. */
-            return (op == JSOP_EQ) ? (ld == rd) : (ld != rd);
-          default:
-            JS_NOT_REACHED("NYI");
-        }
-    }
-
-    JS_NOT_REACHED("NYI");
-    return false;
-}
-
-bool
-mjit::Compiler::constantFoldBranch(jsbytecode *target, bool taken)
-{
-    if (taken) {
-        if (!frame.syncForBranch(target, Uses(0)))
-            return false;
-        Jump j = masm.jump();
-        if (!jumpAndRun(j, target))
-            return false;
-    } else {
-        /*
-         * Branch is never taken, but clean up any loop
-         * if this is a backedge.
-         */
-        if (target < PC && !finishLoop(target))
-            return false;
-    }
-    return true;
-}
-
-bool
-mjit::Compiler::emitStubCmpOp(BoolStub stub, jsbytecode *target, JSOp fused)
-{
-    if (target)
-        frame.syncAndKillEverything();
-    else
-        frame.syncAndKill(Uses(2));
-
-    prepareStubCall(Uses(2));
-    INLINE_STUBCALL(stub, target ? REJOIN_BRANCH : REJOIN_PUSH_BOOLEAN);
-    frame.popn(2);
-
-    if (!target) {
-        frame.takeReg(Registers::ReturnReg);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
-        return true;
-    }
-
-    JS_ASSERT(fused == JSOP_IFEQ || fused == JSOP_IFNE);
-    Jump j = masm.branchTest32(GetStubCompareCondition(fused), Registers::ReturnReg,
-                               Registers::ReturnReg);
-    return jumpAndRun(j, target);
-}
-
-void
-mjit::Compiler::jsop_setprop_slow(HandlePropertyName name)
-{
-    JS_ASSERT(*PC == JSOP_SETPROP || *PC == JSOP_SETNAME);
-
-    prepareStubCall(Uses(2));
-    masm.move(ImmPtr(name), Registers::ArgReg1);
-
-    if (*PC == JSOP_SETPROP)
-        INLINE_STUBCALL(stubs::SetProp, REJOIN_FALLTHROUGH);
-    else
-        INLINE_STUBCALL(stubs::SetName, REJOIN_FALLTHROUGH);
-
-    JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
-    frame.shimmy(1);
-    if (script_->hasScriptCounts)
-        bumpPropCount(PC, PCCounts::PROP_OTHER);
-}
-
-void
-mjit::Compiler::jsop_getprop_slow(HandlePropertyName name, bool forPrototype)
-{
-    /* See ::jsop_getprop */
-    RejoinState rejoin = forPrototype ? REJOIN_THIS_PROTOTYPE : REJOIN_GETTER;
-
-    prepareStubCall(Uses(1));
-    masm.move(ImmPtr(name), Registers::ArgReg1);
-    INLINE_STUBCALL(forPrototype ? stubs::GetPropNoCache : stubs::GetProp, rejoin);
-
-    if (!forPrototype)
-        testPushedType(rejoin, -1, /* ool = */ false);
-
-    frame.pop();
-    frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-
-    if (script_->hasScriptCounts)
-        bumpPropCount(PC, PCCounts::PROP_OTHER);
-}
-
-#ifdef JS_MONOIC
-void
-mjit::Compiler::passMICAddress(GlobalNameICInfo &ic)
-{
-    ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
-}
-#endif
-
-#if defined JS_POLYIC
-void
-mjit::Compiler::passICAddress(BaseICInfo *ic)
-{
-    ic->paramAddr = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
-}
-
-bool
-mjit::Compiler::jsop_getprop(HandlePropertyName name, JSValueType knownType,
-                             bool doTypeCheck, bool forPrototype)
-{
-    FrameEntry *top = frame.peek(-1);
-
-    /*
-     * Use a different rejoin for GETPROP computing the 'this' object, as we
-     * can't use the current bytecode within InternalInterpret to tell this is
-     * fetching the 'this' value.
-     */
-    RejoinState rejoin = REJOIN_GETTER;
-    if (forPrototype) {
-        JS_ASSERT(top->isType(JSVAL_TYPE_OBJECT) && name == cx->names().classPrototype);
-        rejoin = REJOIN_THIS_PROTOTYPE;
-    }
-
-    /* Handle length accesses on known strings without using a PIC. */
-    if (name == cx->names().length &&
-        top->isType(JSVAL_TYPE_STRING) &&
-        (!cx->typeInferenceEnabled() || knownPushedType(0) == JSVAL_TYPE_INT32)) {
-        if (top->isConstant()) {
-            JSString *str = top->getValue().toString();
-            Value v;
-            v.setNumber(uint32_t(str->length()));
-            frame.pop();
-            frame.push(v);
-        } else {
-            RegisterID str = frame.ownRegForData(top);
-            masm.loadPtr(Address(str, JSString::offsetOfLengthAndFlags()), str);
-            masm.urshift32(Imm32(JSString::LENGTH_SHIFT), str);
-            frame.pop();
-            frame.pushTypedPayload(JSVAL_TYPE_INT32, str);
-        }
-        return true;
-    }
-
-    /* Handle lenth accesses of optimize 'arguments'. */
-    if (name == cx->names().length &&
-        cx->typeInferenceEnabled() &&
-        analysis->poppedTypes(PC, 0)->isMagicArguments() &&
-        knownPushedType(0) == JSVAL_TYPE_INT32)
-    {
-        frame.pop();
-        RegisterID reg = frame.allocReg();
-        masm.load32(Address(JSFrameReg, StackFrame::offsetOfNumActual()), reg);
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-        if (script_->hasScriptCounts)
-            bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-        return true;
-    }
-
-    if (top->mightBeType(JSVAL_TYPE_OBJECT) &&
-        JSOp(*PC) == JSOP_LENGTH && cx->typeInferenceEnabled() &&
-        !hasTypeBarriers(PC) && knownPushedType(0) == JSVAL_TYPE_INT32) {
-        /* Check if this is an array we can make a loop invariant entry for. */
-        if (loop && loop->generatingInvariants()) {
-            CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
-            FrameEntry *fe = loop->invariantLength(topv);
-            if (fe) {
-                frame.learnType(fe, JSVAL_TYPE_INT32, false);
-                frame.pop();
-                frame.pushCopyOf(fe);
-                if (script_->hasScriptCounts)
-                    bumpPropCount(PC, PCCounts::PROP_STATIC);
-                return true;
-            }
-        }
-
-        types::StackTypeSet *types = analysis->poppedTypes(PC, 0);
-
-        /*
-         * Check if we are accessing the 'length' property of an array whose
-         * length is known to fit in an int32_t.
-         */
-        if (types->getKnownClass() == &ArrayClass &&
-            !types->hasObjectFlags(cx, types::OBJECT_FLAG_LENGTH_OVERFLOW))
-        {
-            frame.forgetMismatchedObject(top);
-            bool isObject = top->isTypeKnown();
-            if (!isObject) {
-                Jump notObject = frame.testObject(Assembler::NotEqual, top);
-                stubcc.linkExit(notObject, Uses(1));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::GetProp, rejoin);
-                if (rejoin == REJOIN_GETTER)
-                    testPushedType(rejoin, -1);
-            }
-            RegisterID result = frame.allocReg();
-            RegisterID reg = frame.tempRegForData(top);
-            frame.pop();
-            masm.loadPtr(Address(reg, JSObject::offsetOfElements()), result);
-            masm.load32(Address(result, ObjectElements::offsetOfLength()), result);
-            frame.pushTypedPayload(JSVAL_TYPE_INT32, result);
-            if (script_->hasScriptCounts)
-                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-            if (!isObject)
-                stubcc.rejoin(Changes(1));
-            return true;
-        }
-
-        /*
-         * Check if we're accessing the 'length' property of a typed array.
-         * The typed array length always fits in an int32_t.
-         */
-        if (types->getTypedArrayType() != TypedArray::TYPE_MAX) {
-            if (top->isConstant()) {
-                JSObject *obj = &top->getValue().toObject();
-                uint32_t length = TypedArray::length(obj);
-                frame.pop();
-                frame.push(Int32Value(length));
-                return true;
-            }
-            bool isObject = top->isTypeKnown();
-            if (!isObject) {
-                Jump notObject = frame.testObject(Assembler::NotEqual, top);
-                stubcc.linkExit(notObject, Uses(1));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::GetProp, rejoin);
-                if (rejoin == REJOIN_GETTER)
-                    testPushedType(rejoin, -1);
-            }
-            RegisterID reg = frame.copyDataIntoReg(top);
-            frame.pop();
-            masm.loadPayload(Address(reg, TypedArray::lengthOffset()), reg);
-            frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-            if (script_->hasScriptCounts)
-                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-            if (!isObject)
-                stubcc.rejoin(Changes(1));
-            return true;
-        }
-    }
-
-    /* If the access will definitely be fetching a particular value, nop it. */
-    bool testObject;
-    JSObject *singleton =
-        (*PC == JSOP_GETPROP || *PC == JSOP_CALLPROP) ? pushedSingleton(0) : NULL;
-    if (singleton && singleton->isFunction() && !hasTypeBarriers(PC)) {
-        Rooted<jsid> id(cx, NameToId(name));
-        if (testSingletonPropertyTypes(top, id, &testObject)) {
-            if (testObject) {
-                Jump notObject = frame.testObject(Assembler::NotEqual, top);
-                stubcc.linkExit(notObject, Uses(1));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::GetProp, REJOIN_FALLTHROUGH);
-                testPushedType(REJOIN_FALLTHROUGH, -1);
-            }
-
-            frame.pop();
-            frame.push(ObjectValue(*singleton));
-
-            if (script_->hasScriptCounts && cx->typeInferenceEnabled())
-                bumpPropCount(PC, PCCounts::PROP_STATIC);
-
-            if (testObject)
-                stubcc.rejoin(Changes(1));
-
-            return true;
-        }
-    }
-
-    /* Check if this is a property access we can make a loop invariant entry for. */
-    if (loop && loop->generatingInvariants() && !hasTypeBarriers(PC)) {
-        CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
-        RootedId id(cx, NameToId(name));
-        if (FrameEntry *fe = loop->invariantProperty(topv, id)) {
-            if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
-                frame.learnType(fe, knownType, false);
-            frame.pop();
-            frame.pushCopyOf(fe);
-            if (script_->hasScriptCounts)
-                bumpPropCount(PC, PCCounts::PROP_STATIC);
-            return true;
-        }
-    }
-
-    /* If the incoming type will never PIC, take slow path. */
-    if (top->isNotType(JSVAL_TYPE_OBJECT)) {
-        jsop_getprop_slow(name, forPrototype);
-        return true;
-    }
-
-    frame.forgetMismatchedObject(top);
-
-    /*
-     * Check if we are accessing a known type which always has the property
-     * in a particular inline slot. Get the property directly in this case,
-     * without using an IC.
-     */
-    RootedId id(cx, NameToId(name));
-    types::TypeSet *types = frame.extra(top).types;
-    if (types && !types->unknownObject() &&
-        types->getObjectCount() == 1 &&
-        types->getTypeObject(0) != NULL &&
-        !types->getTypeObject(0)->unknownProperties() &&
-        id == types::IdToTypeId(id))
-    {
-        JS_ASSERT(!forPrototype);
-        types::TypeObject *object = types->getTypeObject(0);
-        types::HeapTypeSet *propertyTypes = object->getProperty(cx, id, false);
-        if (!propertyTypes)
-            return false;
-        if (propertyTypes->definiteProperty() &&
-            !propertyTypes->isOwnProperty(cx, object, true)) {
-            uint32_t slot = propertyTypes->definiteSlot();
-            bool isObject = top->isTypeKnown();
-            if (!isObject) {
-                Jump notObject = frame.testObject(Assembler::NotEqual, top);
-                stubcc.linkExit(notObject, Uses(1));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::GetProp, rejoin);
-                if (rejoin == REJOIN_GETTER)
-                    testPushedType(rejoin, -1);
-            }
-            RegisterID reg = frame.tempRegForData(top);
-            frame.pop();
-
-            if (script_->hasScriptCounts)
-                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-
-            Address address(reg, JSObject::getFixedSlotOffset(slot));
-            BarrierState barrier = pushAddressMaybeBarrier(address, knownType, false);
-            if (!isObject)
-                stubcc.rejoin(Changes(1));
-            finishBarrier(barrier, rejoin, 0);
-
-            return true;
-        }
-    }
-
-    /* Check for a dynamic dispatch. */
-    if (cx->typeInferenceEnabled()) {
-        if (*PC == JSOP_CALLPROP && jsop_getprop_dispatch(name))
-            return true;
-    }
-
-    if (script_->hasScriptCounts)
-        bumpPropCount(PC, PCCounts::PROP_OTHER);
-
-    /*
-     * These two must be loaded first. The objReg because the string path
-     * wants to read it, and the shapeReg because it could cause a spill that
-     * the string path wouldn't sink back.
-     */
-    RegisterID objReg = frame.copyDataIntoReg(top);
-    RegisterID shapeReg = frame.allocReg();
-
-    RESERVE_IC_SPACE(masm);
-
-    PICGenInfo pic(ic::PICInfo::GET, PC);
-
-    /*
-     * If this access has been on a shape with a getter hook, make preparations
-     * so that we can generate a stub to call the hook directly (rather than be
-     * forced to make a stub call). Sync the stack up front and kill all
-     * registers so that PIC stubs can contain calls, and always generate a
-     * type barrier if inference is enabled (known property types do not
-     * reflect properties with getter hooks).
-     */
-    pic.canCallHook = pic.forcedTypeBarrier =
-        !forPrototype &&
-        (JSOp(*PC) == JSOP_GETPROP || JSOp(*PC) == JSOP_LENGTH) &&
-        analysis->getCode(PC).accessGetter;
-
-    /* Guard that the type is an object. */
-    Label typeCheck;
-    if (doTypeCheck && !top->isTypeKnown()) {
-        RegisterID reg = frame.tempRegForType(top);
-        pic.typeReg = reg;
-
-        if (pic.canCallHook) {
-            PinRegAcrossSyncAndKill p1(frame, reg);
-            frame.syncAndKillEverything();
-        }
-
-        /* Start the hot path where it's easy to patch it. */
-        pic.fastPathStart = masm.label();
-        Jump j = masm.testObject(Assembler::NotEqual, reg);
-        typeCheck = masm.label();
-        RETURN_IF_OOM(false);
-
-        pic.typeCheck = stubcc.linkExit(j, Uses(1));
-        pic.hasTypeCheck = true;
-    } else {
-        if (pic.canCallHook)
-            frame.syncAndKillEverything();
-
-        pic.fastPathStart = masm.label();
-        pic.hasTypeCheck = false;
-        pic.typeReg = Registers::ReturnReg;
-    }
-
-    pic.shapeReg = shapeReg;
-    pic.name = name;
-
-    /* Guard on shape. */
-    masm.loadShape(objReg, shapeReg);
-    pic.shapeGuard = masm.label();
-
-    DataLabelPtr inlineShapeLabel;
-    Jump j = masm.branchPtrWithPatch(Assembler::NotEqual, shapeReg,
-                                     inlineShapeLabel, ImmPtr(NULL));
-    Label inlineShapeJump = masm.label();
-
-    RESERVE_OOL_SPACE(stubcc.masm);
-    pic.slowPathStart = stubcc.linkExit(j, Uses(1));
-    pic.cached = !forPrototype;
-
-    stubcc.leave();
-    passICAddress(&pic);
-    pic.slowPathCall = OOL_STUBCALL(ic::GetProp, rejoin);
-    CHECK_OOL_SPACE();
-    if (rejoin == REJOIN_GETTER)
-        testPushedType(rejoin, -1);
-
-    /* Load the base slot address. */
-    Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, JSObject::offsetOfSlots()),
-                                                               objReg);
-
-    /* Copy the slot value to the expression stack. */
-    Address slot(objReg, 1 << 24);
-    frame.pop();
-
-    Label fastValueLoad = masm.loadValueWithAddressOffsetPatch(slot, shapeReg, objReg);
-    pic.fastPathRejoin = masm.label();
-
-    RETURN_IF_OOM(false);
-
-    /* Initialize op labels. */
-    GetPropLabels &labels = pic.getPropLabels();
-    labels.setDslotsLoad(masm, pic.fastPathRejoin, dslotsLoadLabel);
-    labels.setInlineShapeData(masm, pic.shapeGuard, inlineShapeLabel);
-
-    labels.setValueLoad(masm, pic.fastPathRejoin, fastValueLoad);
-    if (pic.hasTypeCheck)
-        labels.setInlineTypeJump(masm, pic.fastPathStart, typeCheck);
-    labels.setInlineShapeJump(masm, pic.shapeGuard, inlineShapeJump);
-
-    CHECK_IC_SPACE();
-
-    pic.objReg = objReg;
-    frame.pushRegs(shapeReg, objReg, knownType);
-    BarrierState barrier = testBarrier(pic.shapeReg, pic.objReg, false, false,
-                                       /* force = */ pic.canCallHook);
-
-    stubcc.rejoin(Changes(1));
-    pics.append(pic);
-
-    finishBarrier(barrier, rejoin, 0);
-    return true;
-}
-
-bool
-mjit::Compiler::testSingletonProperty(HandleObject obj, HandleId id)
-{
-    /*
-     * We would like to completely no-op property/global accesses which can
-     * produce only a particular JSObject or undefined, provided we can
-     * determine the pushed value must not be undefined (or, if it could be
-     * undefined, a recompilation will be triggered).
-     *
-     * If the access definitely goes through obj, either directly or on the
-     * prototype chain, then if obj has a defined property now, and the
-     * property has a default or method shape, the only way it can produce
-     * undefined in the future is if it is deleted. Deletion causes type
-     * properties to be explicitly marked with undefined.
-     */
-
-    JSObject *nobj = obj;
-    while (nobj) {
-        if (!nobj->isNative())
-            return false;
-        if (nobj->getClass()->ops.lookupGeneric)
-            return false;
-        nobj = nobj->getProto();
-    }
-
-    RootedObject holder(cx);
-    RootedShape shape(cx);
-    if (!JSObject::lookupGeneric(cx, obj, id, &holder, &shape))
-        return false;
-    if (!shape)
-        return false;
-
-    if (shape->hasDefaultGetter()) {
-        if (!shape->hasSlot())
-            return false;
-        if (holder->getSlot(shape->slot()).isUndefined())
-            return false;
-    } else {
-        return false;
-    }
-
-    return true;
-}
-
-bool
-mjit::Compiler::testSingletonPropertyTypes(FrameEntry *top, HandleId id, bool *testObject)
-{
-    *testObject = false;
-
-    types::StackTypeSet *types = frame.extra(top).types;
-    if (!types || types->unknownObject())
-        return false;
-
-    RootedObject singleton(cx, types->getSingleton());
-    if (singleton)
-        return testSingletonProperty(singleton, id);
-
-    if (!globalObj)
-        return false;
-
-    JSProtoKey key;
-    JSValueType type = types->getKnownTypeTag();
-    switch (type) {
-      case JSVAL_TYPE_STRING:
-        key = JSProto_String;
-        break;
-
-      case JSVAL_TYPE_INT32:
-      case JSVAL_TYPE_DOUBLE:
-        key = JSProto_Number;
-        break;
-
-      case JSVAL_TYPE_BOOLEAN:
-        key = JSProto_Boolean;
-        break;
-
-      case JSVAL_TYPE_OBJECT:
-      case JSVAL_TYPE_UNKNOWN:
-        if (types->getObjectCount() == 1 && !top->isNotType(JSVAL_TYPE_OBJECT)) {
-            JS_ASSERT_IF(top->isTypeKnown(), top->isType(JSVAL_TYPE_OBJECT));
-            types::TypeObject *object = types->getTypeObject(0);
-            if (object && object->proto) {
-                Rooted<JSObject*> proto(cx, object->proto);
-                if (!testSingletonProperty(proto, id))
-                    return false;
-
-                /* If we don't know this is an object, we will need a test. */
-                *testObject = (type != JSVAL_TYPE_OBJECT) && !top->isTypeKnown();
-                return true;
-            }
-        }
-        return false;
-
-      default:
-        return false;
-    }
-
-    RootedObject proto(cx);
-    if (!js_GetClassPrototype(cx, key, &proto, NULL))
-        return false;
-
-    return testSingletonProperty(proto, id);
-}
-
-bool
-mjit::Compiler::jsop_getprop_dispatch(HandlePropertyName name)
-{
-    /*
-     * Check for a CALLPROP which is a dynamic dispatch: every value it can
-     * push is a singleton, and the pushed value is determined by the type of
-     * the object being accessed. Return true if the CALLPROP has been fully
-     * processed, false if no code was generated.
-     */
-    FrameEntry *top = frame.peek(-1);
-    if (top->isNotType(JSVAL_TYPE_OBJECT))
-        return false;
-
-    RootedId id(cx, NameToId(name));
-    if (id.get() != types::IdToTypeId(id))
-        return false;
-
-    types::TypeSet *pushedTypes = pushedTypeSet(0);
-    if (pushedTypes->unknownObject() || pushedTypes->baseFlags() != 0)
-        return false;
-
-    /* Check every pushed value is a singleton. */
-    for (unsigned i = 0; i < pushedTypes->getObjectCount(); i++) {
-        if (pushedTypes->getTypeObject(i) != NULL)
-            return false;
-    }
-
-    types::TypeSet *objTypes = analysis->poppedTypes(PC, 0);
-    if (objTypes->unknownObject() || objTypes->getObjectCount() == 0)
-        return false;
-
-    /* Map each type in the object to the resulting pushed value. */
-    Vector<JSObject *> results(CompilerAllocPolicy(cx, *this));
-
-    /*
-     * For each type of the base object, check it has no 'own' property for the
-     * accessed id and that its prototype does have such a property.
-     */
-    uint32_t last = 0;
-    Rooted<JSObject*> proto(cx);
-    for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
-        if (objTypes->getSingleObject(i) != NULL)
-            return false;
-        types::TypeObject *object = objTypes->getTypeObject(i);
-        if (!object) {
-            results.append((JSObject *) NULL);
-            continue;
-        }
-        if (object->unknownProperties() || !object->proto)
-            return false;
-        types::HeapTypeSet *ownTypes = object->getProperty(cx, id, false);
-        if (ownTypes->isOwnProperty(cx, object, false))
-            return false;
-
-        proto = object->proto;
-        if (!testSingletonProperty(proto, id))
-            return false;
-
-        types::TypeObject *protoType = proto->getType(cx);
-        if (!protoType)
-            return false;
-        if (protoType->unknownProperties())
-            return false;
-        types::HeapTypeSet *protoTypes = proto->type()->getProperty(cx, id, false);
-        if (!protoTypes)
-            return false;
-        JSObject *singleton = protoTypes->getSingleton(cx);
-        if (!singleton)
-            return false;
-
-        results.append(singleton);
-        last = i;
-    }
-
-    if (oomInVector)
-        return false;
-
-    /* Done filtering, now generate code which dispatches on the type. */
-
-    frame.forgetMismatchedObject(top);
-
-    if (!top->isType(JSVAL_TYPE_OBJECT)) {
-        Jump notObject = frame.testObject(Assembler::NotEqual, top);
-        stubcc.linkExit(notObject, Uses(1));
-    }
-
-    RegisterID reg = frame.tempRegForData(top);
-    frame.pinReg(reg);
-    RegisterID pushreg = frame.allocReg();
-    frame.unpinReg(reg);
-
-    Address typeAddress(reg, JSObject::offsetOfType());
-
-    Vector<Jump> rejoins(CompilerAllocPolicy(cx, *this));
-    MaybeJump lastMiss;
-
-    for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
-        types::TypeObject *object = objTypes->getTypeObject(i);
-        if (!object) {
-            JS_ASSERT(results[i] == NULL);
-            continue;
-        }
-        if (lastMiss.isSet())
-            lastMiss.get().linkTo(masm.label(), &masm);
-
-        /*
-         * Check that the pushed result is actually in the known pushed types
-         * for the bytecode; this bytecode may have type barriers. Redirect to
-         * the stub to update said pushed types.
-         */
-        if (!pushedTypes->hasType(types::Type::ObjectType(results[i]))) {
-            JS_ASSERT(hasTypeBarriers(PC));
-            if (i == last) {
-                stubcc.linkExit(masm.jump(), Uses(1));
-                break;
-            } else {
-                lastMiss.setJump(masm.branchPtr(Assembler::NotEqual, typeAddress, ImmPtr(object)));
-                stubcc.linkExit(masm.jump(), Uses(1));
-                continue;
-            }
-        }
-
-        if (i == last) {
-            masm.move(ImmPtr(results[i]), pushreg);
-            break;
-        } else {
-            lastMiss.setJump(masm.branchPtr(Assembler::NotEqual, typeAddress, ImmPtr(object)));
-            masm.move(ImmPtr(results[i]), pushreg);
-            rejoins.append(masm.jump());
-        }
-    }
-
-    for (unsigned i = 0; i < rejoins.length(); i++)
-        rejoins[i].linkTo(masm.label(), &masm);
-
-    stubcc.leave();
-    stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::GetProp, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, -1);
-
-    frame.pop();
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, pushreg);
-
-    if (script_->hasScriptCounts)
-        bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-
-    stubcc.rejoin(Changes(2));
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_setprop(HandlePropertyName name, bool popGuaranteed)
-{
-    FrameEntry *lhs = frame.peek(-2);
-    FrameEntry *rhs = frame.peek(-1);
-
-    /* If the incoming type will never PIC, take slow path. */
-    if (lhs->isTypeKnown() && lhs->getKnownType() != JSVAL_TYPE_OBJECT) {
-        jsop_setprop_slow(name);
-        return true;
-    }
-
-    /*
-     * Set the property directly if we are accessing a known object which
-     * always has the property in a particular inline slot.
-     */
-    RootedId id(cx, NameToId(name));
-    types::StackTypeSet *types = frame.extra(lhs).types;
-    if (JSOp(*PC) == JSOP_SETPROP && id == types::IdToTypeId(id) &&
-        types && !types->unknownObject() &&
-        types->getObjectCount() == 1 &&
-        types->getTypeObject(0) != NULL &&
-        !types->getTypeObject(0)->unknownProperties())
-    {
-        types::TypeObject *object = types->getTypeObject(0);
-        types::HeapTypeSet *propertyTypes = object->getProperty(cx, id, false);
-        if (!propertyTypes)
-            return false;
-        if (propertyTypes->definiteProperty() &&
-            !propertyTypes->isOwnProperty(cx, object, true)) {
-            uint32_t slot = propertyTypes->definiteSlot();
-            RegisterID reg = frame.tempRegForData(lhs);
-            frame.pinReg(reg);
-            bool isObject = lhs->isTypeKnown();
-            MaybeJump notObject;
-            if (!isObject)
-                notObject = frame.testObject(Assembler::NotEqual, lhs);
-#ifdef JSGC_INCREMENTAL_MJ
-            if (cx->zone()->compileBarriers() && propertyTypes->needsBarrier(cx)) {
-                /* Write barrier. */
-                Jump j = masm.testGCThing(Address(reg, JSObject::getFixedSlotOffset(slot)));
-                stubcc.linkExit(j, Uses(0));
-                stubcc.leave();
-                stubcc.masm.addPtr(Imm32(JSObject::getFixedSlotOffset(slot)),
-                                   reg, Registers::ArgReg1);
-                OOL_STUBCALL(stubs::GCThingWriteBarrier, REJOIN_NONE);
-                stubcc.rejoin(Changes(0));
-            }
-#endif
-            if (!isObject) {
-                stubcc.linkExit(notObject.get(), Uses(2));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::SetProp, REJOIN_FALLTHROUGH);
-            }
-            frame.storeTo(rhs, Address(reg, JSObject::getFixedSlotOffset(slot)), popGuaranteed);
-            frame.unpinReg(reg);
-            frame.shimmy(1);
-            if (!isObject)
-                stubcc.rejoin(Changes(1));
-            if (script_->hasScriptCounts)
-                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
-            return true;
-        }
-    }
-
-    if (script_->hasScriptCounts)
-        bumpPropCount(PC, PCCounts::PROP_OTHER);
-
-#ifdef JSGC_INCREMENTAL_MJ
-    /* Write barrier. We don't have type information for JSOP_SETNAME. */
-    if (cx->zone()->compileBarriers() &&
-        (!types || JSOp(*PC) == JSOP_SETNAME || types->propertyNeedsBarrier(cx, id)))
-    {
-        jsop_setprop_slow(name);
-        return true;
-    }
-#endif
-
-    PICGenInfo pic(ic::PICInfo::SET, PC);
-    pic.name = name;
-
-    if (monitored(PC)) {
-        if (script_ == outerScript)
-            monitoredBytecodes.append(PC - script_->code);
-        pic.typeMonitored = true;
-    } else {
-        pic.typeMonitored = false;
-    }
-
-    RESERVE_IC_SPACE(masm);
-    RESERVE_OOL_SPACE(stubcc.masm);
-
-    /* Guard that the type is an object. */
-    Jump typeCheck;
-    if (!lhs->isTypeKnown()) {
-        RegisterID reg = frame.tempRegForType(lhs);
-        pic.typeReg = reg;
-
-        /* Start the hot path where it's easy to patch it. */
-        pic.fastPathStart = masm.label();
-        Jump j = masm.testObject(Assembler::NotEqual, reg);
-
-        pic.typeCheck = stubcc.linkExit(j, Uses(2));
-        stubcc.leave();
-
-        stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-
-        if (*PC == JSOP_SETPROP)
-            OOL_STUBCALL(stubs::SetProp, REJOIN_FALLTHROUGH);
-        else
-            OOL_STUBCALL(stubs::SetName, REJOIN_FALLTHROUGH);
-
-        typeCheck = stubcc.masm.jump();
-        pic.hasTypeCheck = true;
-    } else {
-        pic.fastPathStart = masm.label();
-        pic.hasTypeCheck = false;
-        pic.typeReg = Registers::ReturnReg;
-    }
-
-    frame.forgetMismatchedObject(lhs);
-
-    /* Get the object into a mutable register. */
-    RegisterID objReg = frame.copyDataIntoReg(lhs);
-    pic.objReg = objReg;
-
-    /* Get info about the RHS and pin it. */
-    ValueRemat vr;
-    frame.pinEntry(rhs, vr);
-    pic.vr = vr;
-
-    RegisterID shapeReg = frame.allocReg();
-    pic.shapeReg = shapeReg;
-
-    frame.unpinEntry(vr);
-
-    /* Guard on shape. */
-    masm.loadShape(objReg, shapeReg);
-    pic.shapeGuard = masm.label();
-    DataLabelPtr inlineShapeData;
-    Jump j = masm.branchPtrWithPatch(Assembler::NotEqual, shapeReg,
-                                     inlineShapeData, ImmPtr(NULL));
-    Label afterInlineShapeJump = masm.label();
-
-    /* Slow path. */
-    {
-        pic.slowPathStart = stubcc.linkExit(j, Uses(2));
-
-        stubcc.leave();
-        passICAddress(&pic);
-        pic.slowPathCall = OOL_STUBCALL(ic::SetPropOrName, REJOIN_FALLTHROUGH);
-        CHECK_OOL_SPACE();
-    }
-
-    /* Load dslots. */
-    Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, JSObject::offsetOfSlots()),
-                                                       objReg);
-
-    /* Store RHS into object slot. */
-    Address slot(objReg, 1 << 24);
-    DataLabel32 inlineValueStore = masm.storeValueWithAddressOffsetPatch(vr, slot);
-    pic.fastPathRejoin = masm.label();
-
-    frame.freeReg(objReg);
-    frame.freeReg(shapeReg);
-
-    /* "Pop under", taking out object (LHS) and leaving RHS. */
-    frame.shimmy(1);
-
-    /* Finish slow path. */
-    {
-        if (pic.hasTypeCheck)
-            typeCheck.linkTo(stubcc.masm.label(), &stubcc.masm);
-        stubcc.rejoin(Changes(1));
-    }
-
-    RETURN_IF_OOM(false);
-
-    SetPropLabels &labels = pic.setPropLabels();
-    labels.setInlineShapeData(masm, pic.shapeGuard, inlineShapeData);
-    labels.setDslotsLoad(masm, pic.fastPathRejoin, dslotsLoadLabel);
-    labels.setInlineValueStore(masm, pic.fastPathRejoin, inlineValueStore);
-    labels.setInlineShapeJump(masm, pic.shapeGuard, afterInlineShapeJump);
-
-    pics.append(pic);
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_intrinsic(HandlePropertyName name, JSValueType type)
-{
-    if (type == JSVAL_TYPE_UNKNOWN) {
-        prepareStubCall(Uses(0));
-        masm.move(ImmPtr(name), Registers::ArgReg1);
-        INLINE_STUBCALL(stubs::IntrinsicName, REJOIN_FALLTHROUGH);
-        testPushedType(REJOIN_FALLTHROUGH, 0, /* ool = */ false);
-        frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-        return true;
-    }
-
-    RootedValue vp(cx, NullValue());
-    if (!cx->global().get()->getIntrinsicValue(cx, name, &vp))
-        return false;
-    frame.push(vp);
-    return true;
-}
-
-void
-mjit::Compiler::jsop_name(HandlePropertyName name, JSValueType type)
-{
-    PICGenInfo pic(ic::PICInfo::NAME, PC);
-
-    RESERVE_IC_SPACE(masm);
-
-    pic.shapeReg = frame.allocReg();
-    pic.objReg = frame.allocReg();
-    pic.typeReg = Registers::ReturnReg;
-    pic.name = name;
-    pic.hasTypeCheck = false;
-    pic.fastPathStart = masm.label();
-
-    /* There is no inline implementation, so we always jump to the slow path or to a stub. */
-    pic.shapeGuard = masm.label();
-    Jump inlineJump = masm.jump();
-    {
-        RESERVE_OOL_SPACE(stubcc.masm);
-        pic.slowPathStart = stubcc.linkExit(inlineJump, Uses(0));
-        stubcc.leave();
-        passICAddress(&pic);
-        pic.slowPathCall = OOL_STUBCALL(ic::Name, REJOIN_GETTER);
-        CHECK_OOL_SPACE();
-        testPushedType(REJOIN_GETTER, 0);
-    }
-    pic.fastPathRejoin = masm.label();
-
-    /* Initialize op labels. */
-    ScopeNameLabels &labels = pic.scopeNameLabels();
-    labels.setInlineJump(masm, pic.fastPathStart, inlineJump);
-
-    CHECK_IC_SPACE();
-
-    /*
-     * We can't optimize away the PIC for the NAME access itself, but if we've
-     * only seen a single value pushed by this access, mark it as such and
-     * recompile if a different value becomes possible.
-     */
-    JSObject *singleton = pushedSingleton(0);
-    if (singleton) {
-        frame.push(ObjectValue(*singleton));
-        frame.freeReg(pic.shapeReg);
-        frame.freeReg(pic.objReg);
-    } else {
-        frame.pushRegs(pic.shapeReg, pic.objReg, type);
-    }
-    BarrierState barrier = testBarrier(pic.shapeReg, pic.objReg, /* testUndefined = */ true);
-
-    stubcc.rejoin(Changes(1));
-
-    pics.append(pic);
-
-    finishBarrier(barrier, REJOIN_GETTER, 0);
-}
-
-bool
-mjit::Compiler::jsop_xname(HandlePropertyName name)
-{
-    PICGenInfo pic(ic::PICInfo::XNAME, PC);
-
-    FrameEntry *fe = frame.peek(-1);
-    if (fe->isNotType(JSVAL_TYPE_OBJECT)) {
-        return jsop_getprop(name, knownPushedType(0));
-    }
-
-    if (!fe->isTypeKnown()) {
-        Jump notObject = frame.testObject(Assembler::NotEqual, fe);
-        stubcc.linkExit(notObject, Uses(1));
-    }
-
-    frame.forgetMismatchedObject(fe);
-
-    RESERVE_IC_SPACE(masm);
-
-    pic.shapeReg = frame.allocReg();
-    pic.objReg = frame.copyDataIntoReg(fe);
-    pic.typeReg = Registers::ReturnReg;
-    pic.name = name;
-    pic.hasTypeCheck = false;
-    pic.fastPathStart = masm.label();
-
-    /* There is no inline implementation, so we always jump to the slow path or to a stub. */
-    pic.shapeGuard = masm.label();
-    Jump inlineJump = masm.jump();
-    {
-        RESERVE_OOL_SPACE(stubcc.masm);
-        pic.slowPathStart = stubcc.linkExit(inlineJump, Uses(1));
-        stubcc.leave();
-        passICAddress(&pic);
-        pic.slowPathCall = OOL_STUBCALL(ic::XName, REJOIN_GETTER);
-        CHECK_OOL_SPACE();
-        testPushedType(REJOIN_GETTER, -1);
-    }
-
-    pic.fastPathRejoin = masm.label();
-
-    RETURN_IF_OOM(false);
-
-    /* Initialize op labels. */
-    ScopeNameLabels &labels = pic.scopeNameLabels();
-    labels.setInlineJumpOffset(masm.differenceBetween(pic.fastPathStart, inlineJump));
-
-    CHECK_IC_SPACE();
-
-    frame.pop();
-    frame.pushRegs(pic.shapeReg, pic.objReg, knownPushedType(0));
-
-    BarrierState barrier = testBarrier(pic.shapeReg, pic.objReg, /* testUndefined = */ true);
-
-    stubcc.rejoin(Changes(1));
-
-    pics.append(pic);
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-    return true;
-}
-
-void
-mjit::Compiler::jsop_bindname(HandlePropertyName name)
-{
-    PICGenInfo pic(ic::PICInfo::BIND, PC);
-
-    // This code does not check the frame flags to see if scopeChain has been
-    // set. Rather, it relies on the up-front analysis statically determining
-    // whether BINDNAME can be used, which reifies the scope chain at the
-    // prologue.
-    JS_ASSERT(analysis->usesScopeChain());
-
-    pic.shapeReg = frame.allocReg();
-    pic.objReg = frame.allocReg();
-    pic.typeReg = Registers::ReturnReg;
-    pic.name = name;
-    pic.hasTypeCheck = false;
-
-    RESERVE_IC_SPACE(masm);
-    pic.fastPathStart = masm.label();
-
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), pic.objReg);
-    masm.loadPtr(Address(pic.objReg, JSObject::offsetOfShape()), pic.shapeReg);
-    masm.loadPtr(Address(pic.shapeReg, Shape::offsetOfBase()), pic.shapeReg);
-    Address parent(pic.shapeReg, BaseShape::offsetOfParent());
-
-    pic.shapeGuard = masm.label();
-    Jump inlineJump = masm.branchPtr(Assembler::NotEqual, parent, ImmPtr(NULL));
-    {
-        RESERVE_OOL_SPACE(stubcc.masm);
-        pic.slowPathStart = stubcc.linkExit(inlineJump, Uses(0));
-        stubcc.leave();
-        passICAddress(&pic);
-        pic.slowPathCall = OOL_STUBCALL(ic::BindName, REJOIN_FALLTHROUGH);
-        CHECK_OOL_SPACE();
-    }
-
-    pic.fastPathRejoin = masm.label();
-
-    /* Initialize op labels. */
-    BindNameLabels &labels = pic.bindNameLabels();
-    labels.setInlineJump(masm, pic.shapeGuard, inlineJump);
-
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, pic.objReg);
-    frame.freeReg(pic.shapeReg);
-
-    stubcc.rejoin(Changes(1));
-
-    pics.append(pic);
-}
-
-#else /* !JS_POLYIC */
-
-void
-mjit::Compiler::jsop_name(HandlePropertyName name, JSValueType type, bool isCall)
-{
-    prepareStubCall(Uses(0));
-    INLINE_STUBCALL(isCall ? stubs::CallName : stubs::Name, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, 0, /* ool = */ false);
-    frame.pushSynced(type);
-    if (isCall)
-        frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-}
-
-bool
-mjit::Compiler::jsop_xname(HandlePropertyName name)
-{
-    return jsop_getprop(name, knownPushedType(0), pushedTypeSet(0));
-}
-
-bool
-mjit::Compiler::jsop_getprop(HandlePropertyName name, JSValueType knownType, types::TypeSet *typeSet,
-                             bool typecheck, bool forPrototype)
-{
-    jsop_getprop_slow(name, forPrototype);
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_setprop(HandlePropertyName name)
-{
-    jsop_setprop_slow(name);
-    return true;
-}
-
-void
-mjit::Compiler::jsop_bindname(HandlePropertyName name)
-{
-    RegisterID reg = frame.allocReg();
-    Address scopeChain(JSFrameReg, StackFrame::offsetOfScopeChain());
-    masm.loadPtr(scopeChain, reg);
-
-    Address address(reg, offsetof(JSObject, parent));
-
-    Jump j = masm.branchPtr(Assembler::NotEqual, address, ImmPtr(0));
-
-    stubcc.linkExit(j, Uses(0));
-    stubcc.leave();
-    stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::BindName, REJOIN_FALLTHROUGH);
-
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
-
-    stubcc.rejoin(Changes(1));
-}
-#endif
-
-void
-mjit::Compiler::jsop_aliasedArg(unsigned arg, bool get, bool poppedAfter)
-{
-    RegisterID reg = frame.allocReg(Registers::SavedRegs).reg();
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfArgsObj()), reg);
-    size_t dataOff = ArgumentsObject::getDataSlotOffset();
-    masm.loadPrivate(Address(reg, dataOff), reg);
-    int32_t argsOff = ArgumentsData::offsetOfArgs() + arg * sizeof(Value);
-    masm.addPtr(Imm32(argsOff), reg, reg);
-    if (get) {
-        FrameEntry *fe = frame.getArg(arg);
-        JSValueType type = fe->isTypeKnown() ? fe->getKnownType() : JSVAL_TYPE_UNKNOWN;
-        frame.push(Address(reg), type, true /* = reuseBase */);
-    } else {
-#ifdef JSGC_INCREMENTAL_MJ
-        if (cx->zone()->compileBarriers()) {
-            /* Write barrier. */
-            stubcc.linkExit(masm.testGCThing(Address(reg)), Uses(0));
-            stubcc.leave();
-            stubcc.masm.move(reg, Registers::ArgReg1);
-            OOL_STUBCALL(stubs::GCThingWriteBarrier, REJOIN_NONE);
-            stubcc.rejoin(Changes(0));
-        }
-#endif
-        frame.storeTo(frame.peek(-1), Address(reg), poppedAfter);
-        frame.freeReg(reg);
-    }
-}
-
-void
-mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter)
-{
-    RegisterID reg = frame.allocReg(Registers::SavedRegs).reg();
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), reg);
-    for (unsigned i = 0; i < sc.hops; i++)
-        masm.loadPayload(Address(reg, ScopeObject::offsetOfEnclosingScope()), reg);
-
-    Shape *shape = ScopeCoordinateToStaticScopeShape(cx, script_, PC);
-    Address addr;
-    if (shape->numFixedSlots() <= sc.slot) {
-        masm.loadPtr(Address(reg, JSObject::offsetOfSlots()), reg);
-        addr = Address(reg, (sc.slot - shape->numFixedSlots()) * sizeof(Value));
-    } else {
-        addr = Address(reg, JSObject::getFixedSlotOffset(sc.slot));
-    }
-
-    if (get) {
-        JSValueType type = knownPushedType(0);
-        RegisterID typeReg, dataReg;
-        frame.loadIntoRegisters(addr, /* reuseBase = */ true, &typeReg, &dataReg);
-        frame.pushRegs(typeReg, dataReg, type);
-        BarrierState barrier = testBarrier(typeReg, dataReg,
-                                           /* testUndefined = */ false,
-                                           /* testReturn */ false,
-                                           /* force */ true);
-        finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-    } else {
-#ifdef JSGC_INCREMENTAL_MJ
-        if (cx->zone()->compileBarriers()) {
-            /* Write barrier. */
-            stubcc.linkExit(masm.testGCThing(addr), Uses(0));
-            stubcc.leave();
-            stubcc.masm.addPtr(Imm32(addr.offset), addr.base, Registers::ArgReg1);
-            OOL_STUBCALL(stubs::GCThingWriteBarrier, REJOIN_NONE);
-            stubcc.rejoin(Changes(0));
-        }
-#endif
-        frame.storeTo(frame.peek(-1), addr, poppedAfter);
-        frame.freeReg(reg);
-    }
-}
-
-void
-mjit::Compiler::jsop_this()
-{
-    frame.pushThis();
-
-    /*
-     * In strict mode and self-hosted code, we don't wrap 'this'.
-     * In direct-call eval code, we wrapped 'this' before entering the eval.
-     * In global code, 'this' is always an object.
-     */
-    if (script_->function() && !script_->strict &&
-        !script_->function()->isSelfHostedBuiltin())
-    {
-        FrameEntry *thisFe = frame.peek(-1);
-
-        if (!thisFe->isType(JSVAL_TYPE_OBJECT)) {
-            /*
-             * Watch out for an obscure case where we don't know we are pushing
-             * an object: the script has not yet had a 'this' value assigned,
-             * so no pushed 'this' type has been inferred. Don't mark the type
-             * as known in this case, preserving the invariant that compiler
-             * types reflect inferred types.
-             */
-            if (cx->typeInferenceEnabled() && knownPushedType(0) != JSVAL_TYPE_OBJECT) {
-                prepareStubCall(Uses(1));
-                INLINE_STUBCALL(stubs::This, REJOIN_FALLTHROUGH);
-                return;
-            }
-
-            JSValueType type = cx->typeInferenceEnabled()
-                ? types::TypeScript::ThisTypes(script_)->getKnownTypeTag()
-                : JSVAL_TYPE_UNKNOWN;
-            if (type != JSVAL_TYPE_OBJECT) {
-                Jump notObj = frame.testObject(Assembler::NotEqual, thisFe);
-                stubcc.linkExit(notObj, Uses(1));
-                stubcc.leave();
-                OOL_STUBCALL(stubs::This, REJOIN_FALLTHROUGH);
-                stubcc.rejoin(Changes(1));
-            }
-
-            // Now we know that |this| is an object.
-            frame.pop();
-            frame.learnThisIsObject(type != JSVAL_TYPE_OBJECT);
-            frame.pushThis();
-        }
-
-        JS_ASSERT(thisFe->isType(JSVAL_TYPE_OBJECT));
-    }
-}
-
-bool
-mjit::Compiler::iter(unsigned flags)
-{
-    FrameEntry *fe = frame.peek(-1);
-
-    /*
-     * Stub the call if this is not a simple 'for in' loop or if the iterated
-     * value is known to not be an object.
-     */
-    if ((flags != JSITER_ENUMERATE) || fe->isNotType(JSVAL_TYPE_OBJECT)) {
-        prepareStubCall(Uses(1));
-        masm.move(Imm32(flags), Registers::ArgReg1);
-        INLINE_STUBCALL(stubs::Iter, REJOIN_FALLTHROUGH);
-        frame.pop();
-        frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-        return true;
-    }
-
-    if (!fe->isTypeKnown()) {
-        Jump notObject = frame.testObject(Assembler::NotEqual, fe);
-        stubcc.linkExit(notObject, Uses(1));
-    }
-
-    frame.forgetMismatchedObject(fe);
-
-    RegisterID reg = frame.tempRegForData(fe);
-
-    frame.pinReg(reg);
-    RegisterID ioreg = frame.allocReg();  /* Will hold iterator JSObject */
-    RegisterID nireg = frame.allocReg();  /* Will hold NativeIterator */
-    RegisterID T1 = frame.allocReg();
-    RegisterID T2 = frame.allocReg();
-    frame.unpinReg(reg);
-
-    /* Fetch the most recent iterator. */
-    masm.loadPtr(&cx->runtime->nativeIterCache.last, ioreg);
-
-    /* Test for NULL. */
-    Jump nullIterator = masm.branchTest32(Assembler::Zero, ioreg, ioreg);
-    stubcc.linkExit(nullIterator, Uses(1));
-
-    /* Get NativeIterator from iter obj. */
-    masm.loadObjPrivate(ioreg, nireg, JSObject::ITER_CLASS_NFIXED_SLOTS);
-
-    /* Test for active iterator. */
-    Address flagsAddr(nireg, offsetof(NativeIterator, flags));
-    masm.load32(flagsAddr, T1);
-    Jump activeIterator = masm.branchTest32(Assembler::NonZero, T1,
-                                            Imm32(JSITER_ACTIVE|JSITER_UNREUSABLE));
-    stubcc.linkExit(activeIterator, Uses(1));
-
-    /* Compare shape of object with iterator. */
-    masm.loadShape(reg, T1);
-    masm.loadPtr(Address(nireg, offsetof(NativeIterator, shapes_array)), T2);
-    masm.loadPtr(Address(T2, 0), T2);
-    Jump mismatchedObject = masm.branchPtr(Assembler::NotEqual, T1, T2);
-    stubcc.linkExit(mismatchedObject, Uses(1));
-
-    /* Compare shape of object's prototype with iterator. */
-    masm.loadPtr(Address(reg, JSObject::offsetOfType()), T1);
-    masm.loadPtr(Address(T1, offsetof(types::TypeObject, proto)), T1);
-    masm.loadShape(T1, T1);
-    masm.loadPtr(Address(nireg, offsetof(NativeIterator, shapes_array)), T2);
-    masm.loadPtr(Address(T2, sizeof(Shape *)), T2);
-    Jump mismatchedProto = masm.branchPtr(Assembler::NotEqual, T1, T2);
-    stubcc.linkExit(mismatchedProto, Uses(1));
-
-    /*
-     * Compare object's prototype's prototype with NULL. The last native
-     * iterator will always have a prototype chain length of one
-     * (i.e. it must be a plain object), so we do not need to generate
-     * a loop here.
-     */
-    masm.loadPtr(Address(reg, JSObject::offsetOfType()), T1);
-    masm.loadPtr(Address(T1, offsetof(types::TypeObject, proto)), T1);
-    masm.loadPtr(Address(T1, JSObject::offsetOfType()), T1);
-    masm.loadPtr(Address(T1, offsetof(types::TypeObject, proto)), T1);
-    Jump overlongChain = masm.branchPtr(Assembler::NonZero, T1, T1);
-    stubcc.linkExit(overlongChain, Uses(1));
-
-    /* Compare object's elements() with emptyObjectElements. */
-    Address elementsAddress(reg, JSObject::offsetOfElements());
-    Jump hasElements = masm.branchPtr(Assembler::NotEqual, elementsAddress,
-                                      ImmPtr(js::emptyObjectElements));
-    stubcc.linkExit(hasElements, Uses(1));
-
-#ifdef JSGC_INCREMENTAL_MJ
-    /*
-     * Write barrier for stores to the iterator. We only need to take a write
-     * barrier if NativeIterator::obj is actually going to change.
-     */
-    if (cx->zone()->compileBarriers()) {
-        Jump j = masm.branchPtr(Assembler::NotEqual,
-                                Address(nireg, offsetof(NativeIterator, obj)), reg);
-        stubcc.linkExit(j, Uses(1));
-    }
-#endif
-
-    /* Found a match with the most recent iterator. Hooray! */
-
-    /* Mark iterator as active. */
-    masm.storePtr(reg, Address(nireg, offsetof(NativeIterator, obj)));
-    masm.load32(flagsAddr, T1);
-    masm.or32(Imm32(JSITER_ACTIVE), T1);
-    masm.store32(T1, flagsAddr);
-
-    /* Chain onto the active iterator stack. */
-    masm.move(ImmPtr(cx->compartment), T1);
-    masm.loadPtr(Address(T1, offsetof(JSCompartment, enumerators)), T1);
-
-    /* ni->next = list */
-    masm.storePtr(T1, Address(nireg, NativeIterator::offsetOfNext()));
-
-    /* ni->prev = list->prev */
-    masm.loadPtr(Address(T1, NativeIterator::offsetOfPrev()), T2);
-    masm.storePtr(T2, Address(nireg, NativeIterator::offsetOfPrev()));
-
-    /* list->prev->next = ni */
-    masm.storePtr(nireg, Address(T2, NativeIterator::offsetOfNext()));
-
-    /* list->prev = ni */
-    masm.storePtr(nireg, Address(T1, NativeIterator::offsetOfPrev()));
-
-    frame.freeReg(nireg);
-    frame.freeReg(T1);
-    frame.freeReg(T2);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(flags), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::Iter, REJOIN_FALLTHROUGH);
-
-    /* Push the iterator object. */
-    frame.pop();
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, ioreg);
-
-    stubcc.rejoin(Changes(1));
-
-    return true;
-}
-
-/*
- * This big nasty function implements JSOP_ITERNEXT, which is used in the head
- * of a for-in loop to put the next value on the stack.
- */
-void
-mjit::Compiler::iterNext()
-{
-    FrameEntry *fe = frame.peek(-1);
-    RegisterID reg = frame.tempRegForData(fe);
-
-    /* Is it worth trying to pin this longer? Prolly not. */
-    frame.pinReg(reg);
-    RegisterID T1 = frame.allocReg();
-    frame.unpinReg(reg);
-
-    /* Test clasp */
-    Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, T1,
-                                     &PropertyIteratorObject::class_);
-    stubcc.linkExit(notFast, Uses(1));
-
-    /* Get private from iter obj. */
-    masm.loadObjPrivate(reg, T1, JSObject::ITER_CLASS_NFIXED_SLOTS);
-
-    RegisterID T3 = frame.allocReg();
-    RegisterID T4 = frame.allocReg();
-
-    /* Test for a value iterator, which could come through an Iterator object. */
-    masm.load32(Address(T1, offsetof(NativeIterator, flags)), T3);
-    notFast = masm.branchTest32(Assembler::NonZero, T3, Imm32(JSITER_FOREACH));
-    stubcc.linkExit(notFast, Uses(1));
-
-    RegisterID T2 = frame.allocReg();
-
-    /* Get cursor. */
-    masm.loadPtr(Address(T1, offsetof(NativeIterator, props_cursor)), T2);
-
-    /* Get the next string in the iterator. */
-    masm.loadPtr(T2, T3);
-
-    /* It's safe to increase the cursor now. */
-    masm.addPtr(Imm32(sizeof(JSString*)), T2, T4);
-    masm.storePtr(T4, Address(T1, offsetof(NativeIterator, props_cursor)));
-
-    frame.freeReg(T4);
-    frame.freeReg(T1);
-    frame.freeReg(T2);
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::IterNext, REJOIN_FALLTHROUGH);
-
-    frame.pushUntypedPayload(JSVAL_TYPE_STRING, T3);
-
-    /* Join with the stub call. */
-    stubcc.rejoin(Changes(1));
-}
-
-bool
-mjit::Compiler::iterMore(jsbytecode *target)
-{
-    if (!frame.syncForBranch(target, Uses(1)))
-        return false;
-
-    FrameEntry *fe = frame.peek(-1);
-    RegisterID reg = frame.tempRegForData(fe);
-    RegisterID tempreg = frame.allocReg();
-
-    /* Test clasp */
-    Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, tempreg,
-                                     &PropertyIteratorObject::class_);
-    stubcc.linkExitForBranch(notFast);
-
-    /* Get private from iter obj. */
-    masm.loadObjPrivate(reg, reg, JSObject::ITER_CLASS_NFIXED_SLOTS);
-
-    /* Test that the iterator supports fast iteration. */
-    notFast = masm.branchTest32(Assembler::NonZero, Address(reg, offsetof(NativeIterator, flags)),
-                                Imm32(JSITER_FOREACH));
-    stubcc.linkExitForBranch(notFast);
-
-    /* Get props_cursor, test */
-    masm.loadPtr(Address(reg, offsetof(NativeIterator, props_cursor)), tempreg);
-    masm.loadPtr(Address(reg, offsetof(NativeIterator, props_end)), reg);
-
-    Jump jFast = masm.branchPtr(Assembler::LessThan, tempreg, reg);
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::IterMore, REJOIN_BRANCH);
-    Jump j = stubcc.masm.branchTest32(Assembler::NonZero, Registers::ReturnReg,
-                                      Registers::ReturnReg);
-
-    stubcc.rejoin(Changes(1));
-    frame.freeReg(tempreg);
-
-    return jumpAndRun(jFast, target, &j);
-}
-
-void
-mjit::Compiler::iterEnd()
-{
-    FrameEntry *fe= frame.peek(-1);
-    RegisterID reg = frame.tempRegForData(fe);
-
-    frame.pinReg(reg);
-    RegisterID T1 = frame.allocReg();
-    frame.unpinReg(reg);
-
-    /* Test clasp */
-    Jump notIterator = masm.testObjClass(Assembler::NotEqual, reg, T1,
-                                         &PropertyIteratorObject::class_);
-    stubcc.linkExit(notIterator, Uses(1));
-
-    /* Get private from iter obj. */
-    masm.loadObjPrivate(reg, T1, JSObject::ITER_CLASS_NFIXED_SLOTS);
-
-    RegisterID T2 = frame.allocReg();
-
-    /* Load flags. */
-    Address flagAddr(T1, offsetof(NativeIterator, flags));
-    masm.loadPtr(flagAddr, T2);
-
-    /* Test for a normal enumerate iterator. */
-    Jump notEnumerate = masm.branchTest32(Assembler::Zero, T2, Imm32(JSITER_ENUMERATE));
-    stubcc.linkExit(notEnumerate, Uses(1));
-
-    /* Clear active bit. */
-    masm.and32(Imm32(~JSITER_ACTIVE), T2);
-    masm.storePtr(T2, flagAddr);
-
-    /* Reset property cursor. */
-    masm.loadPtr(Address(T1, offsetof(NativeIterator, props_array)), T2);
-    masm.storePtr(T2, Address(T1, offsetof(NativeIterator, props_cursor)));
-
-    /* Unlink from the iterator list. */
-    RegisterID prev = T2;
-    RegisterID next = frame.allocReg();
-
-    masm.loadPtr(Address(T1, NativeIterator::offsetOfNext()), next);
-    masm.loadPtr(Address(T1, NativeIterator::offsetOfPrev()), prev);
-    masm.storePtr(prev, Address(next, NativeIterator::offsetOfPrev()));
-    masm.storePtr(next, Address(prev, NativeIterator::offsetOfNext()));
-#ifdef DEBUG
-    masm.storePtr(ImmPtr(NULL), Address(T1, NativeIterator::offsetOfNext()));
-    masm.storePtr(ImmPtr(NULL), Address(T1, NativeIterator::offsetOfPrev()));
-#endif
-
-    frame.freeReg(T1);
-    frame.freeReg(T2);
-    frame.freeReg(next);
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::EndIter, REJOIN_FALLTHROUGH);
-
-    frame.pop();
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_getgname_slow(uint32_t index)
-{
-    prepareStubCall(Uses(0));
-    INLINE_STUBCALL(stubs::Name, REJOIN_GETTER);
-    testPushedType(REJOIN_GETTER, 0, /* ool = */ false);
-    frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-}
-
-void
-mjit::Compiler::jsop_bindgname()
-{
-    if (globalObj) {
-        frame.push(ObjectValue(*globalObj));
-        return;
-    }
-
-    /* :TODO: this is slower than it needs to be. */
-    prepareStubCall(Uses(0));
-    INLINE_STUBCALL(stubs::BindGlobalName, REJOIN_NONE);
-    frame.takeReg(Registers::ReturnReg);
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
-}
-
-bool
-mjit::Compiler::jsop_getgname(uint32_t index)
-{
-    /* Optimize undefined, NaN and Infinity. */
-    PropertyName *name = script_->getName(index);
-    if (name == cx->names().undefined) {
-        frame.push(UndefinedValue());
-        return true;
-    }
-    if (name == cx->names().NaN) {
-        frame.push(cx->runtime->NaNValue);
-        return true;
-    }
-    if (name == cx->names().Infinity) {
-        frame.push(cx->runtime->positiveInfinityValue);
-        return true;
-    }
-
-    /* Optimize singletons like Math for JSOP_CALLPROP. */
-    JSObject *obj = pushedSingleton(0);
-    if (obj && !hasTypeBarriers(PC)) {
-        Rooted<jsid> id(cx, NameToId(name));
-        if (testSingletonProperty(globalObj, id)) {
-            frame.push(ObjectValue(*obj));
-            return true;
-        }
-    }
-
-    RootedId id(cx, NameToId(name));
-    JSValueType type = knownPushedType(0);
-
-    types::TypeObject *globalType = NULL;
-    if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::IdToTypeId(id)) {
-        globalType = globalObj->getType(cx);
-        if (globalType && globalType->unknownProperties())
-            globalType = NULL;
-    }
-
-    if (globalType) {
-        types::HeapTypeSet *propertyTypes = globalType->getProperty(cx, id, false);
-        if (!propertyTypes)
-            return false;
-
-        /*
-         * If we are accessing a defined global which is a normal data property
-         * then bake its address into the jitcode and guard against future
-         * reallocation of the global object's slots.
-         */
-        RootedId id(cx, NameToId(name));
-        Shape *shape = globalObj->nativeLookup(cx, id);
-        if (shape && shape->hasDefaultGetter() && shape->hasSlot()) {
-            HeapSlot *value = &globalObj->getSlotRef(shape->slot());
-            if (!value->isUndefined() && !propertyTypes->isOwnProperty(cx, globalType, true)) {
-                if (!watchGlobalReallocation())
-                    return false;
-                RegisterID reg = frame.allocReg();
-                masm.move(ImmPtr(value), reg);
-
-                BarrierState barrier = pushAddressMaybeBarrier(Address(reg), type, true);
-                finishBarrier(barrier, REJOIN_GETTER, 0);
-                return true;
-            }
-        }
-    }
-
-#if defined JS_MONOIC
-    jsop_bindgname();
-
-    FrameEntry *fe = frame.peek(-1);
-    JS_ASSERT(fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT);
-
-    GetGlobalNameICInfo ic;
-    RESERVE_IC_SPACE(masm);
-    RegisterID objReg;
-    Jump shapeGuard;
-
-    ic.fastPathStart = masm.label();
-    if (fe->isConstant()) {
-        JSObject *obj = &fe->getValue().toObject();
-        frame.pop();
-        JS_ASSERT(obj->isNative());
-
-        objReg = frame.allocReg();
-
-        masm.loadPtrFromImm(obj->addressOfShape(), objReg);
-        shapeGuard = masm.branchPtrWithPatch(Assembler::NotEqual, objReg,
-                                             ic.shape, ImmPtr(NULL));
-        masm.move(ImmPtr(obj), objReg);
-    } else {
-        objReg = frame.ownRegForData(fe);
-        frame.pop();
-        RegisterID reg = frame.allocReg();
-
-        masm.loadShape(objReg, reg);
-        shapeGuard = masm.branchPtrWithPatch(Assembler::NotEqual, reg,
-                                             ic.shape, ImmPtr(NULL));
-        frame.freeReg(reg);
-    }
-    stubcc.linkExit(shapeGuard, Uses(0));
-
-    stubcc.leave();
-    passMICAddress(ic);
-    ic.slowPathCall = OOL_STUBCALL(ic::GetGlobalName, REJOIN_GETTER);
-
-    CHECK_IC_SPACE();
-
-    testPushedType(REJOIN_GETTER, 0);
-
-    /* Garbage value. */
-    uint32_t slot = 1 << 24;
-
-    masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
-    Address address(objReg, slot);
-
-    /* Allocate any register other than objReg. */
-    RegisterID treg = frame.allocReg();
-    /* After dreg is loaded, it's safe to clobber objReg. */
-    RegisterID dreg = objReg;
-
-    ic.load = masm.loadValueWithAddressOffsetPatch(address, treg, dreg);
-
-    frame.pushRegs(treg, dreg, type);
-
-    /*
-     * Note: no undefined check is needed for GNAME opcodes. These were not
-     * declared with 'var', so cannot be undefined without triggering an error
-     * or having been a pre-existing global whose value is undefined (which
-     * type inference will know about).
-     */
-    BarrierState barrier = testBarrier(treg, dreg);
-
-    stubcc.rejoin(Changes(1));
-
-    getGlobalNames.append(ic);
-    finishBarrier(barrier, REJOIN_GETTER, 0);
-#else
-    jsop_getgname_slow(index);
-#endif
-    return true;
-}
-
-void
-mjit::Compiler::jsop_setgname_slow(HandlePropertyName name)
-{
-    prepareStubCall(Uses(2));
-    masm.move(ImmPtr(name), Registers::ArgReg1);
-    INLINE_STUBCALL(stubs::SetName, REJOIN_FALLTHROUGH);
-    frame.popn(2);
-    pushSyncedEntry(0);
-}
-
-bool
-mjit::Compiler::jsop_setgname(HandlePropertyName name, bool popGuaranteed)
-{
-    if (monitored(PC)) {
-        if (script_ == outerScript)
-            monitoredBytecodes.append(PC - script_->code);
-
-        /* Global accesses are monitored only for a few names like __proto__. */
-        jsop_setgname_slow(name);
-        return true;
-    }
-
-    RootedId id(cx, NameToId(name));
-    types::TypeObject *globalType = NULL;
-    if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::IdToTypeId(id)) {
-        globalType = globalObj->getType(cx);
-        if (globalType && globalType->unknownProperties())
-            globalType = NULL;
-    }
-
-    if (globalType) {
-        /*
-         * Note: object branding is disabled when inference is enabled. With
-         * branding there is no way to ensure that a non-function property
-         * can't get a function later and cause the global object to become
-         * branded, requiring a shape change if it changes again.
-         */
-        types::HeapTypeSet *types = globalType->getProperty(cx, id, false);
-        if (!types)
-            return false;
-        RootedId id(cx, NameToId(name));
-        RootedShape shape(cx, globalObj->nativeLookup(cx, id));
-        if (shape && shape->hasDefaultSetter() &&
-            shape->writable() && shape->hasSlot() &&
-            !types->isOwnProperty(cx, globalType, true))
-        {
-            if (!watchGlobalReallocation())
-                return false;
-            HeapSlot *value = &globalObj->getSlotRef(shape->slot());
-            RegisterID reg = frame.allocReg();
-#ifdef JSGC_INCREMENTAL_MJ
-            /* Write barrier. */
-            if (cx->zone()->compileBarriers() && types->needsBarrier(cx)) {
-                stubcc.linkExit(masm.jump(), Uses(0));
-                stubcc.leave();
-                stubcc.masm.move(ImmPtr(value), Registers::ArgReg1);
-                OOL_STUBCALL(stubs::WriteBarrier, REJOIN_NONE);
-                stubcc.rejoin(Changes(0));
-            }
-#endif
-            masm.move(ImmPtr(value), reg);
-            frame.storeTo(frame.peek(-1), Address(reg), popGuaranteed);
-            frame.shimmy(1);
-            frame.freeReg(reg);
-            return true;
-        }
-    }
-
-#ifdef JSGC_INCREMENTAL_MJ
-    /* Write barrier. */
-    if (cx->zone()->compileBarriers()) {
-        jsop_setgname_slow(name);
-        return true;
-    }
-#endif
-
-#if defined JS_MONOIC
-    FrameEntry *objFe = frame.peek(-2);
-    FrameEntry *fe = frame.peek(-1);
-    JS_ASSERT_IF(objFe->isTypeKnown(), objFe->getKnownType() == JSVAL_TYPE_OBJECT);
-
-    if (!fe->isConstant() && fe->isType(JSVAL_TYPE_DOUBLE))
-        frame.forgetKnownDouble(fe);
-
-    SetGlobalNameICInfo ic;
-
-    frame.pinEntry(fe, ic.vr);
-    Jump shapeGuard;
-
-    RESERVE_IC_SPACE(masm);
-
-    ic.fastPathStart = masm.label();
-    if (objFe->isConstant()) {
-        JSObject *obj = &objFe->getValue().toObject();
-        JS_ASSERT(obj->isNative());
-
-        ic.objReg = frame.allocReg();
-        ic.shapeReg = ic.objReg;
-        ic.objConst = true;
-
-        masm.loadPtrFromImm(obj->addressOfShape(), ic.shapeReg);
-        shapeGuard = masm.branchPtrWithPatch(Assembler::NotEqual, ic.shapeReg,
-                                             ic.shape, ImmPtr(NULL));
-        masm.move(ImmPtr(obj), ic.objReg);
-    } else {
-        ic.objReg = frame.copyDataIntoReg(objFe);
-        ic.shapeReg = frame.allocReg();
-        ic.objConst = false;
-
-        masm.loadShape(ic.objReg, ic.shapeReg);
-        shapeGuard = masm.branchPtrWithPatch(Assembler::NotEqual, ic.shapeReg,
-                                             ic.shape, ImmPtr(NULL));
-        frame.freeReg(ic.shapeReg);
-    }
-    ic.shapeGuardJump = shapeGuard;
-    ic.slowPathStart = stubcc.linkExit(shapeGuard, Uses(2));
-
-    stubcc.leave();
-    passMICAddress(ic);
-    ic.slowPathCall = OOL_STUBCALL(ic::SetGlobalName, REJOIN_FALLTHROUGH);
-
-    /* Garbage value. */
-    uint32_t slot = 1 << 24;
-
-    masm.loadPtr(Address(ic.objReg, JSObject::offsetOfSlots()), ic.objReg);
-    Address address(ic.objReg, slot);
-
-    if (ic.vr.isConstant()) {
-        ic.store = masm.storeValueWithAddressOffsetPatch(ic.vr.value(), address);
-    } else if (ic.vr.isTypeKnown()) {
-        ic.store = masm.storeValueWithAddressOffsetPatch(ImmType(ic.vr.knownType()),
-                                                          ic.vr.dataReg(), address);
-    } else {
-        ic.store = masm.storeValueWithAddressOffsetPatch(ic.vr.typeReg(), ic.vr.dataReg(), address);
-    }
-
-    frame.freeReg(ic.objReg);
-    frame.unpinEntry(ic.vr);
-    frame.shimmy(1);
-
-    stubcc.rejoin(Changes(1));
-
-    ic.fastPathRejoin = masm.label();
-    setGlobalNames.append(ic);
-#else
-    jsop_setgname_slow(name);
-#endif
-    return true;
-}
-
-void
-mjit::Compiler::jsop_setelem_slow()
-{
-    prepareStubCall(Uses(3));
-    INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
-    frame.popn(3);
-    frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-}
-
-void
-mjit::Compiler::jsop_getelem_slow()
-{
-    prepareStubCall(Uses(2));
-    INLINE_STUBCALL(stubs::GetElem, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, -2, /* ool = */ false);
-    frame.popn(2);
-    pushSyncedEntry(0);
-}
-
-bool
-mjit::Compiler::jsop_instanceof()
-{
-    FrameEntry *lhs = frame.peek(-2);
-    FrameEntry *rhs = frame.peek(-1);
-
-    // The fast path applies only when both operands are objects.
-    if (rhs->isNotType(JSVAL_TYPE_OBJECT) || lhs->isNotType(JSVAL_TYPE_OBJECT)) {
-        stubcc.linkExit(masm.jump(), Uses(2));
-        frame.discardFe(lhs);
-        frame.discardFe(rhs);
-    }
-
-    MaybeJump firstSlow;
-    if (!rhs->isTypeKnown()) {
-        Jump j = frame.testObject(Assembler::NotEqual, rhs);
-        stubcc.linkExit(j, Uses(2));
-    }
-
-    frame.forgetMismatchedObject(lhs);
-    frame.forgetMismatchedObject(rhs);
-
-    RegisterID tmp = frame.allocReg();
-    RegisterID obj = frame.tempRegForData(rhs);
-
-    masm.loadPtr(Address(obj, JSObject::offsetOfType()), tmp);
-    Jump notFunction = masm.branchPtr(Assembler::NotEqual,
-                                      Address(tmp, offsetof(types::TypeObject, clasp)),
-                                      ImmPtr(&FunctionClass));
-
-    stubcc.linkExit(notFunction, Uses(2));
-
-    /* Test for bound functions. */
-    masm.loadBaseShape(obj, tmp);
-    Jump isBound = masm.branchTest32(Assembler::NonZero,
-                                     Address(tmp, BaseShape::offsetOfFlags()),
-                                     Imm32(BaseShape::BOUND_FUNCTION));
-    {
-        stubcc.linkExit(isBound, Uses(2));
-        stubcc.leave();
-        OOL_STUBCALL(stubs::InstanceOf, REJOIN_FALLTHROUGH);
-        firstSlow = stubcc.masm.jump();
-    }
-
-    frame.freeReg(tmp);
-
-    /* This is sadly necessary because the error case needs the object. */
-    frame.dup();
-
-    if (!jsop_getprop(cx->names().classPrototype, JSVAL_TYPE_UNKNOWN))
-        return false;
-
-    /* Primitive prototypes are invalid. */
-    rhs = frame.peek(-1);
-    Jump j = frame.testPrimitive(Assembler::Equal, rhs);
-    stubcc.linkExit(j, Uses(3));
-
-    /* Allocate registers up front, because of branchiness. */
-    obj = frame.copyDataIntoReg(lhs);
-    RegisterID proto = frame.copyDataIntoReg(rhs);
-    RegisterID temp = frame.allocReg();
-
-    MaybeJump isFalse;
-    if (!lhs->isTypeKnown())
-        isFalse = frame.testPrimitive(Assembler::Equal, lhs);
-
-    Label loop = masm.label();
-
-    /* Walk prototype chain, break out on NULL, a lazy proto (0x1), or a hit. */
-    masm.loadPtr(Address(obj, JSObject::offsetOfType()), obj);
-    masm.loadPtr(Address(obj, offsetof(types::TypeObject, proto)), obj);
-    Jump isLazy = masm.branch32(Assembler::Equal, obj, Imm32(1));
-    stubcc.linkExit(isLazy, Uses(2));
-    Jump isFalse2 = masm.branchTestPtr(Assembler::Zero, obj, obj);
-    Jump isTrue = masm.branchPtr(Assembler::NotEqual, obj, proto);
-    isTrue.linkTo(loop, &masm);
-    masm.move(Imm32(1), temp);
-    isTrue = masm.jump();
-
-    if (isFalse.isSet())
-        isFalse.getJump().linkTo(masm.label(), &masm);
-    isFalse2.linkTo(masm.label(), &masm);
-    masm.move(Imm32(0), temp);
-    isTrue.linkTo(masm.label(), &masm);
-
-    frame.freeReg(proto);
-    frame.freeReg(obj);
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::FastInstanceOf, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, temp);
-
-    if (firstSlow.isSet())
-        firstSlow.getJump().linkTo(stubcc.masm.label(), &stubcc.masm);
-    stubcc.rejoin(Changes(1));
-    return true;
-}
-
-void
-mjit::Compiler::emitEval(uint32_t argc)
-{
-    /* Check for interrupts on function call */
-    interruptCheckHelper();
-
-    frame.syncAndKill(Uses(argc + 2));
-    prepareStubCall(Uses(argc + 2));
-    masm.move(Imm32(argc), Registers::ArgReg1);
-    INLINE_STUBCALL(stubs::Eval, REJOIN_FALLTHROUGH);
-    frame.popn(argc + 2);
-    pushSyncedEntry(0);
-}
-
-Compiler::Jump
-Compiler::getNewObject(JSContext *cx, RegisterID result, JSObject *templateObject)
-{
-    rootedTemplates.append(templateObject);
-    return masm.getNewObject(cx, result, templateObject);
-}
-
-bool
-mjit::Compiler::jsop_newinit()
-{
-    bool isArray;
-    unsigned count = 0;
-    RootedObject baseobj(cx);
-    switch (*PC) {
-      case JSOP_NEWINIT:
-        isArray = (GET_UINT8(PC) == JSProto_Array);
-        break;
-      case JSOP_NEWARRAY:
-        isArray = true;
-        count = GET_UINT24(PC);
-        break;
-      case JSOP_NEWOBJECT:
-        /*
-         * Scripts with NEWOBJECT must be compileAndGo, but treat these like
-         * NEWINIT if the script's associated global is not known (or is not
-         * actually a global object). This should only happen in chrome code.
-         */
-        isArray = false;
-        baseobj = globalObj ? script_->getObject(GET_UINT32_INDEX(PC)) : NULL;
-        break;
-      default:
-        JS_NOT_REACHED("Bad op");
-        return false;
-    }
-
-    void *stub, *stubArg;
-    if (isArray) {
-        stub = JS_FUNC_TO_DATA_PTR(void *, stubs::NewInitArray);
-        stubArg = (void *) uintptr_t(count);
-    } else {
-        stub = JS_FUNC_TO_DATA_PTR(void *, stubs::NewInitObject);
-        stubArg = (void *) baseobj;
-    }
-
-    JSProtoKey key = isArray ? JSProto_Array : JSProto_Object;
-
-    /*
-     * Don't bake in types for non-compileAndGo scripts, or at initializers
-     * producing objects with singleton types.
-     */
-    RootedScript script(cx, script_);
-    RootedTypeObject type(cx);
-    if (globalObj && !types::UseNewTypeForInitializer(cx, script, PC, key)) {
-        type = types::TypeScript::InitObject(cx, script, PC, key);
-        if (!type)
-            return false;
-    }
-
-    size_t maxArraySlots =
-        gc::GetGCKindSlots(gc::FINALIZE_OBJECT_LAST) - ObjectElements::VALUES_PER_HEADER;
-
-    if (!cx->typeInferenceEnabled() ||
-        !type ||
-        (isArray && count > maxArraySlots) ||
-        (!isArray && !baseobj) ||
-        (!isArray && baseobj->hasDynamicSlots()))
-    {
-        prepareStubCall(Uses(0));
-        masm.storePtr(ImmPtr(type), FrameAddress(offsetof(VMFrame, scratch)));
-        masm.move(ImmPtr(stubArg), Registers::ArgReg1);
-        INLINE_STUBCALL(stub, REJOIN_FALLTHROUGH);
-        frame.pushSynced(knownPushedType(0));
-
-        frame.extra(frame.peek(-1)).initObject = baseobj;
-        return true;
-    }
-
-    JSObject *templateObject;
-    if (isArray) {
-        templateObject = NewDenseUnallocatedArray(cx, count);
-        types::StackTypeSet::DoubleConversion conversion =
-            script->analysis()->pushedTypes(PC, 0)->convertDoubleElements(cx);
-        if (templateObject && conversion == types::StackTypeSet::AlwaysConvertToDoubles)
-            templateObject->setShouldConvertDoubleElements();
-    } else {
-        templateObject = CopyInitializerObject(cx, baseobj);
-    }
-    if (!templateObject)
-        return false;
-    templateObject->setType(type);
-
-    RegisterID result = frame.allocReg();
-    Jump emptyFreeList = getNewObject(cx, result, templateObject);
-
-    stubcc.linkExit(emptyFreeList, Uses(0));
-    stubcc.leave();
-
-    stubcc.masm.storePtr(ImmPtr(type), FrameAddress(offsetof(VMFrame, scratch)));
-    stubcc.masm.move(ImmPtr(stubArg), Registers::ArgReg1);
-    OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-    frame.pushTypedPayload(knownPushedType(0), result);
-
-    stubcc.rejoin(Changes(1));
-
-    frame.extra(frame.peek(-1)).initObject = baseobj;
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_regexp()
-{
-    JSObject *obj = script_->getRegExp(GET_UINT32_INDEX(PC));
-    RegExpStatics *res = globalObj ? globalObj->getRegExpStatics() : NULL;
-
-    types::TypeObject *globalType;
-    if (globalObj) {
-        globalType = globalObj->getType(cx);
-        if (!globalType)
-            return false;
-    }
-    if (!globalObj ||
-        &obj->global() != globalObj ||
-        !cx->typeInferenceEnabled() ||
-        analysis->localsAliasStack() ||
-        types::HeapTypeSet::HasObjectFlags(cx, globalType, types::OBJECT_FLAG_REGEXP_FLAGS_SET))
-    {
-        prepareStubCall(Uses(0));
-        masm.move(ImmPtr(obj), Registers::ArgReg1);
-        INLINE_STUBCALL(stubs::RegExp, REJOIN_FALLTHROUGH);
-        frame.pushSynced(JSVAL_TYPE_OBJECT);
-        return true;
-    }
-
-    RegExpObject *reobj = &obj->asRegExp();
-
-    DebugOnly<uint32_t> origFlags = reobj->getFlags();
-    DebugOnly<uint32_t> staticsFlags = res->getFlags();
-    JS_ASSERT((origFlags & staticsFlags) == staticsFlags);
-
-    /*
-     * JS semantics require regular expression literals to create different
-     * objects every time they execute. We only need to do this cloning if the
-     * script could actually observe the effect of such cloning, by getting
-     * or setting properties on it. Particular RegExp and String natives take
-     * regular expressions as 'this' or an argument, and do not let that
-     * expression escape and be accessed by the script, so avoid cloning in
-     * these cases.
-     */
-    analyze::SSAUseChain *uses =
-        analysis->useChain(analyze::SSAValue::PushedValue(PC - script_->code, 0));
-    if (uses && uses->popped && !uses->next && !reobj->global() && !reobj->sticky()) {
-        jsbytecode *use = script_->code + uses->offset;
-        uint32_t which = uses->u.which;
-        if (JSOp(*use) == JSOP_CALLPROP) {
-            JSObject *callee = analysis->pushedTypes(use, 0)->getSingleton();
-            if (callee && callee->isFunction()) {
-                Native native = callee->toFunction()->maybeNative();
-                if (native == js::regexp_exec || native == js::regexp_test) {
-                    frame.push(ObjectValue(*obj));
-                    return true;
-                }
-            }
-        } else if (JSOp(*use) == JSOP_CALL && which == 0) {
-            uint32_t argc = GET_ARGC(use);
-            JSObject *callee = analysis->poppedTypes(use, argc + 1)->getSingleton();
-            if (callee && callee->isFunction() && argc >= 1 && which == argc - 1) {
-                Native native = callee->toFunction()->maybeNative();
-                if (native == js::str_match ||
-                    native == js::str_search ||
-                    native == js::str_replace ||
-                    native == js::str_split) {
-                    frame.push(ObjectValue(*obj));
-                    return true;
-                }
-            }
-        }
-    }
-
-    /*
-     * Force creation of the RegExpShared in the script's RegExpObject so that
-     * we grab it in the getNewObject template copy. A strong reference to the
-     * RegExpShared will be added when the jitcode is created. Any GC activity
-     * between now and construction of that jitcode could purge the shared
-     * info, but such activity will also abort compilation.
-     */
-    RegExpGuard g(cx);
-    if (!reobj->getShared(cx, &g))
-        return false;
-
-    rootedRegExps.append(g.re());
-
-    RegisterID result = frame.allocReg();
-    Jump emptyFreeList = getNewObject(cx, result, obj);
-
-    stubcc.linkExit(emptyFreeList, Uses(0));
-    stubcc.leave();
-
-    stubcc.masm.move(ImmPtr(obj), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::RegExp, REJOIN_FALLTHROUGH);
-
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, result);
-
-    stubcc.rejoin(Changes(1));
-    return true;
-}
-
-bool
-mjit::Compiler::startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget)
-{
-    JS_ASSERT(cx->typeInferenceEnabled() && script_ == outerScript);
-    JS_ASSERT(shouldStartLoop(head));
-
-    if (loop) {
-        /*
-         * Convert all loop registers in the outer loop into unassigned registers.
-         * We don't keep track of which registers the inner loop uses, so the only
-         * registers that can be carried in the outer loop must be mentioned before
-         * the inner loop starts.
-         */
-        loop->clearLoopRegisters();
-    }
-
-    LoopState *nloop = js_new<LoopState>(cx, &ssa, this, &frame);
-    if (!nloop || !nloop->init(head, entry, entryTarget)) {
-        js_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    nloop->outer = loop;
-    loop = nloop;
-    frame.setLoop(loop);
-
-    return true;
-}
-
-bool
-mjit::Compiler::finishLoop(jsbytecode *head)
-{
-    if (!cx->typeInferenceEnabled() || !bytecodeInChunk(head))
-        return true;
-
-    /*
-     * We're done processing the current loop. Every loop has exactly one backedge
-     * at the end ('continue' statements are forward jumps to the loop test),
-     * and after jumpAndRun'ing on that edge we can pop it from the frame.
-     */
-    JS_ASSERT(loop && loop->headOffset() == uint32_t(head - script_->code));
-
-    jsbytecode *entryTarget = script_->code + loop->entryOffset();
-
-    /*
-     * Fix up the jump entering the loop. We are doing this after all code has
-     * been emitted for the backedge, so that we are now in the loop's fallthrough
-     * (where we will emit the entry code).
-     */
-    Jump fallthrough = masm.jump();
-
-#ifdef DEBUG
-    if (IsJaegerSpewChannelActive(JSpew_Regalloc)) {
-        RegisterAllocation *alloc = analysis->getAllocation(head);
-        JaegerSpew(JSpew_Regalloc, "loop allocation at %u:", unsigned(head - script_->code));
-        frame.dumpAllocation(alloc);
-    }
-#endif
-
-    loop->entryJump().linkTo(masm.label(), &masm);
-
-    jsbytecode *oldPC = PC;
-
-    PC = entryTarget;
-    {
-        OOL_STUBCALL(stubs::MissedBoundsCheckEntry, REJOIN_RESUME);
-
-        if (loop->generatingInvariants()) {
-            /*
-             * To do the initial load of the invariants, jump to the invariant
-             * restore point after the call just emitted. :XXX: fix hackiness.
-             */
-            if (oomInVector)
-                return false;
-            Label label = callSites[callSites.length() - 1].loopJumpLabel;
-            stubcc.linkExitDirect(masm.jump(), label);
-        }
-        stubcc.crossJump(stubcc.masm.jump(), masm.label());
-    }
-    PC = oldPC;
-
-    frame.prepareForJump(entryTarget, masm, true);
-
-    if (!jumpInScript(masm.jump(), entryTarget))
-        return false;
-
-    PC = head;
-    if (!analysis->getCode(head).safePoint) {
-        /*
-         * Emit a stub into the OOL path which loads registers from a synced state
-         * and jumps to the loop head, for rejoining from the interpreter.
-         */
-        LoopEntry entry;
-        entry.pcOffset = head - script_->code;
-
-        OOL_STUBCALL(stubs::MissedBoundsCheckHead, REJOIN_RESUME);
-
-        if (loop->generatingInvariants()) {
-            if (oomInVector)
-                return false;
-            entry.label = callSites[callSites.length() - 1].loopJumpLabel;
-        } else {
-            entry.label = stubcc.masm.label();
-        }
-
-        /*
-         * The interpreter may store integers in slots we assume are doubles,
-         * make sure state is consistent before joining. Note that we don't
-         * need any handling for other safe points the interpreter can enter
-         * from, i.e. from switch and try blocks, as we don't assume double
-         * variables are coherent in such cases.
-         */
-        for (uint32_t slot = ArgSlot(0); slot < TotalSlots(script_); slot++) {
-            if (a->varTypes[slot].getTypeTag() == JSVAL_TYPE_DOUBLE) {
-                FrameEntry *fe = frame.getSlotEntry(slot);
-                stubcc.masm.ensureInMemoryDouble(frame.addressOf(fe));
-            }
-        }
-
-        /*
-         * Also watch for slots which we assume are doubles at the loop head,
-         * but are known to be int32s at this point.
-         */
-        const SlotValue *newv = analysis->newValues(head);
-        if (newv) {
-            while (newv->slot) {
-                if (newv->value.kind() == SSAValue::PHI &&
-                    newv->value.phiOffset() == uint32_t(head - script_->code) &&
-                    analysis->trackSlot(newv->slot))
-                {
-                    JS_ASSERT(newv->slot < TotalSlots(script_));
-                    types::StackTypeSet *targetTypes = analysis->getValueTypes(newv->value);
-                    if (targetTypes->getKnownTypeTag() == JSVAL_TYPE_DOUBLE) {
-                        FrameEntry *fe = frame.getSlotEntry(newv->slot);
-                        stubcc.masm.ensureInMemoryDouble(frame.addressOf(fe));
-                    }
-                }
-                newv++;
-            }
-        }
-
-        frame.prepareForJump(head, stubcc.masm, true);
-        if (!stubcc.jumpInScript(stubcc.masm.jump(), head))
-            return false;
-
-        loopEntries.append(entry);
-    }
-    PC = oldPC;
-
-    /* Write out loads and tests of loop invariants at all calls in the loop body. */
-    loop->flushLoop(stubcc);
-
-    LoopState *nloop = loop->outer;
-    js_delete(loop);
-    loop = nloop;
-    frame.setLoop(loop);
-
-    fallthrough.linkTo(masm.label(), &masm);
-
-    /*
-     * Clear all registers used for loop temporaries. In the case of loop
-     * nesting, we do not allocate temporaries for the outer loop.
-     */
-    frame.clearTemporaries();
-
-    return true;
-}
-
-/*
- * The state at the fast jump must reflect the frame's current state. If specified
- * the state at the slow jump must be fully synced.
- *
- * The 'trampoline' argument indicates whether a trampoline was emitted into
- * the OOL path loading some registers for the target. If this is the case,
- * the fast path jump was redirected to the stub code's initial label, and the
- * same must happen for any other fast paths for the target (i.e. paths from
- * inline caches).
- *
- * The 'fallthrough' argument indicates this is a jump emitted for a fallthrough
- * at the end of the compiled chunk. In this case the opcode may not be a
- * JOF_JUMP opcode, and the compiler should not watch for fusions.
- */
-bool
-mjit::Compiler::jumpAndRun(Jump j, jsbytecode *target, Jump *slow, bool *trampoline,
-                           bool fallthrough)
-{
-    if (trampoline)
-        *trampoline = false;
-
-    if (!a->parent && !bytecodeInChunk(target)) {
-        /*
-         * syncForBranch() must have ensured the stack is synced. Figure out
-         * the source of the jump, which may be the opcode after PC if two ops
-         * were fused for a branch.
-         */
-        OutgoingChunkEdge edge;
-        edge.source = PC - outerScript->code;
-        JSOp op = JSOp(*PC);
-        if (!fallthrough && !(js_CodeSpec[op].format & JOF_JUMP) && op != JSOP_TABLESWITCH)
-            edge.source += GetBytecodeLength(PC);
-        edge.target = target - outerScript->code;
-        edge.fastJump = j;
-        if (slow)
-            edge.slowJump = *slow;
-        chunkEdges.append(edge);
-        return true;
-    }
-
-    /*
-     * Unless we are coming from a branch which synced everything, syncForBranch
-     * must have been called and ensured an allocation at the target.
-     */
-    RegisterAllocation *lvtarget = NULL;
-    bool consistent = true;
-    if (cx->typeInferenceEnabled()) {
-        RegisterAllocation *&alloc = analysis->getAllocation(target);
-        if (!alloc) {
-            alloc = cx->analysisLifoAlloc().new_<RegisterAllocation>(false);
-            if (!alloc) {
-                js_ReportOutOfMemory(cx);
-                return false;
-            }
-        }
-        lvtarget = alloc;
-        consistent = frame.consistentRegisters(target);
-    }
-
-    if (!lvtarget || lvtarget->synced()) {
-        JS_ASSERT(consistent);
-        if (!jumpInScript(j, target))
-            return false;
-        if (slow && !stubcc.jumpInScript(*slow, target))
-            return false;
-    } else {
-        if (consistent) {
-            if (!jumpInScript(j, target))
-                return false;
-        } else {
-            /*
-             * Make a trampoline to issue remaining loads for the register
-             * state at target.
-             */
-            Label start = stubcc.masm.label();
-            stubcc.linkExitDirect(j, start);
-            frame.prepareForJump(target, stubcc.masm, false);
-            if (!stubcc.jumpInScript(stubcc.masm.jump(), target))
-                return false;
-            if (trampoline)
-                *trampoline = true;
-            if (pcLengths) {
-                /*
-                 * This is OOL code but will usually be executed, so track
-                 * it in the CODE_LENGTH for the opcode.
-                 */
-                uint32_t offset = ssa.frameLength(a->inlineIndex) + PC - script_->code;
-                size_t length = stubcc.masm.size() - stubcc.masm.distanceOf(start);
-                pcLengths[offset].codeLengthAugment += length;
-            }
-        }
-
-        if (slow) {
-            slow->linkTo(stubcc.masm.label(), &stubcc.masm);
-            frame.prepareForJump(target, stubcc.masm, true);
-            if (!stubcc.jumpInScript(stubcc.masm.jump(), target))
-                return false;
-        }
-    }
-
-    if (target < PC)
-        return finishLoop(target);
-    return true;
-}
-
-void
-mjit::Compiler::enterBlock(StaticBlockObject *block)
-{
-    /* For now, don't bother doing anything for this opcode. */
-    frame.syncAndForgetEverything();
-    masm.move(ImmPtr(block), Registers::ArgReg1);
-    INLINE_STUBCALL(stubs::EnterBlock, REJOIN_FALLTHROUGH);
-    if (*PC == JSOP_ENTERBLOCK)
-        frame.enterBlock(StackDefs(script_, PC));
-}
-
-void
-mjit::Compiler::leaveBlock()
-{
-    /*
-     * Note: After bug 535912, we can pass the block obj directly, inline
-     * PutBlockObject, and do away with the muckiness in PutBlockObject.
-     */
-    uint32_t n = StackUses(script_, PC);
-    prepareStubCall(Uses(n));
-    INLINE_STUBCALL(stubs::LeaveBlock, REJOIN_NONE);
-    frame.leaveBlock(n);
-}
-
-// Creates the new object expected for constructors, and places it in |thisv|.
-// It is broken down into the following operations:
-//   CALLEE
-//   GETPROP "prototype"
-//   IFPRIMTOP:
-//       NULL
-//   call CreateThisFromFunctionWithProto(...)
-//
-bool
-mjit::Compiler::constructThis()
-{
-    JS_ASSERT(isConstructing);
-
-    RootedFunction fun(cx, script_->function());
-
-    do {
-        if (!cx->typeInferenceEnabled() ||
-            !fun->hasSingletonType())
-        {
-            break;
-        }
-
-        types::TypeObject *funType = fun->getType(cx);
-        if (!funType)
-            return false;
-        if (funType->unknownProperties())
-            break;
-
-        Rooted<jsid> id(cx, NameToId(cx->names().classPrototype));
-        types::HeapTypeSet *protoTypes = funType->getProperty(cx, HandleId(id), false);
-
-        JSObject *proto = protoTypes->getSingleton(cx);
-        if (!proto)
-            break;
-
-        /*
-         * Generate an inline path to create a 'this' object with the given
-         * prototype. Only do this if the type is actually known as a possible
-         * 'this' type of the script.
-         */
-        types::TypeObject *type = proto->getNewType(cx, &ObjectClass, fun);
-        if (!type)
-            return false;
-        if (!types::TypeScript::ThisTypes(script_)->hasType(types::Type::ObjectType(type)))
-            break;
-
-        JSObject *templateObject = CreateThisForFunctionWithProto(cx, fun, proto);
-        if (!templateObject)
-            return false;
-
-        /*
-         * The template incorporates a shape and/or fixed slots from any
-         * newScript on its type, so make sure recompilation is triggered
-         * should this information change later.
-         */
-        if (templateObject->type()->newScript)
-            types::HeapTypeSet::WatchObjectStateChange(cx, templateObject->type());
-
-        RegisterID result = frame.allocReg();
-        Jump emptyFreeList = getNewObject(cx, result, templateObject);
-
-        stubcc.linkExit(emptyFreeList, Uses(0));
-        stubcc.leave();
-
-        stubcc.masm.move(ImmPtr(proto), Registers::ArgReg1);
-        OOL_STUBCALL(stubs::CreateThis, REJOIN_THIS_CREATED);
-
-        frame.setThis(result);
-
-        stubcc.rejoin(Changes(1));
-        return true;
-    } while (false);
-
-    // Load the callee.
-    frame.pushCallee();
-
-    // Get callee.prototype.
-    if (!jsop_getprop(cx->names().classPrototype, JSVAL_TYPE_UNKNOWN, false, /* forPrototype = */ true))
-        return false;
-
-    // Reach into the proto Value and grab a register for its data.
-    FrameEntry *protoFe = frame.peek(-1);
-    RegisterID protoReg = frame.ownRegForData(protoFe);
-
-    // Now, get the type. If it's not an object, set protoReg to NULL.
-    JS_ASSERT_IF(protoFe->isTypeKnown(), protoFe->isType(JSVAL_TYPE_OBJECT));
-    if (!protoFe->isType(JSVAL_TYPE_OBJECT)) {
-        Jump isNotObject = frame.testObject(Assembler::NotEqual, protoFe);
-        stubcc.linkExitDirect(isNotObject, stubcc.masm.label());
-        stubcc.masm.move(ImmPtr(NULL), protoReg);
-        stubcc.crossJump(stubcc.masm.jump(), masm.label());
-    }
-
-    // Done with the protoFe.
-    frame.pop();
-
-    prepareStubCall(Uses(0));
-    if (protoReg != Registers::ArgReg1)
-        masm.move(protoReg, Registers::ArgReg1);
-    INLINE_STUBCALL(stubs::CreateThis, REJOIN_THIS_CREATED);
-    frame.freeReg(protoReg);
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_tableswitch(jsbytecode *pc)
-{
-#if defined JS_CPU_ARM
-    JS_NOT_REACHED("Implement jump(BaseIndex) for ARM");
-    return true;
-#else
-    jsbytecode *originalPC = pc;
-    DebugOnly<JSOp> op = JSOp(*originalPC);
-    JS_ASSERT(op == JSOP_TABLESWITCH);
-
-    uint32_t defaultTarget = GET_JUMP_OFFSET(pc);
-    pc += JUMP_OFFSET_LEN;
-
-    int32_t low = GET_JUMP_OFFSET(pc);
-    pc += JUMP_OFFSET_LEN;
-    int32_t high = GET_JUMP_OFFSET(pc);
-    pc += JUMP_OFFSET_LEN;
-    int numJumps = high + 1 - low;
-    JS_ASSERT(numJumps >= 0);
-
-    FrameEntry *fe = frame.peek(-1);
-    if (fe->isNotType(JSVAL_TYPE_INT32) || numJumps > 256) {
-        frame.syncAndForgetEverything();
-        masm.move(ImmPtr(originalPC), Registers::ArgReg1);
-
-        /* prepareStubCall() is not needed due to forgetEverything() */
-        INLINE_STUBCALL(stubs::TableSwitch, REJOIN_NONE);
-        frame.pop();
-        masm.jump(Registers::ReturnReg);
-        return true;
-    }
-
-    RegisterID dataReg;
-    if (fe->isConstant()) {
-        JS_ASSERT(fe->isType(JSVAL_TYPE_INT32));
-        dataReg = frame.allocReg();
-        masm.move(Imm32(fe->getValue().toInt32()), dataReg);
-    } else {
-        dataReg = frame.copyDataIntoReg(fe);
-    }
-
-    RegisterID reg = frame.allocReg();
-    frame.syncAndForgetEverything();
-
-    MaybeJump notInt;
-    if (!fe->isType(JSVAL_TYPE_INT32))
-        notInt = masm.testInt32(Assembler::NotEqual, frame.addressOf(fe));
-
-    JumpTable jt;
-    jt.offsetIndex = jumpTableEdges.length();
-    jt.label = masm.moveWithPatch(ImmPtr(NULL), reg);
-    jumpTables.append(jt);
-
-    for (int i = 0; i < numJumps; i++) {
-        uint32_t target = GET_JUMP_OFFSET(pc);
-        if (!target)
-            target = defaultTarget;
-        JumpTableEdge edge;
-        edge.source = originalPC - script_->code;
-        edge.target = (originalPC + target) - script_->code;
-        jumpTableEdges.append(edge);
-        pc += JUMP_OFFSET_LEN;
-    }
-    if (low != 0)
-        masm.sub32(Imm32(low), dataReg);
-    Jump defaultCase = masm.branch32(Assembler::AboveOrEqual, dataReg, Imm32(numJumps));
-    BaseIndex jumpTarget(reg, dataReg, Assembler::ScalePtr);
-    masm.jump(jumpTarget);
-
-    if (notInt.isSet()) {
-        stubcc.linkExitDirect(notInt.get(), stubcc.masm.label());
-        stubcc.leave();
-        stubcc.masm.move(ImmPtr(originalPC), Registers::ArgReg1);
-        OOL_STUBCALL(stubs::TableSwitch, REJOIN_NONE);
-        stubcc.masm.jump(Registers::ReturnReg);
-    }
-    frame.pop();
-    return jumpAndRun(defaultCase, originalPC + defaultTarget);
-#endif
-}
-
-void
-mjit::Compiler::jsop_toid()
-{
-    /* Leave integers alone, stub everything else. */
-    FrameEntry *top = frame.peek(-1);
-
-    if (top->isType(JSVAL_TYPE_INT32))
-        return;
-
-    if (top->isNotType(JSVAL_TYPE_INT32)) {
-        prepareStubCall(Uses(2));
-        INLINE_STUBCALL(stubs::ToId, REJOIN_FALLTHROUGH);
-        frame.pop();
-        pushSyncedEntry(0);
-        return;
-    }
-
-    frame.syncAt(-1);
-
-    Jump j = frame.testInt32(Assembler::NotEqual, top);
-    stubcc.linkExit(j, Uses(2));
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::ToId, REJOIN_FALLTHROUGH);
-
-    frame.pop();
-    pushSyncedEntry(0);
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_in()
-{
-    FrameEntry *obj = frame.peek(-1);
-    FrameEntry *id = frame.peek(-2);
-
-    if (cx->typeInferenceEnabled() && id->isType(JSVAL_TYPE_INT32)) {
-        types::StackTypeSet *types = analysis->poppedTypes(PC, 0);
-        bool isNegative = id->isConstant() && id->getValue().toInt32() < 0;
-
-        if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
-            types->getKnownClass() == &ArrayClass &&
-            !isNegative &&
-            !types->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES) &&
-            !types::ArrayPrototypeHasIndexedProperty(cx, outerScript))
-        {
-            frame.forgetMismatchedObject(obj);
-            bool isPacked = !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
-
-            if (!obj->isTypeKnown()) {
-                Jump guard = frame.testObject(Assembler::NotEqual, obj);
-                stubcc.linkExit(guard, Uses(2));
-            }
-
-            RegisterID dataReg = frame.copyDataIntoReg(obj);
-
-            Int32Key key = id->isConstant()
-                         ? Int32Key::FromConstant(id->getValue().toInt32())
-                         : Int32Key::FromRegister(frame.tempRegForData(id));
-
-            if (!id->isConstant()) {
-                Jump isNegative = masm.branch32(Assembler::LessThan, key.reg(), Imm32(0));
-                stubcc.linkExit(isNegative, Uses(2));
-            }
-
-            masm.loadPtr(Address(dataReg, JSObject::offsetOfElements()), dataReg);
-
-            // Guard on the array's initialized length.
-            Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                                      dataReg, key, Assembler::BelowOrEqual);
-
-            // Guard to make sure we don't have a hole. Skip it if the array is packed.
-            MaybeJump holeCheck;
-            if (!isPacked)
-                holeCheck = masm.guardElementNotHole(dataReg, key);
-
-            masm.move(Imm32(1), dataReg);
-            Jump done = masm.jump();
-
-            Label falseBranch = masm.label();
-            initlenGuard.linkTo(falseBranch, &masm);
-            if (!isPacked)
-                holeCheck.getJump().linkTo(falseBranch, &masm);
-            masm.move(Imm32(0), dataReg);
-
-            done.linkTo(masm.label(), &masm);
-
-            stubcc.leave();
-            OOL_STUBCALL_USES(stubs::In, REJOIN_PUSH_BOOLEAN, Uses(2));
-
-            frame.popn(2);
-            if (dataReg != Registers::ReturnReg)
-                stubcc.masm.move(Registers::ReturnReg, dataReg);
-
-            stubcc.rejoin(Changes(2));
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, dataReg);
-            return;
-        }
-    }
-
-    prepareStubCall(Uses(2));
-    INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
-    frame.popn(2);
-    frame.takeReg(Registers::ReturnReg);
-    frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
-}
-
-/*
- * For any locals or args which we know to be integers but are treated as
- * doubles by the type inference, convert to double. These will be assumed to be
- * doubles at control flow join points. This function must be called before
- * branching to another opcode.
- *
- * We can only carry entries as doubles when we can track all incoming edges to
- * a join point (no try blocks etc.) and when we can track all writes to the
- * local/arg (the slot does not escape) and ensure the Compiler representation
- * matches the inferred type for the variable's SSA value. These properties are
- * both ensured by analysis->trackSlot.
- */
-void
-mjit::Compiler::fixDoubleTypes(jsbytecode *target)
-{
-    if (!cx->typeInferenceEnabled())
-        return;
-
-    /*
-     * Fill fixedIntToDoubleEntries with all variables that are known to be an
-     * int here and a double at the branch target, and fixedDoubleToAnyEntries
-     * with all variables that are known to be a double here but not at the
-     * branch target.
-     *
-     * Per prepareInferenceTypes, the target state consists of the current
-     * state plus any phi nodes or other new values introduced at the target.
-     */
-    JS_ASSERT(fixedIntToDoubleEntries.empty());
-    JS_ASSERT(fixedDoubleToAnyEntries.empty());
-    const SlotValue *newv = analysis->newValues(target);
-    if (newv) {
-        while (newv->slot) {
-            if (newv->value.kind() != SSAValue::PHI ||
-                newv->value.phiOffset() != uint32_t(target - script_->code) ||
-                !analysis->trackSlot(newv->slot)) {
-                newv++;
-                continue;
-            }
-            JS_ASSERT(newv->slot < TotalSlots(script_));
-            types::StackTypeSet *targetTypes = analysis->getValueTypes(newv->value);
-            FrameEntry *fe = frame.getSlotEntry(newv->slot);
-            VarType &vt = a->varTypes[newv->slot];
-            JSValueType type = vt.getTypeTag();
-            if (targetTypes->getKnownTypeTag() == JSVAL_TYPE_DOUBLE) {
-                if (type == JSVAL_TYPE_INT32) {
-                    fixedIntToDoubleEntries.append(newv->slot);
-                    frame.ensureDouble(fe);
-                    frame.forgetLoopReg(fe);
-                } else if (type == JSVAL_TYPE_UNKNOWN) {
-                    /*
-                     * Unknown here but a double at the target. The type
-                     * set for the existing value must be empty, so this
-                     * code is doomed and we can just mark the value as
-                     * a double.
-                     */
-                    frame.ensureDouble(fe);
-                } else {
-                    JS_ASSERT(type == JSVAL_TYPE_DOUBLE);
-                }
-            } else if (type == JSVAL_TYPE_DOUBLE) {
-                fixedDoubleToAnyEntries.append(newv->slot);
-                frame.syncAndForgetFe(fe);
-                frame.forgetLoopReg(fe);
-            }
-            newv++;
-        }
-    }
-}
-
-bool
-mjit::Compiler::watchGlobalReallocation()
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-    if (hasGlobalReallocation)
-        return true;
-    types::TypeObject *globalType = globalObj->getType(cx);
-    if (!globalType)
-        return false;
-    types::HeapTypeSet::WatchObjectStateChange(cx, globalType);
-    hasGlobalReallocation = true;
-    return true;
-}
-
-void
-mjit::Compiler::updateVarType()
-{
-    if (!cx->typeInferenceEnabled())
-        return;
-
-    /*
-     * For any non-escaping variable written at the current opcode, update the
-     * associated type sets according to the written type, keeping the type set
-     * for each variable in sync with what the SSA analysis has determined
-     * (see prepareInferenceTypes).
-     */
-
-    types::StackTypeSet *types = pushedTypeSet(0);
-    uint32_t slot = GetBytecodeSlot(script_, PC);
-
-    if (analysis->trackSlot(slot)) {
-        VarType &vt = a->varTypes[slot];
-        vt.setTypes(types);
-
-        /*
-         * Variables whose type has been inferred as a double need to be
-         * maintained by the frame as a double. We might forget the exact
-         * representation used by the next call to fixDoubleTypes, fix it now.
-         */
-        if (vt.getTypeTag() == JSVAL_TYPE_DOUBLE)
-            frame.ensureDouble(frame.getSlotEntry(slot));
-    }
-}
-
-void
-mjit::Compiler::updateJoinVarTypes()
-{
-    if (!cx->typeInferenceEnabled())
-        return;
-
-    /* Update variable types for all new values at this bytecode. */
-    const SlotValue *newv = analysis->newValues(PC);
-    if (newv) {
-        while (newv->slot) {
-            if (newv->slot < TotalSlots(script_)) {
-                VarType &vt = a->varTypes[newv->slot];
-                JSValueType type = vt.getTypeTag();
-                vt.setTypes(analysis->getValueTypes(newv->value));
-                if (vt.getTypeTag() != type) {
-                    /*
-                     * If the known type of a variable changes (even if the
-                     * variable itself has not been reassigned) then we can't
-                     * carry a loop register for the var.
-                     */
-                    FrameEntry *fe = frame.getSlotEntry(newv->slot);
-                    frame.forgetLoopReg(fe);
-                }
-            }
-            newv++;
-        }
-    }
-}
-
-void
-mjit::Compiler::restoreVarType()
-{
-    if (!cx->typeInferenceEnabled())
-        return;
-
-    uint32_t slot = GetBytecodeSlot(script_, PC);
-
-    if (slot >= analyze::TotalSlots(script_))
-        return;
-
-    /*
-     * Restore the known type of a live local or argument. We ensure that types
-     * of tracked variables match their inferred type (as tracked in varTypes),
-     * but may have forgotten it due to a branch or syncAndForgetEverything.
-     */
-    JSValueType type = a->varTypes[slot].getTypeTag();
-    if (type != JSVAL_TYPE_UNKNOWN &&
-        (type != JSVAL_TYPE_DOUBLE || analysis->trackSlot(slot))) {
-        FrameEntry *fe = frame.getSlotEntry(slot);
-        JS_ASSERT_IF(fe->isTypeKnown(), fe->isType(type));
-        if (!fe->isTypeKnown())
-            frame.learnType(fe, type, false);
-    }
-}
-
-JSValueType
-mjit::Compiler::knownPushedType(uint32_t pushed)
-{
-    if (!cx->typeInferenceEnabled())
-        return JSVAL_TYPE_UNKNOWN;
-    types::StackTypeSet *types = analysis->pushedTypes(PC, pushed);
-    return types->getKnownTypeTag();
-}
-
-bool
-mjit::Compiler::mayPushUndefined(uint32_t pushed)
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-
-    /*
-     * This should only be used when the compiler is checking if it is OK to push
-     * undefined without going to a stub that can trigger recompilation.
-     * If this returns false and undefined subsequently becomes a feasible
-     * value pushed by the bytecode, recompilation will *NOT* be triggered.
-     */
-    types::TypeSet *types = analysis->pushedTypes(PC, pushed);
-    return types->hasType(types::Type::UndefinedType());
-}
-
-types::StackTypeSet *
-mjit::Compiler::pushedTypeSet(uint32_t pushed)
-{
-    if (!cx->typeInferenceEnabled())
-        return NULL;
-    return analysis->pushedTypes(PC, pushed);
-}
-
-bool
-mjit::Compiler::monitored(jsbytecode *pc)
-{
-    if (!cx->typeInferenceEnabled())
-        return false;
-    return analysis->getCode(pc).monitoredTypes;
-}
-
-bool
-mjit::Compiler::hasTypeBarriers(jsbytecode *pc)
-{
-    if (!cx->typeInferenceEnabled())
-        return false;
-
-    return analysis->typeBarriers(cx, pc) != NULL;
-}
-
-void
-mjit::Compiler::pushSyncedEntry(uint32_t pushed)
-{
-    frame.pushSynced(knownPushedType(pushed));
-}
-
-JSObject *
-mjit::Compiler::pushedSingleton(unsigned pushed)
-{
-    if (!cx->typeInferenceEnabled())
-        return NULL;
-
-    types::StackTypeSet *types = analysis->pushedTypes(PC, pushed);
-    return types->getSingleton();
-}
-
-/*
- * Barriers overview.
- *
- * After a property fetch finishes, we may need to do type checks on it to make
- * sure it matches the pushed type set for this bytecode. This can be either
- * because there is a type barrier at the bytecode, or because we cannot rule
- * out an undefined result. For such accesses, we push a register pair, and
- * then use those registers to check the fetched type matches the inferred
- * types for the pushed set. The flow here is tricky:
- *
- * frame.pushRegs(type, data, knownType);
- * --- Depending on knownType, the frame's representation for the pushed entry
- *     may not be a register pair anymore. knownType is based on the observed
- *     types that have been pushed here and may not actually match type/data.
- *     pushRegs must not clobber either register, for the test below.
- *
- * testBarrier(type, data)
- * --- Use the type/data regs and generate a single jump taken if the barrier
- *     has been violated.
- *
- * --- Rearrange stack, rejoin from stub paths. No code must be emitted into
- *     the inline path between testBarrier and finishBarrier. Since a stub path
- *     may be in progress we can't call finishBarrier before stubcc.rejoin,
- *     and since typeReg/dataReg may not be intact after the stub call rejoin
- *     (if knownType != JSVAL_TYPE_UNKNOWN) we can't testBarrier after calling
- *     stubcc.rejoin.
- *
- * finishBarrier()
- * --- Link the barrier jump to a new stub code path which updates the pushed
- *     types (possibly triggering recompilation). The frame has changed since
- *     pushRegs to reflect the final state of the op, which is OK as no inline
- *     code has been emitted since the barrier jump.
- */
-
-mjit::Compiler::BarrierState
-mjit::Compiler::pushAddressMaybeBarrier(Address address, JSValueType type, bool reuseBase,
-                                        bool testUndefined)
-{
-    if (!hasTypeBarriers(PC) && !testUndefined) {
-        frame.push(address, type, reuseBase);
-        return BarrierState();
-    }
-
-    RegisterID typeReg, dataReg;
-    frame.loadIntoRegisters(address, reuseBase, &typeReg, &dataReg);
-
-    frame.pushRegs(typeReg, dataReg, type);
-    return testBarrier(typeReg, dataReg, testUndefined);
-}
-
-MaybeJump
-mjit::Compiler::trySingleTypeTest(types::StackTypeSet *types, RegisterID typeReg)
-{
-    /*
-     * If a type set we have a barrier on is monomorphic, generate a single
-     * jump taken if a type register has a match. This doesn't handle type sets
-     * containing objects, as these require two jumps regardless (test for
-     * object, then test the type of the object).
-     */
-    MaybeJump res;
-
-    switch (types->getKnownTypeTag()) {
-      case JSVAL_TYPE_INT32:
-        res.setJump(masm.testInt32(Assembler::NotEqual, typeReg));
-        return res;
-
-      case JSVAL_TYPE_DOUBLE:
-        res.setJump(masm.testNumber(Assembler::NotEqual, typeReg));
-        return res;
-
-      case JSVAL_TYPE_BOOLEAN:
-        res.setJump(masm.testBoolean(Assembler::NotEqual, typeReg));
-        return res;
-
-      case JSVAL_TYPE_STRING:
-        res.setJump(masm.testString(Assembler::NotEqual, typeReg));
-        return res;
-
-      default:
-        return res;
-    }
-}
-
-JSC::MacroAssembler::Jump
-mjit::Compiler::addTypeTest(types::StackTypeSet *types, RegisterID typeReg, RegisterID dataReg)
-{
-    /*
-     * :TODO: It would be good to merge this with GenerateTypeCheck, but the
-     * two methods have a different format for the tested value (in registers
-     * vs. in memory).
-     */
-
-    Vector<Jump> matches(CompilerAllocPolicy(cx, *this));
-
-    if (types->hasType(types::Type::Int32Type()))
-        matches.append(masm.testInt32(Assembler::Equal, typeReg));
-
-    if (types->hasType(types::Type::DoubleType()))
-        matches.append(masm.testDouble(Assembler::Equal, typeReg));
-
-    if (types->hasType(types::Type::UndefinedType()))
-        matches.append(masm.testUndefined(Assembler::Equal, typeReg));
-
-    if (types->hasType(types::Type::BooleanType()))
-        matches.append(masm.testBoolean(Assembler::Equal, typeReg));
-
-    if (types->hasType(types::Type::StringType()))
-        matches.append(masm.testString(Assembler::Equal, typeReg));
-
-    if (types->hasType(types::Type::NullType()))
-        matches.append(masm.testNull(Assembler::Equal, typeReg));
-
-    unsigned count = 0;
-    if (types->hasType(types::Type::AnyObjectType()))
-        matches.append(masm.testObject(Assembler::Equal, typeReg));
-    else
-        count = types->getObjectCount();
-
-    if (count != 0) {
-        Jump notObject = masm.testObject(Assembler::NotEqual, typeReg);
-        Address typeAddress(dataReg, JSObject::offsetOfType());
-
-        for (unsigned i = 0; i < count; i++) {
-            if (JSObject *object = types->getSingleObject(i))
-                matches.append(masm.branchPtr(Assembler::Equal, dataReg, ImmPtr(object)));
-        }
-
-        for (unsigned i = 0; i < count; i++) {
-            if (types::TypeObject *object = types->getTypeObject(i))
-                matches.append(masm.branchPtr(Assembler::Equal, typeAddress, ImmPtr(object)));
-        }
-
-        notObject.linkTo(masm.label(), &masm);
-    }
-
-    Jump mismatch = masm.jump();
-
-    for (unsigned i = 0; i < matches.length(); i++)
-        matches[i].linkTo(masm.label(), &masm);
-
-    return mismatch;
-}
-
-mjit::Compiler::BarrierState
-mjit::Compiler::testBarrier(RegisterID typeReg, RegisterID dataReg,
-                            bool testUndefined, bool testReturn, bool force)
-{
-    BarrierState state;
-    state.typeReg = typeReg;
-    state.dataReg = dataReg;
-
-    if (!cx->typeInferenceEnabled() || !(js_CodeSpec[*PC].format & JOF_TYPESET))
-        return state;
-
-    types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script_, PC);
-    if (types->unknown()) {
-        /*
-         * If the result of this opcode is already unknown, there is no way for
-         * a type barrier to fail.
-         */
-        return state;
-    }
-
-    if (testReturn) {
-        JS_ASSERT(!testUndefined);
-        if (!analysis->getCode(PC).monitoredTypesReturn)
-            return state;
-    } else if (!hasTypeBarriers(PC) && !force) {
-        if (testUndefined && !types->hasType(types::Type::UndefinedType()))
-            state.jump.setJump(masm.testUndefined(Assembler::Equal, typeReg));
-        return state;
-    }
-
-    if (hasTypeBarriers(PC))
-        typeBarrierBytecodes.append(PC - script_->code);
-
-    /* Cannot have type barriers when the result of the operation is already unknown. */
-    JS_ASSERT(!types->unknown());
-
-    state.jump = trySingleTypeTest(types, typeReg);
-    if (!state.jump.isSet())
-        state.jump.setJump(addTypeTest(types, typeReg, dataReg));
-
-    return state;
-}
-
-void
-mjit::Compiler::finishBarrier(const BarrierState &barrier, RejoinState rejoin, uint32_t which)
-{
-    if (!barrier.jump.isSet())
-        return;
-
-    stubcc.linkExitDirect(barrier.jump.get(), stubcc.masm.label());
-
-    /*
-     * Before syncing, store the entry to sp[0]. (scanInlineCalls accounted for
-     * this when making sure there is enough froom for all frames). The known
-     * type in the frame may be wrong leading to an incorrect sync, and this
-     * sync may also clobber typeReg and/or dataReg.
-     */
-    frame.pushSynced(JSVAL_TYPE_UNKNOWN);
-    stubcc.masm.storeValueFromComponents(barrier.typeReg, barrier.dataReg,
-                                         frame.addressOf(frame.peek(-1)));
-    frame.pop();
-
-    stubcc.syncExit(Uses(0));
-    stubcc.leave();
-
-    stubcc.masm.move(ImmIntPtr(intptr_t(which)), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::TypeBarrierHelper, rejoin);
-    stubcc.rejoin(Changes(0));
-}
-
-void
-mjit::Compiler::testPushedType(RejoinState rejoin, int which, bool ool)
-{
-    if (!cx->typeInferenceEnabled() || !(js_CodeSpec[*PC].format & JOF_TYPESET))
-        return;
-
-    types::TypeSet *types = types::TypeScript::BytecodeTypes(script_, PC);
-    if (types->unknown())
-        return;
-
-    Assembler &masm = ool ? stubcc.masm : this->masm;
-
-    JS_ASSERT(which <= 0);
-    Address address = (which == 0) ? frame.addressOfTop() : frame.addressOf(frame.peek(which));
-
-    Vector<Jump> mismatches(cx);
-    if (!masm.generateTypeCheck(cx, address, types, &mismatches)) {
-        oomInVector = true;
-        return;
-    }
-
-    Jump j = masm.jump();
-
-    for (unsigned i = 0; i < mismatches.length(); i++)
-        mismatches[i].linkTo(masm.label(), &masm);
-
-    masm.move(Imm32(which), Registers::ArgReg1);
-    if (ool)
-        OOL_STUBCALL(stubs::StubTypeHelper, rejoin);
-    else
-        INLINE_STUBCALL(stubs::StubTypeHelper, rejoin);
-
-    j.linkTo(masm.label(), &masm);
-}
deleted file mode 100644
--- a/js/src/methodjit/Compiler.h
+++ /dev/null
@@ -1,825 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-#if !defined jsjaeger_compiler_h__ && defined JS_METHODJIT
-#define jsjaeger_compiler_h__
-
-#include "jsanalyze.h"
-#include "jscntxt.h"
-#include "MethodJIT.h"
-#include "CodeGenIncludes.h"
-#include "BaseCompiler.h"
-#include "StubCompiler.h"
-#include "MonoIC.h"
-#include "PolyIC.h"
-
-namespace js {
-namespace mjit {
-
-/*
- * Patch for storing call site and rejoin site return addresses at, for
- * redirecting the return address in InvariantFailure.
- */
-struct InvariantCodePatch {
-    bool hasPatch;
-    JSC::MacroAssembler::DataLabelPtr codePatch;
-    InvariantCodePatch() : hasPatch(false) {}
-};
-
-struct JSActiveFrame {
-    JSActiveFrame *parent;
-    jsbytecode *parentPC;
-    JSScript *script;
-
-    /*
-     * Index into inlineFrames or OUTER_FRAME, matches this frame's index in
-     * the cross script SSA.
-     */
-    uint32_t inlineIndex;
-
-    /* JIT code generation tracking state */
-    size_t mainCodeStart;
-    size_t stubCodeStart;
-    size_t mainCodeEnd;
-    size_t stubCodeEnd;
-    size_t inlinePCOffset;
-
-    JSActiveFrame();
-};
-
-class Compiler : public BaseCompiler
-{
-    friend class StubCompiler;
-
-    struct BranchPatch {
-        BranchPatch(const Jump &j, jsbytecode *pc, uint32_t inlineIndex)
-          : jump(j), pc(pc), inlineIndex(inlineIndex)
-        { }
-
-        Jump jump;
-        jsbytecode *pc;
-        uint32_t inlineIndex;
-    };
-
-#if defined JS_MONOIC
-    struct GlobalNameICInfo {
-        Label fastPathStart;
-        Call slowPathCall;
-        DataLabelPtr shape;
-        DataLabelPtr addrLabel;
-
-        void copyTo(ic::GlobalNameIC &to, JSC::LinkBuffer &full, JSC::LinkBuffer &stub) {
-            to.fastPathStart = full.locationOf(fastPathStart);
-
-            int offset = full.locationOf(shape) - to.fastPathStart;
-            to.shapeOffset = offset;
-            JS_ASSERT(to.shapeOffset == offset);
-
-            to.slowPathCall = stub.locationOf(slowPathCall);
-        }
-    };
-
-    struct GetGlobalNameICInfo : public GlobalNameICInfo {
-        Label load;
-    };
-
-    struct SetGlobalNameICInfo : public GlobalNameICInfo {
-        Label slowPathStart;
-        Label fastPathRejoin;
-        DataLabel32 store;
-        Jump shapeGuardJump;
-        ValueRemat vr;
-        RegisterID objReg;
-        RegisterID shapeReg;
-        bool objConst;
-    };
-
-    struct EqualityGenInfo {
-        DataLabelPtr addrLabel;
-        Label stubEntry;
-        Call stubCall;
-        BoolStub stub;
-        MaybeJump jumpToStub;
-        Label fallThrough;
-        jsbytecode *jumpTarget;
-        bool trampoline;
-        Label trampolineStart;
-        ValueRemat lvr, rvr;
-        Assembler::Condition cond;
-        JSC::MacroAssembler::RegisterID tempReg;
-    };
-
-    /* InlineFrameAssembler wants to see this. */
-  public:
-    struct CallGenInfo {
-        /*
-         * These members map to members in CallICInfo. See that structure for
-         * more comments.
-         */
-        uint32_t     callIndex;
-        Label        funGuardLabel;
-        DataLabelPtr funGuard;
-        Jump         funJump;
-        Jump         hotJump;
-        Call         oolCall;
-        Label        joinPoint;
-        Label        slowJoinPoint;
-        Label        slowPathStart;
-        Label        hotPathLabel;
-        Label        ionJoinPoint;
-        DataLabelPtr addrLabel1;
-        DataLabelPtr addrLabel2;
-        Jump         oolJump;
-        Label        icCall;
-        RegisterID   funObjReg;
-        FrameSize    frameSize;
-        bool         typeMonitored;
-    };
-
-  private:
-#endif
-
-    /*
-     * Writes of call return addresses which needs to be delayed until the final
-     * absolute address of the join point is known.
-     */
-    struct CallPatchInfo {
-        CallPatchInfo() : hasFastNcode(false), hasSlowNcode(false), joinSlow(false) {}
-        Label joinPoint;
-        DataLabelPtr fastNcodePatch;
-        DataLabelPtr slowNcodePatch;
-        bool hasFastNcode;
-        bool hasSlowNcode;
-        bool joinSlow;
-    };
-
-    struct BaseICInfo {
-        BaseICInfo() : canCallHook(false), forcedTypeBarrier(false)
-        { }
-        Label fastPathStart;
-        Label fastPathRejoin;
-        Label slowPathStart;
-        Call slowPathCall;
-        DataLabelPtr paramAddr;
-        bool canCallHook;
-        bool forcedTypeBarrier;
-
-        void copyTo(ic::BaseIC &to, JSC::LinkBuffer &full, JSC::LinkBuffer &stub) {
-            to.fastPathStart = full.locationOf(fastPathStart);
-            to.fastPathRejoin = full.locationOf(fastPathRejoin);
-            to.slowPathStart = stub.locationOf(slowPathStart);
-            to.slowPathCall = stub.locationOf(slowPathCall);
-            to.canCallHook = canCallHook;
-            to.forcedTypeBarrier = forcedTypeBarrier;
-        }
-    };
-
-    struct GetElementICInfo : public BaseICInfo {
-        RegisterID  typeReg;
-        RegisterID  objReg;
-        ValueRemat  id;
-        MaybeJump   typeGuard;
-        Jump        shapeGuard;
-    };
-
-    struct SetElementICInfo : public BaseICInfo {
-        RegisterID  objReg;
-        StateRemat  objRemat;
-        ValueRemat  vr;
-        Jump        capacityGuard;
-        Jump        shapeGuard;
-        Jump        holeGuard;
-        Int32Key    key;
-        uint32_t    volatileMask;
-    };
-
-    struct PICGenInfo : public BaseICInfo {
-        PICGenInfo(ic::PICInfo::Kind kind, jsbytecode *pc)
-          : kind(kind), pc(pc), typeMonitored(false)
-        { }
-        ic::PICInfo::Kind kind;
-        Label typeCheck;
-        RegisterID shapeReg;
-        RegisterID objReg;
-        RegisterID typeReg;
-        Label shapeGuard;
-        jsbytecode *pc;
-        PropertyName *name;
-        bool hasTypeCheck;
-        bool typeMonitored;
-        bool cached;
-        ValueRemat vr;
-        union {
-            ic::GetPropLabels getPropLabels_;
-            ic::SetPropLabels setPropLabels_;
-            ic::BindNameLabels bindNameLabels_;
-            ic::ScopeNameLabels scopeNameLabels_;
-        };
-
-        ic::GetPropLabels &getPropLabels() {
-            JS_ASSERT(kind == ic::PICInfo::GET);
-            return getPropLabels_;
-        }
-        ic::SetPropLabels &setPropLabels() {
-            JS_ASSERT(kind == ic::PICInfo::SET);
-            return setPropLabels_;
-        }
-        ic::BindNameLabels &bindNameLabels() {
-            JS_ASSERT(kind == ic::PICInfo::BIND);
-            return bindNameLabels_;
-        }
-        ic::ScopeNameLabels &scopeNameLabels() {
-            JS_ASSERT(kind == ic::PICInfo::NAME ||
-                      kind == ic::PICInfo::XNAME);
-            return scopeNameLabels_;
-        }
-
-        void copySimpleMembersTo(ic::PICInfo &ic) {
-            ic.kind = kind;
-            ic.shapeReg = shapeReg;
-            ic.objReg = objReg;
-            ic.name = name;
-            if (ic.isSet()) {
-                ic.u.vr = vr;
-            } else if (ic.isGet()) {
-                ic.u.get.typeReg = typeReg;
-                ic.u.get.hasTypeCheck = hasTypeCheck;
-            }
-            ic.typeMonitored = typeMonitored;
-            ic.cached = cached;
-            if (ic.isGet())
-                ic.setLabels(getPropLabels());
-            else if (ic.isSet())
-                ic.setLabels(setPropLabels());
-            else if (ic.isBind())
-                ic.setLabels(bindNameLabels());
-            else if (ic.isScopeName())
-                ic.setLabels(scopeNameLabels());
-        }
-
-    };
-
-    struct Defs {
-        Defs(uint32_t ndefs)
-          : ndefs(ndefs)
-        { }
-        uint32_t ndefs;
-    };
-
-    struct InternalCallSite {
-        uint32_t returnOffset;
-        DataLabelPtr inlinePatch;
-        uint32_t inlineIndex;
-        jsbytecode *inlinepc;
-        RejoinState rejoin;
-        bool ool;
-        Label loopJumpLabel;
-        InvariantCodePatch loopPatch;
-
-        InternalCallSite(uint32_t returnOffset,
-                         uint32_t inlineIndex, jsbytecode *inlinepc,
-                         RejoinState rejoin, bool ool)
-          : returnOffset(returnOffset),
-            inlineIndex(inlineIndex), inlinepc(inlinepc),
-            rejoin(rejoin), ool(ool)
-        { }
-    };
-
-    struct InternalCompileTrigger {
-        jsbytecode *pc;
-        Jump inlineJump;
-        Label stubLabel;
-    };
-
-    struct DoublePatch {
-        double d;
-        DataLabelPtr label;
-        bool ool;
-    };
-
-    struct JumpTable {
-        DataLabelPtr label;
-        size_t offsetIndex;
-    };
-
-    struct JumpTableEdge {
-        uint32_t source;
-        uint32_t target;
-    };
-
-    struct ChunkJumpTableEdge {
-        JumpTableEdge edge;
-        void **jumpTableEntry;
-    };
-
-    struct LoopEntry {
-        uint32_t pcOffset;
-        Label label;
-    };
-
-    /*
-     * Information about the current type of an argument or local in the
-     * script. The known type tag of these types is cached when possible to
-     * avoid generating duplicate dependency constraints.
-     */
-    class VarType {
-        JSValueType type;
-        types::StackTypeSet *types;
-
-      public:
-        void setTypes(types::StackTypeSet *types) {
-            this->types = types;
-            this->type = JSVAL_TYPE_MISSING;
-        }
-
-        types::TypeSet *getTypes() { return types; }
-
-        JSValueType getTypeTag() {
-            if (type == JSVAL_TYPE_MISSING)
-                type = types ? types->getKnownTypeTag() : JSVAL_TYPE_UNKNOWN;
-            return type;
-        }
-    };
-
-    struct OutgoingChunkEdge {
-        uint32_t source;
-        uint32_t target;
-
-#ifdef JS_CPU_X64
-        Label sourceTrampoline;
-#endif
-
-        Jump fastJump;
-        MaybeJump slowJump;
-    };
-
-    struct SlotType
-    {
-        uint32_t slot;
-        VarType vt;
-        SlotType(uint32_t slot, VarType vt) : slot(slot), vt(vt) {}
-    };
-
-    RootedScript outerScript;
-    unsigned chunkIndex;
-    bool isConstructing;
-    ChunkDescriptor outerChunk;
-
-    /* SSA information for the outer script and all frames we will be inlining. */
-    analyze::CrossScriptSSA ssa;
-
-    Rooted<GlobalObject*> globalObj;
-    const HeapSlot *globalSlots;  /* Original slots pointer. */
-
-    MJITInstrumentation sps;
-    Assembler masm;
-    FrameState frame;
-
-    /*
-     * State for the current stack frame, and links to its parents going up to
-     * the outermost script.
-     */
-
-public:
-    struct ActiveFrame : public JSActiveFrame {
-        Label *jumpMap;
-
-        /* Current types for non-escaping vars in the script. */
-        VarType *varTypes;
-
-        /* State for managing return from inlined frames. */
-        bool needReturnValue;          /* Return value will be used. */
-        bool syncReturnValue;          /* Return value should be fully synced. */
-        bool returnValueDouble;        /* Return value should be a double. */
-        bool returnSet;                /* Whether returnRegister is valid. */
-        AnyRegisterID returnRegister;  /* Register holding return value. */
-        const FrameEntry *returnEntry; /* Entry copied by return value. */
-        Vector<Jump, 4, CompilerAllocPolicy> *returnJumps;
-
-        /*
-         * Snapshot of the heap state to use after the call, in case
-         * there are multiple return paths the inlined frame could take.
-         */
-        RegisterAllocation *exitState;
-
-        ActiveFrame(JSContext *cx);
-        ~ActiveFrame();
-    };
-
-private:
-    ActiveFrame *a;
-    ActiveFrame *outer;
-
-    RootedScript script_;
-    analyze::ScriptAnalysis *analysis;
-    jsbytecode *PC;
-
-    LoopState *loop;
-
-    /* State spanning all stack frames. */
-
-    js::Vector<ActiveFrame*, 4, CompilerAllocPolicy> inlineFrames;
-    js::Vector<BranchPatch, 64, CompilerAllocPolicy> branchPatches;
-#if defined JS_MONOIC
-    js::Vector<GetGlobalNameICInfo, 16, CompilerAllocPolicy> getGlobalNames;
-    js::Vector<SetGlobalNameICInfo, 16, CompilerAllocPolicy> setGlobalNames;
-    js::Vector<CallGenInfo, 64, CompilerAllocPolicy> callICs;
-    js::Vector<EqualityGenInfo, 64, CompilerAllocPolicy> equalityICs;
-#endif
-#if defined JS_POLYIC
-    js::Vector<PICGenInfo, 16, CompilerAllocPolicy> pics;
-    js::Vector<GetElementICInfo, 16, CompilerAllocPolicy> getElemICs;
-    js::Vector<SetElementICInfo, 16, CompilerAllocPolicy> setElemICs;
-#endif
-    js::Vector<CallPatchInfo, 64, CompilerAllocPolicy> callPatches;
-    js::Vector<InternalCallSite, 64, CompilerAllocPolicy> callSites;
-    js::Vector<InternalCompileTrigger, 4, CompilerAllocPolicy> compileTriggers;
-    js::Vector<DoublePatch, 16, CompilerAllocPolicy> doubleList;
-    js::Vector<JSObject*, 0, CompilerAllocPolicy> rootedTemplates;
-    js::Vector<RegExpShared*, 0, CompilerAllocPolicy> rootedRegExps;
-    js::Vector<uint32_t> monitoredBytecodes;
-    js::Vector<uint32_t> typeBarrierBytecodes;
-    js::Vector<uint32_t> fixedIntToDoubleEntries;
-    js::Vector<uint32_t> fixedDoubleToAnyEntries;
-    js::Vector<JumpTable, 16> jumpTables;
-    js::Vector<JumpTableEdge, 16> jumpTableEdges;
-    js::Vector<LoopEntry, 16> loopEntries;
-    js::Vector<OutgoingChunkEdge, 16> chunkEdges;
-    StubCompiler stubcc;
-    Label fastEntryLabel;
-    Label arityLabel;
-    Label argsCheckLabel;
-#ifdef JS_MONOIC
-    Label argsCheckStub;
-    Label argsCheckFallthrough;
-    Jump argsCheckJump;
-#endif
-    bool debugMode_;
-    bool inlining_;
-    bool hasGlobalReallocation;
-    bool oomInVector;       // True if we have OOM'd appending to a vector.
-    bool overflowICSpace;   // True if we added a constant pool in a reserved space.
-    uint64_t gcNumber;
-    PCLengthEntry *pcLengths;
-
-    Compiler *thisFromCtor() { return this; }
-
-    friend class CompilerAllocPolicy;
-  public:
-    Compiler(JSContext *cx, JSScript *outerScript, unsigned chunkIndex, bool isConstructing);
-    ~Compiler();
-
-    CompileStatus compile();
-
-    Label getLabel() { return masm.label(); }
-    bool knownJump(jsbytecode *pc);
-    Label labelOf(jsbytecode *target, uint32_t inlineIndex);
-    void addCallSite(const InternalCallSite &callSite);
-    void addReturnSite();
-    void inlineStubCall(void *stub, RejoinState rejoin, Uses uses);
-
-    bool debugMode() { return debugMode_; }
-    bool inlining() { return inlining_; }
-    bool constructing() { return isConstructing; }
-
-    jsbytecode *outerPC() {
-        if (a == outer)
-            return PC;
-        ActiveFrame *scan = a;
-        while (scan && scan->parent != outer)
-            scan = static_cast<ActiveFrame *>(scan->parent);
-        return scan->parentPC;
-    }
-
-    JITScript *outerJIT() {
-        return outerScript->getJIT(isConstructing, cx->zone()->compileBarriers());
-    }
-
-    ChunkDescriptor &outerChunkRef() {
-        return outerJIT()->chunkDescriptor(chunkIndex);
-    }
-
-    bool bytecodeInChunk(jsbytecode *pc) {
-        return (unsigned(pc - outerScript->code) >= outerChunk.begin)
-            && (unsigned(pc - outerScript->code) < outerChunk.end);
-    }
-
-    jsbytecode *inlinePC() { return PC; }
-    uint32_t inlineIndex() { return a->inlineIndex; }
-
-    Assembler &getAssembler(bool ool) { return ool ? stubcc.masm : masm; }
-
-    InvariantCodePatch *getInvariantPatch(unsigned index) {
-        return &callSites[index].loopPatch;
-    }
-    jsbytecode *getInvariantPC(unsigned index) {
-        return callSites[index].inlinepc;
-    }
-
-    bool activeFrameHasMultipleExits() {
-        ActiveFrame *na = a;
-        while (na->parent) {
-            if (na->exitState)
-                return true;
-            na = static_cast<ActiveFrame *>(na->parent);
-        }
-        return false;
-    }
-
-  private:
-    CompileStatus performCompilation();
-    CompileStatus generatePrologue();
-    CompileStatus generateMethod();
-    CompileStatus generateEpilogue();
-    CompileStatus finishThisUp();
-    CompileStatus pushActiveFrame(JSScript *script, uint32_t argc);
-    void popActiveFrame();
-    void updatePCCounts(jsbytecode *pc, bool *updated);
-    void updatePCTypes(jsbytecode *pc, FrameEntry *fe);
-    void updateArithCounts(jsbytecode *pc, FrameEntry *fe,
-                             JSValueType firstUseType, JSValueType secondUseType);
-    void updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
-    void bumpPropCount(jsbytecode *pc, int count);
-
-    /* Analysis helpers. */
-    CompileStatus prepareInferenceTypes(JSScript *script, ActiveFrame *a);
-    void ensureDoubleArguments();
-    void markUndefinedLocal(uint32_t offset, uint32_t i);
-    void markUndefinedLocals();
-    void fixDoubleTypes(jsbytecode *target);
-    bool watchGlobalReallocation();
-    void updateVarType();
-    void updateJoinVarTypes();
-    void restoreVarType();
-    JSValueType knownPushedType(uint32_t pushed);
-    bool mayPushUndefined(uint32_t pushed);
-    types::StackTypeSet *pushedTypeSet(uint32_t which);
-    bool monitored(jsbytecode *pc);
-    bool hasTypeBarriers(jsbytecode *pc);
-    bool testSingletonProperty(HandleObject obj, HandleId id);
-    bool testSingletonPropertyTypes(FrameEntry *top, HandleId id, bool *testObject);
-    CompileStatus addInlineFrame(HandleScript script, uint32_t depth, uint32_t parent, jsbytecode *parentpc);
-    CompileStatus scanInlineCalls(uint32_t index, uint32_t depth);
-    CompileStatus checkAnalysis(HandleScript script);
-
-    struct BarrierState {
-        MaybeJump jump;
-        RegisterID typeReg;
-        RegisterID dataReg;
-    };
-
-    MaybeJump trySingleTypeTest(types::StackTypeSet *types, RegisterID typeReg);
-    Jump addTypeTest(types::StackTypeSet *types, RegisterID typeReg, RegisterID dataReg);
-    BarrierState pushAddressMaybeBarrier(Address address, JSValueType type, bool reuseBase,
-                                         bool testUndefined = false);
-    BarrierState testBarrier(RegisterID typeReg, RegisterID dataReg,
-                             bool testUndefined = false, bool testReturn = false,
-                             bool force = false);
-    void finishBarrier(const BarrierState &barrier, RejoinState rejoin, uint32_t which);
-
-    void testPushedType(RejoinState rejoin, int which, bool ool = true);
-
-    /* Non-emitting helpers. */
-    void pushSyncedEntry(uint32_t pushed);
-    bool jumpInScript(Jump j, jsbytecode *pc);
-    bool compareTwoValues(JSContext *cx, JSOp op, const Value &lhs, const Value &rhs);
-
-    /* Emitting helpers. */
-    bool constantFoldBranch(jsbytecode *target, bool taken);
-    bool emitStubCmpOp(BoolStub stub, jsbytecode *target, JSOp fused);
-    bool iter(unsigned flags);
-    void iterNext();
-    bool iterMore(jsbytecode *target);
-    void iterEnd();
-    MaybeJump loadDouble(FrameEntry *fe, FPRegisterID *fpReg, bool *allocated);
-#ifdef JS_POLYIC
-    void passICAddress(BaseICInfo *ic);
-#endif
-#ifdef JS_MONOIC
-    void passMICAddress(GlobalNameICInfo &mic);
-#endif
-    bool constructThis();
-    void ensureDouble(FrameEntry *fe);
-
-    /*
-     * Ensure fe is an integer, truncating from double if necessary, or jump to
-     * the slow path per uses.
-     */
-    void ensureInteger(FrameEntry *fe, Uses uses);
-
-    /* Convert fe from a double to integer (per ValueToECMAInt32) in place. */
-    void truncateDoubleToInt32(FrameEntry *fe, Uses uses);
-
-    /*
-     * Try to convert a double fe to an integer, with no truncation performed,
-     * or jump to the slow path per uses.
-     */
-    void tryConvertInteger(FrameEntry *fe, Uses uses);
-
-    /* Opcode handlers. */
-    bool jumpAndRun(Jump j, jsbytecode *target,
-                    Jump *slow = NULL, bool *trampoline = NULL,
-                    bool fallthrough = false);
-    bool startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
-    bool finishLoop(jsbytecode *head);
-    inline bool shouldStartLoop(jsbytecode *head);
-    void jsop_bindname(HandlePropertyName name);
-    void jsop_setglobal(uint32_t index);
-    void jsop_getprop_slow(HandlePropertyName name, bool forPrototype = false);
-    void jsop_aliasedArg(unsigned i, bool get, bool poppedAfter = false);
-    void jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter = false);
-    void jsop_this();
-    void emitReturn(FrameEntry *fe);
-    void emitFinalReturn(Assembler &masm);
-    void loadReturnValue(Assembler *masm, FrameEntry *fe);
-    void emitReturnValue(Assembler *masm, FrameEntry *fe);
-    void emitInlineReturnValue(FrameEntry *fe);
-    void dispatchCall(VoidPtrStubUInt32 stub, uint32_t argc);
-    void interruptCheckHelper();
-    void ionCompileHelper();
-    void inliningCompileHelper();
-    CompileStatus methodEntryHelper();
-    CompileStatus profilingPushHelper();
-    void profilingPopHelper();
-    void emitUncachedCall(uint32_t argc, bool callingNew);
-    void checkCallApplySpeculation(uint32_t argc, FrameEntry *origCallee, FrameEntry *origThis,
-                                   MaybeRegisterID origCalleeType, RegisterID origCalleeData,
-                                   MaybeRegisterID origThisType, RegisterID origThisData,
-                                   Jump *uncachedCallSlowRejoin, CallPatchInfo *uncachedCallPatch);
-    bool inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &callFrameSize);
-    void fixPrimitiveReturn(Assembler *masm, FrameEntry *fe);
-    bool jsop_getgname(uint32_t index);
-    void jsop_getgname_slow(uint32_t index);
-    bool jsop_setgname(HandlePropertyName name, bool popGuaranteed);
-    void jsop_setgname_slow(HandlePropertyName name);
-    void jsop_bindgname();
-    void jsop_setelem_slow();
-    void jsop_getelem_slow();
-    bool jsop_getprop(HandlePropertyName name, JSValueType type,
-                      bool typeCheck = true, bool forPrototype = false);
-    bool jsop_getprop_dispatch(HandlePropertyName name);
-    bool jsop_setprop(HandlePropertyName name, bool popGuaranteed);
-    void jsop_setprop_slow(HandlePropertyName name);
-    bool jsop_instanceof();
-    bool jsop_intrinsic(HandlePropertyName name, JSValueType type);
-    void jsop_name(HandlePropertyName name, JSValueType type);
-    bool jsop_xname(HandlePropertyName name);
-    void enterBlock(StaticBlockObject *block);
-    void leaveBlock();
-    void emitEval(uint32_t argc);
-    bool jsop_tableswitch(jsbytecode *pc);
-    Jump getNewObject(JSContext *cx, RegisterID result, JSObject *templateObject);
-
-    /* Fast arithmetic. */
-    bool jsop_binary_slow(JSOp op, VoidStub stub, JSValueType type, FrameEntry *lhs, FrameEntry *rhs);
-    bool jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::TypeSet *typeSet);
-    void jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op, VoidStub stub,
-                          JSValueType type, bool cannotOverflow, bool ignoreOverflow);
-    void jsop_binary_full_simple(FrameEntry *fe, JSOp op, VoidStub stub,
-                                 JSValueType type);
-    void jsop_binary_double(FrameEntry *lhs, FrameEntry *rhs, JSOp op, VoidStub stub,
-                            JSValueType type);
-    void slowLoadConstantDouble(Assembler &masm, FrameEntry *fe,
-                                FPRegisterID fpreg);
-    void maybeJumpIfNotInt32(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
-                             MaybeRegisterID &mreg);
-    void maybeJumpIfNotDouble(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
-                              MaybeRegisterID &mreg);
-    bool jsop_relational(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
-    bool jsop_relational_full(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
-    bool jsop_relational_double(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
-    bool jsop_relational_int(JSOp op, jsbytecode *target, JSOp fused);
-
-    void emitLeftDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
-                            MaybeJump &lhsNotDouble, MaybeJump &rhsNotNumber,
-                            MaybeJump &lhsUnknownDone);
-    void emitRightDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
-                             MaybeJump &rhsNotNumber2);
-    bool tryBinaryConstantFold(JSContext *cx, FrameState &frame, JSOp op,
-                               FrameEntry *lhs, FrameEntry *rhs, Value *vp);
-
-    /* Fast opcodes. */
-    void jsop_bitop(JSOp op);
-    bool jsop_mod();
-    void jsop_neg();
-    void jsop_bitnot();
-    void jsop_not();
-    void jsop_typeof();
-    bool booleanJumpScript(JSOp op, jsbytecode *target);
-    bool jsop_ifneq(JSOp op, jsbytecode *target);
-    bool jsop_andor(JSOp op, jsbytecode *target);
-    bool jsop_newinit();
-    bool jsop_regexp();
-    void jsop_initmethod();
-    void jsop_initprop();
-    void jsop_initelem_array();
-    void jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion);
-#ifdef JS_METHODJIT_TYPED_ARRAY
-    void jsop_setelem_typed(int atype);
-    void convertForTypedArray(int atype, ValueRemat *vr, bool *allocated);
-#endif
-    bool jsop_setelem(bool popGuaranteed);
-    bool jsop_getelem();
-    void jsop_getelem_dense(bool isPacked);
-    void jsop_getelem_args();
-#ifdef JS_METHODJIT_TYPED_ARRAY
-    bool jsop_getelem_typed(int atype);
-#endif
-    void jsop_toid();
-    bool isCacheableBaseAndIndex(FrameEntry *obj, FrameEntry *id);
-    void jsop_stricteq(JSOp op);
-    bool jsop_equality(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
-    CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused);
-    bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
-    void jsop_pos();
-    void jsop_in();
-
-    static inline Assembler::Condition
-    GetCompareCondition(JSOp op, JSOp fused)
-    {
-        bool ifeq = fused == JSOP_IFEQ;
-        switch (op) {
-          case JSOP_GT:
-            return ifeq ? Assembler::LessThanOrEqual : Assembler::GreaterThan;
-          case JSOP_GE:
-            return ifeq ? Assembler::LessThan : Assembler::GreaterThanOrEqual;
-          case JSOP_LT:
-            return ifeq ? Assembler::GreaterThanOrEqual : Assembler::LessThan;
-          case JSOP_LE:
-            return ifeq ? Assembler::GreaterThan : Assembler::LessThanOrEqual;
-          case JSOP_STRICTEQ:
-          case JSOP_EQ:
-            return ifeq ? Assembler::NotEqual : Assembler::Equal;
-          case JSOP_STRICTNE:
-          case JSOP_NE:
-            return ifeq ? Assembler::Equal : Assembler::NotEqual;
-          default:
-            JS_NOT_REACHED("unrecognized op");
-            return Assembler::Equal;
-        }
-    }
-
-    static inline Assembler::Condition
-    GetStubCompareCondition(JSOp fused)
-    {
-        return fused == JSOP_IFEQ ? Assembler::Zero : Assembler::NonZero;
-    }
-
-    /* Fast builtins. */
-    JSObject *pushedSingleton(unsigned pushed);
-    CompileStatus inlineNativeFunction(uint32_t argc, bool callingNew);
-    CompileStatus inlineScriptedFunction(uint32_t argc, bool callingNew);
-    CompileStatus compileMathAbsInt(FrameEntry *arg);
-    CompileStatus compileMathAbsDouble(FrameEntry *arg);
-    CompileStatus compileMathSqrt(FrameEntry *arg);
-    CompileStatus compileMathMinMaxDouble(FrameEntry *arg1, FrameEntry *arg2,
-                                          Assembler::DoubleCondition cond);
-    CompileStatus compileMathMinMaxInt(FrameEntry *arg1, FrameEntry *arg2,
-                                       Assembler::Condition cond);
-    CompileStatus compileMathPowSimple(FrameEntry *arg1, FrameEntry *arg2);
-    CompileStatus compileArrayPush(FrameEntry *thisv, FrameEntry *arg,
-                                   types::StackTypeSet::DoubleConversion conversion);
-    CompileStatus compileArrayConcat(types::TypeSet *thisTypes, types::TypeSet *argTypes,
-                                     FrameEntry *thisValue, FrameEntry *argValue);
-    CompileStatus compileArrayPopShift(FrameEntry *thisv, bool isPacked, bool isArrayPop);
-    CompileStatus compileArrayWithLength(uint32_t argc);
-    CompileStatus compileArrayWithArgs(uint32_t argc);
-
-    enum RoundingMode { Floor, Round };
-    CompileStatus compileRound(FrameEntry *arg, RoundingMode mode);
-
-    enum GetCharMode { GetChar, GetCharCode };
-    CompileStatus compileGetChar(FrameEntry *thisValue, FrameEntry *arg, GetCharMode mode);
-
-    CompileStatus compileStringFromCode(FrameEntry *arg);
-    CompileStatus compileParseInt(JSValueType argType, uint32_t argc);
-
-    void prepareStubCall(Uses uses);
-    Call emitStubCall(void *ptr, DataLabelPtr *pinline);
-};
-
-// Given a stub call, emits the call into the inline assembly path. rejoin
-// indicates how to rejoin should this call trigger expansion/discarding.
-#define INLINE_STUBCALL(stub, rejoin)                                       \
-    inlineStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0))
-#define INLINE_STUBCALL_USES(stub, rejoin, uses)                            \
-    inlineStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, uses)
-
-// Given a stub call, emits the call into the out-of-line assembly path.
-// Unlike the INLINE_STUBCALL variant, this returns the Call offset.
-#define OOL_STUBCALL(stub, rejoin)                                          \
-    stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0))
-#define OOL_STUBCALL_USES(stub, rejoin, uses)                               \
-    stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, uses)
-
-// Same as OOL_STUBCALL, but specifies a slot depth.
-#define OOL_STUBCALL_LOCAL_SLOTS(stub, rejoin, slots)                       \
-    stubcc.emitStubCall(JS_FUNC_TO_DATA_PTR(void *, (stub)), rejoin, Uses(0), (slots))
-
-} /* namespace js */
-} /* namespace mjit */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/FastArithmetic.cpp
+++ /dev/null
@@ -1,1738 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/MathAlgorithms.h"
-
-#include "jsbool.h"
-#include "jslibmath.h"
-#include "jsnum.h"
-
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Compiler.h"
-#include "methodjit/StubCalls.h"
-#include "methodjit/FrameState-inl.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::analyze;
-using namespace JSC;
-
-using mozilla::Abs;
-
-typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-
-bool
-mjit::Compiler::tryBinaryConstantFold(JSContext *cx, FrameState &frame, JSOp op,
-                                      FrameEntry *lhs, FrameEntry *rhs, Value *vp)
-{
-    if (!lhs->isConstant() || !rhs->isConstant())
-        return false;
-
-    const Value &L = lhs->getValue();
-    const Value &R = rhs->getValue();
-
-    if (!L.isPrimitive() || !R.isPrimitive() ||
-        (op == JSOP_ADD && (L.isString() || R.isString()))) {
-        return false;
-    }
-
-    bool needInt;
-    switch (op) {
-      case JSOP_ADD:
-      case JSOP_SUB:
-      case JSOP_MUL:
-      case JSOP_DIV:
-        needInt = false;
-        break;
-
-      case JSOP_MOD:
-        needInt = (L.isInt32() && R.isInt32() &&
-                   L.toInt32() >= 0 && R.toInt32() > 0);
-        break;
-
-      default:
-        JS_NOT_REACHED("NYI");
-        needInt = false; /* Silence compiler warning. */
-        break;
-    }
-
-    double dL = 0, dR = 0;
-    int32_t nL = 0, nR = 0;
-    /*
-     * We don't need to check for conversion failure, since primitive conversion
-     * is infallible.
-     */
-    if (needInt) {
-        JS_ALWAYS_TRUE(ToInt32(cx, L, &nL));
-        JS_ALWAYS_TRUE(ToInt32(cx, R, &nR));
-    } else {
-        JS_ALWAYS_TRUE(ToNumber(cx, L, &dL));
-        JS_ALWAYS_TRUE(ToNumber(cx, R, &dR));
-    }
-
-    switch (op) {
-      case JSOP_ADD:
-        dL += dR;
-        break;
-      case JSOP_SUB:
-        dL -= dR;
-        break;
-      case JSOP_MUL:
-        dL *= dR;
-        break;
-      case JSOP_DIV:
-        dL = js::NumberDiv(dL, dR);
-        break;
-      case JSOP_MOD:
-        if (needInt)
-            nL %= nR;
-        else if (dR == 0)
-            dL = js_NaN;
-        else
-            dL = js_fmod(dL, dR);
-        break;
-
-      default:
-        JS_NOT_REACHED("NYI");
-        break;
-    }
-
-    if (needInt)
-        vp->setInt32(nL);
-    else
-        vp->setNumber(dL);
-
-    return true;
-}
-
-void
-mjit::Compiler::slowLoadConstantDouble(Assembler &masm,
-                                       FrameEntry *fe, FPRegisterID fpreg)
-{
-    if (fe->getValue().isInt32())
-        masm.slowLoadConstantDouble((double) fe->getValue().toInt32(), fpreg);
-    else
-        masm.slowLoadConstantDouble(fe->getValue().toDouble(), fpreg);
-}
-
-void
-mjit::Compiler::maybeJumpIfNotInt32(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
-                                    MaybeRegisterID &mreg)
-{
-    if (!fe->isTypeKnown()) {
-        if (mreg.isSet())
-            mj.setJump(masm.testInt32(Assembler::NotEqual, mreg.reg()));
-        else
-            mj.setJump(masm.testInt32(Assembler::NotEqual, frame.addressOf(fe)));
-    } else if (fe->getKnownType() != JSVAL_TYPE_INT32) {
-        mj.setJump(masm.jump());
-    }
-}
-
-void
-mjit::Compiler::maybeJumpIfNotDouble(Assembler &masm, MaybeJump &mj, FrameEntry *fe,
-                                    MaybeRegisterID &mreg)
-{
-    if (!fe->isTypeKnown()) {
-        if (mreg.isSet())
-            mj.setJump(masm.testDouble(Assembler::NotEqual, mreg.reg()));
-        else
-            mj.setJump(masm.testDouble(Assembler::NotEqual, frame.addressOf(fe)));
-    } else if (fe->getKnownType() != JSVAL_TYPE_DOUBLE) {
-        mj.setJump(masm.jump());
-    }
-}
-
-bool
-mjit::Compiler::jsop_binary_slow(JSOp op, VoidStub stub, JSValueType type,
-                                 FrameEntry *lhs, FrameEntry *rhs)
-{
-    bool isStringResult = (op == JSOP_ADD) &&
-                          (lhs->isType(JSVAL_TYPE_STRING) || rhs->isType(JSVAL_TYPE_STRING));
-    JS_ASSERT_IF(isStringResult && type != JSVAL_TYPE_UNKNOWN, type == JSVAL_TYPE_STRING);
-
-    prepareStubCall(Uses(2));
-    INLINE_STUBCALL(stub, REJOIN_FALLTHROUGH);
-    frame.popn(2);
-    frame.pushSynced(isStringResult ? JSVAL_TYPE_STRING : type);
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::TypeSet *typeSet)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    Value v;
-    if (tryBinaryConstantFold(cx, frame, op, lhs, rhs, &v)) {
-        if (!v.isInt32() && typeSet && !typeSet->hasType(types::Type::DoubleType())) {
-            /*
-             * OK to ignore failure here, we aren't performing the operation
-             * itself. Note that monitorOverflow will propagate the type as
-             * necessary if a *INC operation overflowed.
-             */
-            RootedScript script(cx, script_);
-            types::TypeScript::MonitorOverflow(cx, script, PC);
-            return false;
-        }
-        frame.popn(2);
-        frame.push(v);
-        return true;
-    }
-
-    /*
-     * Bail out if there are unhandled types or ops.
-     * This is temporary while ops are still being implemented.
-     */
-    if ((lhs->isConstant() && rhs->isConstant()) ||
-        (lhs->isTypeKnown() && (lhs->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)) ||
-        (rhs->isTypeKnown() && (rhs->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)))
-    {
-        return jsop_binary_slow(op, stub, type, lhs, rhs);
-    }
-
-    /*
-     * If this is an operation on which integer overflows can be ignored, treat
-     * the result as an integer even if it has been marked as overflowing by
-     * the interpreter. Doing this changes the values we maintain on the stack
-     * from those the interpreter would maintain; this is OK as values derived
-     * from ignored overflows are not live across points where the interpreter
-     * can join into JIT code (loop heads and safe points).
-     */
-    CrossSSAValue pushv(a->inlineIndex, SSAValue::PushedValue(PC - script_->code, 0));
-    bool cannotOverflow = loop && loop->cannotIntegerOverflow(pushv);
-    bool ignoreOverflow = loop && loop->ignoreIntegerOverflow(pushv);
-
-    if (rhs->isType(JSVAL_TYPE_INT32) && lhs->isType(JSVAL_TYPE_INT32) &&
-        op == JSOP_ADD && ignoreOverflow) {
-        type = JSVAL_TYPE_INT32;
-    }
-
-    /* Can do int math iff there is no double constant and the op is not division. */
-    bool canDoIntMath = op != JSOP_DIV && type != JSVAL_TYPE_DOUBLE &&
-                        !(rhs->isType(JSVAL_TYPE_DOUBLE) || lhs->isType(JSVAL_TYPE_DOUBLE));
-
-    if (!masm.supportsFloatingPoint() && (!canDoIntMath || frame.haveSameBacking(lhs, rhs)))
-        return jsop_binary_slow(op, stub, type, lhs, rhs);
-
-    if (canDoIntMath)
-        jsop_binary_full(lhs, rhs, op, stub, type, cannotOverflow, ignoreOverflow);
-    else
-        jsop_binary_double(lhs, rhs, op, stub, type);
-
-    return true;
-}
-
-static void
-EmitDoubleOp(JSOp op, FPRegisterID fpRight, FPRegisterID fpLeft, Assembler &masm)
-{
-    switch (op) {
-      case JSOP_ADD:
-        masm.addDouble(fpRight, fpLeft);
-        break;
-
-      case JSOP_SUB:
-        masm.subDouble(fpRight, fpLeft);
-        break;
-
-      case JSOP_MUL:
-        masm.mulDouble(fpRight, fpLeft);
-        break;
-
-      case JSOP_DIV:
-        masm.divDouble(fpRight, fpLeft);
-        break;
-
-      default:
-        JS_NOT_REACHED("unrecognized binary op");
-    }
-}
-
-mjit::MaybeJump
-mjit::Compiler::loadDouble(FrameEntry *fe, FPRegisterID *fpReg, bool *allocated)
-{
-    MaybeJump notNumber;
-
-    if (!fe->isConstant() && fe->isType(JSVAL_TYPE_DOUBLE)) {
-        *fpReg = frame.tempFPRegForData(fe);
-        *allocated = false;
-        return notNumber;
-    }
-
-    *fpReg = frame.allocFPReg();
-    *allocated = true;
-
-    if (fe->isConstant()) {
-        slowLoadConstantDouble(masm, fe, *fpReg);
-    } else if (!fe->isTypeKnown()) {
-        frame.tempRegForType(fe);
-        Jump j = frame.testDouble(Assembler::Equal, fe);
-        notNumber = frame.testInt32(Assembler::NotEqual, fe);
-        frame.convertInt32ToDouble(masm, fe, *fpReg);
-        Jump converted = masm.jump();
-        j.linkTo(masm.label(), &masm);
-        // CANDIDATE
-        frame.loadDouble(fe, *fpReg, masm);
-        converted.linkTo(masm.label(), &masm);
-    } else {
-        JS_ASSERT(fe->isType(JSVAL_TYPE_INT32));
-        frame.tempRegForData(fe);
-        frame.convertInt32ToDouble(masm, fe, *fpReg);
-    }
-
-    return notNumber;
-}
-
-/*
- * This function emits a single fast-path for handling numerical arithmetic.
- * Unlike jsop_binary_full(), all integers are converted to doubles.
- */
-void
-mjit::Compiler::jsop_binary_double(FrameEntry *lhs, FrameEntry *rhs, JSOp op,
-                                   VoidStub stub, JSValueType type)
-{
-    FPRegisterID fpLeft, fpRight;
-    bool allocateLeft, allocateRight;
-
-    MaybeJump lhsNotNumber = loadDouble(lhs, &fpLeft, &allocateLeft);
-    if (lhsNotNumber.isSet())
-        stubcc.linkExit(lhsNotNumber.get(), Uses(2));
-
-    /* The left register holds the result, and needs to be mutable. */
-    if (!allocateLeft) {
-        FPRegisterID res = frame.allocFPReg();
-        masm.moveDouble(fpLeft, res);
-        fpLeft = res;
-        allocateLeft = true;
-    }
-
-    MaybeJump rhsNotNumber;
-    if (frame.haveSameBacking(lhs, rhs)) {
-        fpRight = fpLeft;
-        allocateRight = false;
-    } else {
-        rhsNotNumber = loadDouble(rhs, &fpRight, &allocateRight);
-        if (rhsNotNumber.isSet())
-            stubcc.linkExit(rhsNotNumber.get(), Uses(2));
-    }
-
-    EmitDoubleOp(op, fpRight, fpLeft, masm);
-
-    MaybeJump done;
-
-    /*
-     * Try to convert result to integer, if the result has unknown or integer type.
-     * Skip this for 1/x or -1/x, as the result is unlikely to fit in an int.
-     */
-    if (op == JSOP_DIV &&
-        (type == JSVAL_TYPE_INT32 ||
-         (type == JSVAL_TYPE_UNKNOWN &&
-          !(lhs->isConstant() && lhs->isType(JSVAL_TYPE_INT32) &&
-            Abs(lhs->getValue().toInt32()) == 1))))
-    {
-        RegisterID reg = frame.allocReg();
-        FPRegisterID fpReg = frame.allocFPReg();
-        JumpList isDouble;
-        masm.branchConvertDoubleToInt32(fpLeft, reg, isDouble, fpReg);
-
-        masm.storeValueFromComponents(ImmType(JSVAL_TYPE_INT32), reg,
-                                      frame.addressOf(lhs));
-
-        frame.freeReg(reg);
-        frame.freeReg(fpReg);
-        done.setJump(masm.jump());
-
-        isDouble.linkTo(masm.label(), &masm);
-    }
-
-    /*
-     * Inference needs to know about any operation on integers that produces a
-     * double result. Unless the pushed type set already contains the double
-     * type, we need to call a stub rather than push. Note that looking at
-     * the pushed type tag is not sufficient, as it will be UNKNOWN if
-     * we do not yet know the possible types of the division's operands.
-     */
-    types::TypeSet *resultTypes = pushedTypeSet(0);
-    if (resultTypes && !resultTypes->hasType(types::Type::DoubleType())) {
-        /*
-         * Call a stub and try harder to convert to int32_t, failing that trigger
-         * recompilation of this script.
-         */
-        stubcc.linkExit(masm.jump(), Uses(2));
-    } else {
-        JS_ASSERT(type != JSVAL_TYPE_INT32);
-        if (type != JSVAL_TYPE_DOUBLE)
-            masm.storeDouble(fpLeft, frame.addressOf(lhs));
-    }
-
-    if (done.isSet())
-        done.getJump().linkTo(masm.label(), &masm);
-
-    stubcc.leave();
-    OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-    if (allocateRight)
-        frame.freeReg(fpRight);
-
-    frame.popn(2);
-
-    if (type == JSVAL_TYPE_DOUBLE) {
-        frame.pushDouble(fpLeft);
-    } else {
-        frame.freeReg(fpLeft);
-        frame.pushSynced(type);
-    }
-
-    stubcc.rejoin(Changes(1));
-}
-
-/*
- * Simpler version of jsop_binary_full() for when lhs == rhs.
- */
-void
-mjit::Compiler::jsop_binary_full_simple(FrameEntry *fe, JSOp op, VoidStub stub, JSValueType type)
-{
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* Easiest case: known double. Don't bother conversion back yet? */
-    if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-        FPRegisterID fpreg = frame.allocFPReg();
-        FPRegisterID lhs = frame.tempFPRegForData(fe);
-        masm.moveDouble(lhs, fpreg);
-        EmitDoubleOp(op, fpreg, fpreg, masm);
-        frame.popn(2);
-
-        JS_ASSERT(type == JSVAL_TYPE_DOUBLE);  /* :XXX: can fail */
-        frame.pushDouble(fpreg);
-        return;
-    }
-
-    /* Allocate all registers up-front. */
-    FrameState::BinaryAlloc regs;
-    frame.allocForSameBinary(fe, op, regs);
-
-    MaybeJump notNumber;
-    MaybeJump doublePathDone;
-    if (!fe->isTypeKnown()) {
-        Jump notInt = masm.testInt32(Assembler::NotEqual, regs.lhsType.reg());
-        stubcc.linkExitDirect(notInt, stubcc.masm.label());
-
-        notNumber = stubcc.masm.testDouble(Assembler::NotEqual, regs.lhsType.reg());
-        frame.loadDouble(fe, regs.lhsFP, stubcc.masm);
-        EmitDoubleOp(op, regs.lhsFP, regs.lhsFP, stubcc.masm);
-
-        /* Force the double back to memory. */
-        Address result = frame.addressOf(lhs);
-        stubcc.masm.storeDouble(regs.lhsFP, result);
-
-        /* Load the payload into the result reg so the rejoin is safe. */
-        stubcc.masm.loadPayload(result, regs.result);
-
-        doublePathDone = stubcc.masm.jump();
-    }
-
-    /* Okay - good to emit the integer fast-path. */
-    MaybeJump overflow;
-    switch (op) {
-      case JSOP_ADD:
-        overflow = masm.branchAdd32(Assembler::Overflow, regs.result, regs.result);
-        break;
-
-      case JSOP_SUB:
-        overflow = masm.branchSub32(Assembler::Overflow, regs.result, regs.result);
-        break;
-
-      case JSOP_MUL:
-        overflow = masm.branchMul32(Assembler::Overflow, regs.result, regs.result);
-        break;
-
-      default:
-        JS_NOT_REACHED("unrecognized op");
-    }
-
-    JS_ASSERT(overflow.isSet());
-
-    /*
-     * Integer overflow path. Restore the original values and make a stub call,
-     * which could trigger recompilation.
-     */
-    stubcc.linkExitDirect(overflow.get(), stubcc.masm.label());
-    frame.rematBinary(fe, NULL, regs, stubcc.masm);
-    stubcc.syncExitAndJump(Uses(2));
-
-    /* Slow paths funnel here. */
-    if (notNumber.isSet())
-        notNumber.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-    /* Slow call - use frame.sync to avoid erroneous jump repatching in stubcc. */
-    frame.sync(stubcc.masm, Uses(2));
-    stubcc.leave();
-    OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-    /* Finish up stack operations. */
-    frame.popn(2);
-
-    if (type == JSVAL_TYPE_INT32)
-        frame.pushTypedPayload(type, regs.result);
-    else
-        frame.pushNumber(regs.result, true);
-
-    frame.freeReg(regs.lhsFP);
-
-    /* Merge back OOL double path. */
-    if (doublePathDone.isSet())
-        stubcc.linkRejoin(doublePathDone.get());
-
-    stubcc.rejoin(Changes(1));
-}
-
-/*
- * This function emits multiple fast-paths for handling numerical arithmetic.
- * Currently, it handles only ADD, SUB, and MUL, where both LHS and RHS are
- * known not to be doubles.
- *
- * The control flow of the emitted code depends on which types are known.
- * Given both types are unknown, the full spread looks like:
- *
- * Inline                              OOL
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Is LHS Int32?  ------ No -------->  Is LHS Double?  ----- No -------,
- *                                     Sync LHS                        |
- *                                     Load LHS into XMM1              |
- *                                     Is RHS Double? ---- Yes --,     |
- *                                       Is RHS Int32? ---- No --|-----|
- *                                       Convert RHS into XMM0   |     |
- *                                     Else  <-------------------'     |
- *                                       Sync RHS                      |
- *                                       Load RHS into XMM0            |
- *                                     [Add,Sub,Mul] XMM0,XMM1         |
- *                                     Jump ---------------------,     |
- *                                                               |     |
- * Is RHS Int32?  ------ No ------->   Is RHS Double? ----- No --|-----|
- *                                     Sync RHS                  |     |
- *                                     Load RHS into XMM0        |     |
- *                                     Convert LHS into XMM1     |     |
- *                                     [Add,Sub,Mul] XMM0,XMM1   |     |
- *                                     Jump ---------------------|   Slow Call
- *                                                               |
- * [Add,Sub,Mul] RHS, LHS                                        |
- * Overflow      ------ Yes ------->   Convert RHS into XMM0     |
- *                                     Convert LHS into XMM1     |
- *                                     [Add,Sub,Mul] XMM0,XMM1   |
- *                                     Sync XMM1 to stack    <---'
- *  <--------------------------------- Rejoin
- */
-void
-mjit::Compiler::jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op,
-                                 VoidStub stub, JSValueType type,
-                                 bool cannotOverflow, bool ignoreOverflow)
-{
-    if (frame.haveSameBacking(lhs, rhs)) {
-        jsop_binary_full_simple(lhs, op, stub, type);
-        return;
-    }
-
-    /* Allocate all registers up-front. */
-    FrameState::BinaryAlloc regs;
-    frame.allocForBinary(lhs, rhs, op, regs);
-
-    /* Quick-test some invariants. */
-    JS_ASSERT_IF(lhs->isTypeKnown(), lhs->getKnownType() == JSVAL_TYPE_INT32);
-    JS_ASSERT_IF(rhs->isTypeKnown(), rhs->getKnownType() == JSVAL_TYPE_INT32);
-
-    MaybeJump lhsNotDouble, rhsNotNumber, lhsUnknownDone;
-    if (!lhs->isTypeKnown())
-        emitLeftDoublePath(lhs, rhs, regs, lhsNotDouble, rhsNotNumber, lhsUnknownDone);
-
-    MaybeJump rhsNotNumber2;
-    if (!rhs->isTypeKnown())
-        emitRightDoublePath(lhs, rhs, regs, rhsNotNumber2);
-
-    /* Perform the double addition. */
-    MaybeJump doublePathDone;
-    if (masm.supportsFloatingPoint() && (!rhs->isTypeKnown() || !lhs->isTypeKnown())) {
-        /* If the LHS type was not known, link its path here. */
-        if (lhsUnknownDone.isSet())
-            lhsUnknownDone.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        /* Perform the double operation. */
-        EmitDoubleOp(op, regs.rhsFP, regs.lhsFP, stubcc.masm);
-
-        /* Force the double back to memory. */
-        Address result = frame.addressOf(lhs);
-        stubcc.masm.storeDouble(regs.lhsFP, result);
-
-        /* Load the payload into the result reg so the rejoin is safe. */
-        stubcc.masm.loadPayload(result, regs.result);
-
-        /* We'll link this back up later, at the bottom of the op. */
-        doublePathDone = stubcc.masm.jump();
-    }
-
-    /* Time to do the integer path. Figure out the immutable side. */
-    int32_t value = 0;
-    JSOp origOp = op;
-    MaybeRegisterID reg;
-    MaybeJump preOverflow;
-    if (!regs.resultHasRhs) {
-        if (!regs.rhsData.isSet())
-            value = rhs->getValue().toInt32();
-        else
-            reg = regs.rhsData.reg();
-    } else {
-        if (!regs.lhsData.isSet())
-            value = lhs->getValue().toInt32();
-        else
-            reg = regs.lhsData.reg();
-        if (op == JSOP_SUB) {
-            // If the RHS is 0x80000000, the smallest negative value, neg does
-            // not work. Guard against this and treat it as an overflow.
-            preOverflow = masm.branch32(Assembler::Equal, regs.result, Imm32(0x80000000));
-            masm.neg32(regs.result);
-            op = JSOP_ADD;
-        }
-    }
-
-    /* Okay - good to emit the integer fast-path. */
-    MaybeJump overflow;
-    switch (op) {
-      case JSOP_ADD:
-        if (cannotOverflow || ignoreOverflow) {
-            if (reg.isSet())
-                masm.add32(reg.reg(), regs.result);
-            else
-                masm.add32(Imm32(value), regs.result);
-        } else {
-            if (reg.isSet())
-                overflow = masm.branchAdd32(Assembler::Overflow, reg.reg(), regs.result);
-            else
-                overflow = masm.branchAdd32(Assembler::Overflow, Imm32(value), regs.result);
-        }
-        break;
-
-      case JSOP_SUB:
-        if (cannotOverflow) {
-            if (reg.isSet())
-                masm.sub32(reg.reg(), regs.result);
-            else
-                masm.sub32(Imm32(value), regs.result);
-        } else {
-            if (reg.isSet())
-                overflow = masm.branchSub32(Assembler::Overflow, reg.reg(), regs.result);
-            else
-                overflow = masm.branchSub32(Assembler::Overflow, Imm32(value), regs.result);
-        }
-        break;
-
-      case JSOP_MUL:
-      {
-        MaybeJump storeNegZero;
-        bool maybeNegZero = !ignoreOverflow;
-        bool hasConstant = (lhs->isConstant() || rhs->isConstant());
-
-        if (hasConstant && maybeNegZero) {
-            value = (lhs->isConstant() ? lhs : rhs)->getValue().toInt32();
-            RegisterID nonConstReg = lhs->isConstant() ? regs.rhsData.reg() : regs.lhsData.reg();
-
-            if (value > 0)
-                maybeNegZero = false;
-            else if (value < 0)
-                storeNegZero = masm.branchTest32(Assembler::Zero, nonConstReg);
-            else
-                storeNegZero = masm.branch32(Assembler::LessThan, nonConstReg, Imm32(0));
-        }
-
-        if (cannotOverflow) {
-            if (reg.isSet())
-                masm.mul32(reg.reg(), regs.result);
-            else
-                masm.mul32(Imm32(value), regs.result, regs.result);
-        } else {
-            if (reg.isSet()) {
-                overflow = masm.branchMul32(Assembler::Overflow, reg.reg(), regs.result);
-            } else {
-                overflow = masm.branchMul32(Assembler::Overflow, Imm32(value), regs.result,
-                                            regs.result);
-            }
-        }
-
-        if (maybeNegZero) {
-            if (hasConstant) {
-                stubcc.linkExit(storeNegZero.get(), Uses(2));
-            } else {
-                Jump isZero = masm.branchTest32(Assembler::Zero, regs.result);
-                stubcc.linkExitDirect(isZero, stubcc.masm.label());
-
-                /* Restore original value. */
-                if (regs.resultHasRhs) {
-                    if (regs.rhsNeedsRemat)
-                        stubcc.masm.loadPayload(frame.addressForDataRemat(rhs), regs.result);
-                    else
-                        stubcc.masm.move(regs.rhsData.reg(), regs.result);
-                } else {
-                    if (regs.lhsNeedsRemat)
-                        stubcc.masm.loadPayload(frame.addressForDataRemat(lhs), regs.result);
-                    else
-                        stubcc.masm.move(regs.lhsData.reg(), regs.result);
-                }
-                storeNegZero = stubcc.masm.branchOr32(Assembler::Signed, reg.reg(), regs.result);
-                stubcc.masm.xor32(regs.result, regs.result);
-                stubcc.crossJump(stubcc.masm.jump(), masm.label());
-                storeNegZero.getJump().linkTo(stubcc.masm.label(), &stubcc.masm);
-                frame.rematBinary(lhs, rhs, regs, stubcc.masm);
-            }
-            stubcc.syncExitAndJump(Uses(2));
-        }
-        break;
-      }
-
-      default:
-        JS_NOT_REACHED("unrecognized op");
-    }
-    op = origOp;
-
-    /*
-     * Integer overflow path. Restore the original values and make a stub call,
-     * which could trigger recompilation.
-     */
-    MaybeJump overflowDone;
-    if (preOverflow.isSet())
-        stubcc.linkExitDirect(preOverflow.get(), stubcc.masm.label());
-    if (overflow.isSet())
-        stubcc.linkExitDirect(overflow.get(), stubcc.masm.label());
-
-    /* Restore the original operand registers for ADD. */
-    if (regs.undoResult) {
-        if (reg.isSet()) {
-            JS_ASSERT(op == JSOP_ADD);
-            stubcc.masm.neg32(reg.reg());
-            stubcc.masm.add32(reg.reg(), regs.result);
-            stubcc.masm.neg32(reg.reg());
-        } else {
-            JS_ASSERT(op == JSOP_ADD || op == JSOP_SUB);
-            int32_t fixValue = (op == JSOP_ADD) ? -value : value;
-            stubcc.masm.add32(Imm32(fixValue), regs.result);
-        }
-    }
-
-    frame.rematBinary(lhs, rhs, regs, stubcc.masm);
-    stubcc.syncExitAndJump(Uses(2));
-
-    /* The register allocator creates at most one temporary. */
-    if (regs.extraFree.isSet())
-        frame.freeReg(regs.extraFree.reg());
-
-    /* Slow paths funnel here. */
-    if (lhsNotDouble.isSet()) {
-        lhsNotDouble.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-        if (rhsNotNumber.isSet())
-            rhsNotNumber.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-    }
-    if (rhsNotNumber2.isSet())
-        rhsNotNumber2.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-    /* Slow call - use frame.sync to avoid erroneous jump repatching in stubcc. */
-    frame.sync(stubcc.masm, Uses(2));
-    stubcc.leave();
-    OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-    /* Finish up stack operations. */
-    frame.popn(2);
-
-    /*
-     * Steal the result register if we remat the LHS/RHS by undoing the operation.
-     * In this case the result register was still assigned to the corresponding
-     * frame entry (so it is synced properly in OOL paths), so steal it back.
-     */
-    if (regs.undoResult)
-        frame.takeReg(regs.result);
-
-    if (type == JSVAL_TYPE_INT32)
-        frame.pushTypedPayload(type, regs.result);
-    else
-        frame.pushNumber(regs.result, true);
-
-    frame.freeReg(regs.lhsFP);
-    frame.freeReg(regs.rhsFP);
-
-    /* Merge back OOL double path. */
-    if (doublePathDone.isSet())
-        stubcc.linkRejoin(doublePathDone.get());
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_neg()
-{
-    FrameEntry *fe = frame.peek(-1);
-    JSValueType type = knownPushedType(0);
-
-    if ((fe->isTypeKnown() && fe->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET) ||
-        !masm.supportsFloatingPoint())
-    {
-        prepareStubCall(Uses(1));
-        INLINE_STUBCALL(stubs::Neg, REJOIN_FALLTHROUGH);
-        frame.pop();
-        frame.pushSynced(type);
-        return;
-    }
-
-    JS_ASSERT(!fe->isConstant());
-
-    /* Handle negation of a known double, or of a known integer which has previously overflowed. */
-    if (fe->isType(JSVAL_TYPE_DOUBLE) ||
-        (fe->isType(JSVAL_TYPE_INT32) && type == JSVAL_TYPE_DOUBLE))
-    {
-        FPRegisterID fpreg;
-        if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-            fpreg = frame.tempFPRegForData(fe);
-        } else {
-            fpreg = frame.allocFPReg();
-            frame.convertInt32ToDouble(masm, fe, fpreg);
-        }
-
-        FPRegisterID res = frame.allocFPReg();
-        masm.moveDouble(fpreg, res);
-        masm.negateDouble(res);
-
-        if (!fe->isType(JSVAL_TYPE_DOUBLE))
-            frame.freeReg(fpreg);
-
-        frame.pop();
-        frame.pushDouble(res);
-
-        return;
-    }
-
-    /* Inline integer path for known integers. */
-    if (fe->isType(JSVAL_TYPE_INT32) && type == JSVAL_TYPE_INT32) {
-        RegisterID reg = frame.copyDataIntoReg(fe);
-
-        /* Test for 0 and -2147483648 (both result in a double). */
-        Jump zeroOrMinInt = masm.branchTest32(Assembler::Zero, reg, Imm32(0x7fffffff));
-        stubcc.linkExit(zeroOrMinInt, Uses(1));
-
-        masm.neg32(reg);
-
-        stubcc.leave();
-        OOL_STUBCALL(stubs::Neg, REJOIN_FALLTHROUGH);
-
-        frame.pop();
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-        stubcc.rejoin(Changes(1));
-        return;
-    }
-
-    /* Load type information into register. */
-    MaybeRegisterID feTypeReg;
-    if (!fe->isTypeKnown() && !frame.shouldAvoidTypeRemat(fe)) {
-        /* Safe because only one type is loaded. */
-        feTypeReg.setReg(frame.tempRegForType(fe));
-
-        /* Don't get clobbered by copyDataIntoReg(). */
-        frame.pinReg(feTypeReg.reg());
-    }
-
-    RegisterID reg = frame.copyDataIntoReg(masm, fe);
-    Label feSyncTarget = stubcc.syncExitAndJump(Uses(1));
-
-    /* Try a double path (inline). */
-    MaybeJump jmpNotDbl;
-    {
-        maybeJumpIfNotDouble(masm, jmpNotDbl, fe, feTypeReg);
-
-        FPRegisterID fpreg = frame.allocFPReg();
-        frame.loadDouble(fe, fpreg, masm);
-        masm.negateDouble(fpreg);
-
-        /* Overwrite pushed frame's memory (before push). */
-        masm.storeDouble(fpreg, frame.addressOf(fe));
-        frame.freeReg(fpreg);
-    }
-
-    /* Try an integer path (out-of-line). */
-    MaybeJump jmpNotInt;
-    MaybeJump jmpMinIntOrIntZero;
-    MaybeJump jmpIntRejoin;
-    Label lblIntPath = stubcc.masm.label();
-    {
-        maybeJumpIfNotInt32(stubcc.masm, jmpNotInt, fe, feTypeReg);
-
-        /* Test for 0 and -2147483648 (both result in a double). */
-        jmpMinIntOrIntZero = stubcc.masm.branchTest32(Assembler::Zero, reg, Imm32(0x7fffffff));
-
-        stubcc.masm.neg32(reg);
-
-        /* Sync back with double path. */
-        if (type == JSVAL_TYPE_DOUBLE) {
-            stubcc.masm.convertInt32ToDouble(reg, Registers::FPConversionTemp);
-            stubcc.masm.storeDouble(Registers::FPConversionTemp, frame.addressOf(fe));
-        } else {
-            stubcc.masm.storeValueFromComponents(ImmType(JSVAL_TYPE_INT32), reg,
-                                                 frame.addressOf(fe));
-        }
-
-        jmpIntRejoin.setJump(stubcc.masm.jump());
-    }
-
-    frame.freeReg(reg);
-    if (feTypeReg.isSet())
-        frame.unpinReg(feTypeReg.reg());
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::Neg, REJOIN_FALLTHROUGH);
-
-    frame.pop();
-    frame.pushSynced(type);
-
-    /* Link jumps. */
-    if (jmpNotDbl.isSet())
-        stubcc.linkExitDirect(jmpNotDbl.getJump(), lblIntPath);
-
-    if (jmpNotInt.isSet())
-        jmpNotInt.getJump().linkTo(feSyncTarget, &stubcc.masm);
-    if (jmpMinIntOrIntZero.isSet())
-        jmpMinIntOrIntZero.getJump().linkTo(feSyncTarget, &stubcc.masm);
-    if (jmpIntRejoin.isSet())
-        stubcc.crossJump(jmpIntRejoin.getJump(), masm.label());
-
-    stubcc.rejoin(Changes(1));
-}
-
-bool
-mjit::Compiler::jsop_mod()
-{
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    JSValueType type = knownPushedType(0);
-    FrameEntry *lhs = frame.peek(-2);
-    FrameEntry *rhs = frame.peek(-1);
-
-    Value v;
-    if (tryBinaryConstantFold(cx, frame, JSOP_MOD, lhs, rhs, &v)) {
-        types::TypeSet *pushed = pushedTypeSet(0);
-        if (!v.isInt32() && pushed && !pushed->hasType(types::Type::DoubleType())) {
-            RootedScript script(cx, script_);
-            types::TypeScript::MonitorOverflow(cx, script, PC);
-            return false;
-        }
-        frame.popn(2);
-        frame.push(v);
-        return true;
-    }
-
-    if ((lhs->isConstant() && rhs->isConstant()) ||
-        (lhs->isTypeKnown() && lhs->getKnownType() != JSVAL_TYPE_INT32) ||
-        (rhs->isTypeKnown() && rhs->getKnownType() != JSVAL_TYPE_INT32) ||
-        (type != JSVAL_TYPE_INT32 && type != JSVAL_TYPE_UNKNOWN))
-#endif
-    {
-        prepareStubCall(Uses(2));
-        INLINE_STUBCALL(stubs::Mod, REJOIN_FALLTHROUGH);
-        frame.popn(2);
-        frame.pushSynced(knownPushedType(0));
-        return true;
-    }
-
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    if (!lhs->isTypeKnown()) {
-        Jump j = frame.testInt32(Assembler::NotEqual, lhs);
-        stubcc.linkExit(j, Uses(2));
-    }
-    if (!rhs->isTypeKnown()) {
-        Jump j = frame.testInt32(Assembler::NotEqual, rhs);
-        stubcc.linkExit(j, Uses(2));
-    }
-
-    /* LHS must be in EAX:EDX */
-    if (!lhs->isConstant()) {
-        frame.copyDataIntoReg(lhs, X86Registers::eax);
-    } else {
-        frame.takeReg(X86Registers::eax);
-        masm.move(Imm32(lhs->getValue().toInt32()), X86Registers::eax);
-    }
-
-    /* Get RHS into anything but EDX - could avoid more spilling? */
-    MaybeRegisterID temp;
-    RegisterID rhsReg;
-    uint32_t mask = Registers::AvailRegs & ~Registers::maskReg(X86Registers::edx);
-    if (!rhs->isConstant()) {
-        rhsReg = frame.tempRegInMaskForData(rhs, mask).reg();
-        JS_ASSERT(rhsReg != X86Registers::edx);
-    } else {
-        rhsReg = frame.allocReg(mask).reg();
-        JS_ASSERT(rhsReg != X86Registers::edx);
-        masm.move(Imm32(rhs->getValue().toInt32()), rhsReg);
-        temp = rhsReg;
-    }
-    frame.takeReg(X86Registers::edx);
-    frame.freeReg(X86Registers::eax);
-
-    if (temp.isSet())
-        frame.freeReg(temp.reg());
-
-    bool slowPath = !(lhs->isTypeKnown() && rhs->isTypeKnown());
-    if (rhs->isConstant() && rhs->getValue().toInt32() != 0) {
-        if (rhs->getValue().toInt32() == -1) {
-            /* Guard against -1 / INT_MIN which throws a hardware exception. */
-            Jump checkDivExc = masm.branch32(Assembler::Equal, X86Registers::eax,
-                                             Imm32(0x80000000));
-            stubcc.linkExit(checkDivExc, Uses(2));
-            slowPath = true;
-        }
-    } else {
-        Jump checkDivExc = masm.branch32(Assembler::Equal, X86Registers::eax, Imm32(0x80000000));
-        stubcc.linkExit(checkDivExc, Uses(2));
-        Jump checkZero = masm.branchTest32(Assembler::Zero, rhsReg, rhsReg);
-        stubcc.linkExit(checkZero, Uses(2));
-        slowPath = true;
-    }
-
-    /* Perform division. */
-    masm.idiv(rhsReg);
-
-    /* ECMA-262 11.5.3 requires the result to have the same sign as the lhs.
-     * Thus, if the remainder of the div instruction is zero and the lhs is
-     * negative, we must return negative 0. */
-
-    bool lhsMaybeNeg = true;
-    bool lhsIsNeg = false;
-    if (lhs->isConstant()) {
-        /* This condition is established at the top of this function. */
-        JS_ASSERT(lhs->getValue().isInt32());
-        lhsMaybeNeg = lhsIsNeg = (lhs->getValue().toInt32() < 0);
-    }
-
-    MaybeJump gotNegZero;
-    MaybeJump done;
-    if (lhsMaybeNeg) {
-        MaybeRegisterID lhsData;
-        if (!lhsIsNeg)
-            lhsData = frame.tempRegForData(lhs);
-        Jump negZero1 = masm.branchTest32(Assembler::NonZero, X86Registers::edx);
-        MaybeJump negZero2;
-        if (!lhsIsNeg)
-            negZero2 = masm.branchTest32(Assembler::Zero, lhsData.reg(), Imm32(0x80000000));
-        /*
-         * Darn, negative 0. This goes to a stub call (after our in progress call)
-         * which triggers recompilation if necessary.
-         */
-        gotNegZero = masm.jump();
-
-        /* :TODO: This is wrong, must load into EDX as well. */
-
-        done = masm.jump();
-        negZero1.linkTo(masm.label(), &masm);
-        if (negZero2.isSet())
-            negZero2.getJump().linkTo(masm.label(), &masm);
-    }
-
-    /* Better - integer. */
-    masm.storeTypeTag(ImmType(JSVAL_TYPE_INT32), frame.addressOf(lhs));
-
-    if (done.isSet())
-        done.getJump().linkTo(masm.label(), &masm);
-
-    if (slowPath) {
-        stubcc.leave();
-        OOL_STUBCALL(stubs::Mod, REJOIN_FALLTHROUGH);
-    }
-
-    frame.popn(2);
-
-    if (type == JSVAL_TYPE_INT32)
-        frame.pushTypedPayload(type, X86Registers::edx);
-    else
-        frame.pushNumber(X86Registers::edx);
-
-    if (slowPath)
-        stubcc.rejoin(Changes(1));
-
-    if (gotNegZero.isSet()) {
-        stubcc.linkExit(gotNegZero.getJump(), Uses(2));
-        stubcc.leave();
-        OOL_STUBCALL(stubs::NegZeroHelper, REJOIN_FALLTHROUGH);
-        stubcc.rejoin(Changes(1));
-    }
-#endif
-
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_equality_int_string(JSOp op, BoolStub stub,
-                                         jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* Swap the LHS and RHS if it makes register allocation better... or possible. */
-    if (lhs->isConstant() ||
-        (frame.shouldAvoidDataRemat(lhs) && !rhs->isConstant())) {
-        FrameEntry *temp = rhs;
-        rhs = lhs;
-        lhs = temp;
-    }
-
-    bool lhsInt = lhs->isType(JSVAL_TYPE_INT32);
-    bool rhsInt = rhs->isType(JSVAL_TYPE_INT32);
-
-    /* Invert the condition if fusing with an IFEQ branch. */
-    bool flipCondition = (target && fused == JSOP_IFEQ);
-
-    /* Get the condition being tested. */
-    Assembler::Condition cond;
-    switch (op) {
-      case JSOP_EQ:
-        cond = flipCondition ? Assembler::NotEqual : Assembler::Equal;
-        break;
-      case JSOP_NE:
-        cond = flipCondition ? Assembler::Equal : Assembler::NotEqual;
-        break;
-      default:
-        JS_NOT_REACHED("wat");
-        return false;
-    }
-
-    if (target) {
-        Value rval = UndefinedValue();  /* quiet gcc warning */
-        bool rhsConst = false;
-        if (rhs->isConstant()) {
-            rhsConst = true;
-            rval = rhs->getValue();
-        }
-
-        ValueRemat lvr, rvr;
-        frame.pinEntry(lhs, lvr);
-        frame.pinEntry(rhs, rvr);
-
-        /*
-         * Sync everything except the top two entries.
-         * We will handle the lhs/rhs in the stub call path.
-         */
-        frame.syncAndKill(Registers(Registers::AvailRegs), Uses(frame.frameSlots()), Uses(2));
-
-        RegisterID tempReg = frame.allocReg();
-
-        JaegerSpew(JSpew_Insns, " ---- BEGIN STUB CALL CODE ---- \n");
-
-        RESERVE_OOL_SPACE(stubcc.masm);
-
-        /* Start of the slow path for equality stub call. */
-        Label stubEntry = stubcc.masm.label();
-
-        /* The lhs/rhs need to be synced in the stub call path. */
-        frame.ensureValueSynced(stubcc.masm, lhs, lvr);
-        frame.ensureValueSynced(stubcc.masm, rhs, rvr);
-
-        bool needIntPath = (!lhs->isTypeKnown() || lhsInt) && (!rhs->isTypeKnown() || rhsInt);
-
-        frame.pop();
-        frame.pop();
-        frame.discardFrame();
-
-        bool needStub = true;
-
-#ifdef JS_MONOIC
-        EqualityGenInfo ic;
-
-        ic.cond = cond;
-        ic.tempReg = tempReg;
-        ic.lvr = lvr;
-        ic.rvr = rvr;
-        ic.stubEntry = stubEntry;
-        ic.stub = stub;
-
-        bool useIC = !a->parent && bytecodeInChunk(target);
-
-        /* Call the IC stub, which may generate a fast path. */
-        if (useIC) {
-            /* Adjust for the two values just pushed. */
-            ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
-            ic.stubCall = OOL_STUBCALL_LOCAL_SLOTS(ic::Equality, REJOIN_BRANCH,
-                                                   frame.totalDepth() + 2);
-            needStub = false;
-        }
-#endif
-
-        if (needStub)
-            OOL_STUBCALL_LOCAL_SLOTS(stub, REJOIN_BRANCH, frame.totalDepth() + 2);
-
-        /*
-         * The stub call has no need to rejoin, since state is synced.
-         * Instead, we can just test the return value.
-         */
-        Jump stubBranch = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
-                                                   Registers::ReturnReg, Registers::ReturnReg);
-        Jump stubFallthrough = stubcc.masm.jump();
-
-        JaegerSpew(JSpew_Insns, " ---- END STUB CALL CODE ---- \n");
-        CHECK_OOL_SPACE();
-
-        Jump fast;
-        MaybeJump firstStubJump;
-
-        if (needIntPath) {
-            if (!lhsInt) {
-                Jump lhsFail = masm.testInt32(Assembler::NotEqual, lvr.typeReg());
-                stubcc.linkExitDirect(lhsFail, stubEntry);
-                firstStubJump = lhsFail;
-            }
-            if (!rhsInt) {
-                Jump rhsFail = masm.testInt32(Assembler::NotEqual, rvr.typeReg());
-                stubcc.linkExitDirect(rhsFail, stubEntry);
-                if (!firstStubJump.isSet())
-                    firstStubJump = rhsFail;
-            }
-
-            if (rhsConst)
-                fast = masm.branch32(cond, lvr.dataReg(), Imm32(rval.toInt32()));
-            else
-                fast = masm.branch32(cond, lvr.dataReg(), rvr.dataReg());
-        } else {
-            Jump j = masm.jump();
-            stubcc.linkExitDirect(j, stubEntry);
-            firstStubJump = j;
-
-            /* This is just a dummy jump. */
-            fast = masm.jump();
-        }
-
-        /* Jump from the stub call fallthrough to here. */
-        stubcc.crossJump(stubFallthrough, masm.label());
-
-        bool *ptrampoline = NULL;
-#ifdef JS_MONOIC
-        /* Remember the stub label in case there is a trampoline for the IC. */
-        ic.trampoline = false;
-        ic.trampolineStart = stubcc.masm.label();
-        if (useIC)
-            ptrampoline = &ic.trampoline;
-#endif
-
-        /*
-         * NB: jumpAndRun emits to the OOL path, so make sure not to use it
-         * in the middle of an in-progress slow path.
-         */
-        if (!jumpAndRun(fast, target, &stubBranch, ptrampoline))
-            return false;
-
-#ifdef JS_MONOIC
-        if (useIC) {
-            ic.jumpToStub = firstStubJump;
-            ic.fallThrough = masm.label();
-            ic.jumpTarget = target;
-            equalityICs.append(ic);
-        }
-#endif
-
-    } else {
-        /* No fusing. Compare, set, and push a boolean. */
-
-        /* Should have filtered these out in the caller. */
-        JS_ASSERT(!lhs->isType(JSVAL_TYPE_STRING) && !rhs->isType(JSVAL_TYPE_STRING));
-
-        /* Test the types. */
-        if ((lhs->isTypeKnown() && !lhsInt) || (rhs->isTypeKnown() && !rhsInt)) {
-            stubcc.linkExit(masm.jump(), Uses(2));
-        } else {
-            if (!lhsInt) {
-                Jump lhsFail = frame.testInt32(Assembler::NotEqual, lhs);
-                stubcc.linkExit(lhsFail, Uses(2));
-            }
-            if (!rhsInt) {
-                Jump rhsFail = frame.testInt32(Assembler::NotEqual, rhs);
-                stubcc.linkExit(rhsFail, Uses(2));
-            }
-        }
-
-        stubcc.leave();
-        OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-        RegisterID reg = frame.ownRegForData(lhs);
-
-        /* x86/64's SET instruction can only take single-byte regs.*/
-        RegisterID resultReg = reg;
-        if (!(Registers::maskReg(reg) & Registers::SingleByteRegs))
-            resultReg = frame.allocReg(Registers::SingleByteRegs).reg();
-
-        /* Emit the compare & set. */
-        if (rhs->isConstant()) {
-            masm.set32(cond, reg, Imm32(rhs->getValue().toInt32()), resultReg);
-        } else if (frame.shouldAvoidDataRemat(rhs)) {
-            masm.set32(cond, reg,
-                       masm.payloadOf(frame.addressOf(rhs)),
-                       resultReg);
-        } else {
-            masm.set32(cond, reg, frame.tempRegForData(rhs), resultReg);
-        }
-
-        /* Clean up and push a boolean. */
-        frame.pop();
-        frame.pop();
-        if (reg != resultReg)
-            frame.freeReg(reg);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, resultReg);
-        stubcc.rejoin(Changes(1));
-    }
-    return true;
-}
-
-/*
- * Emit an OOL path for a possibly double LHS, and possibly int32_t or number RHS.
- */
-void
-mjit::Compiler::emitLeftDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
-                                   MaybeJump &lhsNotDouble, MaybeJump &rhsNotNumber,
-                                   MaybeJump &lhsUnknownDone)
-{
-    /* If the LHS is not a 32-bit integer, take OOL path. */
-    Jump lhsNotInt32 = masm.testInt32(Assembler::NotEqual, regs.lhsType.reg());
-    stubcc.linkExitDirect(lhsNotInt32, stubcc.masm.label());
-
-    if (!masm.supportsFloatingPoint()) {
-        lhsNotDouble = stubcc.masm.jump();
-        return;
-    }
-
-    /* OOL path for LHS as a double - first test LHS is double. */
-    lhsNotDouble = stubcc.masm.testDouble(Assembler::NotEqual, regs.lhsType.reg());
-
-    /* Ensure the RHS is a number. */
-    MaybeJump rhsIsDouble;
-    if (!rhs->isTypeKnown()) {
-        rhsIsDouble = stubcc.masm.testDouble(Assembler::Equal, regs.rhsType.reg());
-        rhsNotNumber = stubcc.masm.testInt32(Assembler::NotEqual, regs.rhsType.reg());
-    }
-
-    /* If RHS is constant, convert now. */
-    if (rhs->isConstant())
-        slowLoadConstantDouble(stubcc.masm, rhs, regs.rhsFP);
-    else
-        stubcc.masm.convertInt32ToDouble(regs.rhsData.reg(), regs.rhsFP);
-
-    if (!rhs->isTypeKnown()) {
-        /* Jump past double load, bind double type check. */
-        Jump converted = stubcc.masm.jump();
-        rhsIsDouble.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        /* Load the double. */
-        frame.loadDouble(regs.rhsType.reg(), regs.rhsData.reg(),
-                         rhs, regs.rhsFP, stubcc.masm);
-
-        converted.linkTo(stubcc.masm.label(), &stubcc.masm);
-    }
-
-    /* Load the LHS. */
-    frame.loadDouble(regs.lhsType.reg(), regs.lhsData.reg(),
-                     lhs, regs.lhsFP, stubcc.masm);
-    lhsUnknownDone = stubcc.masm.jump();
-}
-
-/*
- * Emit an OOL path for an integer LHS, possibly double RHS.
- */
-void
-mjit::Compiler::emitRightDoublePath(FrameEntry *lhs, FrameEntry *rhs, FrameState::BinaryAlloc &regs,
-                                    MaybeJump &rhsNotNumber2)
-{
-    /* If the RHS is not a double, take OOL path. */
-    Jump notInt32 = masm.testInt32(Assembler::NotEqual, regs.rhsType.reg());
-    stubcc.linkExitDirect(notInt32, stubcc.masm.label());
-
-    if (!masm.supportsFloatingPoint()) {
-        rhsNotNumber2 = stubcc.masm.jump();
-        return;
-    }
-
-    /* Now test if RHS is a double. */
-    rhsNotNumber2 = stubcc.masm.testDouble(Assembler::NotEqual, regs.rhsType.reg());
-
-    /* We know LHS is an integer. */
-    if (lhs->isConstant())
-        slowLoadConstantDouble(stubcc.masm, lhs, regs.lhsFP);
-    else
-        stubcc.masm.convertInt32ToDouble(regs.lhsData.reg(), regs.lhsFP);
-
-    /* Load the RHS. */
-    frame.loadDouble(regs.rhsType.reg(), regs.rhsData.reg(),
-                     rhs, regs.rhsFP, stubcc.masm);
-}
-
-static inline Assembler::DoubleCondition
-DoubleCondForOp(JSOp op, JSOp fused)
-{
-    bool ifeq = fused == JSOP_IFEQ;
-    switch (op) {
-      case JSOP_GT:
-        return ifeq
-               ? Assembler::DoubleLessThanOrEqualOrUnordered
-               : Assembler::DoubleGreaterThan;
-      case JSOP_GE:
-        return ifeq
-               ? Assembler::DoubleLessThanOrUnordered
-               : Assembler::DoubleGreaterThanOrEqual;
-      case JSOP_LT:
-        return ifeq
-               ? Assembler::DoubleGreaterThanOrEqualOrUnordered
-               : Assembler::DoubleLessThan;
-      case JSOP_LE:
-        return ifeq
-               ? Assembler::DoubleGreaterThanOrUnordered
-               : Assembler::DoubleLessThanOrEqual;
-      default:
-        JS_NOT_REACHED("unrecognized op");
-        return Assembler::DoubleLessThan;
-    }
-}
-
-bool
-mjit::Compiler::jsop_relational_double(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    JS_ASSERT_IF(!target, fused != JSOP_IFEQ);
-
-    FPRegisterID fpLeft, fpRight;
-    bool allocateLeft, allocateRight;
-
-    MaybeJump lhsNotNumber = loadDouble(lhs, &fpLeft, &allocateLeft);
-    if (lhsNotNumber.isSet()) {
-        if (target)
-            stubcc.linkExitForBranch(lhsNotNumber.get());
-        else
-            stubcc.linkExit(lhsNotNumber.get(), Uses(2));
-    }
-    if (!allocateLeft)
-        frame.pinReg(fpLeft);
-
-    MaybeJump rhsNotNumber = loadDouble(rhs, &fpRight, &allocateRight);
-    if (rhsNotNumber.isSet()) {
-        if (target)
-            stubcc.linkExitForBranch(rhsNotNumber.get());
-        else
-            stubcc.linkExit(rhsNotNumber.get(), Uses(2));
-    }
-    if (!allocateLeft)
-        frame.unpinReg(fpLeft);
-
-    Assembler::DoubleCondition dblCond = DoubleCondForOp(op, fused);
-
-    if (target) {
-        stubcc.leave();
-        OOL_STUBCALL(stub, REJOIN_BRANCH);
-
-        if (!allocateLeft)
-            frame.pinReg(fpLeft);
-        if (!allocateRight)
-            frame.pinReg(fpRight);
-
-        frame.syncAndKillEverything();
-
-        Jump j = masm.branchDouble(dblCond, fpLeft, fpRight);
-
-        if (allocateLeft)
-            frame.freeReg(fpLeft);
-        else
-            frame.unpinKilledReg(fpLeft);
-
-        if (allocateRight)
-            frame.freeReg(fpRight);
-        else
-            frame.unpinKilledReg(fpRight);
-
-        frame.popn(2);
-
-        Jump sj = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
-                                           Registers::ReturnReg, Registers::ReturnReg);
-
-        /* Rejoin from the slow path. */
-        stubcc.rejoin(Changes(0));
-
-        /*
-         * NB: jumpAndRun emits to the OOL path, so make sure not to use it
-         * in the middle of an in-progress slow path.
-         */
-        if (!jumpAndRun(j, target, &sj))
-            return false;
-    } else {
-        stubcc.leave();
-        OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-        frame.popn(2);
-
-        RegisterID reg = frame.allocReg();
-        Jump j = masm.branchDouble(dblCond, fpLeft, fpRight);
-        masm.move(Imm32(0), reg);
-        Jump skip = masm.jump();
-        j.linkTo(masm.label(), &masm);
-        masm.move(Imm32(1), reg);
-        skip.linkTo(masm.label(), &masm);
-
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, reg);
-
-        stubcc.rejoin(Changes(1));
-
-        if (allocateLeft)
-            frame.freeReg(fpLeft);
-        if (allocateRight)
-            frame.freeReg(fpRight);
-    }
-
-    return true;
-}
-
-bool
-mjit::Compiler::jsop_relational_int(JSOp op, jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* Reverse N cmp A comparisons.  The left side must be in a register. */
-    if (lhs->isConstant()) {
-        JS_ASSERT(!rhs->isConstant());
-        FrameEntry *tmp = lhs;
-        lhs = rhs;
-        rhs = tmp;
-        op = ReverseCompareOp(op);
-    }
-
-    JS_ASSERT_IF(!target, fused != JSOP_IFEQ);
-    Assembler::Condition cond = GetCompareCondition(op, fused);
-
-    if (target) {
-        if (!frame.syncForBranch(target, Uses(2)))
-            return false;
-
-        RegisterID lreg = frame.tempRegForData(lhs);
-        Jump fast;
-        if (rhs->isConstant()) {
-            fast = masm.branch32(cond, lreg, Imm32(rhs->getValue().toInt32()));
-        } else {
-            frame.pinReg(lreg);
-            RegisterID rreg = frame.tempRegForData(rhs);
-            frame.unpinReg(lreg);
-            fast = masm.branch32(cond, lreg, rreg);
-        }
-        frame.popn(2);
-
-        Jump sj = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
-                                           Registers::ReturnReg, Registers::ReturnReg);
-
-        return jumpAndRun(fast, target, &sj);
-    } else {
-        RegisterID result = frame.allocReg();
-        RegisterID lreg = frame.tempRegForData(lhs);
-
-        if (rhs->isConstant()) {
-            masm.branchValue(cond, lreg, rhs->getValue().toInt32(), result);
-        } else {
-            frame.pinReg(lreg);
-            RegisterID rreg = frame.tempRegForData(rhs);
-            frame.unpinReg(lreg);
-            masm.branchValue(cond, lreg, rreg, result);
-        }
-
-        frame.popn(2);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-    }
-
-    return true;
-}
-
-/* See jsop_binary_full() for more information on how this works. */
-bool
-mjit::Compiler::jsop_relational_full(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* Allocate all registers up-front. */
-    FrameState::BinaryAlloc regs;
-    frame.allocForBinary(lhs, rhs, op, regs, !target);
-
-    MaybeJump lhsNotDouble, rhsNotNumber, lhsUnknownDone;
-    if (!lhs->isTypeKnown())
-        emitLeftDoublePath(lhs, rhs, regs, lhsNotDouble, rhsNotNumber, lhsUnknownDone);
-
-    MaybeJump rhsNotNumber2;
-    if (!rhs->isTypeKnown())
-        emitRightDoublePath(lhs, rhs, regs, rhsNotNumber2);
-
-    /* Both double paths will join here. */
-    bool hasDoublePath = false;
-    if (masm.supportsFloatingPoint() && (!rhs->isTypeKnown() || !lhs->isTypeKnown()))
-        hasDoublePath = true;
-
-    /* Integer path - figure out the immutable side. */
-    JSOp cmpOp = op;
-    int32_t value = 0;
-    RegisterID cmpReg;
-    MaybeRegisterID reg;
-    if (regs.lhsData.isSet()) {
-        cmpReg = regs.lhsData.reg();
-        if (!regs.rhsData.isSet())
-            value = rhs->getValue().toInt32();
-        else
-            reg = regs.rhsData.reg();
-    } else {
-        cmpReg = regs.rhsData.reg();
-        value = lhs->getValue().toInt32();
-        cmpOp = ReverseCompareOp(op);
-    }
-
-    /*
-     * Emit the actual comparisons. When a fusion is in play, it's faster to
-     * combine the comparison with the jump, so these two cases are implemented
-     * separately.
-     */
-
-    if (target) {
-        /*
-         * Emit the double path now, necessary to complete the OOL fast-path
-         * before emitting the slow path.
-         *
-         * Note: doubles have not been swapped yet. Use original op.
-         */
-        MaybeJump doubleTest, doubleFall;
-        Assembler::DoubleCondition dblCond = DoubleCondForOp(op, fused);
-        if (hasDoublePath) {
-            if (lhsUnknownDone.isSet())
-                lhsUnknownDone.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-            frame.sync(stubcc.masm, Uses(frame.frameSlots()));
-            doubleTest = stubcc.masm.branchDouble(dblCond, regs.lhsFP, regs.rhsFP);
-            doubleFall = stubcc.masm.jump();
-        }
-
-        /* Link all incoming slow paths to here. */
-        if (lhsNotDouble.isSet()) {
-            lhsNotDouble.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-            if (rhsNotNumber.isSet())
-                rhsNotNumber.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-        }
-        if (rhsNotNumber2.isSet())
-            rhsNotNumber2.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        /*
-         * For fusions, spill the tracker state. xmm* remain intact. Note
-         * that frame.sync() must be used directly, to avoid syncExit()'s
-         * jumping logic.
-         */
-        frame.sync(stubcc.masm, Uses(frame.frameSlots()));
-        stubcc.leave();
-        OOL_STUBCALL(stub, REJOIN_BRANCH);
-
-        /* Forget the world, preserving data. */
-        frame.pinReg(cmpReg);
-        if (reg.isSet())
-            frame.pinReg(reg.reg());
-
-        frame.popn(2);
-
-        frame.syncAndKillEverything();
-        frame.unpinKilledReg(cmpReg);
-        if (reg.isSet())
-            frame.unpinKilledReg(reg.reg());
-        frame.freeReg(regs.lhsFP);
-        frame.freeReg(regs.rhsFP);
-
-        /* Operands could have been reordered, so use cmpOp. */
-        Assembler::Condition i32Cond = GetCompareCondition(cmpOp, fused);
-
-        /* Emit the i32 path. */
-        Jump fast;
-        if (reg.isSet())
-            fast = masm.branch32(i32Cond, cmpReg, reg.reg());
-        else
-            fast = masm.branch32(i32Cond, cmpReg, Imm32(value));
-
-        /*
-         * The stub call has no need to rejoin since state is synced. Instead,
-         * we can just test the return value.
-         */
-        Jump j = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
-                                          Registers::ReturnReg, Registers::ReturnReg);
-
-        /* Rejoin from the slow path. */
-        Jump j2 = stubcc.masm.jump();
-        stubcc.crossJump(j2, masm.label());
-
-        if (hasDoublePath) {
-            j.linkTo(stubcc.masm.label(), &stubcc.masm);
-            doubleTest.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-            j = stubcc.masm.jump();
-        }
-
-        /*
-         * NB: jumpAndRun emits to the OOL path, so make sure not to use it
-         * in the middle of an in-progress slow path.
-         */
-        if (!jumpAndRun(fast, target, &j))
-            return false;
-
-        /* Rejoin from the double path. */
-        if (hasDoublePath)
-            stubcc.crossJump(doubleFall.get(), masm.label());
-    } else {
-        /*
-         * Emit the double path now, necessary to complete the OOL fast-path
-         * before emitting the slow path.
-         */
-        MaybeJump doubleDone;
-        Assembler::DoubleCondition dblCond = DoubleCondForOp(op, JSOP_NOP);
-        if (hasDoublePath) {
-            if (lhsUnknownDone.isSet())
-                lhsUnknownDone.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-            /* :FIXME: Use SET if we can? */
-            Jump test = stubcc.masm.branchDouble(dblCond, regs.lhsFP, regs.rhsFP);
-            stubcc.masm.move(Imm32(0), regs.result);
-            Jump skip = stubcc.masm.jump();
-            test.linkTo(stubcc.masm.label(), &stubcc.masm);
-            stubcc.masm.move(Imm32(1), regs.result);
-            skip.linkTo(stubcc.masm.label(), &stubcc.masm);
-            doubleDone = stubcc.masm.jump();
-        }
-
-        /* Link all incoming slow paths to here. */
-        if (lhsNotDouble.isSet()) {
-            lhsNotDouble.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-            if (rhsNotNumber.isSet())
-                rhsNotNumber.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-        }
-        if (rhsNotNumber2.isSet())
-            rhsNotNumber2.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        /* Emit the slow path - note full frame syncage. */
-        frame.sync(stubcc.masm, Uses(2));
-        stubcc.leave();
-        OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-        /* Get an integer comparison condition. */
-        Assembler::Condition i32Cond = GetCompareCondition(cmpOp, fused);
-
-        /* Emit the compare & set. */
-        if (reg.isSet())
-            masm.branchValue(i32Cond, cmpReg, reg.reg(), regs.result);
-        else
-            masm.branchValue(i32Cond, cmpReg, value, regs.result);
-
-        frame.popn(2);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, regs.result);
-
-        if (hasDoublePath)
-            stubcc.crossJump(doubleDone.get(), masm.label());
-        stubcc.rejoin(Changes(1));
-
-        frame.freeReg(regs.lhsFP);
-        frame.freeReg(regs.rhsFP);
-    }
-
-    return true;
-}
-
deleted file mode 100644
--- a/js/src/methodjit/FastBuiltins.cpp
+++ /dev/null
@@ -1,1060 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/DebugOnly.h"
-
-#include "jsbool.h"
-#include "jslibmath.h"
-#include "jsmath.h"
-#include "jsnum.h"
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Compiler.h"
-#include "methodjit/StubCalls.h"
-#include "methodjit/FrameState-inl.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace JSC;
-
-using mozilla::DebugOnly;
-
-typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-
-CompileStatus
-mjit::Compiler::compileMathAbsInt(FrameEntry *arg)
-{
-    RegisterID reg;
-    if (arg->isConstant()) {
-        reg = frame.allocReg();
-        masm.move(Imm32(arg->getValue().toInt32()), reg);
-    } else {
-        reg = frame.copyDataIntoReg(arg);
-    }
-
-    Jump isPositive = masm.branch32(Assembler::GreaterThanOrEqual, reg, Imm32(0));
-
-    /* Math.abs(INT32_MIN) results in a double */
-    Jump isMinInt = masm.branch32(Assembler::Equal, reg, Imm32(INT32_MIN));
-    stubcc.linkExit(isMinInt, Uses(3));
-
-    masm.neg32(reg);
-
-    isPositive.linkTo(masm.label(), &masm);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileMathAbsDouble(FrameEntry *arg)
-{
-    FPRegisterID fpResultReg = frame.allocFPReg();
-
-    FPRegisterID fpReg;
-    bool allocate;
-
-    DebugOnly<MaybeJump> notNumber = loadDouble(arg, &fpReg, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-    masm.absDouble(fpReg, fpResultReg);
-
-    if (allocate)
-        frame.freeReg(fpReg);
-
-    frame.popn(3);
-    frame.pushDouble(fpResultReg);
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileRound(FrameEntry *arg, RoundingMode mode)
-{
-    FPRegisterID fpScratchReg = frame.allocFPReg();
-
-    FPRegisterID fpReg;
-    bool allocate;
-
-    DebugOnly<MaybeJump> notNumber = loadDouble(arg, &fpReg, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-    masm.zeroDouble(fpScratchReg);
-
-    /* Slow path for NaN and numbers <= 0. */
-    Jump negOrNan = masm.branchDouble(Assembler::DoubleLessThanOrEqualOrUnordered, fpReg, fpScratchReg);
-    stubcc.linkExit(negOrNan, Uses(3));
-
-    /* For round add 0.5 and floor. */
-    FPRegisterID fpSourceReg;
-    if (mode == Round) {
-        masm.slowLoadConstantDouble(0.5, fpScratchReg);
-        masm.addDouble(fpReg, fpScratchReg);
-        fpSourceReg = fpScratchReg;
-    } else {
-        fpSourceReg = fpReg;
-    }
-
-    /* Truncate to integer, slow path if this overflows. */
-    RegisterID reg = frame.allocReg();
-    Jump overflow = masm.branchTruncateDoubleToInt32(fpSourceReg, reg);
-    stubcc.linkExit(overflow, Uses(3));
-
-    if (allocate)
-        frame.freeReg(fpReg);
-    frame.freeReg(fpScratchReg);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileMathSqrt(FrameEntry *arg)
-{
-    FPRegisterID fpResultReg = frame.allocFPReg();
-
-    FPRegisterID fpReg;
-    bool allocate;
-
-    DebugOnly<MaybeJump> notNumber = loadDouble(arg, &fpReg, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-    masm.sqrtDouble(fpReg, fpResultReg);
-
-    if (allocate)
-        frame.freeReg(fpReg);
-
-    frame.popn(3);
-    frame.pushDouble(fpResultReg);
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileMathMinMaxDouble(FrameEntry *arg1, FrameEntry *arg2,
-                                        Assembler::DoubleCondition cond)
-{
-    FPRegisterID fpReg1;
-    FPRegisterID fpReg2;
-    bool allocate;
-
-    DebugOnly<MaybeJump> notNumber = loadDouble(arg1, &fpReg1, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-    if (!allocate) {
-        FPRegisterID fpResultReg = frame.allocFPReg();
-        masm.moveDouble(fpReg1, fpResultReg);
-        fpReg1 = fpResultReg;
-    }
-
-    DebugOnly<MaybeJump> notNumber2 = loadDouble(arg2, &fpReg2, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber2).isSet());
-
-
-    /* Slow path for 0 and NaN, because they have special requriments. */
-    masm.zeroDouble(Registers::FPConversionTemp);
-    Jump zeroOrNan = masm.branchDouble(Assembler::DoubleEqualOrUnordered, fpReg1,
-                                       Registers::FPConversionTemp);
-    stubcc.linkExit(zeroOrNan, Uses(4));
-    Jump zeroOrNan2 = masm.branchDouble(Assembler::DoubleEqualOrUnordered, fpReg2,
-                                        Registers::FPConversionTemp);
-    stubcc.linkExit(zeroOrNan2, Uses(4));
-
-
-    Jump ifTrue = masm.branchDouble(cond, fpReg1, fpReg2);
-    masm.moveDouble(fpReg2, fpReg1);
-
-    ifTrue.linkTo(masm.label(), &masm);
-
-    if (allocate)
-        frame.freeReg(fpReg2);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(2), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(4);
-    frame.pushDouble(fpReg1);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileMathMinMaxInt(FrameEntry *arg1, FrameEntry *arg2, Assembler::Condition cond)
-{
-    /* Get this case out of the way */
-    if (arg1->isConstant() && arg2->isConstant()) {
-        int32_t a = arg1->getValue().toInt32();
-        int32_t b = arg2->getValue().toInt32();
-
-        frame.popn(4);
-        if (cond == Assembler::LessThan)
-            frame.push(Int32Value(a < b ? a : b));
-        else
-            frame.push(Int32Value(a > b ? a : b));
-        return Compile_Okay;
-    }
-
-    Jump ifTrue;
-    RegisterID reg;
-    if (arg1->isConstant()) {
-        reg = frame.copyDataIntoReg(arg2);
-        int32_t v = arg1->getValue().toInt32();
-
-        ifTrue = masm.branch32(cond, reg, Imm32(v));
-        masm.move(Imm32(v), reg);
-    } else if (arg2->isConstant()) {
-        reg = frame.copyDataIntoReg(arg1);
-        int32_t v = arg2->getValue().toInt32();
-
-        ifTrue = masm.branch32(cond, reg, Imm32(v));
-        masm.move(Imm32(v), reg);
-    } else {
-        reg = frame.copyDataIntoReg(arg1);
-        RegisterID regB = frame.tempRegForData(arg2);
-
-        ifTrue = masm.branch32(cond, reg, regB);
-        masm.move(regB, reg);
-    }
-
-    ifTrue.linkTo(masm.label(), &masm);
-    frame.popn(4);
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileMathPowSimple(FrameEntry *arg1, FrameEntry *arg2)
-{
-    FPRegisterID fpScratchReg = frame.allocFPReg();
-    FPRegisterID fpResultReg = frame.allocFPReg();
-
-    FPRegisterID fpReg;
-    bool allocate;
-
-    DebugOnly<MaybeJump> notNumber = loadDouble(arg1, &fpReg, &allocate);
-    JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-    /* Slow path for -Infinity (must return Infinity, not NaN). */
-    masm.slowLoadConstantDouble(js_NegativeInfinity, fpResultReg);
-    Jump isNegInfinity = masm.branchDouble(Assembler::DoubleEqual, fpReg, fpResultReg);
-    stubcc.linkExit(isNegInfinity, Uses(4));
-
-    /* Convert -0 to +0. */
-    masm.zeroDouble(fpResultReg);
-    masm.moveDouble(fpReg, fpScratchReg);
-    masm.addDouble(fpResultReg, fpScratchReg);
-
-    double y = arg2->getValue().toDouble();
-    if (y == 0.5) {
-        /* pow(x, 0.5) => sqrt(x) */
-        masm.sqrtDouble(fpScratchReg, fpResultReg);
-
-    } else if (y == -0.5) {
-        /* pow(x, -0.5) => 1/sqrt(x) */
-        masm.sqrtDouble(fpScratchReg, fpScratchReg);
-        masm.slowLoadConstantDouble(1, fpResultReg);
-        masm.divDouble(fpScratchReg, fpResultReg);
-    }
-
-    frame.freeReg(fpScratchReg);
-
-    if (allocate)
-        frame.freeReg(fpReg);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(2), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(4);
-    frame.pushDouble(fpResultReg);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileGetChar(FrameEntry *thisValue, FrameEntry *arg, GetCharMode mode)
-{
-    RegisterID reg1 = frame.allocReg();
-    RegisterID reg2 = frame.allocReg();
-
-    /* Load string in strReg. */
-    RegisterID strReg;
-    if (thisValue->isConstant()) {
-        strReg = frame.allocReg();
-        masm.move(ImmPtr(thisValue->getValue().toString()), strReg);
-    } else {
-        strReg = frame.tempRegForData(thisValue);
-        frame.pinReg(strReg);
-    }
-
-    /* Load index in argReg. */
-    RegisterID argReg;
-    if (arg->isConstant()) {
-        argReg = frame.allocReg();
-        masm.move(Imm32(arg->getValue().toInt32()), argReg);
-    } else {
-        argReg = frame.tempRegForData(arg);
-    }
-    if (!thisValue->isConstant())
-        frame.unpinReg(strReg);
-
-    Address lengthAndFlagsAddr(strReg, JSString::offsetOfLengthAndFlags());
-
-    /* Load lengthAndFlags in reg1 and reg2 */
-    masm.loadPtr(lengthAndFlagsAddr, reg1);
-    masm.move(reg1, reg2);
-
-    /* Slow path if string is a rope */
-    masm.andPtr(ImmPtr((void *)JSString::FLAGS_MASK), reg1);
-    Jump isRope = masm.branchTestPtr(Assembler::Zero, reg1);
-    stubcc.linkExit(isRope, Uses(3));
-
-    /* Slow path if out-of-range. */
-    masm.rshiftPtr(Imm32(JSString::LENGTH_SHIFT), reg2);
-    Jump outOfRange = masm.branchPtr(Assembler::AboveOrEqual, argReg, reg2);
-    stubcc.linkExit(outOfRange, Uses(3));
-
-    /* Load char code in reg2. */
-    masm.move(argReg, reg1);
-    masm.loadPtr(Address(strReg, JSString::offsetOfChars()), reg2);
-    masm.lshiftPtr(Imm32(1), reg1);
-    masm.addPtr(reg1, reg2);
-    masm.load16(Address(reg2), reg2);
-
-    /* Convert char code to string. */
-    if (mode == GetChar) {
-        /* Slow path if there's no unit string for this character. */
-        Jump notUnitString = masm.branch32(Assembler::AboveOrEqual, reg2,
-                                           Imm32(StaticStrings::UNIT_STATIC_LIMIT));
-        stubcc.linkExit(notUnitString, Uses(3));
-
-        /* Load unit string in reg2. */
-        masm.lshiftPtr(Imm32(sizeof(JSAtom *) == 4 ? 2 : 3), reg2);
-        masm.addPtr(ImmPtr(&cx->runtime->staticStrings.unitStaticTable), reg2);
-        masm.loadPtr(Address(reg2), reg2);
-    }
-
-    if (thisValue->isConstant())
-        frame.freeReg(strReg);
-    if (arg->isConstant())
-        frame.freeReg(argReg);
-    frame.freeReg(reg1);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    switch(mode) {
-      case GetCharCode:
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg2);
-        break;
-      case GetChar:
-        frame.pushTypedPayload(JSVAL_TYPE_STRING, reg2);
-        break;
-      default:
-        JS_NOT_REACHED("unknown getchar mode");
-    }
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileStringFromCode(FrameEntry *arg)
-{
-    /* Load Char-Code into argReg */
-    RegisterID argReg;
-    if (arg->isConstant()) {
-        argReg = frame.allocReg();
-        masm.move(Imm32(arg->getValue().toInt32()), argReg);
-    } else {
-        argReg = frame.copyDataIntoReg(arg);
-    }
-
-    /* Slow path if there's no unit string for this character. */
-    Jump notUnitString = masm.branch32(Assembler::AboveOrEqual, argReg,
-                                       Imm32(StaticStrings::UNIT_STATIC_LIMIT));
-    stubcc.linkExit(notUnitString, Uses(3));
-
-    /* Load unit string in reg. */
-    masm.lshiftPtr(Imm32(sizeof(JSAtom *) == 4 ? 2 : 3), argReg);
-    masm.addPtr(ImmPtr(&cx->runtime->staticStrings.unitStaticTable), argReg);
-    masm.loadPtr(Address(argReg), argReg);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    frame.pushTypedPayload(JSVAL_TYPE_STRING, argReg);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileArrayPush(FrameEntry *thisValue, FrameEntry *arg,
-                                 types::StackTypeSet::DoubleConversion conversion)
-{
-    /* This behaves like an assignment this[this.length] = arg; */
-
-    /* Filter out silly cases. */
-    if (frame.haveSameBacking(thisValue, arg) || thisValue->isConstant())
-        return Compile_InlineAbort;
-
-    if (conversion == types::StackTypeSet::AlwaysConvertToDoubles ||
-        conversion == types::StackTypeSet::MaybeConvertToDoubles)
-    {
-        frame.ensureDouble(arg);
-    }
-
-    /* Allocate registers. */
-    ValueRemat vr;
-    frame.pinEntry(arg, vr, /* breakDouble = */ false);
-
-    RegisterID objReg = frame.tempRegForData(thisValue);
-    frame.pinReg(objReg);
-
-    RegisterID slotsReg = frame.allocReg();
-    masm.loadPtr(Address(objReg, JSObject::offsetOfElements()), slotsReg);
-
-    RegisterID lengthReg = frame.allocReg();
-    masm.load32(Address(slotsReg, ObjectElements::offsetOfLength()), lengthReg);
-
-    frame.unpinReg(objReg);
-
-    Int32Key key = Int32Key::FromRegister(lengthReg);
-
-    /* Test for 'length == initializedLength' */
-    Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                              slotsReg, key, Assembler::NotEqual);
-    stubcc.linkExit(initlenGuard, Uses(3));
-
-    /* Test for 'length < capacity' */
-    Jump capacityGuard = masm.guardArrayExtent(ObjectElements::offsetOfCapacity(),
-                                               slotsReg, key, Assembler::BelowOrEqual);
-    stubcc.linkExit(capacityGuard, Uses(3));
-
-    masm.storeValue(vr, BaseIndex(slotsReg, lengthReg, masm.JSVAL_SCALE));
-
-    masm.bumpKey(key, 1);
-    masm.store32(lengthReg, Address(slotsReg, ObjectElements::offsetOfLength()));
-    masm.store32(lengthReg, Address(slotsReg, ObjectElements::offsetOfInitializedLength()));
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.unpinEntry(vr);
-    frame.freeReg(slotsReg);
-    frame.popn(3);
-
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, lengthReg);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileArrayPopShift(FrameEntry *thisValue, bool isPacked, bool isArrayPop)
-{
-    /* Filter out silly cases. */
-    if (thisValue->isConstant())
-        return Compile_InlineAbort;
-
-#ifdef JSGC_INCREMENTAL_MJ
-    /* Write barrier. */
-    if (cx->zone()->compileBarriers())
-        return Compile_InlineAbort;
-#endif
-
-    RegisterID objReg = frame.tempRegForData(thisValue);
-    frame.pinReg(objReg);
-
-    RegisterID lengthReg = frame.allocReg();
-    RegisterID slotsReg = frame.allocReg();
-
-    JSValueType type = knownPushedType(0);
-
-    MaybeRegisterID dataReg, typeReg;
-    if (!analysis->popGuaranteed(PC)) {
-        dataReg = frame.allocReg();
-        if (type == JSVAL_TYPE_UNKNOWN || type == JSVAL_TYPE_DOUBLE)
-            typeReg = frame.allocReg();
-    }
-
-    if (isArrayPop) {
-        frame.unpinReg(objReg);
-    } else {
-        /*
-         * Sync up front for shift() so we can jump over the inline stub.
-         * The result will be stored in memory rather than registers.
-         */
-        frame.syncAndKillEverything();
-        frame.unpinKilledReg(objReg);
-    }
-
-    masm.loadPtr(Address(objReg, JSObject::offsetOfElements()), slotsReg);
-    masm.load32(Address(slotsReg, ObjectElements::offsetOfLength()), lengthReg);
-
-    /* Test for 'length == initializedLength' */
-    Int32Key key = Int32Key::FromRegister(lengthReg);
-    Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                              slotsReg, key, Assembler::NotEqual);
-    stubcc.linkExit(initlenGuard, Uses(3));
-
-    /*
-     * Test for length != 0. On zero length either take a slow call or generate
-     * an undefined value, depending on whether the call is known to produce
-     * undefined.
-     */
-    bool maybeUndefined = pushedTypeSet(0)->hasType(types::Type::UndefinedType());
-    Jump emptyGuard = masm.branch32(Assembler::Equal, lengthReg, Imm32(0));
-    if (!maybeUndefined)
-        stubcc.linkExit(emptyGuard, Uses(3));
-
-    masm.bumpKey(key, -1);
-
-    if (dataReg.isSet()) {
-        Jump holeCheck;
-        if (isArrayPop) {
-            BaseIndex slot(slotsReg, lengthReg, masm.JSVAL_SCALE);
-            holeCheck = masm.fastArrayLoadSlot(slot, !isPacked, typeReg, dataReg.reg());
-        } else {
-            holeCheck = masm.fastArrayLoadSlot(Address(slotsReg), !isPacked, typeReg, dataReg.reg());
-            Address addr = frame.addressOf(frame.peek(-2));
-            if (typeReg.isSet())
-                masm.storeValueFromComponents(typeReg.reg(), dataReg.reg(), addr);
-            else
-                masm.storeValueFromComponents(ImmType(type), dataReg.reg(), addr);
-        }
-        if (!isPacked)
-            stubcc.linkExit(holeCheck, Uses(3));
-    }
-
-    masm.store32(lengthReg, Address(slotsReg, ObjectElements::offsetOfLength()));
-    masm.store32(lengthReg, Address(slotsReg, ObjectElements::offsetOfInitializedLength()));
-
-    if (!isArrayPop)
-        INLINE_STUBCALL(stubs::ArrayShift, REJOIN_NONE);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(0), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.freeReg(slotsReg);
-    frame.freeReg(lengthReg);
-    frame.popn(2);
-
-    if (dataReg.isSet()) {
-        if (isArrayPop) {
-            if (typeReg.isSet())
-                frame.pushRegs(typeReg.reg(), dataReg.reg(), type);
-            else
-                frame.pushTypedPayload(type, dataReg.reg());
-        } else {
-            frame.pushSynced(type);
-            if (typeReg.isSet())
-                frame.freeReg(typeReg.reg());
-            frame.freeReg(dataReg.reg());
-        }
-    } else {
-        frame.push(UndefinedValue());
-    }
-
-    stubcc.rejoin(Changes(1));
-
-    if (maybeUndefined) {
-        /* Generate an OOL path to push an undefined value, and rejoin. */
-        if (dataReg.isSet()) {
-            stubcc.linkExitDirect(emptyGuard, stubcc.masm.label());
-            if (isArrayPop) {
-                if (typeReg.isSet()) {
-                    stubcc.masm.loadValueAsComponents(UndefinedValue(), typeReg.reg(), dataReg.reg());
-                } else {
-                    JS_ASSERT(type == JSVAL_TYPE_UNDEFINED);
-                    stubcc.masm.loadValuePayload(UndefinedValue(), dataReg.reg());
-                }
-            } else {
-                stubcc.masm.storeValue(UndefinedValue(), frame.addressOf(frame.peek(-1)));
-            }
-            stubcc.crossJump(stubcc.masm.jump(), masm.label());
-        } else {
-            emptyGuard.linkTo(masm.label(), &masm);
-        }
-    }
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileArrayConcat(types::TypeSet *thisTypes, types::TypeSet *argTypes,
-                                   FrameEntry *thisValue, FrameEntry *argValue)
-{
-    frame.forgetMismatchedObject(thisValue);
-    frame.forgetMismatchedObject(argValue);
-
-    /*
-     * Require the 'this' types to have a specific type matching the current
-     * global, so we can create the result object inline.
-     */
-    if (thisTypes->getObjectCount() != 1)
-        return Compile_InlineAbort;
-    types::TypeObject *thisType = thisTypes->getTypeObject(0);
-    if (!thisType || &thisType->proto->global() != globalObj)
-        return Compile_InlineAbort;
-
-    /*
-     * Constraints modeling this concat have not been generated by inference,
-     * so check that type information already reflects possible side effects of
-     * this call.
-     */
-    types::HeapTypeSet *thisElemTypes = thisType->getProperty(cx, JSID_VOID, false);
-    if (!thisElemTypes)
-        return Compile_Error;
-    if (!pushedTypeSet(0)->hasType(types::Type::ObjectType(thisType)))
-        return Compile_InlineAbort;
-    for (unsigned i = 0; i < argTypes->getObjectCount(); i++) {
-        if (argTypes->getSingleObject(i))
-            return Compile_InlineAbort;
-        types::TypeObject *argType = argTypes->getTypeObject(i);
-        if (!argType)
-            continue;
-        types::HeapTypeSet *elemTypes = argType->getProperty(cx, JSID_VOID, false);
-        if (!elemTypes)
-            return Compile_Error;
-        if (!elemTypes->knownSubset(cx, thisElemTypes))
-            return Compile_InlineAbort;
-    }
-
-    /* Test for 'length == initializedLength' on both arrays. */
-
-    RegisterID slotsReg = frame.allocReg();
-    RegisterID reg = frame.allocReg();
-
-    Int32Key key = Int32Key::FromRegister(reg);
-
-    RegisterID objReg = frame.tempRegForData(thisValue);
-    masm.loadPtr(Address(objReg, JSObject::offsetOfElements()), slotsReg);
-    masm.load32(Address(slotsReg, ObjectElements::offsetOfLength()), reg);
-    Jump initlenOneGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                                 slotsReg, key, Assembler::NotEqual);
-    stubcc.linkExit(initlenOneGuard, Uses(3));
-
-    objReg = frame.tempRegForData(argValue);
-    masm.loadPtr(Address(objReg, JSObject::offsetOfElements()), slotsReg);
-    masm.load32(Address(slotsReg, ObjectElements::offsetOfLength()), reg);
-    Jump initlenTwoGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                                 slotsReg, key, Assembler::NotEqual);
-    stubcc.linkExit(initlenTwoGuard, Uses(3));
-
-    frame.freeReg(reg);
-    frame.freeReg(slotsReg);
-    frame.syncAndForgetEverything();
-
-    /*
-     * The current stack layout is 'CALLEE THIS ARG'. Allocate the result and
-     * scribble it over the callee, which will be its final position after the
-     * call.
-     */
-
-    JSObject *templateObject = NewDenseEmptyArray(cx, thisType->proto);
-    if (!templateObject)
-        return Compile_Error;
-    templateObject->setType(thisType);
-
-    RegisterID result = Registers::ReturnReg;
-    Jump emptyFreeList = getNewObject(cx, result, templateObject);
-    stubcc.linkExit(emptyFreeList, Uses(3));
-
-    masm.storeValueFromComponents(ImmType(JSVAL_TYPE_OBJECT), result, frame.addressOf(frame.peek(-3)));
-    INLINE_STUBCALL(stubs::ArrayConcatTwoArrays, REJOIN_FALLTHROUGH);
-
-    stubcc.leave();
-    stubcc.masm.move(Imm32(1), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(3);
-    frame.pushSynced(JSVAL_TYPE_OBJECT);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileArrayWithLength(uint32_t argc)
-{
-    /* Match Array() or Array(n) for constant n. */
-    JS_ASSERT(argc == 0 || argc == 1);
-
-    int32_t length = 0;
-    if (argc == 1) {
-        FrameEntry *arg = frame.peek(-1);
-        if (!arg->isConstant() || !arg->getValue().isInt32())
-            return Compile_InlineAbort;
-        length = arg->getValue().toInt32();
-        if (length < 0)
-            return Compile_InlineAbort;
-    }
-
-    RootedScript script(cx, script_);
-    types::TypeObject *type = types::TypeScript::InitObject(cx, script, PC, JSProto_Array);
-    if (!type)
-        return Compile_Error;
-
-    JSObject *templateObject = NewDenseUnallocatedArray(cx, length, type->proto);
-    if (!templateObject)
-        return Compile_Error;
-    templateObject->setType(type);
-
-    RegisterID result = frame.allocReg();
-    Jump emptyFreeList = getNewObject(cx, result, templateObject);
-
-    stubcc.linkExit(emptyFreeList, Uses(0));
-    stubcc.leave();
-
-    stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(argc + 2);
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, result);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileArrayWithArgs(uint32_t argc)
-{
-    /*
-     * Match Array(x, y, z) with at least two arguments. Don't inline the case
-     * where a non-number argument is passed, so we don't need to care about
-     * the types of the arguments.
-     */
-    JS_ASSERT(argc >= 2);
-
-    size_t maxArraySlots =
-        gc::GetGCKindSlots(gc::FINALIZE_OBJECT_LAST) - ObjectElements::VALUES_PER_HEADER;
-
-    if (argc > maxArraySlots)
-        return Compile_InlineAbort;
-
-    RootedScript script(cx, script_);
-    types::TypeObject *type = types::TypeScript::InitObject(cx, script, PC, JSProto_Array);
-    if (!type)
-        return Compile_Error;
-
-    JSObject *templateObject = NewDenseUnallocatedArray(cx, argc, type->proto);
-    if (!templateObject)
-        return Compile_Error;
-    templateObject->setType(type);
-
-    JS_ASSERT(templateObject->getDenseCapacity() >= argc);
-
-    types::StackTypeSet::DoubleConversion conversion =
-        script->analysis()->pushedTypes(PC, 0)->convertDoubleElements(cx);
-    if (conversion == types::StackTypeSet::AlwaysConvertToDoubles) {
-        templateObject->setShouldConvertDoubleElements();
-        for (unsigned i = 0; i < argc; i++) {
-            FrameEntry *arg = frame.peek(-(int32_t)argc + i);
-            frame.ensureDouble(arg);
-        }
-    }
-
-    RegisterID result = frame.allocReg();
-    Jump emptyFreeList = getNewObject(cx, result, templateObject);
-    stubcc.linkExit(emptyFreeList, Uses(0));
-
-    int offset = JSObject::offsetOfFixedElements();
-    masm.store32(Imm32(argc),
-                 Address(result, offset + ObjectElements::offsetOfInitializedLength()));
-
-    for (unsigned i = 0; i < argc; i++) {
-        FrameEntry *arg = frame.peek(-(int32_t)argc + i);
-        frame.storeTo(arg, Address(result, offset), /* popped = */ true);
-        offset += sizeof(Value);
-    }
-
-    stubcc.leave();
-
-    stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
-    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-    frame.popn(argc + 2);
-    frame.pushTypedPayload(JSVAL_TYPE_OBJECT, result);
-
-    stubcc.rejoin(Changes(1));
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::compileParseInt(JSValueType argType, uint32_t argc)
-{
-    bool needStubCall = false;
-
-    if (argc > 1) {
-        FrameEntry *arg = frame.peek(-(int32_t)argc + 1);
-
-        if (!arg->isTypeKnown() || arg->getKnownType() != JSVAL_TYPE_INT32)
-            return Compile_InlineAbort;
-
-        if (arg->isConstant()) {
-            int32_t base = arg->getValue().toInt32();
-            if (base != 0 && base != 10)
-                return Compile_InlineAbort;
-        } else {
-            RegisterID baseReg = frame.tempRegForData(arg);
-            needStubCall = true;
-
-            Jump isTen = masm.branch32(Assembler::Equal, baseReg, Imm32(10));
-            Jump isNotZero = masm.branch32(Assembler::NotEqual, baseReg, Imm32(0));
-            stubcc.linkExit(isNotZero, Uses(2 + argc));
-
-            isTen.linkTo(masm.label(), &masm);
-        }
-    }
-
-    if (argType == JSVAL_TYPE_INT32) {
-        if (needStubCall) {
-            stubcc.leave();
-            stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
-            OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-        }
-
-        /*
-         * Stack looks like callee, this, arg1, arg2, argN.
-         * First pop all args other than arg1.
-         */
-        frame.popn(argc - 1);
-        /* "Shimmy" arg1 to the callee slot and pop this + arg1. */
-        frame.shimmy(2);
-
-        if (needStubCall) {
-            stubcc.rejoin(Changes(1));
-        }
-    } else {
-        FrameEntry *arg = frame.peek(-(int32_t)argc);
-        FPRegisterID fpScratchReg = frame.allocFPReg();
-        FPRegisterID fpReg;
-        bool allocate;
-
-        DebugOnly<MaybeJump> notNumber = loadDouble(arg, &fpReg, &allocate);
-        JS_ASSERT(!((MaybeJump)notNumber).isSet());
-
-        masm.slowLoadConstantDouble(1, fpScratchReg);
-
-        /* Slow path for NaN and numbers < 1. */
-        Jump lessThanOneOrNan = masm.branchDouble(Assembler::DoubleLessThanOrUnordered,
-                                                  fpReg, fpScratchReg);
-        stubcc.linkExit(lessThanOneOrNan, Uses(2 + argc));
-
-        frame.freeReg(fpScratchReg);
-
-        /* Truncate to integer, slow path if this overflows. */
-        RegisterID reg = frame.allocReg();
-        Jump overflow = masm.branchTruncateDoubleToInt32(fpReg, reg);
-        stubcc.linkExit(overflow, Uses(2 + argc));
-
-        if (allocate)
-            frame.freeReg(fpReg);
-
-        stubcc.leave();
-        stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
-        OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
-
-        frame.popn(2 + argc);
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-        stubcc.rejoin(Changes(1));
-    }
-
-    return Compile_Okay;
-}
-
-CompileStatus
-mjit::Compiler::inlineNativeFunction(uint32_t argc, bool callingNew)
-{
-    if (!cx->typeInferenceEnabled())
-        return Compile_InlineAbort;
-
-    FrameEntry *origCallee = frame.peek(-((int)argc + 2));
-    FrameEntry *thisValue = frame.peek(-((int)argc + 1));
-    types::StackTypeSet *thisTypes = analysis->poppedTypes(PC, argc);
-
-    if (!origCallee->isConstant() || !origCallee->isType(JSVAL_TYPE_OBJECT))
-        return Compile_InlineAbort;
-
-    JSObject *callee = &origCallee->getValue().toObject();
-    if (!callee->isFunction())
-        return Compile_InlineAbort;
-
-    /*
-     * The callee must have the same parent as the script's global, otherwise
-     * inference may not have accounted for any side effects correctly.
-     */
-    if (!globalObj || globalObj != &callee->global())
-        return Compile_InlineAbort;
-
-    Native native = callee->toFunction()->maybeNative();
-
-    if (!native)
-        return Compile_InlineAbort;
-
-    JSValueType type = knownPushedType(0);
-    JSValueType thisType = thisValue->isTypeKnown()
-                           ? thisValue->getKnownType()
-                           : JSVAL_TYPE_UNKNOWN;
-
-    /*
-     * Note: when adding new natives which operate on properties, add relevant
-     * constraint generation to the behavior of TypeConstraintCall.
-     */
-
-    /* Handle natives that can be called either with or without 'new'. */
-
-    if (native == js_Array && type == JSVAL_TYPE_OBJECT && globalObj) {
-        if (argc == 0 || argc == 1)
-            return compileArrayWithLength(argc);
-        return compileArrayWithArgs(argc);
-    }
-
-    /* Remaining natives must not be called with 'new'. */
-    if (callingNew)
-        return Compile_InlineAbort;
-
-    if (native == js::num_parseInt && argc >= 1) {
-        FrameEntry *arg = frame.peek(-(int32_t)argc);
-        JSValueType argType = arg->isTypeKnown() ? arg->getKnownType() : JSVAL_TYPE_UNKNOWN;
-
-        if ((argType == JSVAL_TYPE_DOUBLE || argType == JSVAL_TYPE_INT32) &&
-            type == JSVAL_TYPE_INT32) {
-            return compileParseInt(argType, argc);
-        }
-    }
-
-    if (argc == 0) {
-    } else if (argc == 1) {
-        FrameEntry *arg = frame.peek(-1);
-        types::StackTypeSet *argTypes = frame.extra(arg).types;
-        if (!argTypes)
-            return Compile_InlineAbort;
-        JSValueType argType = arg->isTypeKnown() ? arg->getKnownType() : JSVAL_TYPE_UNKNOWN;
-
-        if (native == js_math_abs) {
-            if (argType == JSVAL_TYPE_INT32 && type == JSVAL_TYPE_INT32)
-                return compileMathAbsInt(arg);
-
-            if (argType == JSVAL_TYPE_DOUBLE && type == JSVAL_TYPE_DOUBLE)
-                return compileMathAbsDouble(arg);
-        }
-        if (native == js_math_floor && argType == JSVAL_TYPE_DOUBLE &&
-            type == JSVAL_TYPE_INT32) {
-            return compileRound(arg, Floor);
-        }
-        if (native == js_math_round && argType == JSVAL_TYPE_DOUBLE &&
-            type == JSVAL_TYPE_INT32) {
-            return compileRound(arg, Round);
-        }
-        if (native == js_math_sqrt && type == JSVAL_TYPE_DOUBLE &&
-             masm.supportsFloatingPointSqrt() &&
-            (argType == JSVAL_TYPE_INT32 || argType == JSVAL_TYPE_DOUBLE)) {
-            return compileMathSqrt(arg);
-        }
-        if (native == js_str_charCodeAt && argType == JSVAL_TYPE_INT32 &&
-            thisType == JSVAL_TYPE_STRING && type == JSVAL_TYPE_INT32) {
-            return compileGetChar(thisValue, arg, GetCharCode);
-        }
-        if (native == js_str_charAt && argType == JSVAL_TYPE_INT32 &&
-            thisType == JSVAL_TYPE_STRING && type == JSVAL_TYPE_STRING) {
-            return compileGetChar(thisValue, arg, GetChar);
-        }
-        if (native == js::str_fromCharCode && argType == JSVAL_TYPE_INT32 &&
-            type == JSVAL_TYPE_STRING) {
-            return compileStringFromCode(arg);
-        }
-        if (native == js::array_push &&
-            thisType == JSVAL_TYPE_OBJECT && type == JSVAL_TYPE_INT32) {
-            /*
-             * Constraints propagating properties into the 'this' object are
-             * generated by TypeConstraintCall during inference.
-             */
-            if (thisTypes->getKnownClass() == &ArrayClass &&
-                !thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                           types::OBJECT_FLAG_LENGTH_OVERFLOW) &&
-                !types::ArrayPrototypeHasIndexedProperty(cx, outerScript)) {
-                types::StackTypeSet::DoubleConversion conversion = thisTypes->convertDoubleElements(cx);
-                if (conversion != types::StackTypeSet::AmbiguousDoubleConversion)
-                    return compileArrayPush(thisValue, arg, conversion);
-            }
-        }
-        if (native == js::array_concat && argType == JSVAL_TYPE_OBJECT &&
-            thisType == JSVAL_TYPE_OBJECT && type == JSVAL_TYPE_OBJECT &&
-            thisTypes->getKnownClass() == &ArrayClass &&
-            !thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                       types::OBJECT_FLAG_LENGTH_OVERFLOW) &&
-            argTypes->getKnownClass() == &ArrayClass &&
-            !argTypes->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                      types::OBJECT_FLAG_LENGTH_OVERFLOW) &&
-            !types::ArrayPrototypeHasIndexedProperty(cx, outerScript))
-        {
-            // Don't inline if 'this' is packed and the argument may not be packed.
-            bool argPacked = !argTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
-            bool thisPacked = !thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
-            if (!(thisPacked && !argPacked))
-                return compileArrayConcat(thisTypes, argTypes, thisValue, arg);
-        }
-    } else if (argc == 2) {
-        FrameEntry *arg1 = frame.peek(-2);
-        FrameEntry *arg2 = frame.peek(-1);
-
-        JSValueType arg1Type = arg1->isTypeKnown() ? arg1->getKnownType() : JSVAL_TYPE_UNKNOWN;
-        JSValueType arg2Type = arg2->isTypeKnown() ? arg2->getKnownType() : JSVAL_TYPE_UNKNOWN;
-
-        if (native == js_math_pow && type == JSVAL_TYPE_DOUBLE &&
-             masm.supportsFloatingPointSqrt() &&
-            (arg1Type == JSVAL_TYPE_DOUBLE || arg1Type == JSVAL_TYPE_INT32) &&
-            arg2Type == JSVAL_TYPE_DOUBLE && arg2->isConstant())
-        {
-            Value arg2Value = arg2->getValue();
-            if (arg2Value.toDouble() == -0.5 || arg2Value.toDouble() == 0.5)
-                return compileMathPowSimple(arg1, arg2);
-        }
-        if ((native == js_math_min || native == js_math_max)) {
-            if (arg1Type == JSVAL_TYPE_INT32 && arg2Type == JSVAL_TYPE_INT32 &&
-                type == JSVAL_TYPE_INT32) {
-                return compileMathMinMaxInt(arg1, arg2,
-                        native == js_math_min ? Assembler::LessThan : Assembler::GreaterThan);
-            }
-            if ((arg1Type == JSVAL_TYPE_INT32 || arg1Type == JSVAL_TYPE_DOUBLE) &&
-                (arg2Type == JSVAL_TYPE_INT32 || arg2Type == JSVAL_TYPE_DOUBLE) &&
-                type == JSVAL_TYPE_DOUBLE) {
-                return compileMathMinMaxDouble(arg1, arg2,
-                        (native == js_math_min)
-                        ? Assembler::DoubleLessThan
-                        : Assembler::DoubleGreaterThan);
-            }
-        }
-    }
-    return Compile_InlineAbort;
-}
-
deleted file mode 100644
--- a/js/src/methodjit/FastOps.cpp
+++ /dev/null
@@ -1,2559 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "jsbool.h"
-#include "jscntxt.h"
-#include "jslibmath.h"
-
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Compiler.h"
-#include "methodjit/StubCalls.h"
-#include "vm/NumericConversions.h"
-#include "vm/Shape.h"
-
-#include "jsobjinlines.h"
-#include "jsscriptinlines.h"
-#include "jstypedarrayinlines.h"
-
-#include "methodjit/FrameState-inl.h"
-
-#include "jsautooplen.h"
-
-using namespace js;
-using namespace js::mjit;
-
-typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-static inline bool
-SuitableForBitop(FrameEntry *fe)
-{
-    return !(fe->isNotType(JSVAL_TYPE_INT32) &&
-             fe->isNotType(JSVAL_TYPE_DOUBLE) &&
-             fe->isNotType(JSVAL_TYPE_BOOLEAN));
-}
-
-void
-mjit::Compiler::ensureInteger(FrameEntry *fe, Uses uses)
-{
-    JS_ASSERT(SuitableForBitop(fe));
-
-    if (fe->isConstant()) {
-        if (!fe->isType(JSVAL_TYPE_INT32))
-            fe->convertConstantDoubleOrBooleanToInt32(cx);
-    } else if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-        FPRegisterID fpreg = frame.tempFPRegForData(fe);
-        FPRegisterID fptemp = frame.allocFPReg();
-        RegisterID data = frame.allocReg();
-        Jump truncateGuard = masm.branchTruncateDoubleToInt32(fpreg, data);
-
-        Label syncPath = stubcc.syncExitAndJump(uses);
-        stubcc.linkExitDirect(truncateGuard, stubcc.masm.label());
-
-        /*
-         * Try an OOL path to convert doubles representing integers within 2^32
-         * of a signed integer, by adding/subtracting 2^32 and then trying to
-         * convert to int32_t. This has to be an exact conversion, as otherwise
-         * the truncation works incorrectly on the modified value.
-         */
-
-        stubcc.masm.zeroDouble(fptemp);
-        Jump positive = stubcc.masm.branchDouble(Assembler::DoubleGreaterThan, fpreg, fptemp);
-        stubcc.masm.slowLoadConstantDouble(double(4294967296.0), fptemp);
-        Jump skip = stubcc.masm.jump();
-        positive.linkTo(stubcc.masm.label(), &stubcc.masm);
-        stubcc.masm.slowLoadConstantDouble(double(-4294967296.0), fptemp);
-        skip.linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        JumpList isDouble;
-        stubcc.masm.addDouble(fpreg, fptemp);
-        stubcc.masm.branchConvertDoubleToInt32(fptemp, data, isDouble, Registers::FPConversionTemp);
-        stubcc.crossJump(stubcc.masm.jump(), masm.label());
-        isDouble.linkTo(syncPath, &stubcc.masm);
-
-        frame.freeReg(fptemp);
-        frame.learnType(fe, JSVAL_TYPE_INT32, data);
-    } else if (!fe->isType(JSVAL_TYPE_INT32) && !fe->isType(JSVAL_TYPE_BOOLEAN)) {
-        if (masm.supportsFloatingPoint()) {
-            FPRegisterID fptemp = frame.allocFPReg();
-            RegisterID typeReg = frame.tempRegForType(fe);
-            frame.pinReg(typeReg);
-            RegisterID dataReg = frame.copyDataIntoReg(fe);
-            frame.unpinReg(typeReg);
-
-            Jump intGuard = masm.testInt32(Assembler::NotEqual, typeReg);
-
-            Label syncPath = stubcc.syncExitAndJump(uses);
-            stubcc.linkExitDirect(intGuard, stubcc.masm.label());
-
-            /* Try an OOL path to truncate doubles representing int32s. */
-            Jump doubleGuard = stubcc.masm.testDouble(Assembler::NotEqual, typeReg);
-            doubleGuard.linkTo(syncPath, &stubcc.masm);
-
-            frame.loadDouble(fe, fptemp, stubcc.masm);
-            Jump truncateGuard = stubcc.masm.branchTruncateDoubleToInt32(fptemp, dataReg);
-            truncateGuard.linkTo(syncPath, &stubcc.masm);
-            stubcc.crossJump(stubcc.masm.jump(), masm.label());
-
-            frame.freeReg(fptemp);
-            frame.learnType(fe, JSVAL_TYPE_INT32, dataReg);
-        } else {
-            RegisterID typeReg = frame.tempRegForType(fe);
-            frame.pinReg(typeReg);
-            RegisterID dataReg = frame.copyDataIntoReg(fe);
-            frame.unpinReg(typeReg);
-
-            Jump intGuard = masm.testInt32(Assembler::NotEqual, typeReg);
-
-            Label syncPath = stubcc.syncExitAndJump(uses);
-            stubcc.linkExitDirect(intGuard, syncPath);
-
-            frame.learnType(fe, JSVAL_TYPE_INT32, dataReg);
-        }
-    }
-}
-
-void
-mjit::Compiler::jsop_bitnot()
-{
-    FrameEntry *top = frame.peek(-1);
-
-    /* We only want to handle integers here. */
-    if (!SuitableForBitop(top)) {
-        prepareStubCall(Uses(1));
-        INLINE_STUBCALL(stubs::BitNot, REJOIN_FALLTHROUGH);
-        frame.pop();
-        frame.pushSynced(JSVAL_TYPE_INT32);
-        return;
-    }
-
-    ensureInteger(top, Uses(1));
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::BitNot, REJOIN_FALLTHROUGH);
-
-    RegisterID reg = frame.ownRegForData(top);
-    masm.not32(reg);
-    frame.pop();
-    frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_bitop(JSOp op)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* The operands we ensure are integers cannot be copied by each other. */
-    frame.separateBinaryEntries(lhs, rhs);
-
-    VoidStub stub;
-    switch (op) {
-      case JSOP_BITOR:
-        stub = stubs::BitOr;
-        break;
-      case JSOP_BITAND:
-        stub = stubs::BitAnd;
-        break;
-      case JSOP_BITXOR:
-        stub = stubs::BitXor;
-        break;
-      case JSOP_LSH:
-        stub = stubs::Lsh;
-        break;
-      case JSOP_RSH:
-        stub = stubs::Rsh;
-        break;
-      case JSOP_URSH:
-        stub = stubs::Ursh;
-        break;
-      default:
-        JS_NOT_REACHED("wat");
-        return;
-    }
-
-    /* Convert a double RHS to integer if it's constant for the test below. */
-    if (rhs->isConstant() && (rhs->isType(JSVAL_TYPE_DOUBLE) || rhs->isType(JSVAL_TYPE_BOOLEAN)))
-        rhs->convertConstantDoubleOrBooleanToInt32(cx);
-
-    /* We only want to handle integers here. */
-    if (!SuitableForBitop(lhs) || !SuitableForBitop(rhs) ||
-        (op == JSOP_URSH && rhs->isConstant() && rhs->getValue().toInt32() % 32 == 0)) {
-        prepareStubCall(Uses(2));
-        INLINE_STUBCALL(stub, REJOIN_FALLTHROUGH);
-        frame.popn(2);
-        frame.pushSynced(op != JSOP_URSH ? JSVAL_TYPE_INT32 : knownPushedType(0));
-        return;
-    }
-
-    ensureInteger(lhs, Uses(2));
-    ensureInteger(rhs, Uses(2));
-
-    if (lhs->isConstant() && rhs->isConstant()) {
-        int32_t L = lhs->getValue().toInt32();
-        int32_t R = rhs->getValue().toInt32();
-
-        frame.popn(2);
-        switch (op) {
-          case JSOP_BITOR:
-            frame.push(Int32Value(L | R));
-            return;
-          case JSOP_BITXOR:
-            frame.push(Int32Value(L ^ R));
-            return;
-          case JSOP_BITAND:
-            frame.push(Int32Value(L & R));
-            return;
-          case JSOP_LSH:
-            frame.push(Int32Value(L << (R & 31)));
-            return;
-          case JSOP_RSH:
-            frame.push(Int32Value(L >> (R & 31)));
-            return;
-          case JSOP_URSH:
-          {
-            uint32_t unsignedL;
-            ToUint32(cx, Int32Value(L), (uint32_t*)&unsignedL);  /* Can't fail. */
-            Value v = NumberValue(uint32_t(unsignedL >> (R & 31)));
-            JS_ASSERT(v.isInt32());
-            frame.push(v);
-            return;
-          }
-          default:
-            JS_NOT_REACHED("say wat");
-        }
-    }
-
-    RegisterID reg;
-
-    switch (op) {
-      case JSOP_BITOR:
-      case JSOP_BITXOR:
-      case JSOP_BITAND:
-      {
-        /* Commutative, and we're guaranteed both are ints. */
-        if (lhs->isConstant()) {
-            JS_ASSERT(!rhs->isConstant());
-            FrameEntry *temp = rhs;
-            rhs = lhs;
-            lhs = temp;
-        }
-
-        reg = frame.ownRegForData(lhs);
-        if (rhs->isConstant()) {
-            int32_t rhsInt = rhs->getValue().toInt32();
-            if (op == JSOP_BITAND)
-                masm.and32(Imm32(rhsInt), reg);
-            else if (op == JSOP_BITXOR)
-                masm.xor32(Imm32(rhsInt), reg);
-            else if (rhsInt != 0)
-                masm.or32(Imm32(rhsInt), reg);
-        } else if (frame.shouldAvoidDataRemat(rhs)) {
-            Address rhsAddr = masm.payloadOf(frame.addressOf(rhs));
-            if (op == JSOP_BITAND)
-                masm.and32(rhsAddr, reg);
-            else if (op == JSOP_BITXOR)
-                masm.xor32(rhsAddr, reg);
-            else
-                masm.or32(rhsAddr, reg);
-        } else {
-            RegisterID rhsReg = frame.tempRegForData(rhs);
-            if (op == JSOP_BITAND)
-                masm.and32(rhsReg, reg);
-            else if (op == JSOP_BITXOR)
-                masm.xor32(rhsReg, reg);
-            else
-                masm.or32(rhsReg, reg);
-        }
-
-        break;
-      }
-
-      case JSOP_LSH:
-      case JSOP_RSH:
-      case JSOP_URSH:
-      {
-        /* Not commutative. */
-        if (rhs->isConstant()) {
-            RegisterID reg = frame.ownRegForData(lhs);
-            int shift = rhs->getValue().toInt32() & 0x1F;
-
-            stubcc.leave();
-            OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-            if (shift) {
-                if (op == JSOP_LSH)
-                    masm.lshift32(Imm32(shift), reg);
-                else if (op == JSOP_RSH)
-                    masm.rshift32(Imm32(shift), reg);
-                else
-                    masm.urshift32(Imm32(shift), reg);
-            }
-            frame.popn(2);
-
-            /* x >>> 0 may result in a double, handled above. */
-            JS_ASSERT_IF(op == JSOP_URSH, shift >= 1);
-            frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-            stubcc.rejoin(Changes(1));
-            return;
-        }
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-        /* Grosssssss! RHS _must_ be in ECX, on x86 */
-        RegisterID rr = frame.tempRegInMaskForData(rhs,
-                                                   Registers::maskReg(JSC::X86Registers::ecx)).reg();
-#else
-        RegisterID rr = frame.tempRegForData(rhs);
-#endif
-
-        if (frame.haveSameBacking(lhs, rhs)) {
-            // It's okay to allocReg(). If |rr| is evicted, it won't result in
-            // a load, and |rr == reg| is fine since this is (x << x).
-            reg = frame.allocReg();
-            if (rr != reg)
-                masm.move(rr, reg);
-        } else {
-            frame.pinReg(rr);
-            if (lhs->isConstant()) {
-                reg = frame.allocReg();
-                masm.move(Imm32(lhs->getValue().toInt32()), reg);
-            } else {
-                reg = frame.copyDataIntoReg(lhs);
-            }
-            frame.unpinReg(rr);
-        }
-
-        if (op == JSOP_LSH) {
-            masm.lshift32(rr, reg);
-        } else if (op == JSOP_RSH) {
-            masm.rshift32(rr, reg);
-        } else {
-            masm.urshift32(rr, reg);
-
-            Jump isNegative = masm.branch32(Assembler::LessThan, reg, Imm32(0));
-            stubcc.linkExit(isNegative, Uses(2));
-        }
-        break;
-      }
-
-      default:
-        JS_NOT_REACHED("NYI");
-        return;
-    }
-
-    stubcc.leave();
-    OOL_STUBCALL(stub, REJOIN_FALLTHROUGH);
-
-    frame.pop();
-    frame.pop();
-
-    JSValueType type = knownPushedType(0);
-
-    if (type != JSVAL_TYPE_UNKNOWN && type != JSVAL_TYPE_DOUBLE)
-        frame.pushTypedPayload(type, reg);
-    else if (op == JSOP_URSH)
-        frame.pushNumber(reg, true);
-    else
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-
-    stubcc.rejoin(Changes(1));
-}
-
-static inline bool
-CheckNullOrUndefined(FrameEntry *fe)
-{
-    if (!fe->isTypeKnown())
-        return false;
-    JSValueType type = fe->getKnownType();
-    return type == JSVAL_TYPE_NULL || type == JSVAL_TYPE_UNDEFINED;
-}
-
-CompileStatus
-mjit::Compiler::jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    JS_ASSERT(cx->typeInferenceEnabled() &&
-              lhs->isType(JSVAL_TYPE_OBJECT) && rhs->isType(JSVAL_TYPE_OBJECT));
-
-    /* :TODO: Merge with jsop_relational_int? */
-    JS_ASSERT_IF(!target, fused != JSOP_IFEQ);
-    frame.forgetMismatchedObject(lhs);
-    frame.forgetMismatchedObject(rhs);
-    Assembler::Condition cond = GetCompareCondition(op, fused);
-    if (target) {
-        Jump sj = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
-                                           Registers::ReturnReg, Registers::ReturnReg);
-        if (!frame.syncForBranch(target, Uses(2)))
-            return Compile_Error;
-        RegisterID lreg = frame.tempRegForData(lhs);
-        frame.pinReg(lreg);
-        RegisterID rreg = frame.tempRegForData(rhs);
-        frame.unpinReg(lreg);
-        Jump fast = masm.branchPtr(cond, lreg, rreg);
-        frame.popn(2);
-        return jumpAndRun(fast, target, &sj) ? Compile_Okay : Compile_Error;
-    }
-
-    RegisterID result = frame.allocReg();
-    RegisterID lreg = frame.tempRegForData(lhs);
-    frame.pinReg(lreg);
-    RegisterID rreg = frame.tempRegForData(rhs);
-    frame.unpinReg(lreg);
-    masm.branchValue(cond, lreg, rreg, result);
-
-    frame.popn(2);
-    frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-    return Compile_Okay;
-}
-
-bool
-mjit::Compiler::jsop_equality(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* The compiler should have handled constant folding. */
-    JS_ASSERT(!(rhs->isConstant() && lhs->isConstant()));
-
-    bool lhsTest;
-    if ((lhsTest = CheckNullOrUndefined(lhs)) || CheckNullOrUndefined(rhs)) {
-        /* What's the other mask? */
-        FrameEntry *test = lhsTest ? rhs : lhs;
-
-        // Use a stub when comparing to object to address EmulatesUndefined.
-        if (test->isType(JSVAL_TYPE_NULL) ||
-            test->isType(JSVAL_TYPE_UNDEFINED) ||
-            test->isType(JSVAL_TYPE_OBJECT))
-        {
-            return emitStubCmpOp(stub, target, fused);
-        }
-
-        if (test->isTypeKnown()) {
-            /* The test will not succeed, constant fold the compare. */
-            bool result = GetCompareCondition(op, fused) == Assembler::NotEqual;
-            frame.pop();
-            frame.pop();
-            if (target)
-                return constantFoldBranch(target, result);
-            frame.push(BooleanValue(result));
-            return true;
-        }
-
-        // If the type of the other side is unknown, use a stub for simplicity.
-        return emitStubCmpOp(stub, target, fused);
-   }
-
-    if (cx->typeInferenceEnabled() &&
-        lhs->isType(JSVAL_TYPE_OBJECT) && rhs->isType(JSVAL_TYPE_OBJECT))
-    {
-        CompileStatus status = jsop_equality_obj_obj(op, target, fused);
-        if (status == Compile_Okay) return true;
-        else if (status == Compile_Error) return false;
-    }
-
-    return emitStubCmpOp(stub, target, fused);
-}
-
-bool
-mjit::Compiler::jsop_relational(JSOp op, BoolStub stub,
-                                jsbytecode *target, JSOp fused)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    /* The compiler should have handled constant folding. */
-    JS_ASSERT(!(rhs->isConstant() && lhs->isConstant()));
-    JS_ASSERT(fused == JSOP_NOP || fused == JSOP_IFEQ || fused == JSOP_IFNE);
-
-    /* Always slow path... */
-    if ((lhs->isNotType(JSVAL_TYPE_INT32) && lhs->isNotType(JSVAL_TYPE_DOUBLE) &&
-         lhs->isNotType(JSVAL_TYPE_STRING)) ||
-        (rhs->isNotType(JSVAL_TYPE_INT32) && rhs->isNotType(JSVAL_TYPE_DOUBLE) &&
-         rhs->isNotType(JSVAL_TYPE_STRING))) {
-        if (op == JSOP_EQ || op == JSOP_NE)
-            return jsop_equality(op, stub, target, fused);
-        return emitStubCmpOp(stub, target, fused);
-    }
-
-    if (op == JSOP_EQ || op == JSOP_NE) {
-        if ((lhs->isNotType(JSVAL_TYPE_INT32) && lhs->isNotType(JSVAL_TYPE_STRING)) ||
-            (rhs->isNotType(JSVAL_TYPE_INT32) && rhs->isNotType(JSVAL_TYPE_STRING))) {
-            return emitStubCmpOp(stub, target, fused);
-        } else if (!target && (lhs->isType(JSVAL_TYPE_STRING) || rhs->isType(JSVAL_TYPE_STRING))) {
-            return emitStubCmpOp(stub, target, fused);
-        } else if (frame.haveSameBacking(lhs, rhs)) {
-            return emitStubCmpOp(stub, target, fused);
-        } else {
-            return jsop_equality_int_string(op, stub, target, fused);
-        }
-    }
-
-    if (frame.haveSameBacking(lhs, rhs)) {
-        return emitStubCmpOp(stub, target, fused);
-    } else if (lhs->isType(JSVAL_TYPE_STRING) || rhs->isType(JSVAL_TYPE_STRING)) {
-        return emitStubCmpOp(stub, target, fused);
-    } else if (lhs->isType(JSVAL_TYPE_DOUBLE) || rhs->isType(JSVAL_TYPE_DOUBLE)) {
-        if (!masm.supportsFloatingPoint())
-            return emitStubCmpOp(stub, target, fused);
-        return jsop_relational_double(op, stub, target, fused);
-    } else if (cx->typeInferenceEnabled() &&
-               lhs->isType(JSVAL_TYPE_INT32) && rhs->isType(JSVAL_TYPE_INT32)) {
-        return jsop_relational_int(op, target, fused);
-    } else {
-        return jsop_relational_full(op, stub, target, fused);
-    }
-}
-
-void
-mjit::Compiler::jsop_not()
-{
-    FrameEntry *top = frame.peek(-1);
-
-    if (top->isConstant()) {
-        const Value &v = top->getValue();
-        frame.pop();
-        frame.push(BooleanValue(!ToBoolean(v)));
-        return;
-    }
-
-    if (top->isTypeKnown()) {
-        JSValueType type = top->getKnownType();
-        switch (type) {
-          case JSVAL_TYPE_INT32:
-          {
-            RegisterID data = frame.allocReg(Registers::SingleByteRegs).reg();
-            if (frame.shouldAvoidDataRemat(top))
-                masm.loadPayload(frame.addressOf(top), data);
-            else
-                masm.move(frame.tempRegForData(top), data);
-
-            masm.set32(Assembler::Equal, data, Imm32(0), data);
-
-            frame.pop();
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, data);
-            break;
-          }
-
-          case JSVAL_TYPE_BOOLEAN:
-          {
-            RegisterID reg = frame.ownRegForData(top);
-
-            masm.xor32(Imm32(1), reg);
-
-            frame.pop();
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, reg);
-            break;
-          }
-
-          case JSVAL_TYPE_OBJECT: // EmulatesUndefined makes this non-trivial.
-          default:
-          {
-            prepareStubCall(Uses(1));
-            INLINE_STUBCALL_USES(stubs::ValueToBoolean, REJOIN_NONE, Uses(1));
-
-            RegisterID reg = Registers::ReturnReg;
-            frame.takeReg(reg);
-            masm.xor32(Imm32(1), reg);
-
-            frame.pop();
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, reg);
-            break;
-          }
-        }
-
-        return;
-    }
-
-    RegisterID data = frame.allocReg(Registers::SingleByteRegs).reg();
-    if (frame.shouldAvoidDataRemat(top))
-        masm.loadPayload(frame.addressOf(top), data);
-    else
-        masm.move(frame.tempRegForData(top), data);
-    RegisterID type = frame.tempRegForType(top);
-    Label syncTarget = stubcc.syncExitAndJump(Uses(1));
-
-
-    /* Inline path is for booleans. */
-    Jump jmpNotBool = masm.testBoolean(Assembler::NotEqual, type);
-    masm.xor32(Imm32(1), data);
-
-    /* OOL path is for int. */
-    Label lblMaybeInt32 = stubcc.masm.label();
-
-    Jump jmpNotInt32 = stubcc.masm.testInt32(Assembler::NotEqual, type);
-    stubcc.masm.set32(Assembler::Equal, data, Imm32(0), data);
-    Jump jmpInt32Exit = stubcc.masm.jump();
-
-    /* Rejoin location. */
-    Label lblRejoin = masm.label();
-
-    /* Patch up jumps. */
-    stubcc.linkExitDirect(jmpNotBool, lblMaybeInt32);
-
-    jmpNotInt32.linkTo(syncTarget, &stubcc.masm);
-    stubcc.crossJump(jmpInt32Exit, lblRejoin);
-
-    /* Leave. */
-    stubcc.leave();
-    OOL_STUBCALL(stubs::Not, REJOIN_FALLTHROUGH);
-
-    frame.pop();
-    frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, data);
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_typeof()
-{
-    FrameEntry *fe = frame.peek(-1);
-
-    if (fe->isTypeKnown()) {
-        JSRuntime *rt = cx->runtime;
-
-        JSAtom *atom = NULL;
-        switch (fe->getKnownType()) {
-          case JSVAL_TYPE_STRING:
-            atom = rt->atomState.string;
-            break;
-          case JSVAL_TYPE_UNDEFINED:
-            atom = rt->atomState.undefined;
-            break;
-          case JSVAL_TYPE_NULL:
-            atom = rt->atomState.object;
-            break;
-          case JSVAL_TYPE_OBJECT:
-            atom = NULL;
-            break;
-          case JSVAL_TYPE_BOOLEAN:
-            atom = rt->atomState.boolean;
-            break;
-          default:
-            atom = rt->atomState.number;
-            break;
-        }
-
-        if (atom) {
-            frame.pop();
-            frame.push(StringValue(atom));
-            return;
-        }
-    }
-
-    JSOp fused = JSOp(PC[JSOP_TYPEOF_LENGTH]);
-    if (fused == JSOP_STRING && !fe->isTypeKnown()) {
-        JSOp op = JSOp(PC[JSOP_TYPEOF_LENGTH + JSOP_STRING_LENGTH]);
-
-        if (op == JSOP_STRICTEQ || op == JSOP_EQ || op == JSOP_STRICTNE || op == JSOP_NE) {
-            JSAtom *atom = script_->getAtom(GET_UINT32_INDEX(PC + JSOP_TYPEOF_LENGTH));
-            JSRuntime *rt = cx->runtime;
-            JSValueType type = JSVAL_TYPE_UNKNOWN;
-            Assembler::Condition cond = (op == JSOP_STRICTEQ || op == JSOP_EQ)
-                                        ? Assembler::Equal
-                                        : Assembler::NotEqual;
-
-            if (atom == rt->atomState.undefined) {
-                type = JSVAL_TYPE_UNDEFINED;
-            } else if (atom == rt->atomState.string) {
-                type = JSVAL_TYPE_STRING;
-            } else if (atom == rt->atomState.boolean) {
-                type = JSVAL_TYPE_BOOLEAN;
-            } else if (atom == rt->atomState.number) {
-                type = JSVAL_TYPE_INT32;
-
-                /* JSVAL_TYPE_DOUBLE is 0x0 and JSVAL_TYPE_INT32 is 0x1, use <= or > to match both */
-                cond = (cond == Assembler::Equal) ? Assembler::BelowOrEqual : Assembler::Above;
-            }
-
-            jsbytecode *afterPC = PC + JSOP_STRING_LENGTH + JSOP_EQ_LENGTH;
-
-            if (type != JSVAL_TYPE_UNKNOWN && bytecodeInChunk(afterPC)) {
-                PC = afterPC;
-
-                RegisterID result = frame.allocReg(Registers::SingleByteRegs).reg();
-
-#if defined JS_NUNBOX32
-                if (frame.shouldAvoidTypeRemat(fe))
-                    masm.set32(cond, masm.tagOf(frame.addressOf(fe)), ImmType(type), result);
-                else
-                    masm.set32(cond, frame.tempRegForType(fe), ImmType(type), result);
-#elif defined JS_PUNBOX64
-                masm.setPtr(cond, frame.tempRegForType(fe), ImmType(type), result);
-#endif
-
-                frame.pop();
-                frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-                return;
-            }
-        }
-    }
-
-    prepareStubCall(Uses(1));
-    INLINE_STUBCALL(stubs::TypeOf, REJOIN_NONE);
-    frame.pop();
-    frame.takeReg(Registers::ReturnReg);
-    frame.pushTypedPayload(JSVAL_TYPE_STRING, Registers::ReturnReg);
-}
-
-bool
-mjit::Compiler::booleanJumpScript(JSOp op, jsbytecode *target)
-{
-    // JSOP_AND and JSOP_OR may leave the value on the stack (despite
-    // the frame.pop() below), so we need to sync it.
-    if (op == JSOP_AND || op == JSOP_OR) {
-        frame.syncForBranch(target, Uses(0));
-    } else {
-        JS_ASSERT(op == JSOP_IFEQ || op == JSOP_IFNE);
-        frame.syncForBranch(target, Uses(1));
-    }
-
-    FrameEntry *fe = frame.peek(-1);
-    Assembler::Condition cond = (op == JSOP_IFNE || op == JSOP_OR)
-                                ? Assembler::NonZero
-                                : Assembler::Zero;
-
-    // Load data register and pin it so that frame.testBoolean
-    // below cannot evict it.
-    MaybeRegisterID data;
-    if (!fe->isType(JSVAL_TYPE_DOUBLE)) {
-        data = frame.tempRegForData(fe);
-        frame.pinReg(data.reg());
-    }
-
-    // Test for boolean if needed.
-    bool needStub = false;
-    if (!fe->isType(JSVAL_TYPE_BOOLEAN) && !fe->isType(JSVAL_TYPE_INT32)) {
-        Jump notBool;
-        if (fe->mightBeType(JSVAL_TYPE_BOOLEAN))
-            notBool = frame.testBoolean(Assembler::NotEqual, fe);
-        else
-            notBool = masm.jump();
-
-        stubcc.linkExitForBranch(notBool);
-        needStub = true;
-    }
-    if (data.isSet())
-        frame.unpinReg(data.reg());
-
-    // Test + branch.
-    Jump branch;
-    if (!fe->isType(JSVAL_TYPE_DOUBLE))
-        branch = masm.branchTest32(cond, data.reg());
-    else
-        branch = masm.jump(); // dummy jump
-
-    // OOL path: call ValueToBoolean and branch.
-    if (needStub) {
-        stubcc.leave();
-
-        // Note: this cannot overwrite slots holding loop invariants.
-        stubcc.masm.infallibleVMCall(JS_FUNC_TO_DATA_PTR(void *, stubs::ValueToBoolean),
-                                     frame.totalDepth());
-    }
-
-    Jump stubBranch = stubcc.masm.branchTest32(cond, Registers::ReturnReg);
-
-    // Rejoin from the stub call fallthrough.
-    if (needStub)
-        stubcc.rejoin(Changes(0));
-
-    frame.pop();
-
-    return jumpAndRun(branch, target, &stubBranch);
-}
-
-bool
-mjit::Compiler::jsop_ifneq(JSOp op, jsbytecode *target)
-{
-    FrameEntry *fe = frame.peek(-1);
-
-    if (fe->isConstant()) {
-        JSBool b = ToBoolean(fe->getValue());
-
-        frame.pop();
-
-        if (op == JSOP_IFEQ)
-            b = !b;
-        if (b) {
-            if (!frame.syncForBranch(target, Uses(0)))
-                return false;
-            if (!jumpAndRun(masm.jump(), target))
-                return false;
-        } else {
-            if (target < PC && !finishLoop(target))
-                return false;
-        }
-        return true;
-    }
-
-    return booleanJumpScript(op, target);
-}
-
-bool
-mjit::Compiler::jsop_andor(JSOp op, jsbytecode *target)
-{
-    FrameEntry *fe = frame.peek(-1);
-
-    if (fe->isConstant()) {
-        JSBool b = ToBoolean(fe->getValue());
-
-        /* Short-circuit. */
-        if ((op == JSOP_OR && b == JS_TRUE) ||
-            (op == JSOP_AND && b == JS_FALSE)) {
-            if (!frame.syncForBranch(target, Uses(0)))
-                return false;
-            if (!jumpAndRun(masm.jump(), target))
-                return false;
-        }
-
-        frame.pop();
-        return true;
-    }
-
-    return booleanJumpScript(op, target);
-}
-
-static inline bool
-IsCacheableSetElem(FrameEntry *obj, FrameEntry *id, FrameEntry *value)
-{
-    if (obj->isNotType(JSVAL_TYPE_OBJECT))
-        return false;
-    if (id->isNotType(JSVAL_TYPE_INT32) && id->isNotType(JSVAL_TYPE_DOUBLE))
-        return false;
-    if (id->isConstant()) {
-        if (id->isNotType(JSVAL_TYPE_INT32))
-            return false;
-        if (id->getValue().toInt32() < 0)
-            return false;
-        if (id->getValue().toInt32() + 1 < 0)  // watch for overflow in hole paths
-            return false;
-    }
-
-    // obj[obj] * is not allowed, since it will never optimize.
-    // obj[id] = id is allowed.
-    // obj[id] = obj is allowed.
-    if (obj->hasSameBacking(id))
-        return false;
-
-    return true;
-}
-
-void
-mjit::Compiler::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion)
-{
-    FrameEntry *obj = frame.peek(-3);
-    FrameEntry *id = frame.peek(-2);
-    FrameEntry *value = frame.peek(-1);
-
-    frame.forgetMismatchedObject(obj);
-
-    bool convertDouble = false;
-
-    // If the array being written to might need integer elements converted to
-    // doubles, make the conversion before writing.
-    if (conversion == types::StackTypeSet::AlwaysConvertToDoubles ||
-        conversion == types::StackTypeSet::MaybeConvertToDoubles)
-    {
-        // A constant value may still be live and the entry itself should not
-        // be updated.
-        convertDouble = true;
-        if (!value->isConstant())
-            frame.ensureDouble(value);
-    }
-
-    // We might not know whether this is an object, but if it is an object we
-    // know it is a dense array.
-    if (!obj->isTypeKnown()) {
-        Jump guard = frame.testObject(Assembler::NotEqual, obj);
-        stubcc.linkExit(guard, Uses(3));
-    }
-
-    if (id->isType(JSVAL_TYPE_DOUBLE))
-        tryConvertInteger(id, Uses(2));
-
-    // Test for integer index.
-    if (!id->isTypeKnown()) {
-        Jump guard = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(guard, Uses(3));
-    }
-
-    // Allocate registers.
-
-    ValueRemat vr;
-    frame.pinEntry(value, vr, /* breakDouble = */ false);
-
-    // Constant values that need conversion to double have not been fixed yet.
-    if (convertDouble && value->isConstant() && value->getValue().isInt32())
-        vr = ValueRemat::FromConstant(DoubleValue(value->getValue().toInt32()));
-
-    Int32Key key = id->isConstant()
-                 ? Int32Key::FromConstant(id->getValue().toInt32())
-                 : Int32Key::FromRegister(frame.tempRegForData(id));
-    bool pinKey = !key.isConstant() && !frame.haveSameBacking(id, value);
-    if (pinKey)
-        frame.pinReg(key.reg());
-
-    // Register to hold the computed slots pointer for the object. If we can
-    // hoist the initialized length check, we make the slots pointer loop
-    // invariant and never access the object itself.
-    RegisterID slotsReg;
-    analyze::CrossSSAValue objv(a->inlineIndex, analysis->poppedValue(PC, 2));
-    analyze::CrossSSAValue indexv(a->inlineIndex, analysis->poppedValue(PC, 1));
-    bool hoisted = loop && id->isType(JSVAL_TYPE_INT32) &&
-        loop->hoistArrayLengthCheck(DENSE_ARRAY, objv, indexv);
-
-    MaybeJump initlenExit;
-
-    if (hoisted) {
-        FrameEntry *slotsFe = loop->invariantArraySlots(objv);
-        slotsReg = frame.tempRegForData(slotsFe);
-
-        frame.unpinEntry(vr);
-        if (pinKey)
-            frame.unpinReg(key.reg());
-    } else {
-        // Get a register for the object which we can clobber, and load its elements.
-        if (frame.haveSameBacking(obj, value)) {
-            slotsReg = frame.allocReg();
-            masm.move(vr.dataReg(), slotsReg);
-        } else if (frame.haveSameBacking(obj, id)) {
-            slotsReg = frame.allocReg();
-            masm.move(key.reg(), slotsReg);
-        } else {
-            slotsReg = frame.copyDataIntoReg(obj);
-        }
-        masm.loadPtr(Address(slotsReg, JSObject::offsetOfElements()), slotsReg);
-
-        frame.unpinEntry(vr);
-        if (pinKey)
-            frame.unpinReg(key.reg());
-
-        // Make an OOL path for setting exactly the initialized length.
-        Label syncTarget = stubcc.syncExitAndJump(Uses(3));
-
-        Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                                  slotsReg, key, Assembler::BelowOrEqual);
-        stubcc.linkExitDirect(initlenGuard, stubcc.masm.label());
-
-        // Recheck for an exact initialized length. :TODO: would be nice to
-        // reuse the condition bits from the previous test.
-        Jump exactlenGuard = stubcc.masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                                          slotsReg, key, Assembler::NotEqual);
-        exactlenGuard.linkTo(syncTarget, &stubcc.masm);
-
-        // Check array capacity.
-        Jump capacityGuard = stubcc.masm.guardArrayExtent(ObjectElements::offsetOfCapacity(),
-                                                          slotsReg, key, Assembler::BelowOrEqual);
-        capacityGuard.linkTo(syncTarget, &stubcc.masm);
-
-        // Bump the index for setting the array length.  The above guard
-        // ensures this won't overflow, due to NSLOTS_LIMIT.
-        stubcc.masm.bumpKey(key, 1);
-
-        // Update the initialized length.
-        stubcc.masm.storeKey(key, Address(slotsReg, ObjectElements::offsetOfInitializedLength()));
-
-        // Update the array length if needed.
-        Jump lengthGuard = stubcc.masm.guardArrayExtent(ObjectElements::offsetOfLength(),
-                                                        slotsReg, key, Assembler::AboveOrEqual);
-        stubcc.masm.storeKey(key, Address(slotsReg, ObjectElements::offsetOfLength()));
-        lengthGuard.linkTo(stubcc.masm.label(), &stubcc.masm);
-
-        // Restore the index.
-        stubcc.masm.bumpKey(key, -1);
-
-        initlenExit = stubcc.masm.jump();
-    }
-
-#ifdef JSGC_INCREMENTAL_MJ
-    /*
-     * Write barrier.
-     * We skip over the barrier if we incremented initializedLength above,
-     * because in that case the slot we're overwriting was previously
-     * undefined.
-     */
-    types::StackTypeSet *types = frame.extra(obj).types;
-    if (cx->zone()->compileBarriers() && (!types || types->propertyNeedsBarrier(cx, JSID_VOID))) {
-        Label barrierStart = stubcc.masm.label();
-        stubcc.linkExitDirect(masm.jump(), barrierStart);
-
-        /*
-         * The sync call below can potentially clobber key.reg() and slotsReg.
-         * We pin key.reg() to avoid it being clobbered. If |hoisted| is true,
-         * we can also pin slotsReg. If not, then slotsReg is owned by the
-         * compiler and we save in manually to VMFrame::scratch.
-         *
-         * Additionally, the WriteBarrier stub can clobber both registers. The
-         * rejoin call will restore key.reg() but not slotsReg. So we save
-         * slotsReg in the frame and restore it after the stub call.
-         */
-        stubcc.masm.storePtr(slotsReg, FrameAddress(offsetof(VMFrame, scratch)));
-        if (hoisted)
-            frame.pinReg(slotsReg);
-        if (!key.isConstant())
-            frame.pinReg(key.reg());
-        frame.sync(stubcc.masm, Uses(3));
-        if (!key.isConstant())
-            frame.unpinReg(key.reg());
-        if (hoisted)
-            frame.unpinReg(slotsReg);
-        else
-            stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
-
-        if (key.isConstant())
-            stubcc.masm.lea(Address(slotsReg, key.index() * sizeof(Value)), Registers::ArgReg1);
-        else
-            stubcc.masm.lea(BaseIndex(slotsReg, key.reg(), masm.JSVAL_SCALE), Registers::ArgReg1);
-        OOL_STUBCALL(stubs::WriteBarrier, REJOIN_NONE);
-        stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
-        stubcc.rejoin(Changes(0));
-    }
-#endif
-
-    /* Jump over the write barrier in the initlen case. */
-    if (initlenExit.isSet())
-        stubcc.crossJump(initlenExit.get(), masm.label());
-
-    // Fully store the value. :TODO: don't need to do this in the non-initlen case
-    // if the array is packed and monomorphic.
-    if (key.isConstant())
-        masm.storeValue(vr, Address(slotsReg, key.index() * sizeof(Value)));
-    else
-        masm.storeValue(vr, BaseIndex(slotsReg, key.reg(), masm.JSVAL_SCALE));
-
-    stubcc.leave();
-    OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
-
-    if (!hoisted)
-        frame.freeReg(slotsReg);
-    frame.shimmy(2);
-    stubcc.rejoin(Changes(2));
-}
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-void
-mjit::Compiler::convertForTypedArray(int atype, ValueRemat *vr, bool *allocated)
-{
-    FrameEntry *value = frame.peek(-1);
-    bool floatArray = (atype == TypedArray::TYPE_FLOAT32 ||
-                       atype == TypedArray::TYPE_FLOAT64);
-    *allocated = false;
-
-    if (value->isConstant()) {
-        Value v = value->getValue();
-        if (floatArray) {
-            double d = v.isDouble() ? v.toDouble() : v.toInt32();
-            *vr = ValueRemat::FromConstant(DoubleValue(d));
-        } else {
-            int i32;
-            if (v.isInt32()) {
-                i32 = v.toInt32();
-                if (atype == TypedArray::TYPE_UINT8_CLAMPED)
-                    i32 = ClampIntForUint8Array(i32);
-            } else {
-                i32 = (atype == TypedArray::TYPE_UINT8_CLAMPED)
-                    ? ClampDoubleToUint8(v.toDouble())
-                    : ToInt32(v.toDouble());
-            }
-            *vr = ValueRemat::FromConstant(Int32Value(i32));
-        }
-    } else {
-        if (floatArray) {
-            FPRegisterID fpReg;
-            MaybeJump notNumber = loadDouble(value, &fpReg, allocated);
-            if (notNumber.isSet())
-                stubcc.linkExit(notNumber.get(), Uses(3));
-
-            if (atype == TypedArray::TYPE_FLOAT32) {
-                if (!*allocated) {
-                    frame.pinReg(fpReg);
-                    FPRegisterID newFpReg = frame.allocFPReg();
-                    masm.convertDoubleToFloat(fpReg, newFpReg);
-                    frame.unpinReg(fpReg);
-                    fpReg = newFpReg;
-                    *allocated = true;
-                } else {
-                    masm.convertDoubleToFloat(fpReg, fpReg);
-                }
-            }
-            *vr = ValueRemat::FromFPRegister(fpReg);
-        } else {
-            /*
-             * Allocate a register with the following properties:
-             * 1) For byte arrays the value must be in a byte register.
-             * 2) For Uint8ClampedArray the register must be writable.
-             * 3) If the value is definitely int32_t (and the array is not
-             *    Uint8ClampedArray) we don't have to allocate a new register.
-             * 4) If id and value have the same backing (e.g. arr[i] = i) and
-             *    we need a byte register, we have to allocate a new register
-             *    because we've already pinned a key register and can't use
-             *    tempRegInMaskForData.
-             */
-            MaybeRegisterID reg, dataReg;
-            bool needsByteReg = (atype == TypedArray::TYPE_INT8 ||
-                                 atype == TypedArray::TYPE_UINT8 ||
-                                 atype == TypedArray::TYPE_UINT8_CLAMPED);
-            FrameEntry *id = frame.peek(-2);
-            if (!value->isType(JSVAL_TYPE_INT32) || atype == TypedArray::TYPE_UINT8_CLAMPED ||
-                (needsByteReg && frame.haveSameBacking(id, value))) {
-                // Grab data register before branching.
-                if (value->mightBeType(JSVAL_TYPE_INT32)) {
-                    dataReg = frame.tempRegForData(value);
-
-                    // Make sure it's not clobbered by allocReg or tempRegForType.
-                    if (!frame.haveSameBacking(id, value))
-                        frame.pinReg(dataReg.reg());
-                }
-
-                // x86 has 4 single byte registers. Worst case we've pinned 3
-                // registers, one for each of object, key and value. This means
-                // there must be at least one single byte register available.
-                if (needsByteReg)
-                    reg = frame.allocReg(Registers::SingleByteRegs).reg();
-                else
-                    reg = frame.allocReg();
-                *allocated = true;
-            } else {
-                if (needsByteReg)
-                    reg = frame.tempRegInMaskForData(value, Registers::SingleByteRegs).reg();
-                else
-                    reg = frame.tempRegForData(value);
-            }
-
-            // Get type register before branching.
-            MaybeRegisterID typeReg;
-            if (!value->isTypeKnown()) {
-                // Note: we don't need to pin reg, it's never a temporary register if the
-                // type of value is not known.
-                JS_ASSERT(*allocated);
-                typeReg = frame.tempRegForType(value);
-            }
-
-            MaybeJump intDone;
-            if (value->mightBeType(JSVAL_TYPE_INT32)) {
-                // Check if the value is an integer.
-                MaybeJump notInt;
-                if (!value->isTypeKnown()) {
-                    JS_ASSERT(*allocated);
-                    notInt = masm.testInt32(Assembler::NotEqual, typeReg.reg());
-                }
-
-                if (*allocated) {
-                    masm.move(dataReg.reg(), reg.reg());
-                    if (!frame.haveSameBacking(id, value))
-                        frame.unpinReg(dataReg.reg());
-                }
-
-                if (atype == TypedArray::TYPE_UINT8_CLAMPED)
-                    masm.clampInt32ToUint8(reg.reg());
-
-                if (notInt.isSet()) {
-                    intDone = masm.jump();
-                    notInt.get().linkTo(masm.label(), &masm);
-                }
-            }
-            if (value->mightBeType(JSVAL_TYPE_DOUBLE)) {
-                // Check if the value is a double.
-                if (!value->isTypeKnown()) {
-                    Jump notNumber = masm.testDouble(Assembler::NotEqual, typeReg.reg());
-                    stubcc.linkExit(notNumber, Uses(3));
-                }
-
-                // Load value in fpReg.
-                FPRegisterID fpReg;
-                if (value->isTypeKnown()) {
-                    fpReg = frame.tempFPRegForData(value);
-                } else {
-                    fpReg = frame.allocFPReg();
-                    frame.loadDouble(value, fpReg, masm);
-                }
-
-                // Convert double to integer.
-                if (atype == TypedArray::TYPE_UINT8_CLAMPED) {
-                    if (value->isTypeKnown())
-                        frame.pinReg(fpReg);
-                    FPRegisterID fpTemp = frame.allocFPReg();
-                    if (value->isTypeKnown())
-                        frame.unpinReg(fpReg);
-                    masm.clampDoubleToUint8(fpReg, fpTemp, reg.reg());
-                    frame.freeReg(fpTemp);
-                } else {
-                    Jump j = masm.branchTruncateDoubleToInt32(fpReg, reg.reg());
-                    stubcc.linkExit(j, Uses(3));
-                }
-                if (!value->isTypeKnown())
-                    frame.freeReg(fpReg);
-            }
-            if (intDone.isSet())
-                intDone.get().linkTo(masm.label(), &masm);
-            *vr = ValueRemat::FromKnownType(JSVAL_TYPE_INT32, reg.reg());
-        }
-    }
-}
-
-void
-mjit::Compiler::jsop_setelem_typed(int atype)
-{
-    FrameEntry *obj = frame.peek(-3);
-    FrameEntry *id = frame.peek(-2);
-    FrameEntry *value = frame.peek(-1);
-
-    // We might not know whether this is an object, but if it is an object we
-    // know it's a typed array.
-    if (!obj->isTypeKnown()) {
-        Jump guard = frame.testObject(Assembler::NotEqual, obj);
-        stubcc.linkExit(guard, Uses(3));
-    }
-
-    if (id->isType(JSVAL_TYPE_DOUBLE))
-        tryConvertInteger(id, Uses(2));
-
-    // Test for integer index.
-    if (!id->isTypeKnown()) {
-        Jump guard = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(guard, Uses(3));
-    }
-
-    // Pin value.
-    ValueRemat vr;
-    frame.pinEntry(value, vr, /* breakDouble = */ false);
-
-    // Allocate and pin object and key regs.
-    Int32Key key = id->isConstant()
-                 ? Int32Key::FromConstant(id->getValue().toInt32())
-                 : Int32Key::FromRegister(frame.tempRegForData(id));
-
-    bool pinKey = !key.isConstant() && !frame.haveSameBacking(id, value);
-    if (pinKey)
-        frame.pinReg(key.reg());
-
-    analyze::CrossSSAValue objv(a->inlineIndex, analysis->poppedValue(PC, 1));
-    analyze::CrossSSAValue indexv(a->inlineIndex, analysis->poppedValue(PC, 0));
-    bool hoisted = loop && id->isType(JSVAL_TYPE_INT32) &&
-        loop->hoistArrayLengthCheck(TYPED_ARRAY, objv, indexv);
-
-    RegisterID objReg;
-    if (hoisted) {
-        FrameEntry *slotsFe = loop->invariantArraySlots(objv);
-        objReg = frame.tempRegForData(slotsFe);
-        frame.pinReg(objReg);
-    } else if (obj->isConstant()) {
-        JSObject *array = &obj->getValue().toObject();
-        int32_t length = (int32_t) TypedArray::length(array);
-        void *data = TypedArray::viewData(array);
-
-        // The 'data' pointer can change in rare circumstances
-        // (ArrayBufferObject::changeContents).
-        types::HeapTypeSet::WatchObjectStateChange(cx, array->getType(cx));
-
-        objReg = frame.allocReg();
-
-        if (key.isConstant()) {
-            if (key.index() >= length)
-                stubcc.linkExit(masm.jump(), Uses(2));
-        } else {
-            Jump lengthGuard = masm.branch32(Assembler::AboveOrEqual, key.reg(), Imm32(length));
-            stubcc.linkExit(lengthGuard, Uses(2));
-        }
-
-        masm.move(ImmPtr(data), objReg);
-    } else {
-        objReg = frame.copyDataIntoReg(obj);
-
-        // Bounds check.
-        int lengthOffset = TypedArray::lengthOffset() + offsetof(jsval_layout, s.payload);
-        Jump lengthGuard = masm.guardArrayExtent(lengthOffset,
-                                                 objReg, key, Assembler::BelowOrEqual);
-        stubcc.linkExit(lengthGuard, Uses(3));
-
-        // Load the array's packed data vector.
-        masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
-    }
-
-    // Unpin value so that convertForTypedArray can assign a new data
-    // register using tempRegInMaskForData.
-    frame.unpinEntry(vr);
-
-    // Make sure key is pinned.
-    if (frame.haveSameBacking(id, value)) {
-        frame.pinReg(key.reg());
-        pinKey = true;
-    }
-    JS_ASSERT(pinKey == !id->isConstant());
-
-    bool allocated;
-    convertForTypedArray(atype, &vr, &allocated);
-
-    // Store the value.
-    masm.storeToTypedArray(atype, objReg, key, vr);
-    if (allocated) {
-        if (vr.isFPRegister())
-            frame.freeReg(vr.fpReg());
-        else
-            frame.freeReg(vr.dataReg());
-    }
-    if (pinKey)
-        frame.unpinReg(key.reg());
-    if (hoisted)
-        frame.unpinReg(objReg);
-    else
-        frame.freeReg(objReg);
-
-    stubcc.leave();
-    OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
-
-    frame.shimmy(2);
-    stubcc.rejoin(Changes(2));
-}
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-void
-mjit::Compiler::tryConvertInteger(FrameEntry *fe, Uses uses)
-{
-    JS_ASSERT(fe->isType(JSVAL_TYPE_DOUBLE));
-
-    JumpList isDouble;
-    FPRegisterID fpreg = frame.tempFPRegForData(fe);
-    RegisterID reg = frame.allocReg();
-    masm.branchConvertDoubleToInt32(fpreg, reg, isDouble, Registers::FPConversionTemp);
-    Jump j = masm.jump();
-    isDouble.linkTo(masm.label(), &masm);
-    stubcc.linkExit(masm.jump(), uses);
-    j.linkTo(masm.label(), &masm);
-    frame.learnType(fe, JSVAL_TYPE_INT32, reg);
-}
-
-bool
-mjit::Compiler::jsop_setelem(bool popGuaranteed)
-{
-    FrameEntry *obj = frame.peek(-3);
-    FrameEntry *id = frame.peek(-2);
-    FrameEntry *value = frame.peek(-1);
-
-    if (!IsCacheableSetElem(obj, id, value) || monitored(PC)) {
-        if (monitored(PC) && script_ == outerScript)
-            monitoredBytecodes.append(PC - script_->code);
-
-        jsop_setelem_slow();
-        return true;
-    }
-
-    types::StackTypeSet::DoubleConversion conversion = types::StackTypeSet::DontConvertToDoubles;
-
-    // If the object is definitely a dense array or a typed array we can generate
-    // code directly without using an inline cache.
-    if (cx->typeInferenceEnabled()) {
-        types::StackTypeSet *types = analysis->poppedTypes(PC, 2);
-
-        conversion = types->convertDoubleElements(cx);
-        if (types->getKnownClass() == &ArrayClass &&
-            !types->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                   types::OBJECT_FLAG_LENGTH_OVERFLOW) &&
-            !types::ArrayPrototypeHasIndexedProperty(cx, outerScript) &&
-            conversion != types::StackTypeSet::AmbiguousDoubleConversion &&
-            (conversion == types::StackTypeSet::DontConvertToDoubles ||
-             value->isType(JSVAL_TYPE_DOUBLE) ||
-             value->isConstant() ||
-             popGuaranteed))
-        {
-            // Inline dense array path.
-            jsop_setelem_dense(conversion);
-            return true;
-        }
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-        int atype = types->getTypedArrayType();
-        if ((value->mightBeType(JSVAL_TYPE_INT32) || value->mightBeType(JSVAL_TYPE_DOUBLE)) &&
-            atype != TypedArray::TYPE_MAX)
-        {
-            // Inline typed array path.
-            jsop_setelem_typed(atype);
-            return true;
-        }
-#endif
-    }
-
-    frame.forgetMismatchedObject(obj);
-
-    if (id->isType(JSVAL_TYPE_DOUBLE) || !globalObj || conversion != types::StackTypeSet::DontConvertToDoubles) {
-        jsop_setelem_slow();
-        return true;
-    }
-
-#ifdef JSGC_INCREMENTAL_MJ
-    // Write barrier.
-    if (cx->zone()->compileBarriers()) {
-        jsop_setelem_slow();
-        return true;
-    }
-#endif
-
-    SetElementICInfo ic;
-
-    // One by one, check if the most important stack entries have registers,
-    // and if so, pin them. This is to avoid spilling and reloading from the
-    // stack as we incrementally allocate other registers.
-    MaybeRegisterID pinnedValueType = frame.maybePinType(value);
-    MaybeRegisterID pinnedValueData = frame.maybePinData(value);
-
-    // Pin |obj| if it doesn't share a backing with |value|.
-    MaybeRegisterID pinnedObjData;
-    if (!obj->hasSameBacking(value))
-        pinnedObjData = frame.maybePinData(obj);
-
-    // Pin |id| if it doesn't share a backing with |value|.
-    MaybeRegisterID pinnedIdData;
-    if (!id->hasSameBacking(value))
-        pinnedIdData = frame.maybePinData(id);
-
-    // Note: The fact that |obj| and |value|, or |id| and |value| can be
-    // copies, is a little complicated, but it is safe. Explanations
-    // follow at each point. Keep in mind two points:
-    //  1) maybePin() never allocates a register, it only pins if a register
-    //     already existed.
-    //  2) tempRegForData() will work fine on a pinned register.
-
-    // Guard that the object is an object.
-    if (!obj->isTypeKnown()) {
-        Jump j = frame.testObject(Assembler::NotEqual, obj);
-        stubcc.linkExit(j, Uses(3));
-    }
-
-    // Guard that the id is int32_t.
-    if (!id->isTypeKnown()) {
-        Jump j = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(j, Uses(3));
-    }
-
-    // Grab a register for the object. It's safe to unpin |obj| because it
-    // won't have been pinned if it shares a backing with |value|. However,
-    // it would not be safe to copyDataIntoReg() if the value was pinned,
-    // since this could evict the register. So we special case.
-    frame.maybeUnpinReg(pinnedObjData);
-    if (obj->hasSameBacking(value) && pinnedValueData.isSet()) {
-        ic.objReg = frame.allocReg();
-        masm.move(pinnedValueData.reg(), ic.objReg);
-    } else {
-        ic.objReg = frame.copyDataIntoReg(obj);
-    }
-
-    // pinEntry() will ensure pinned registers for |value|. To avoid a
-    // double-pin assert, first unpin any registers that |value| had.
-    frame.maybeUnpinReg(pinnedValueType);
-    frame.maybeUnpinReg(pinnedValueData);
-    frame.pinEntry(value, ic.vr);
-
-    // Store rematerialization information about the key. This is the final
-    // register we allocate, and thus it can use tempRegForData() without
-    // the worry of being spilled. Once again, this is safe even if |id|
-    // shares a backing with |value|, because tempRegForData() will work on
-    // the pinned register, and |pinnedIdData| will not double-pin.
-    frame.maybeUnpinReg(pinnedIdData);
-    if (id->isConstant())
-        ic.key = Int32Key::FromConstant(id->getValue().toInt32());
-    else
-        ic.key = Int32Key::FromRegister(frame.tempRegForData(id));
-
-    // Unpin the value since register allocation is complete.
-    frame.unpinEntry(ic.vr);
-
-    // Now it's also safe to grab remat info for obj (all exits that can
-    // generate stubs must have the same register state).
-    ic.objRemat = frame.dataRematInfo(obj);
-
-    // All patchable guards must occur after this point.
-    RESERVE_IC_SPACE(masm);
-    ic.fastPathStart = masm.label();
-
-    // Create the common out-of-line sync block, taking care to link previous
-    // guards here after.
-    RESERVE_OOL_SPACE(stubcc.masm);
-    ic.slowPathStart = stubcc.syncExit(Uses(3));
-
-    // Guard obj is a dense array.
-    Shape *shape = GetDenseArrayShape(cx, globalObj);
-    if (!shape)
-        return false;
-    ic.shapeGuard = masm.guardShape(ic.objReg, shape);
-    stubcc.linkExitDirect(ic.shapeGuard, ic.slowPathStart);
-
-    // Load the dynamic elements vector.
-    masm.loadPtr(Address(ic.objReg, JSObject::offsetOfElements()), ic.objReg);
-
-    // Guard in range of initialized length.
-    Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                              ic.objReg, ic.key, Assembler::BelowOrEqual);
-    stubcc.linkExitDirect(initlenGuard, ic.slowPathStart);
-
-    // Guard there's no hole, then store directly to the slot.
-    if (ic.key.isConstant()) {
-        Address slot(ic.objReg, ic.key.index() * sizeof(Value));
-        ic.holeGuard = masm.guardNotHole(slot);
-        masm.storeValue(ic.vr, slot);
-    } else {
-        BaseIndex slot(ic.objReg, ic.key.reg(), Assembler::JSVAL_SCALE);
-        ic.holeGuard = masm.guardNotHole(slot);
-        masm.storeValue(ic.vr, slot);
-    }
-    stubcc.linkExitDirect(ic.holeGuard, ic.slowPathStart);
-
-    stubcc.leave();
-#if defined JS_POLYIC
-    passICAddress(&ic);
-    ic.slowPathCall = OOL_STUBCALL(STRICT_VARIANT(script_, ic::SetElement), REJOIN_FALLTHROUGH);
-#else
-    OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
-#endif
-
-    ic.fastPathRejoin = masm.label();
-
-    // When generating typed array stubs, it may be necessary to call
-    // ToInt32(), which would clobber registers. To deal with this, we tell the
-    // IC exactly which registers need to be saved across calls.
-    ic.volatileMask = frame.regsInUse();
-
-    // If the RHS will be popped, and doesn't overlap any live values, then
-    // there's no need to save it across calls. Note that this is not true of
-    // |obj| or |key|, which will be used to compute the LHS reference for
-    // assignment.
-    //
-    // Note that the IC wants to clobber |vr.dataReg| to convert for typed
-    // arrays. If this clobbering is necessary, we must preserve dataReg,
-    // even if it's not in a volatile register.
-    if (popGuaranteed &&
-        !ic.vr.isConstant() &&
-        !value->isCopy() &&
-        !frame.haveSameBacking(value, obj) &&
-        !frame.haveSameBacking(value, id))
-    {
-        ic.volatileMask &= ~Registers::maskReg(ic.vr.dataReg());
-        if (!ic.vr.isTypeKnown())
-            ic.volatileMask &= ~Registers::maskReg(ic.vr.typeReg());
-    } else if (!ic.vr.isConstant()) {
-        ic.volatileMask |= Registers::maskReg(ic.vr.dataReg());
-    }
-
-    frame.freeReg(ic.objReg);
-    frame.shimmy(2);
-    stubcc.rejoin(Changes(2));
-
-#if defined JS_POLYIC
-    if (!setElemICs.append(ic))
-        return false;
-#endif
-
-    return true;
-}
-
-static inline bool
-IsCacheableGetElem(FrameEntry *obj, FrameEntry *id)
-{
-    if (id->isTypeKnown() &&
-        !(id->isType(JSVAL_TYPE_INT32) || id->isType(JSVAL_TYPE_DOUBLE)
-#if defined JS_POLYIC
-          || id->isType(JSVAL_TYPE_STRING)
-#endif
-         )) {
-        return false;
-    }
-
-    if (id->isType(JSVAL_TYPE_DOUBLE) && id->isConstant())
-        return false;
-
-    if (id->isType(JSVAL_TYPE_INT32) && id->isConstant() &&
-        id->getValue().toInt32() < 0) {
-        return false;
-    }
-
-    // obj[obj] is not allowed, since it will never optimize.
-    if (obj->hasSameBacking(id))
-        return false;
-
-    return true;
-}
-
-void
-mjit::Compiler::jsop_getelem_dense(bool isPacked)
-{
-    FrameEntry *obj = frame.peek(-2);
-    FrameEntry *id = frame.peek(-1);
-
-    frame.forgetMismatchedObject(obj);
-
-    // We might not know whether this is an object, but if it is an object we
-    // know it is a dense array.
-    if (!obj->isTypeKnown()) {
-        Jump guard = frame.testObject(Assembler::NotEqual, obj);
-        stubcc.linkExit(guard, Uses(2));
-    }
-
-    if (id->isType(JSVAL_TYPE_DOUBLE))
-        tryConvertInteger(id, Uses(2));
-
-    // Test for integer index.
-    if (!id->isTypeKnown()) {
-        Jump guard = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(guard, Uses(2));
-    }
-
-    JSValueType type = knownPushedType(0);
-
-    // Allocate registers.
-
-    // If we know the result of the GETELEM may be undefined, then misses on the
-    // initialized length or hole checks can just produce an undefined value.
-    // We checked in the caller that prototypes do not have indexed properties.
-    bool allowUndefined = mayPushUndefined(0);
-
-    analyze::CrossSSAValue objv(a->inlineIndex, analysis->poppedValue(PC, 1));
-    analyze::CrossSSAValue indexv(a->inlineIndex, analysis->poppedValue(PC, 0));
-    bool hoisted = loop && id->isType(JSVAL_TYPE_INT32) &&
-        loop->hoistArrayLengthCheck(DENSE_ARRAY, objv, indexv);
-
-    // Get a register with either the object or its slots, depending on whether
-    // we are hoisting the slots computation.
-    RegisterID baseReg;
-    if (hoisted) {
-        FrameEntry *slotsFe = loop->invariantArraySlots(objv);
-        baseReg = frame.tempRegForData(slotsFe);
-    } else {
-        baseReg = frame.tempRegForData(obj);
-    }
-    frame.pinReg(baseReg);
-
-    Int32Key key = id->isConstant()
-                 ? Int32Key::FromConstant(id->getValue().toInt32())
-                 : Int32Key::FromRegister(frame.tempRegForData(id));
-    bool pinKey = !key.isConstant() && key.reg() != baseReg;
-    if (pinKey)
-        frame.pinReg(key.reg());
-
-    RegisterID dataReg = frame.allocReg();
-
-    MaybeRegisterID typeReg;
-    if (type == JSVAL_TYPE_UNKNOWN || type == JSVAL_TYPE_DOUBLE || hasTypeBarriers(PC))
-        typeReg = frame.allocReg();
-
-    frame.unpinReg(baseReg);
-    if (pinKey)
-        frame.unpinReg(key.reg());
-
-    RegisterID slotsReg;
-    if (hoisted) {
-        slotsReg = baseReg;
-    } else {
-        masm.loadPtr(Address(baseReg, JSObject::offsetOfElements()), dataReg);
-        slotsReg = dataReg;
-    }
-
-    // Guard on the array's initialized length.
-    MaybeJump initlenGuard;
-    if (!hoisted) {
-        initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
-                                             slotsReg, key, Assembler::BelowOrEqual);
-        if (!allowUndefined)
-            stubcc.linkExit(initlenGuard.get(), Uses(2));
-    }
-
-    // Get the slot, skipping the hole check if the array is known to be packed.
-    Jump holeCheck;
-    if (key.isConstant()) {
-        Address slot(slotsReg, key.index() * sizeof(Value));
-        holeCheck = masm.fastArrayLoadSlot(slot, !isPacked, typeReg, dataReg);
-    } else {
-        JS_ASSERT(key.reg() != dataReg);
-        BaseIndex slot(slotsReg, key.reg(), masm.JSVAL_SCALE);
-        holeCheck = masm.fastArrayLoadSlot(slot, !isPacked, typeReg, dataReg);
-    }
-
-    if (!isPacked && !allowUndefined)
-        stubcc.linkExit(holeCheck, Uses(2));
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::GetElem, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, -2);
-
-    frame.popn(2);
-
-    BarrierState barrier;
-    if (typeReg.isSet()) {
-        frame.pushRegs(typeReg.reg(), dataReg, type);
-        barrier = testBarrier(typeReg.reg(), dataReg, false);
-    } else {
-        frame.pushTypedPayload(type, dataReg);
-    }
-
-    stubcc.rejoin(Changes(2));
-
-    if (allowUndefined) {
-        if (!hoisted)
-            stubcc.linkExitDirect(initlenGuard.get(), stubcc.masm.label());
-        if (!isPacked)
-            stubcc.linkExitDirect(holeCheck, stubcc.masm.label());
-        JS_ASSERT(type == JSVAL_TYPE_UNKNOWN || type == JSVAL_TYPE_UNDEFINED);
-        if (type == JSVAL_TYPE_UNDEFINED)
-            stubcc.masm.loadValuePayload(UndefinedValue(), dataReg);
-        else
-            stubcc.masm.loadValueAsComponents(UndefinedValue(), typeReg.reg(), dataReg);
-        stubcc.linkRejoin(stubcc.masm.jump());
-    }
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-}
-
-void
-mjit::Compiler::jsop_getelem_args()
-{
-    FrameEntry *id = frame.peek(-1);
-
-    if (id->isType(JSVAL_TYPE_DOUBLE))
-        tryConvertInteger(id, Uses(2));
-
-    // Test for integer index.
-    if (!id->isTypeKnown()) {
-        Jump guard = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(guard, Uses(2));
-    }
-
-    // Allocate registers.
-
-    analyze::CrossSSAValue indexv(a->inlineIndex, analysis->poppedValue(PC, 0));
-    bool hoistedLength = loop && id->isType(JSVAL_TYPE_INT32) &&
-        loop->hoistArgsLengthCheck(indexv);
-    FrameEntry *actualsFe = loop ? loop->invariantArguments() : NULL;
-
-    Int32Key key = id->isConstant()
-                 ? Int32Key::FromConstant(id->getValue().toInt32())
-                 : Int32Key::FromRegister(frame.tempRegForData(id));
-    if (!key.isConstant())
-        frame.pinReg(key.reg());
-
-    RegisterID dataReg = frame.allocReg();
-    RegisterID typeReg = frame.allocReg();
-
-    // Guard on nactual.
-    if (!hoistedLength) {
-        Address nactualAddr(JSFrameReg, StackFrame::offsetOfNumActual());
-        MaybeJump rangeGuard;
-        if (key.isConstant()) {
-            JS_ASSERT(key.index() >= 0);
-            rangeGuard = masm.branch32(Assembler::BelowOrEqual, nactualAddr, Imm32(key.index()));
-        } else {
-            rangeGuard = masm.branch32(Assembler::BelowOrEqual, nactualAddr, key.reg());
-        }
-        stubcc.linkExit(rangeGuard.get(), Uses(2));
-    }
-
-    RegisterID actualsReg;
-    if (actualsFe) {
-        actualsReg = frame.tempRegForData(actualsFe);
-    } else {
-        actualsReg = dataReg;
-        masm.loadFrameActuals(outerScript->function(), actualsReg);
-    }
-
-    if (!key.isConstant())
-        frame.unpinReg(key.reg());
-
-    if (key.isConstant()) {
-        Address arg(actualsReg, key.index() * sizeof(Value));
-        masm.loadValueAsComponents(arg, typeReg, dataReg);
-    } else {
-        JS_ASSERT(key.reg() != dataReg);
-        BaseIndex arg(actualsReg, key.reg(), masm.JSVAL_SCALE);
-        masm.loadValueAsComponents(arg, typeReg, dataReg);
-    }
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::GetElem, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, -2);
-
-    frame.popn(2);
-    frame.pushRegs(typeReg, dataReg, knownPushedType(0));
-    BarrierState barrier = testBarrier(typeReg, dataReg, false);
-
-    stubcc.rejoin(Changes(2));
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-}
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-bool
-mjit::Compiler::jsop_getelem_typed(int atype)
-{
-    // Unlike dense arrays, the types of elements in typed arrays are not
-    // guaranteed to be present in the object's type, and we need to use
-    // knowledge about the possible contents of the array vs. the types
-    // that have been read out of it to figure out how to do the load.
-
-    //                          Array contents
-    //                   Float     Uint32_t         Int32
-    // Observed types
-    //
-    // {int}             XXX       reg pair+test  reg
-    // {int,float}       FP reg    FP reg         reg pair
-    // {X,int}           XXX       reg pair+test  reg pair
-    // {X,int,float}     reg pair  reg pair       reg pair
-    // {X}               XXX       XXX            XXX
-
-    // Reject entries marked 'XXX' above, and compile a normal GETELEM.
-    types::TypeSet *pushedTypes = pushedTypeSet(0);
-    if (atype == TypedArray::TYPE_FLOAT32 || atype == TypedArray::TYPE_FLOAT64) {
-        if (!pushedTypes->hasType(types::Type::DoubleType()))
-            return false;
-    } else {
-        if (!pushedTypes->hasType(types::Type::Int32Type()))
-            return false;
-    }
-
-    FrameEntry *obj = frame.peek(-2);
-    FrameEntry *id = frame.peek(-1);
-
-    // We might not know whether this is an object, but if it's an object we
-    // know it is a typed array.
-    if (!obj->isTypeKnown()) {
-        Jump guard = frame.testObject(Assembler::NotEqual, obj);
-        stubcc.linkExit(guard, Uses(2));
-    }
-
-    if (id->isType(JSVAL_TYPE_DOUBLE))
-        tryConvertInteger(id, Uses(2));
-
-    // Test for integer index.
-    if (!id->isTypeKnown()) {
-        Jump guard = frame.testInt32(Assembler::NotEqual, id);
-        stubcc.linkExit(guard, Uses(2));
-    }
-
-    // Load object and key.
-    Int32Key key = id->isConstant()
-                 ? Int32Key::FromConstant(id->getValue().toInt32())
-                 : Int32Key::FromRegister(frame.tempRegForData(id));
-    if (!key.isConstant())
-        frame.pinReg(key.reg());
-
-    analyze::CrossSSAValue objv(a->inlineIndex, analysis->poppedValue(PC, 1));
-    analyze::CrossSSAValue indexv(a->inlineIndex, analysis->poppedValue(PC, 0));
-    bool hoisted = loop && id->isType(JSVAL_TYPE_INT32) &&
-        loop->hoistArrayLengthCheck(TYPED_ARRAY, objv, indexv);
-
-    RegisterID objReg;
-    if (hoisted) {
-        FrameEntry *slotsFe = loop->invariantArraySlots(objv);
-        objReg = frame.tempRegForData(slotsFe);
-        frame.pinReg(objReg);
-    } else if (obj->isConstant()) {
-        JSObject *array = &obj->getValue().toObject();
-        int32_t length = (int32_t) TypedArray::length(array);
-        void *data = TypedArray::viewData(array);
-
-        // The 'data' pointer can change in rare circumstances
-        // (ArrayBufferObject::changeContents).
-        types::HeapTypeSet::WatchObjectStateChange(cx, array->getType(cx));
-
-        objReg = frame.allocReg();
-
-        if (key.isConstant()) {
-            if (key.index() >= length)
-                stubcc.linkExit(masm.jump(), Uses(2));
-        } else {
-            Jump lengthGuard = masm.branch32(Assembler::AboveOrEqual, key.reg(), Imm32(length));
-            stubcc.linkExit(lengthGuard, Uses(2));
-        }
-
-        masm.move(ImmPtr(data), objReg);
-    } else {
-        objReg = frame.copyDataIntoReg(obj);
-
-        // Bounds check.
-        int lengthOffset = TypedArray::lengthOffset() + offsetof(jsval_layout, s.payload);
-        Jump lengthGuard = masm.guardArrayExtent(lengthOffset,
-                                                 objReg, key, Assembler::BelowOrEqual);
-        stubcc.linkExit(lengthGuard, Uses(2));
-
-        // Load the array's packed data vector.
-        masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
-    }
-
-    // We can load directly into an FP-register if the following conditions
-    // are met:
-    // 1) The array is an Uint32Array or a float array (loadFromTypedArray
-    //    can't load into an FP-register for other arrays).
-    // 2) The result is definitely a double (the result type set can include
-    //    other types after reading out-of-bound values).
-    AnyRegisterID dataReg;
-    MaybeRegisterID typeReg, tempReg;
-    JSValueType type = knownPushedType(0);
-    bool maybeReadFloat = (atype == TypedArray::TYPE_FLOAT32 ||
-                           atype == TypedArray::TYPE_FLOAT64 ||
-                           atype == TypedArray::TYPE_UINT32);
-    if (maybeReadFloat && type == JSVAL_TYPE_DOUBLE) {
-        dataReg = frame.allocFPReg();
-        // Need an extra reg to convert uint32_t to double.
-        if (atype == TypedArray::TYPE_UINT32)
-            tempReg = frame.allocReg();
-    } else {
-        dataReg = frame.allocReg();
-        // loadFromTypedArray expects a type register for Uint32Array or
-        // float arrays. Also allocate a type register if the result may not
-        // be int32_t (due to reading out-of-bound values) or if there's a
-        // type barrier.
-        if (maybeReadFloat || type != JSVAL_TYPE_INT32)
-            typeReg = frame.allocReg();
-    }
-
-    // Load value from the array.
-    masm.loadFromTypedArray(atype, objReg, key, typeReg, dataReg, tempReg);
-
-    if (hoisted)
-        frame.unpinReg(objReg);
-    else
-        frame.freeReg(objReg);
-    if (!key.isConstant())
-        frame.unpinReg(key.reg());
-    if (tempReg.isSet())
-        frame.freeReg(tempReg.reg());
-
-    if (atype == TypedArray::TYPE_UINT32 &&
-        !pushedTypes->hasType(types::Type::DoubleType())) {
-        Jump isDouble = masm.testDouble(Assembler::Equal, typeReg.reg());
-        stubcc.linkExit(isDouble, Uses(2));
-    }
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::GetElem, REJOIN_FALLTHROUGH);
-    testPushedType(REJOIN_FALLTHROUGH, -2);
-
-    frame.popn(2);
-
-    BarrierState barrier;
-    if (dataReg.isFPReg()) {
-        frame.pushDouble(dataReg.fpreg());
-    } else if (typeReg.isSet()) {
-        frame.pushRegs(typeReg.reg(), dataReg.reg(), knownPushedType(0));
-    } else {
-        JS_ASSERT(type == JSVAL_TYPE_INT32);
-        frame.pushTypedPayload(JSVAL_TYPE_INT32, dataReg.reg());
-    }
-    stubcc.rejoin(Changes(2));
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-
-    return true;
-}
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-bool
-mjit::Compiler::jsop_getelem()
-{
-    FrameEntry *obj = frame.peek(-2);
-    FrameEntry *id = frame.peek(-1);
-
-    if (!IsCacheableGetElem(obj, id)) {
-        jsop_getelem_slow();
-        return true;
-    }
-
-    // If the object is definitely an arguments object, a dense array or a typed array
-    // we can generate code directly without using an inline cache.
-    if (cx->typeInferenceEnabled() && !id->isType(JSVAL_TYPE_STRING)) {
-        types::StackTypeSet *types = analysis->poppedTypes(PC, 1);
-        if (types->isMagicArguments() && !outerScript->analysis()->modifiesArguments()) {
-            // Inline arguments path.
-            jsop_getelem_args();
-            return true;
-        }
-
-        if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
-            types->getKnownClass() == &ArrayClass &&
-            !types->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                   types::OBJECT_FLAG_LENGTH_OVERFLOW) &&
-            !types::ArrayPrototypeHasIndexedProperty(cx, outerScript))
-        {
-            // Inline dense array path.
-            bool packed = !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
-            jsop_getelem_dense(packed);
-            return true;
-        }
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-        int atype = types->getTypedArrayType();
-        if (obj->mightBeType(JSVAL_TYPE_OBJECT) && atype != TypedArray::TYPE_MAX) {
-            // Inline typed array path.
-            if (jsop_getelem_typed(atype))
-                return true;
-            // Fallthrough to the normal GETELEM path.
-        }
-#endif
-    }
-
-    frame.forgetMismatchedObject(obj);
-
-    if (id->isType(JSVAL_TYPE_DOUBLE) || !globalObj) {
-        jsop_getelem_slow();
-        return true;
-    }
-
-    GetElementICInfo ic;
-
-    // Pin the top of the stack to avoid spills, before allocating registers.
-    MaybeRegisterID pinnedIdData = frame.maybePinData(id);
-    MaybeRegisterID pinnedIdType = frame.maybePinType(id);
-
-    MaybeJump objTypeGuard;
-    if (!obj->isTypeKnown()) {
-        // Test the type of the object without spilling the payload.
-        MaybeRegisterID pinnedObjData = frame.maybePinData(obj);
-        Jump guard = frame.testObject(Assembler::NotEqual, obj);
-        frame.maybeUnpinReg(pinnedObjData);
-
-        // Create a sync path, which we'll rejoin manually later. This is safe
-        // as long as the IC does not build a stub; it won't, because |obj|
-        // won't be an object. If we extend this IC to support strings, all
-        // that needs to change is a little code movement.
-        stubcc.linkExit(guard, Uses(2));
-        objTypeGuard = stubcc.masm.jump();
-    }
-
-    // Get a mutable register for the object. This will be the data reg.
-    ic.objReg = frame.copyDataIntoReg(obj);
-
-    // Get a mutable register for pushing the result type. We kill two birds
-    // with one stone by making sure, if the key type is not known, to be loaded
-    // into this register. In this case it is both an input and an output.
-    frame.maybeUnpinReg(pinnedIdType);
-    if (id->isConstant() || id->isTypeKnown())
-        ic.typeReg = frame.allocReg();
-    else
-        ic.typeReg = frame.copyTypeIntoReg(id);
-
-    // Fill in the id value.
-    frame.maybeUnpinReg(pinnedIdData);
-    if (id->isConstant()) {
-        ic.id = ValueRemat::FromConstant(id->getValue());
-    } else {
-        RegisterID dataReg = frame.tempRegForData(id);
-        if (id->isTypeKnown())
-            ic.id = ValueRemat::FromKnownType(id->getKnownType(), dataReg);
-        else
-            ic.id = ValueRemat::FromRegisters(ic.typeReg, dataReg);
-    }
-
-    RESERVE_IC_SPACE(masm);
-    ic.fastPathStart = masm.label();
-
-    // Note: slow path here is safe, since the frame will not be modified.
-    RESERVE_OOL_SPACE(stubcc.masm);
-    ic.slowPathStart = stubcc.masm.label();
-    frame.sync(stubcc.masm, Uses(2));
-
-    if (id->mightBeType(JSVAL_TYPE_INT32)) {
-        // Always test the type first (see comment in PolyIC.h).
-        if (!id->isTypeKnown()) {
-            ic.typeGuard = masm.testInt32(Assembler::NotEqual, ic.typeReg);
-            stubcc.linkExitDirect(ic.typeGuard.get(), ic.slowPathStart);
-        }
-
-        // Guard obj is a dense array.
-        Shape *shape = GetDenseArrayShape(cx, globalObj);
-        if (!shape)
-            return false;
-        ic.shapeGuard = masm.guardShape(ic.objReg, shape);
-        stubcc.linkExitDirect(ic.shapeGuard, ic.slowPathStart);
-
-        Int32Key key = id->isConstant()
-                       ? Int32Key::FromConstant(id->getValue().toInt32())
-                       : Int32Key::FromRegister(ic.id.dataReg());
-
-        Assembler::FastArrayLoadFails fails =
-            masm.fastArrayLoad(ic.objReg, key, ic.typeReg, ic.objReg);
-
-        stubcc.linkExitDirect(fails.rangeCheck, ic.slowPathStart);
-        stubcc.linkExitDirect(fails.holeCheck, ic.slowPathStart);
-    } else {
-        // The type is known to not be dense-friendly ahead of time, so always
-        // fall back to a slow path.
-        ic.shapeGuard = masm.jump();
-        stubcc.linkExitDirect(ic.shapeGuard, ic.slowPathStart);
-    }
-
-    stubcc.leave();
-    if (objTypeGuard.isSet())
-        objTypeGuard.get().linkTo(stubcc.masm.label(), &stubcc.masm);
-#ifdef JS_POLYIC
-    passICAddress(&ic);
-    ic.slowPathCall = OOL_STUBCALL(ic::GetElement, REJOIN_FALLTHROUGH);
-#else
-    ic.slowPathCall = OOL_STUBCALL(stubs::GetElem, REJOIN_FALLTHROUGH);
-#endif
-
-    testPushedType(REJOIN_FALLTHROUGH, -2);
-
-    ic.fastPathRejoin = masm.label();
-    ic.forcedTypeBarrier = analysis->getCode(PC).getStringElement;
-
-    CHECK_IC_SPACE();
-
-    frame.popn(2);
-    frame.pushRegs(ic.typeReg, ic.objReg, knownPushedType(0));
-    BarrierState barrier = testBarrier(ic.typeReg, ic.objReg, false, false,
-                                       /* force = */ ic.forcedTypeBarrier);
-
-    stubcc.rejoin(Changes(1));
-
-#ifdef JS_POLYIC
-    if (!getElemICs.append(ic))
-        return false;
-#endif
-
-    finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
-    return true;
-}
-
-static inline bool
-ReallySimpleStrictTest(FrameEntry *fe)
-{
-    if (!fe->isTypeKnown())
-        return false;
-    JSValueType type = fe->getKnownType();
-    return type == JSVAL_TYPE_NULL || type == JSVAL_TYPE_UNDEFINED;
-}
-
-static inline bool
-BooleanStrictTest(FrameEntry *fe)
-{
-    return fe->isConstant() && fe->getKnownType() == JSVAL_TYPE_BOOLEAN;
-}
-
-void
-mjit::Compiler::jsop_stricteq(JSOp op)
-{
-    FrameEntry *rhs = frame.peek(-1);
-    FrameEntry *lhs = frame.peek(-2);
-
-    Assembler::Condition cond = (op == JSOP_STRICTEQ) ? Assembler::Equal : Assembler::NotEqual;
-
-    /*
-     * NB: x64 can do full-Value comparisons. This is beneficial
-     * to do if the payload/type are not yet in registers.
-     */
-
-    /* Constant-fold. */
-    if (lhs->isConstant() && rhs->isConstant()) {
-        bool b;
-        StrictlyEqual(cx, lhs->getValue(), rhs->getValue(), &b);
-        frame.popn(2);
-        frame.push(BooleanValue((op == JSOP_STRICTEQ) ? b : !b));
-        return;
-    }
-
-    if (frame.haveSameBacking(lhs, rhs)) {
-        /* False iff NaN. */
-        frame.pop();
-
-        if (lhs->isTypeKnown() && lhs->isNotType(JSVAL_TYPE_DOUBLE)) {
-            frame.pop();
-            frame.push(BooleanValue(op == JSOP_STRICTEQ));
-            return;
-        }
-
-        if (lhs->isType(JSVAL_TYPE_DOUBLE))
-            frame.forgetKnownDouble(lhs);
-
-        /* Assume NaN is either in canonical form or has the sign bit set (by jsop_neg). */
-        RegisterID result = frame.allocReg(Registers::SingleByteRegs).reg();
-        RegisterID treg = frame.copyTypeIntoReg(lhs);
-
-        Assembler::Condition oppositeCond = (op == JSOP_STRICTEQ) ? Assembler::NotEqual : Assembler::Equal;
-
-        /* Ignore the sign bit. */
-        masm.lshiftPtr(Imm32(1), treg);
-#ifdef JS_CPU_SPARC
-        /* On Sparc the result 0/0 is 0x7FFFFFFF not 0x7FF80000 */
-        static const int ShiftedCanonicalNaNType1 = 0x7FFFFFFF << 1;
-        static const int ShiftedCanonicalNaNType2 = 0x7FF80000 << 1;
-        RegisterID result1 = frame.allocReg();
-        masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType1), result1);
-        masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType2), result);
-        if(op == JSOP_STRICTEQ) {
-            masm.and32(result1, result);
-        } else {
-            masm.or32(result1, result);
-        }
-        frame.freeReg(result1);
-#elif defined(JS_CPU_MIPS)
-        /* On MIPS the result 0.0/0.0 is 0x7FF7FFFF.
-           We need to manually set it to 0x7FF80000. */
-        static const int ShiftedCanonicalNaNType = 0x7FF80000 << 1;
-        masm.setShiftedCanonicalNaN(treg, treg);
-        masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType), result);
-#elif !defined(JS_CPU_X64)
-        static const int ShiftedCanonicalNaNType = 0x7FF80000 << 1;
-        masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType), result);
-#else
-        static const void *ShiftedCanonicalNaNType = (void *)(0x7FF8000000000000 << 1);
-        masm.move(ImmPtr(ShiftedCanonicalNaNType), Registers::ScratchReg);
-        masm.setPtr(oppositeCond, treg, Registers::ScratchReg, result);
-#endif
-        frame.freeReg(treg);
-
-        frame.pop();
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-        return;
-    }
-
-    /* Comparison against undefined or null is super easy. */
-    bool lhsTest;
-    if ((lhsTest = ReallySimpleStrictTest(lhs)) || ReallySimpleStrictTest(rhs)) {
-        FrameEntry *test = lhsTest ? rhs : lhs;
-        FrameEntry *known = lhsTest ? lhs : rhs;
-        RegisterID result = frame.allocReg(Registers::SingleByteRegs).reg();
-
-        if (test->isTypeKnown()) {
-            masm.move(Imm32((test->getKnownType() == known->getKnownType()) ==
-                            (op == JSOP_STRICTEQ)), result);
-            frame.popn(2);
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-            return;
-        }
-
-        /* This is only true if the other side is |null|. */
-#ifndef JS_CPU_X64
-        JSValueTag mask = known->getKnownTag();
-        if (frame.shouldAvoidTypeRemat(test))
-            masm.set32(cond, masm.tagOf(frame.addressOf(test)), Imm32(mask), result);
-        else
-            masm.set32(cond, frame.tempRegForType(test), Imm32(mask), result);
-#else
-        RegisterID maskReg = frame.allocReg();
-        masm.move(ImmTag(known->getKnownTag()), maskReg);
-
-        RegisterID r = frame.tempRegForType(test);
-        masm.setPtr(cond, r, maskReg, result);
-
-        frame.freeReg(maskReg);
-#endif
-        frame.popn(2);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-        return;
-    }
-
-    /* Hardcoded booleans are easy too. */
-    if ((lhsTest = BooleanStrictTest(lhs)) || BooleanStrictTest(rhs)) {
-        FrameEntry *test = lhsTest ? rhs : lhs;
-
-        if (test->isTypeKnown() && test->isNotType(JSVAL_TYPE_BOOLEAN)) {
-            RegisterID result = frame.allocReg(Registers::SingleByteRegs).reg();
-            frame.popn(2);
-
-            masm.move(Imm32(op == JSOP_STRICTNE), result);
-            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-            return;
-        }
-
-        if (test->isConstant()) {
-            frame.popn(2);
-            const Value &L = lhs->getValue();
-            const Value &R = rhs->getValue();
-            frame.push(BooleanValue((L.toBoolean() == R.toBoolean()) == (op == JSOP_STRICTEQ)));
-            return;
-        }
-
-        RegisterID data = frame.copyDataIntoReg(test);
-
-        RegisterID result = data;
-        if (!(Registers::maskReg(data) & Registers::SingleByteRegs))
-            result = frame.allocReg(Registers::SingleByteRegs).reg();
-
-        Jump notBoolean;
-        if (!test->isTypeKnown())
-           notBoolean = frame.testBoolean(Assembler::NotEqual, test);
-
-        /* Do a dynamic test. */
-        bool val = lhsTest ? lhs->getValue().toBoolean() : rhs->getValue().toBoolean();
-        masm.set32(cond, data, Imm32(val), result);
-
-        if (!test->isTypeKnown()) {
-            Jump done = masm.jump();
-            notBoolean.linkTo(masm.label(), &masm);
-            masm.move(Imm32((op == JSOP_STRICTNE)), result);
-            done.linkTo(masm.label(), &masm);
-        }
-
-        if (data != result)
-            frame.freeReg(data);
-
-        frame.popn(2);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, result);
-        return;
-    }
-
-    if (lhs->isType(JSVAL_TYPE_STRING) || rhs->isType(JSVAL_TYPE_STRING)) {
-        FrameEntry *maybeNotStr = lhs->isType(JSVAL_TYPE_STRING) ? rhs : lhs;
-
-        if (maybeNotStr->isNotType(JSVAL_TYPE_STRING)) {
-            frame.popn(2);
-            frame.push(BooleanValue(op == JSOP_STRICTNE));
-            return;
-        }
-
-        if (!maybeNotStr->isTypeKnown()) {
-            JS_ASSERT(!maybeNotStr->isConstant());
-            Jump j = frame.testString(Assembler::NotEqual, maybeNotStr);
-            stubcc.linkExit(j, Uses(2));
-        }
-
-        FrameEntry *op1 = lhs->isConstant() ? rhs : lhs;
-        FrameEntry *op2 = lhs->isConstant() ? lhs : rhs;
-        JS_ASSERT(!op1->isConstant());
-
-        /* ReturnReg is safely usable with set32, since %ah can be accessed. */
-        RegisterID resultReg = Registers::ReturnReg;
-        frame.takeReg(resultReg);
-        RegisterID tmpReg = frame.allocReg();
-        RegisterID reg1 = frame.tempRegForData(op1);
-        frame.pinReg(reg1);
-
-        RegisterID reg2;
-        if (op2->isConstant()) {
-            reg2 = frame.allocReg();
-            JSString *str = op2->getValue().toString();
-            JS_ASSERT(str->isAtom());
-            masm.move(ImmPtr(str), reg2);
-        } else {
-            reg2 = frame.tempRegForData(op2);
-            frame.pinReg(reg2);
-        }
-
-        JS_ASSERT(reg1 != resultReg);
-        JS_ASSERT(reg1 != tmpReg);
-        JS_ASSERT(reg2 != resultReg);
-        JS_ASSERT(reg2 != tmpReg);
-
-        /* JSString::isAtom === (lengthAndFlags & ATOM_BIT) */
-        Imm32 atomBit(JSString::ATOM_BIT);
-
-        masm.load32(Address(reg1, JSString::offsetOfLengthAndFlags()), tmpReg);
-        Jump op1NotAtomized = masm.branchTest32(Assembler::Zero, tmpReg, atomBit);
-        stubcc.linkExit(op1NotAtomized, Uses(2));
-
-        if (!op2->isConstant()) {
-            masm.load32(Address(reg2, JSString::offsetOfLengthAndFlags()), tmpReg);
-            Jump op2NotAtomized = masm.branchTest32(Assembler::Zero, tmpReg, atomBit);
-            stubcc.linkExit(op2NotAtomized, Uses(2));
-        }
-
-        masm.set32(cond, reg1, reg2, resultReg);
-
-        frame.unpinReg(reg1);
-        if (op2->isConstant())
-            frame.freeReg(reg2);
-        else
-            frame.unpinReg(reg2);
-        frame.freeReg(tmpReg);
-
-        stubcc.leave();
-        if (op == JSOP_STRICTEQ)
-            OOL_STUBCALL_USES(stubs::StrictEq, REJOIN_NONE, Uses(2));
-        else
-            OOL_STUBCALL_USES(stubs::StrictNe, REJOIN_NONE, Uses(2));
-
-        frame.popn(2);
-        frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, resultReg);
-
-        stubcc.rejoin(Changes(1));
-        return;
-    }
-
-    if (cx->typeInferenceEnabled() &&
-        lhs->isType(JSVAL_TYPE_OBJECT) && rhs->isType(JSVAL_TYPE_OBJECT))
-    {
-        CompileStatus status = jsop_equality_obj_obj(op, NULL, JSOP_NOP);
-        if (status == Compile_Okay) return;
-        JS_ASSERT(status == Compile_Skipped);
-    }
-
-    /* Is it impossible that both Values are ints? */
-    if ((lhs->isTypeKnown() && lhs->isNotType(JSVAL_TYPE_INT32)) ||
-        (rhs->isTypeKnown() && rhs->isNotType(JSVAL_TYPE_INT32))) {
-        prepareStubCall(Uses(2));
-
-        if (op == JSOP_STRICTEQ)
-            INLINE_STUBCALL_USES(stubs::StrictEq, REJOIN_NONE, Uses(2));
-        else
-            INLINE_STUBCALL_USES(stubs::StrictNe, REJOIN_NONE, Uses(2));
-
-        frame.popn(2);
-        frame.pushSynced(JSVAL_TYPE_BOOLEAN);
-        return;
-    }
-
-#if !defined JS_CPU_ARM && !defined JS_CPU_SPARC
-    /* Try an integer fast-path. */
-    bool needStub = false;
-    if (!lhs->isTypeKnown()) {
-        Jump j = frame.testInt32(Assembler::NotEqual, lhs);
-        stubcc.linkExit(j, Uses(2));
-        needStub = true;
-    }
-
-    if (!rhs->isTypeKnown() && !frame.haveSameBacking(lhs, rhs)) {
-        Jump j = frame.testInt32(Assembler::NotEqual, rhs);
-        stubcc.linkExit(j, Uses(2));
-        needStub = true;
-    }
-
-    FrameEntry *test  = lhs->isConstant() ? rhs : lhs;
-    FrameEntry *other = lhs->isConstant() ? lhs : rhs;
-
-    /* ReturnReg is safely usable with set32, since %ah can be accessed. */
-    RegisterID resultReg = Registers::ReturnReg;
-    frame.takeReg(resultReg);
-    RegisterID testReg = frame.tempRegForData(test);
-    frame.pinReg(testReg);
-
-    JS_ASSERT(resultReg != testReg);
-
-    /* Set boolean in resultReg. */
-    if (other->isConstant()) {
-        masm.set32(cond, testReg, Imm32(other->getValue().toInt32()), resultReg);
-    } else if (frame.shouldAvoidDataRemat(other)) {
-        masm.set32(cond, testReg, frame.addressOf(other), resultReg);
-    } else {
-        RegisterID otherReg = frame.tempRegForData(other);
-
-        JS_ASSERT(otherReg != resultReg);
-        JS_ASSERT(otherReg != testReg);
-
-        masm.set32(cond, testReg, otherReg, resultReg);
-    }
-
-    frame.unpinReg(testReg);
-
-    if (needStub) {
-        stubcc.leave();
-        if (op == JSOP_STRICTEQ)
-            OOL_STUBCALL_USES(stubs::StrictEq, REJOIN_NONE, Uses(2));
-        else
-            OOL_STUBCALL_USES(stubs::StrictNe, REJOIN_NONE, Uses(2));
-    }
-
-    frame.popn(2);
-    frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, resultReg);
-
-    if (needStub)
-        stubcc.rejoin(Changes(1));
-#else
-    /* TODO: Port set32() logic to ARM. */
-    prepareStubCall(Uses(2));
-
-    if (op == JSOP_STRICTEQ)
-        INLINE_STUBCALL_USES(stubs::StrictEq, REJOIN_NONE, Uses(2));
-    else
-        INLINE_STUBCALL_USES(stubs::StrictNe, REJOIN_NONE, Uses(2));
-
-    frame.popn(2);
-    frame.pushSynced(JSVAL_TYPE_BOOLEAN);
-    return;
-#endif
-}
-
-void
-mjit::Compiler::jsop_pos()
-{
-    FrameEntry *top = frame.peek(-1);
-
-    if (top->isTypeKnown()) {
-        if (top->getKnownType() <= JSVAL_TYPE_INT32)
-            return;
-        prepareStubCall(Uses(1));
-        INLINE_STUBCALL(stubs::Pos, REJOIN_FALLTHROUGH);
-        frame.pop();
-        frame.pushSynced(knownPushedType(0));
-        return;
-    }
-
-    frame.giveOwnRegs(top);
-
-    Jump j;
-    if (frame.shouldAvoidTypeRemat(top))
-        j = masm.testNumber(Assembler::NotEqual, frame.addressOf(top));
-    else
-        j = masm.testNumber(Assembler::NotEqual, frame.tempRegForType(top));
-    stubcc.linkExit(j, Uses(1));
-
-    stubcc.leave();
-    OOL_STUBCALL(stubs::Pos, REJOIN_FALLTHROUGH);
-
-    stubcc.rejoin(Changes(1));
-}
-
-void
-mjit::Compiler::jsop_initprop()
-{
-    FrameEntry *obj = frame.peek(-2);
-    FrameEntry *fe = frame.peek(-1);
-    PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
-
-    RootedObject baseobj(cx, frame.extra(obj).initObject);
-
-    if (!baseobj || monitored(PC) || cx->zone()->compileBarriers()) {
-        if (monitored(PC) && script_ == outerScript)
-            monitoredBytecodes.append(PC - script_->code);
-
-        prepareStubCall(Uses(2));
-        masm.move(ImmPtr(name), Registers::ArgReg1);
-        INLINE_STUBCALL(stubs::InitProp, REJOIN_FALLTHROUGH);
-        return;
-    }
-
-    RootedObject holder(cx);
-    RootedShape shape(cx);
-    Rooted<jsid> id(cx, NameToId(name));
-#ifdef DEBUG
-    bool res =
-#endif
-    LookupPropertyWithFlags(cx, baseobj, id, 0, &holder, &shape);
-    JS_ASSERT(res && shape && holder == baseobj);
-
-    RegisterID objReg = frame.copyDataIntoReg(obj);
-
-    /* Perform the store. */
-    Address address = masm.objPropAddress(baseobj, objReg, shape->slot());
-    frame.storeTo(fe, address);
-    frame.freeReg(objReg);
-}
-
-void
-mjit::Compiler::jsop_initelem_array()
-{
-    FrameEntry *obj = frame.peek(-2);
-    FrameEntry *fe = frame.peek(-1);
-
-    if (cx->typeInferenceEnabled()) {
-        types::StackTypeSet::DoubleConversion conversion =
-            script_->analysis()->poppedTypes(PC, 1)->convertDoubleElements(cx);
-        if (conversion == types::StackTypeSet::AlwaysConvertToDoubles)
-            frame.ensureDouble(fe);
-    }
-
-    uint32_t index = GET_UINT24(PC);
-
-    RegisterID objReg = frame.copyDataIntoReg(obj);
-    masm.loadPtr(Address(objReg, JSObject::offsetOfElements()), objReg);
-
-    /* Update the initialized length. */
-    masm.store32(Imm32(index + 1), Address(objReg, ObjectElements::offsetOfInitializedLength()));
-
-    /* Perform the store. */
-    frame.storeTo(fe, Address(objReg, index * sizeof(Value)));
-    frame.freeReg(objReg);
-
-    frame.pop();
-}
deleted file mode 100644
--- a/js/src/methodjit/FrameEntry.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_valueinfo_h__ && defined JS_METHODJIT
-#define jsjaeger_valueinfo_h__
-
-#include "jsapi.h"
-#include "jsnum.h"
-#include "jstypes.h"
-#include "methodjit/MachineRegs.h"
-#include "methodjit/RematInfo.h"
-#include "assembler/assembler/MacroAssembler.h"
-
-namespace js {
-namespace mjit {
-
-class FrameEntry
-{
-    friend class FrameState;
-    friend class ImmutableSync;
-
-  public:
-
-    /* Accessors for entries which are known constants. */
-
-    bool isConstant() const {
-        if (isCopy())
-            return false;
-        return data.isConstant();
-    }
-
-    const jsval_layout &getConstant() const {
-        JS_ASSERT(isConstant());
-        return v_;
-    }
-
-    Value getValue() const {
-        JS_ASSERT(isConstant());
-        return IMPL_TO_JSVAL(v_);
-    }
-
-#if defined JS_NUNBOX32
-    uint32_t getPayload() const {
-        JS_ASSERT(isConstant());
-        return v_.s.payload.u32;
-    }
-#elif defined JS_PUNBOX64
-    uint64_t getPayload() const {
-        JS_ASSERT(isConstant());
-        return v_.asBits & JSVAL_PAYLOAD_MASK;
-    }
-#endif
-
-    /* For a constant double FrameEntry, truncate to an int32_t. */
-    void convertConstantDoubleOrBooleanToInt32(JSContext *cx) {
-        JS_ASSERT(isConstant());
-        JS_ASSERT(isType(JSVAL_TYPE_DOUBLE) || isType(JSVAL_TYPE_BOOLEAN));
-
-        int32_t value;
-        ToInt32(cx, getValue(), &value);
-
-        Value newValue = Int32Value(value);
-        setConstant(newValue);
-    }
-
-    /*
-     * Accessors for entries whose type is known. Any entry can have a known
-     * type, and constant entries must have one.
-     */
-
-    bool isTypeKnown() const {
-        return backing()->type.isConstant();
-    }
-
-    /*
-     * The known type should not be used in generated code if it is JSVAL_TYPE_DOUBLE.
-     * In such cases either the value is constant, in memory or in a floating point register.
-     */
-    JSValueType getKnownType() const {
-        JS_ASSERT(isTypeKnown());
-        return backing()->knownType;
-    }
-
-#if defined JS_NUNBOX32
-    JSValueTag getKnownTag() const {
-        JS_ASSERT(backing()->v_.s.tag != JSVAL_TAG_CLEAR);
-        return backing()->v_.s.tag;
-    }
-#elif defined JS_PUNBOX64
-    JSValueShiftedTag getKnownTag() const {
-        return JSValueShiftedTag(backing()->v_.asBits & JSVAL_TAG_MASK);
-    }
-#endif
-
-    // Return true iff the type of this value is definitely known to be type_.
-    bool isType(JSValueType type_) const {
-        return isTypeKnown() && getKnownType() == type_;
-    }
-
-    // Return true iff the type of this value is definitely known not to be type_.
-    bool isNotType(JSValueType type_) const {
-        return isTypeKnown() && getKnownType() != type_;
-    }
-
-    // Return true if the type of this value is definitely type_, or is unknown
-    // and thus potentially type_ at runtime.
-    bool mightBeType(JSValueType type_) const {
-        return !isNotType(type_);
-    }
-
-    /* Accessors for entries which are copies of other mutable entries. */
-
-    bool isCopy() const { return !!copy; }
-    bool isCopied() const { return copied != 0; }
-
-    const FrameEntry *backing() const {
-        return isCopy() ? copyOf() : this;
-    }
-
-    bool hasSameBacking(const FrameEntry *other) const {
-        return backing() == other->backing();
-    }
-
-  private:
-    void setType(JSValueType type_) {
-        JS_ASSERT(!isCopy() && type_ != JSVAL_TYPE_UNKNOWN);
-        type.setConstant();
-#if defined JS_NUNBOX32
-        v_.s.tag = JSVAL_TYPE_TO_TAG(type_);
-#elif defined JS_PUNBOX64
-        v_.asBits &= JSVAL_PAYLOAD_MASK;
-        v_.asBits |= JSVAL_TYPE_TO_SHIFTED_TAG(type_);
-#endif
-        knownType = type_;
-    }
-
-    void track(uint32_t index) {
-        copied = 0;
-        copy = NULL;
-        index_ = index;
-        tracked = true;
-    }
-
-    void clear() {
-        JS_ASSERT(copied == 0);
-        if (copy) {
-            JS_ASSERT(copy->copied != 0);
-            copy->copied--;
-            copy = NULL;
-        }
-    }
-
-    uint32_t trackerIndex() {
-        return index_;
-    }
-
-    /*
-     * Marks the FE as unsynced & invalid.
-     */
-    void resetUnsynced() {
-        clear();
-        type.unsync();
-        data.unsync();
-        type.invalidate();
-        data.invalidate();
-    }
-
-    /*
-     * Marks the FE as synced & in memory.
-     */
-    void resetSynced() {
-        clear();
-        type.setMemory();
-        data.setMemory();
-    }
-
-    /*
-     * Marks the FE as having a constant.
-     */
-    void setConstant(const Value &v) {
-        clear();
-        type.unsync();
-        data.unsync();
-        type.setConstant();
-        data.setConstant();
-        v_ = JSVAL_TO_IMPL(v);
-        if (v.isDouble())
-            knownType = JSVAL_TYPE_DOUBLE;
-        else
-            knownType = v.extractNonDoubleType();
-    }
-
-    FrameEntry *copyOf() const {
-        JS_ASSERT(isCopy());
-        JS_ASSERT_IF(!copy->temporary, copy < this);
-        return copy;
-    }
-
-    /*
-     * Set copy index.
-     */
-    void setCopyOf(FrameEntry *fe) {
-        clear();
-        copy = fe;
-        if (fe) {
-            type.invalidate();
-            data.invalidate();
-            fe->copied++;
-        }
-    }
-
-    inline bool isTracked() const {
-        return tracked;
-    }
-
-    inline void untrack() {
-        tracked = false;
-    }
-
-    inline bool dataInRegister(AnyRegisterID reg) const {
-        JS_ASSERT(!copy);
-        return reg.isReg()
-            ? (data.inRegister() && data.reg() == reg.reg())
-            : (data.inFPRegister() && data.fpreg() == reg.fpreg());
-    }
-
-  private:
-    JSValueType knownType;
-    jsval_layout v_;
-    RematInfo  type;
-    RematInfo  data;
-    uint32_t   index_;
-    FrameEntry *copy;
-    bool       tracked;
-    bool       temporary;
-
-    /* Number of copies of this entry. */
-    uint32_t   copied;
-
-    /*
-     * Offset of the last loop in which this entry was written or had a loop
-     * register assigned.
-     */
-    uint32_t   lastLoop;
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_valueinfo_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/FrameState-inl.h
+++ /dev/null
@@ -1,1504 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_framestate_inl_h__ && defined JS_METHODJIT
-#define jsjaeger_framestate_inl_h__
-
-#include "methodjit/LoopState.h"
-
-namespace js {
-namespace mjit {
-
-inline void
-FrameState::addToTracker(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isTracked());
-    fe->track(tracker.nentries);
-    tracker.add(fe);
-}
-
-inline FrameEntry *
-FrameState::peek(int32_t depth)
-{
-    JS_ASSERT(depth < 0);
-    JS_ASSERT(a->sp + depth >= a->spBase);
-    FrameEntry *fe = a->sp + depth;
-    if (!fe->isTracked()) {
-        addToTracker(fe);
-        fe->resetSynced();
-    }
-    return fe;
-}
-
-inline void
-FrameState::popn(uint32_t n)
-{
-    for (uint32_t i = 0; i < n; i++)
-        pop();
-}
-
-inline bool
-FrameState::haveSameBacking(FrameEntry *lhs, FrameEntry *rhs)
-{
-    if (lhs->isCopy())
-        lhs = lhs->copyOf();
-    if (rhs->isCopy())
-        rhs = rhs->copyOf();
-    return lhs == rhs;
-}
-
-inline FrameEntry *
-FrameState::getTemporary(uint32_t which)
-{
-    JS_ASSERT(which < TEMPORARY_LIMIT);
-
-    FrameEntry *fe = temporaries + which;
-    JS_ASSERT(fe < temporariesTop);
-
-    return getOrTrack(uint32_t(fe - entries));
-}
-
-inline AnyRegisterID
-FrameState::allocReg(uint32_t mask)
-{
-    if (freeRegs.hasRegInMask(mask)) {
-        AnyRegisterID reg = freeRegs.takeAnyReg(mask);
-        modifyReg(reg);
-        return reg;
-    }
-
-    AnyRegisterID reg = evictSomeReg(mask);
-    modifyReg(reg);
-    return reg;
-}
-
-inline JSC::MacroAssembler::RegisterID
-FrameState::allocReg()
-{
-    return allocReg(Registers::AvailRegs).reg();
-}
-
-inline JSC::MacroAssembler::FPRegisterID
-FrameState::allocFPReg()
-{
-    return allocReg(Registers::AvailFPRegs).fpreg();
-}
-
-inline AnyRegisterID
-FrameState::allocAndLoadReg(FrameEntry *fe, bool fp, RematInfo::RematType type)
-{
-    AnyRegisterID reg;
-    uint32_t mask = fp ? (uint32_t) Registers::AvailFPRegs : (uint32_t) Registers::AvailRegs;
-
-    /*
-     * Decide whether to retroactively mark a register as holding the entry
-     * at the start of the current loop. We can do this if (a) the register has
-     * not been touched since the start of the loop (it is in loopRegs), (b)
-     * the entry has also not been written to or already had a loop register
-     * assigned, and (c) we are not in an inline call with multiple callees or
-     * exit points --- we won't pick up the new loop register when restoring.
-     */
-    if (loop && freeRegs.hasRegInMask(loop->getLoopRegs() & mask) &&
-        type == RematInfo::DATA && isOuterSlot(fe) && !cc.activeFrameHasMultipleExits() &&
-        fe->lastLoop < loop->headOffset()) {
-        reg = freeRegs.takeAnyReg(loop->getLoopRegs() & mask);
-        regstate(reg).associate(fe, RematInfo::DATA);
-        fe->lastLoop = loop->headOffset();
-        loop->setLoopReg(reg, fe);
-        return reg;
-    }
-
-    if (!freeRegs.empty(mask))
-        reg = freeRegs.takeAnyReg(mask);
-    else
-        reg = evictSomeReg(mask);
-    modifyReg(reg);
-
-    if (fp)
-        masm.loadDouble(addressOf(fe), reg.fpreg());
-    else if (type == RematInfo::TYPE)
-        masm.loadTypeTag(addressOf(fe), reg.reg());
-    else
-        masm.loadPayload(addressOf(fe), reg.reg());
-
-    regstate(reg).associate(fe, type);
-    return reg;
-}
-
-inline void
-FrameState::modifyReg(AnyRegisterID reg)
-{
-    if (loop)
-        loop->clearLoopReg(reg);
-}
-
-inline void
-FrameState::convertInt32ToDouble(Assembler &masm, FrameEntry *fe, FPRegisterID fpreg) const
-{
-    JS_ASSERT(!fe->isConstant());
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (fe->data.inRegister())
-        masm.convertInt32ToDouble(fe->data.reg(), fpreg);
-    else
-        masm.convertInt32ToDouble(masm.payloadOf(addressOf(fe)), fpreg);
-}
-
-inline bool
-FrameState::peekTypeInRegister(FrameEntry *fe) const
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-    return fe->type.inRegister();
-}
-
-inline void
-FrameState::pop()
-{
-    JS_ASSERT(a->sp > a->spBase);
-
-    FrameEntry *fe = --a->sp;
-    if (!fe->isTracked())
-        return;
-
-    forgetAllRegs(fe);
-    fe->type.invalidate();
-    fe->data.invalidate();
-    fe->clear();
-
-    extraArray[fe - entries].reset();
-}
-
-inline void
-FrameState::freeReg(AnyRegisterID reg)
-{
-    JS_ASSERT(!regstate(reg).usedBy());
-
-    freeRegs.putReg(reg);
-}
-
-inline void
-FrameState::forgetReg(AnyRegisterID reg)
-{
-    /*
-     * Important: Do not touch the fe here. We can peephole optimize away
-     * loads and stores by re-using the contents of old FEs.
-     */
-    JS_ASSERT_IF(regstate(reg).fe(), !regstate(reg).fe()->isCopy());
-
-    if (!regstate(reg).isPinned()) {
-        regstate(reg).forget();
-        freeRegs.putReg(reg);
-    }
-}
-
-inline FrameEntry *
-FrameState::rawPush()
-{
-    JS_ASSERT(a->sp < temporaries);
-    FrameEntry *fe = a->sp++;
-
-    if (!fe->isTracked())
-        addToTracker(fe);
-    fe->type.invalidate();
-    fe->data.invalidate();
-    fe->clear();
-
-    extraArray[fe - entries].reset();
-
-    return fe;
-}
-
-inline void
-FrameState::push(const Value &v)
-{
-    FrameEntry *fe = rawPush();
-    fe->setConstant(v);
-}
-
-inline void
-FrameState::pushSynced(JSValueType type)
-{
-    FrameEntry *fe = rawPush();
-
-    fe->resetSynced();
-    if (type != JSVAL_TYPE_UNKNOWN) {
-        fe->setType(type);
-        if (type == JSVAL_TYPE_DOUBLE)
-            masm.ensureInMemoryDouble(addressOf(fe));
-    }
-}
-
-inline void
-FrameState::pushSynced(JSValueType type, RegisterID reg)
-{
-    FrameEntry *fe = rawPush();
-
-    fe->resetUnsynced();
-    fe->type.sync();
-    fe->data.sync();
-    fe->setType(type);
-    fe->data.setRegister(reg);
-    regstate(reg).associate(fe, RematInfo::DATA);
-}
-
-inline void
-FrameState::loadIntoRegisters(Address address, bool reuseBase,
-                              RegisterID *ptypeReg, RegisterID *pdataReg)
-{
-
-#ifdef JS_PUNBOX64
-
-    // It's okay if either of these clobbers address.base, since we guarantee
-    // eviction will not physically clobber. It's also safe, on x64, for
-    // loadValueAsComponents() to take either type or data regs as address.base.
-    RegisterID typeReg = allocReg();
-    RegisterID dataReg = reuseBase ? address.base : allocReg();
-    masm.loadValueAsComponents(address, typeReg, dataReg);
-
-#elif JS_NUNBOX32
-
-    // Prevent us from clobbering this reg.
-    bool free = freeRegs.hasReg(address.base);
-    bool needsPin = !free && regstate(address.base).fe();
-    if (free)
-        freeRegs.takeReg(address.base);
-    if (needsPin)
-        pinReg(address.base);
-
-    RegisterID typeReg = allocReg();
-
-    masm.loadTypeTag(address, typeReg);
-
-    // Allow re-use of the base register. This could avoid a spill, and
-    // is safe because the following allocReg() won't actually emit any
-    // writes to the register.
-    if (free)
-        freeRegs.putReg(address.base);
-    if (needsPin)
-        unpinReg(address.base);
-
-    RegisterID dataReg = reuseBase ? address.base : allocReg();
-    masm.loadPayload(address, dataReg);
-
-#endif
-
-    *ptypeReg = typeReg;
-    *pdataReg = dataReg;
-}
-
-inline void
-FrameState::push(Address address, JSValueType knownType, bool reuseBase)
-{
-    if (knownType == JSVAL_TYPE_DOUBLE) {
-        FPRegisterID fpreg = allocFPReg();
-        masm.moveInt32OrDouble(address, fpreg);
-        pushDouble(fpreg);
-        if (reuseBase)
-            freeReg(address.base);
-        return;
-    }
-
-    if (knownType != JSVAL_TYPE_UNKNOWN) {
-        RegisterID dataReg = reuseBase ? address.base : allocReg();
-        masm.loadPayload(address, dataReg);
-        pushTypedPayload(knownType, dataReg);
-        return;
-    }
-
-    RegisterID typeReg, dataReg;
-    loadIntoRegisters(address, reuseBase, &typeReg, &dataReg);
-
-    pushRegs(typeReg, dataReg, JSVAL_TYPE_UNKNOWN);
-}
-
-inline void
-FrameState::pushWord(Address address, JSValueType knownType, bool reuseBase)
-{
-    JS_ASSERT(knownType != JSVAL_TYPE_DOUBLE);
-    JS_ASSERT(knownType != JSVAL_TYPE_UNKNOWN);
-
-    RegisterID dataReg = reuseBase ? address.base : allocReg();
-    masm.loadPtr(address, dataReg);
-    pushTypedPayload(knownType, dataReg);
-}
-
-inline JSC::MacroAssembler::FPRegisterID
-FrameState::storeRegs(int32_t depth, RegisterID type, RegisterID data, JSValueType knownType)
-{
-    FrameEntry *fe = peek(depth);
-    forgetEntry(fe);
-    fe->resetUnsynced();
-
-    /*
-     * Even if the type or data gets freed due to knownType or a double result,
-     * neither register should be clobbered (see Compiler::testBarrier).
-     */
-    JS_ASSERT(!freeRegs.hasReg(type) && !freeRegs.hasReg(data));
-
-    if (knownType == JSVAL_TYPE_UNKNOWN) {
-        fe->type.setRegister(type);
-        fe->data.setRegister(data);
-        regstate(type).associate(fe, RematInfo::TYPE);
-        regstate(data).associate(fe, RematInfo::DATA);
-        return Registers::FPConversionTemp;
-    }
-
-    if (knownType == JSVAL_TYPE_DOUBLE) {
-        FPRegisterID fpreg = allocFPReg();
-        masm.moveInt32OrDouble(data, type, addressOf(fe), fpreg);
-        fe->setType(JSVAL_TYPE_DOUBLE);
-        fe->data.setFPRegister(fpreg);
-        regstate(fpreg).associate(fe, RematInfo::DATA);
-        freeReg(type);
-        freeReg(data);
-        return fpreg;
-    }
-
-    freeReg(type);
-    fe->setType(knownType);
-    fe->data.setRegister(data);
-    regstate(data).associate(fe, RematInfo::DATA);
-    return Registers::FPConversionTemp;
-}
-
-inline JSC::MacroAssembler::FPRegisterID
-FrameState::pushRegs(RegisterID type, RegisterID data, JSValueType knownType)
-{
-    pushSynced(JSVAL_TYPE_UNKNOWN);
-    return storeRegs(-1, type, data, knownType);
-}
-
-inline void
-FrameState::reloadEntry(Assembler &masm, Address address, FrameEntry *fe)
-{
-    if (fe->data.inRegister()) {
-        if (fe->type.inRegister()) {
-            masm.loadValueAsComponents(address, fe->type.reg(), fe->data.reg());
-        } else {
-            JS_ASSERT(fe->isTypeKnown());
-            masm.loadPayload(address, fe->data.reg());
-        }
-    } else {
-        JS_ASSERT(fe->data.inFPRegister());
-        masm.moveInt32OrDouble(address, fe->data.fpreg());
-    }
-}
-
-inline void
-FrameState::pushTypedPayload(JSValueType type, RegisterID payload)
-{
-    JS_ASSERT(type != JSVAL_TYPE_DOUBLE);
-    JS_ASSERT(!freeRegs.hasReg(payload));
-
-    FrameEntry *fe = rawPush();
-
-    fe->resetUnsynced();
-    fe->setType(type);
-    fe->data.setRegister(payload);
-    regstate(payload).associate(fe, RematInfo::DATA);
-}
-
-inline void
-FrameState::pushNumber(RegisterID payload, bool asInt32)
-{
-    JS_ASSERT(!freeRegs.hasReg(payload));
-
-    FrameEntry *fe = rawPush();
-
-    if (asInt32) {
-        if (!fe->type.synced())
-            masm.storeTypeTag(ImmType(JSVAL_TYPE_INT32), addressOf(fe));
-        fe->type.setMemory();
-    } else {
-        fe->type.setMemory();
-    }
-
-    fe->data.unsync();
-    fe->data.setRegister(payload);
-    regstate(payload).associate(fe, RematInfo::DATA);
-}
-
-inline void
-FrameState::pushInt32(RegisterID payload)
-{
-    FrameEntry *fe = rawPush();
-
-    masm.storeTypeTag(ImmType(JSVAL_TYPE_INT32), addressOf(fe));
-    fe->type.setMemory();
-
-    fe->data.unsync();
-    fe->data.setRegister(payload);
-    regstate(payload).associate(fe, RematInfo::DATA);
-}
-
-inline void
-FrameState::pushUntypedPayload(JSValueType type, RegisterID payload)
-{
-    JS_ASSERT(!freeRegs.hasReg(payload));
-
-    FrameEntry *fe = rawPush();
-
-    masm.storeTypeTag(ImmType(type), addressOf(fe));
-
-    /* The forceful type sync will assert otherwise. */
-#ifdef DEBUG
-    fe->type.unsync();
-#endif
-    fe->type.setMemory();
-    fe->data.unsync();
-    fe->data.setRegister(payload);
-    regstate(payload).associate(fe, RematInfo::DATA);
-}
-
-inline void
-FrameState::pushUntypedValue(const Value &v)
-{
-    FrameEntry *fe = rawPush();
-
-    masm.storeValue(v, addressOf(fe));
-
-    /* The forceful type sync will assert otherwise. */
-#ifdef DEBUG
-    fe->type.unsync();
-#endif
-    fe->type.setMemory();
-    fe->data.unsync();
-    fe->data.setMemory();
-}
-
-inline JSC::MacroAssembler::RegisterID
-FrameState::tempRegForType(FrameEntry *fe, RegisterID fallback)
-{
-    JS_ASSERT(!regstate(fallback).fe());
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->type.isConstant());
-
-    if (fe->type.inRegister())
-        return fe->type.reg();
-
-    /* :XXX: X86 */
-
-    masm.loadTypeTag(addressOf(fe), fallback);
-    return fallback;
-}
-
-
-inline JSC::MacroAssembler::RegisterID
-FrameState::tempRegForType(FrameEntry *fe)
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->type.isConstant());
-
-    if (fe->type.inRegister())
-        return fe->type.reg();
-
-    /* :XXX: X86 */
-
-    RegisterID reg = allocAndLoadReg(fe, false, RematInfo::TYPE).reg();
-    fe->type.setRegister(reg);
-    return reg;
-}
-
-inline void
-FrameState::loadTypeIntoReg(const FrameEntry *fe, RegisterID reg)
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->type.isConstant());
-
-    if (fe->type.inRegister()) {
-        if (fe->type.reg() == reg)
-            return;
-        masm.move(fe->type.reg(), reg);
-        return;
-    }
-
-    masm.loadTypeTag(addressOf(fe), reg);
-}
-
-inline void
-FrameState::loadDataIntoReg(const FrameEntry *fe, RegisterID reg)
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->data.isConstant());
-
-    if (fe->data.inRegister()) {
-        if (fe->data.reg() == reg)
-            return;
-        masm.move(fe->data.reg(), reg);
-        return;
-    }
-
-    masm.loadPayload(addressOf(fe), reg);
-}
-
-inline JSC::MacroAssembler::RegisterID
-FrameState::tempRegForData(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (fe->data.inRegister())
-        return fe->data.reg();
-
-    RegisterID reg = allocAndLoadReg(fe, false, RematInfo::DATA).reg();
-    fe->data.setRegister(reg);
-    return reg;
-}
-
-inline void
-FrameState::forgetMismatchedObject(FrameEntry *fe)
-{
-    if (fe->isNotType(JSVAL_TYPE_OBJECT)) {
-        if (fe->isCopied()) {
-            syncFe(fe);
-            uncopy(fe);
-            fe->resetSynced();
-        } else {
-            syncAndForgetFe(fe);
-        }
-        fe->clear();
-    }
-
-    if (fe->isConstant()) {
-        RegisterID reg = allocReg();
-        regstate(reg).associate(fe, RematInfo::DATA);
-
-        masm.move(JSC::MacroAssembler::ImmPtr(&fe->getValue().toObject()), reg);
-        fe->data.setRegister(reg);
-    }
-}
-
-inline JSC::MacroAssembler::FPRegisterID
-FrameState::tempFPRegForData(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT(fe->isType(JSVAL_TYPE_DOUBLE));
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->data.inRegister());
-
-    if (fe->data.inFPRegister())
-        return fe->data.fpreg();
-
-    FPRegisterID reg = allocAndLoadReg(fe, true, RematInfo::DATA).fpreg();
-    fe->data.setFPRegister(reg);
-    return reg;
-}
-
-inline AnyRegisterID
-FrameState::tempRegInMaskForData(FrameEntry *fe, uint32_t mask)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT_IF(fe->isType(JSVAL_TYPE_DOUBLE), !(mask & ~Registers::AvailFPRegs));
-    JS_ASSERT_IF(!fe->isType(JSVAL_TYPE_DOUBLE), !(mask & ~Registers::AvailRegs));
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    AnyRegisterID reg;
-    if (fe->data.inRegister() || fe->data.inFPRegister()) {
-        AnyRegisterID old;
-        if (fe->data.inRegister())
-            old = fe->data.reg();
-        else
-            old = fe->data.fpreg();
-        if (Registers::maskReg(old) & mask)
-            return old;
-
-        /* Keep the old register pinned. */
-        regstate(old).forget();
-        reg = allocReg(mask);
-        if (reg.isReg())
-            masm.move(old.reg(), reg.reg());
-        else
-            masm.moveDouble(old.fpreg(), reg.fpreg());
-        freeReg(old);
-    } else {
-        reg = allocReg(mask);
-        if (reg.isReg())
-            masm.loadPayload(addressOf(fe), reg.reg());
-        else
-            masm.loadDouble(addressOf(fe), reg.fpreg());
-    }
-    regstate(reg).associate(fe, RematInfo::DATA);
-    if (reg.isReg())
-        fe->data.setRegister(reg.reg());
-    else
-        fe->data.setFPRegister(reg.fpreg());
-    return reg;
-}
-
-inline JSC::MacroAssembler::RegisterID
-FrameState::tempRegForData(FrameEntry *fe, RegisterID reg, Assembler &masm) const
-{
-    JS_ASSERT(!fe->data.isConstant());
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->data.inFPRegister());
-
-    if (fe->data.inRegister()) {
-        JS_ASSERT(fe->data.reg() != reg);
-        return fe->data.reg();
-    } else {
-        masm.loadPayload(addressOf(fe), reg);
-        return reg;
-    }
-}
-
-inline bool
-FrameState::shouldAvoidTypeRemat(FrameEntry *fe)
-{
-    return !fe->isCopy() && fe->type.inMemory();
-}
-
-inline bool
-FrameState::shouldAvoidDataRemat(FrameEntry *fe)
-{
-    return !fe->isCopy() && fe->data.inMemory();
-}
-
-inline void
-FrameState::ensureFeSynced(const FrameEntry *fe, Assembler &masm) const
-{
-    Address to = addressOf(fe);
-    const FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-    if (backing->isType(JSVAL_TYPE_DOUBLE)) {
-        if (fe->data.synced()) {
-            /* Entries representing known doubles can't be partially synced. */
-            JS_ASSERT(fe->type.synced());
-            return;
-        }
-        if (backing->isConstant()) {
-            masm.storeValue(backing->getValue(), to);
-        } else if (backing->data.inFPRegister()) {
-            masm.storeDouble(backing->data.fpreg(), to);
-        } else {
-            /* Use a temporary so the entry can be synced without allocating a register. */
-            JS_ASSERT(backing->data.inMemory() && backing != fe);
-            masm.loadDouble(addressOf(backing), Registers::FPConversionTemp);
-            masm.storeDouble(Registers::FPConversionTemp, to);
-        }
-        return;
-    }
-
-#if defined JS_PUNBOX64
-    /* If we can, sync the type and data in one go. */
-    if (!fe->data.synced() && !fe->type.synced()) {
-        if (backing->isConstant())
-            masm.storeValue(backing->getValue(), to);
-        else if (backing->isTypeKnown())
-            masm.storeValueFromComponents(ImmType(backing->getKnownType()), backing->data.reg(), to);
-        else
-            masm.storeValueFromComponents(backing->type.reg(), backing->data.reg(), to);
-        return;
-    }
-#endif
-
-    /*
-     * On x86_64, only one of the following two calls will have output,
-     * and a load will only occur if necessary.
-     */
-    ensureDataSynced(fe, masm);
-    ensureTypeSynced(fe, masm);
-}
-
-inline void
-FrameState::ensureTypeSynced(const FrameEntry *fe, Assembler &masm) const
-{
-    if (fe->type.synced())
-        return;
-
-    Address to = addressOf(fe);
-    const FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-#if defined JS_PUNBOX64
-    /* Attempt to store the entire Value, to prevent a load. */
-    if (backing->isConstant()) {
-        masm.storeValue(backing->getValue(), to);
-        return;
-    }
-
-    if (backing->data.inRegister()) {
-        RegisterID dreg = backing->data.reg();
-        if (backing->isTypeKnown())
-            masm.storeValueFromComponents(ImmType(backing->getKnownType()), dreg, to);
-        else
-            masm.storeValueFromComponents(backing->type.reg(), dreg, to);
-        return;
-    }
-#endif
-
-    /* Store a double's type bits, even though !isTypeKnown(). */
-    if (backing->isConstant())
-        masm.storeTypeTag(ImmTag(backing->getKnownTag()), to);
-    else if (backing->isTypeKnown())
-        masm.storeTypeTag(ImmType(backing->getKnownType()), to);
-    else
-        masm.storeTypeTag(backing->type.reg(), to);
-}
-
-inline void
-FrameState::ensureDataSynced(const FrameEntry *fe, Assembler &masm) const
-{
-    if (fe->data.synced())
-        return;
-
-    Address to = addressOf(fe);
-    const FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-#if defined JS_PUNBOX64
-    if (backing->isConstant())
-        masm.storeValue(backing->getValue(), to);
-    else if (backing->isTypeKnown())
-        masm.storeValueFromComponents(ImmType(backing->getKnownType()), backing->data.reg(), to);
-    else if (backing->type.inRegister())
-        masm.storeValueFromComponents(backing->type.reg(), backing->data.reg(), to);
-    else
-        masm.storePayload(backing->data.reg(), to);
-#elif defined JS_NUNBOX32
-    if (backing->isConstant())
-        masm.storePayload(ImmPayload(backing->getPayload()), to);
-    else
-        masm.storePayload(backing->data.reg(), to);
-#endif
-}
-
-inline void
-FrameState::syncFe(FrameEntry *fe)
-{
-    if (fe->type.synced() && fe->data.synced())
-        return;
-
-    FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-    if (backing->isType(JSVAL_TYPE_DOUBLE)) {
-        if (!backing->isConstant())
-            tempFPRegForData(backing);
-        ensureFeSynced(fe, masm);
-
-        if (!fe->type.synced())
-            fe->type.sync();
-        if (!fe->data.synced())
-            fe->data.sync();
-        return;
-    }
-
-    bool needTypeReg = !fe->type.synced() && backing->type.inMemory();
-    bool needDataReg = !fe->data.synced() && backing->data.inMemory();
-
-#if defined JS_NUNBOX32
-    /* Determine an ordering that won't spill known regs. */
-    if (needTypeReg && !needDataReg) {
-        syncData(fe);
-        syncType(fe);
-    } else {
-        syncType(fe);
-        syncData(fe);
-    }
-#elif defined JS_PUNBOX64
-    if (JS_UNLIKELY(needTypeReg && needDataReg)) {
-        /* Memory-to-memory moves can only occur for copies backed by memory. */
-        JS_ASSERT(backing != fe);
-
-        /* Use ValueReg to do a whole-Value mem-to-mem move. */
-        masm.loadValue(addressOf(backing), Registers::ValueReg);
-        masm.storeValue(Registers::ValueReg, addressOf(fe));
-    } else {
-        /* Store in case unpinning is necessary. */
-        MaybeRegisterID pairReg;
-
-        /* Get a register if necessary, without clobbering its pair. */
-        if (needTypeReg) {
-            if (backing->data.inRegister() && !regstate(backing->data.reg()).isPinned()) {
-                pairReg = backing->data.reg();
-                pinReg(backing->data.reg());
-            }
-            tempRegForType(backing);
-        } else if (needDataReg) {
-            if (backing->type.inRegister() && !regstate(backing->type.reg()).isPinned()) {
-                pairReg = backing->type.reg();
-                pinReg(backing->type.reg());
-            }
-            tempRegForData(backing);
-        }
-
-        ensureFeSynced(fe, masm);
-
-        if (pairReg.isSet())
-            unpinReg(pairReg.reg());
-    }
-
-    if (!fe->type.synced())
-        fe->type.sync();
-    if (!fe->data.synced())
-        fe->data.sync();
-#endif
-}
-
-inline void
-FrameState::syncAndForgetFe(FrameEntry *fe, bool markSynced)
-{
-    if (markSynced) {
-        if (!fe->type.synced())
-            fe->type.sync();
-        if (!fe->data.synced())
-            fe->data.sync();
-    }
-
-    syncFe(fe);
-    forgetAllRegs(fe);
-    fe->type.setMemory();
-    fe->data.setMemory();
-}
-
-inline void
-FrameState::forgetLoopReg(FrameEntry *fe)
-{
-    /*
-     * Don't use a loop register for fe in the active loop, as its underlying
-     * representation may have changed since the start of the loop.
-     */
-    if (loop)
-        fe->lastLoop = loop->headOffset();
-}
-
-inline void
-FrameState::syncType(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-    if (!fe->type.synced() && backing->type.inMemory())
-        tempRegForType(backing);
-
-    ensureTypeSynced(fe, masm);
-
-    if (!fe->type.synced())
-        fe->type.sync();
-}
-
-inline void
-FrameState::syncData(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    FrameEntry *backing = fe;
-    if (fe->isCopy())
-        backing = fe->copyOf();
-
-    if (!fe->data.synced() && backing->data.inMemory())
-        tempRegForData(backing);
-
-    ensureDataSynced(fe, masm);
-
-    if (!fe->data.synced())
-        fe->data.sync();
-}
-
-inline void
-FrameState::fakeSync(FrameEntry *fe)
-{
-    /*
-     * If a frame entry's value will no longer be used, we can mark it as being
-     * synced without actually performing the sync: the value is not observed.
-     */
-    if (!fe->data.synced())
-        fe->data.sync();
-}
-
-inline void
-FrameState::forgetType(FrameEntry *fe)
-{
-    /*
-     * The type may have been forgotten with an intervening storeLocal in the
-     * presence of eval or closed variables. For defense in depth and to make
-     * callers' lives simpler, bail out if the type is not known.
-     */
-    if (!fe->isTypeKnown())
-        return;
-
-    /*
-     * Likewise, storeLocal() may have set this FE, with a known type,
-     * to be a copy of another FE, which has an unknown type.
-     */
-    if (fe->isCopy()) {
-        syncFe(fe);
-        fe->clear();
-        fe->resetSynced();
-        return;
-    }
-
-    ensureTypeSynced(fe, masm);
-    fe->type.setMemory();
-}
-
-inline void
-FrameState::learnType(FrameEntry *fe, JSValueType type, bool unsync)
-{
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-    JS_ASSERT(type != JSVAL_TYPE_UNKNOWN);
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (type == JSVAL_TYPE_DOUBLE)
-        JS_ASSERT(!fe->data.inRegister());
-    else
-        JS_ASSERT(!fe->data.inFPRegister());
-
-    if (fe->type.inRegister())
-        forgetReg(fe->type.reg());
-    fe->setType(type);
-    if (unsync)
-        fe->type.unsync();
-}
-
-inline void
-FrameState::learnType(FrameEntry *fe, JSValueType type, RegisterID data)
-{
-    JS_ASSERT(!fe->isCopied());
-    JS_ASSERT(type != JSVAL_TYPE_UNKNOWN && type != JSVAL_TYPE_DOUBLE);
-
-    forgetAllRegs(fe);
-    fe->clear();
-
-    fe->type.setConstant();
-    fe->knownType = type;
-
-    fe->data.setRegister(data);
-    regstate(data).associate(fe, RematInfo::DATA);
-
-    fe->data.unsync();
-    fe->type.unsync();
-}
-
-inline int32_t
-FrameState::frameOffset(const FrameEntry *fe, ActiveFrame *a) const
-{
-    /*
-     * The stored frame offsets for analysis temporaries are immediately above
-     * the script's normal slots (and will thus be clobbered should a C++ or
-     * scripted call push another frame). There must be enough room in the
-     * reserved stack space.
-     */
-    JS_STATIC_ASSERT(StackSpace::STACK_JIT_EXTRA >= TEMPORARY_LIMIT);
-
-    /* Note: fe == a->sp is allowed for addressOfTop */
-    JS_ASSERT(fe >= a->callee_ && fe <= a->sp);
-
-    if (fe >= a->locals)
-        return StackFrame::offsetOfFixed(uint32_t(fe - a->locals));
-    if (fe >= a->args)
-        return StackFrame::offsetOfFormalArg(a->script->function(), uint32_t(fe - a->args));
-    if (fe == a->this_)
-        return StackFrame::offsetOfThis(a->script->function());
-    if (fe == a->callee_)
-        return StackFrame::offsetOfCallee(a->script->function());
-    JS_NOT_REACHED("Bad fe");
-    return 0;
-}
-
-inline JSC::MacroAssembler::Address
-FrameState::addressOf(const FrameEntry *fe) const
-{
-    if (isTemporary(fe)) {
-        /*
-         * Temporary addresses are common to the outermost loop, and are shared
-         * by all active frames.
-         */
-        return Address(JSFrameReg, (loop->temporariesStart + fe - temporaries) * sizeof(Value));
-    }
-
-    ActiveFrame *na = a;
-    while (fe < na->callee_)
-        na = na->parent;
-
-    int32_t offset = frameOffset(fe, na);
-    return Address(JSFrameReg, offset + (na->depth * sizeof(Value)));
-}
-
-inline uint32_t
-FrameState::frameSlot(ActiveFrame *a, const FrameEntry *fe) const
-{
-    if (isTemporary(fe))
-        return fe - entries;
-
-    JS_ASSERT(fe >= a->callee_ && fe < a->sp);
-
-    if (fe >= a->locals)
-        return analyze::LocalSlot(a->script, fe - a->locals);
-    if (fe >= a->args)
-        return analyze::ArgSlot(fe - a->args);
-    if (fe == a->this_)
-        return analyze::ThisSlot();
-    if (fe == a->callee_)
-        return analyze::CalleeSlot();
-    JS_NOT_REACHED("Bad fe");
-    return 0;
-}
-
-inline JSC::MacroAssembler::Address
-FrameState::addressForInlineReturn()
-{
-    if (a->callee_->isTracked())
-        discardFe(a->callee_);
-    return addressOf(a->callee_);
-}
-
-inline JSC::MacroAssembler::Address
-FrameState::addressForDataRemat(const FrameEntry *fe) const
-{
-    if (fe->isCopy() && !fe->data.synced())
-        fe = fe->copyOf();
-    JS_ASSERT(fe->data.synced());
-    return addressOf(fe);
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testNull(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testNull(cond, addressOf(fe));
-    return masm.testNull(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testUndefined(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testUndefined(cond, addressOf(fe));
-    return masm.testUndefined(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testInt32(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testInt32(cond, addressOf(fe));
-    return masm.testInt32(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testPrimitive(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testPrimitive(cond, addressOf(fe));
-    return masm.testPrimitive(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testObject(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testObject(cond, addressOf(fe));
-    return masm.testObject(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testGCThing(FrameEntry *fe)
-{
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testGCThing(addressOf(fe));
-    return masm.testGCThing(tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testDouble(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testDouble(cond, addressOf(fe));
-    return masm.testDouble(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testBoolean(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testBoolean(cond, addressOf(fe));
-    return masm.testBoolean(cond, tempRegForType(fe));
-}
-
-inline JSC::MacroAssembler::Jump
-FrameState::testString(Assembler::Condition cond, FrameEntry *fe)
-{
-    JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    if (shouldAvoidTypeRemat(fe))
-        return masm.testString(cond, addressOf(fe));
-    return masm.testString(cond, tempRegForType(fe));
-}
-
-inline FrameEntry *
-FrameState::getOrTrack(uint32_t index)
-{
-    FrameEntry *fe = &entries[index];
-    if (!fe->isTracked()) {
-        addToTracker(fe);
-        fe->resetSynced();
-    }
-    return fe;
-}
-
-inline FrameEntry *
-FrameState::getStack(uint32_t slot)
-{
-    if (slot >= uint32_t(a->sp - a->spBase))
-        return NULL;
-    return getOrTrack(uint32_t(a->spBase + slot - entries));
-}
-
-inline FrameEntry *
-FrameState::getLocal(uint32_t slot)
-{
-    JS_ASSERT(slot < a->script->nslots);
-    return getOrTrack(uint32_t(a->locals + slot - entries));
-}
-
-inline FrameEntry *
-FrameState::getArg(uint32_t slot)
-{
-    JS_ASSERT(slot < a->script->function()->nargs);
-    return getOrTrack(uint32_t(a->args + slot - entries));
-}
-
-inline FrameEntry *
-FrameState::getThis()
-{
-    return getOrTrack(uint32_t(a->this_ - entries));
-}
-
-inline FrameEntry *
-FrameState::getSlotEntry(uint32_t slot)
-{
-    JS_ASSERT(slot < analyze::TotalSlots(a->script));
-    return getOrTrack(uint32_t(a->callee_ + slot - entries));
-}
-
-inline FrameEntry *
-FrameState::getCallee()
-{
-    // Callee can only be used in function code, and it's always an object.
-    JS_ASSERT(a->script->function());
-    FrameEntry *fe = a->callee_;
-    if (!fe->isTracked()) {
-        addToTracker(fe);
-        fe->resetSynced();
-        fe->setType(JSVAL_TYPE_OBJECT);
-    }
-    return fe;
-}
-
-inline void
-FrameState::unpinKilledReg(AnyRegisterID reg)
-{
-    regstate(reg).unpinUnsafe();
-    freeRegs.putReg(reg);
-}
-
-inline void
-FrameState::forgetAllRegs(FrameEntry *fe)
-{
-    if (fe->isCopy())
-        return;
-    if (fe->type.inRegister())
-        forgetReg(fe->type.reg());
-    if (fe->data.inRegister())
-        forgetReg(fe->data.reg());
-    if (fe->data.inFPRegister())
-        forgetReg(fe->data.fpreg());
-}
-
-inline void
-FrameState::swapInTracker(FrameEntry *lhs, FrameEntry *rhs)
-{
-    uint32_t li = lhs->trackerIndex();
-    uint32_t ri = rhs->trackerIndex();
-    JS_ASSERT(tracker[li] == lhs);
-    JS_ASSERT(tracker[ri] == rhs);
-    tracker.entries[ri] = lhs;
-    tracker.entries[li] = rhs;
-    lhs->index_ = ri;
-    rhs->index_ = li;
-}
-
-inline void
-FrameState::dup()
-{
-    dupAt(-1);
-}
-
-inline void
-FrameState::dup2()
-{
-    FrameEntry *lhs = peek(-2);
-    FrameEntry *rhs = peek(-1);
-    pushCopyOf(lhs);
-    pushCopyOf(rhs);
-}
-
-inline void
-FrameState::dupAt(int32_t n)
-{
-    JS_ASSERT(n < 0);
-    FrameEntry *fe = peek(n);
-    pushCopyOf(fe);
-}
-
-inline void
-FrameState::syncAt(int32_t n)
-{
-    JS_ASSERT(n < 0);
-    FrameEntry *fe = peek(n);
-    syncFe(fe);
-}
-
-inline void
-FrameState::pushLocal(uint32_t n)
-{
-    FrameEntry *fe = getLocal(n);
-    if (!a->analysis->slotEscapes(analyze::LocalSlot(a->script, n))) {
-        pushCopyOf(fe);
-    } else {
-#ifdef DEBUG
-        /*
-         * We really want to assert on local variables, but in the presence of
-         * SETLOCAL equivocation of stack slots, and let expressions, just
-         * weakly assert on the fixed local vars.
-         */
-        if (fe->isTracked() && n < a->script->nfixed)
-            JS_ASSERT(fe->data.inMemory());
-#endif
-        if (n >= a->script->nfixed)
-            syncFe(fe);
-        JSValueType type = fe->isTypeKnown() ? fe->getKnownType() : JSVAL_TYPE_UNKNOWN;
-        push(addressOf(fe), type);
-    }
-}
-
-inline void
-FrameState::pushArg(uint32_t n)
-{
-    FrameEntry *fe = getArg(n);
-    if (!a->analysis->slotEscapes(analyze::ArgSlot(n))) {
-        pushCopyOf(fe);
-    } else {
-#ifdef DEBUG
-        if (fe->isTracked())
-            JS_ASSERT(fe->data.inMemory());
-#endif
-        JSValueType type = fe->isTypeKnown() ? fe->getKnownType() : JSVAL_TYPE_UNKNOWN;
-        push(addressOf(fe), type);
-    }
-}
-
-inline void
-FrameState::pushCallee()
-{
-    FrameEntry *fe = getCallee();
-    pushCopyOf(fe);
-}
-
-inline void
-FrameState::pushThis()
-{
-    FrameEntry *fe = getThis();
-    pushCopyOf(fe);
-}
-
-void
-FrameState::learnThisIsObject(bool unsync)
-{
-    // If the 'this' object is a copy, this must be an inline frame, in which
-    // case we will trigger recompilation if the 'this' entry isn't actually
-    // an object (thus, it is OK to modify the backing directly).
-    FrameEntry *fe = getThis();
-    if (fe->isCopy())
-        fe = fe->copyOf();
-    learnType(fe, JSVAL_TYPE_OBJECT, unsync);
-}
-
-void
-FrameState::setThis(RegisterID reg)
-{
-    FrameEntry *fe = getThis();
-    JS_ASSERT(!fe->isCopy());
-    learnType(fe, JSVAL_TYPE_OBJECT, reg);
-}
-
-void
-FrameState::syncThis()
-{
-    FrameEntry *fe = getThis();
-    syncFe(fe);
-}
-
-inline bool
-FrameState::isConstructorThis(const FrameEntry *fe) const
-{
-    return isThis(fe) && cc.constructing();
-}
-
-inline void
-FrameState::leaveBlock(uint32_t n)
-{
-    popn(n);
-}
-
-inline void
-FrameState::enterBlock(uint32_t n)
-{
-    /* expect that tracker has 0 entries, for now. */
-    JS_ASSERT(!tracker.nentries);
-    JS_ASSERT(uint32_t(a->sp + n - a->locals) <= a->script->nslots);
-
-    a->sp += n;
-}
-
-inline void
-FrameState::eviscerate(FrameEntry *fe)
-{
-    forgetAllRegs(fe);
-    fe->resetUnsynced();
-}
-
-inline StateRemat
-FrameState::dataRematInfo(const FrameEntry *fe) const
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (fe->data.inRegister())
-        return StateRemat::FromRegister(fe->data.reg());
-
-    JS_ASSERT(fe->data.synced());
-    return StateRemat::FromAddress(addressOf(fe));
-}
-
-inline void
-FrameState::giveOwnRegs(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT(fe == peek(-1));
-
-    if (!fe->isCopy())
-        return;
-
-    RegisterID data = copyDataIntoReg(fe);
-    if (fe->isTypeKnown()) {
-        JSValueType type = fe->getKnownType();
-        pop();
-        pushTypedPayload(type, data);
-    } else {
-        RegisterID type = copyTypeIntoReg(fe);
-        pop();
-        pushRegs(type, data, JSVAL_TYPE_UNKNOWN);
-    }
-}
-
-inline void
-FrameState::loadDouble(RegisterID t, RegisterID d, FrameEntry *fe, FPRegisterID fpreg,
-                       Assembler &masm) const
-{
-#ifdef JS_CPU_X86
-    masm.fastLoadDouble(d, t, fpreg);
-#else
-    loadDouble(fe, fpreg, masm);
-#endif
-}
-
-inline bool
-FrameState::tryFastDoubleLoad(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) const
-{
-#ifdef JS_CPU_X86
-    if (!fe->isCopy() && fe->type.inRegister() && fe->data.inRegister()) {
-        masm.fastLoadDouble(fe->data.reg(), fe->type.reg(), fpReg);
-        return true;
-    }
-#endif
-    return false;
-}
-
-inline void
-FrameState::loadDouble(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) const
-{
-    if (fe->isCopy()) {
-        FrameEntry *backing = fe->copyOf();
-        if (tryFastDoubleLoad(fe, fpReg, masm))
-            return;
-        fe = backing;
-    }
-
-    if (tryFastDoubleLoad(fe, fpReg, masm))
-        return;
-
-    ensureFeSynced(fe, masm);
-    masm.loadDouble(addressOf(fe), fpReg);
-}
-
-class PinRegAcrossSyncAndKill
-{
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    FrameState &frame;
-    MaybeRegisterID maybeReg;
-  public:
-    PinRegAcrossSyncAndKill(FrameState &frame, RegisterID reg)
-      : frame(frame), maybeReg(reg)
-    {
-        frame.pinReg(reg);
-    }
-    PinRegAcrossSyncAndKill(FrameState &frame, MaybeRegisterID maybeReg)
-      : frame(frame), maybeReg(maybeReg)
-    {
-        if (maybeReg.isSet())
-            frame.pinReg(maybeReg.reg());
-    }
-    ~PinRegAcrossSyncAndKill() {
-        if (maybeReg.isSet())
-            frame.unpinKilledReg(maybeReg.reg());
-    }
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* include */
-
deleted file mode 100644
--- a/js/src/methodjit/FrameState.cpp
+++ /dev/null
@@ -1,2861 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/PodOperations.h"
-
-#include "jscntxt.h"
-#include "FrameState.h"
-#include "FrameState-inl.h"
-#include "StubCompiler.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::analyze;
-
-using mozilla::PodArrayZero;
-using mozilla::PodCopy;
-
-/* Because of Value alignment */
-JS_STATIC_ASSERT(sizeof(FrameEntry) % 8 == 0);
-
-FrameState::FrameState(JSContext *cx, mjit::Compiler &cc,
-                       Assembler &masm, StubCompiler &stubcc)
-  : cx(cx),
-    masm(masm), cc(cc), stubcc(stubcc),
-    a(NULL), entries(NULL), nentries(0), freeRegs(Registers::AvailAnyRegs),
-    loop(NULL), inTryBlock(false)
-{
-}
-
-FrameState::~FrameState()
-{
-    while (a) {
-        ActiveFrame *parent = a->parent;
-        if (a->script->hasAnalysis())
-            a->script->analysis()->clearAllocations();
-        js_free(a);
-        a = parent;
-    }
-    js_free(entries);
-}
-
-void
-FrameState::pruneDeadEntries()
-{
-    unsigned shift = 0;
-    for (unsigned i = 0; i < tracker.nentries; i++) {
-        FrameEntry *fe = tracker[i];
-        if (deadEntry(fe)) {
-            fe->untrack();
-            shift++;
-        } else if (shift) {
-            fe->index_ -= shift;
-            tracker.entries[fe->index_] = fe;
-        }
-    }
-    tracker.nentries -= shift;
-}
-
-bool
-FrameState::pushActiveFrame(JSScript *script, uint32_t argc)
-{
-    if (!a) {
-        this->nentries = analyze::TotalSlots(script) + (script->nslots - script->nfixed) +
-            StackSpace::STACK_JIT_EXTRA - VALUES_PER_STACK_FRAME;
-        size_t totalBytes = sizeof(FrameEntry) * nentries +       // entries[]
-                            sizeof(FrameEntry *) * nentries +     // tracker.entries
-                            sizeof(StackEntryExtra) * nentries;   // extraArray
-        uint8_t *cursor = (uint8_t *)js_calloc(totalBytes);
-        if (!cursor)
-            return false;
-
-        this->entries = (FrameEntry *) cursor;
-        cursor += sizeof(FrameEntry) * nentries;
-
-        this->tracker.entries = (FrameEntry **)cursor;
-        cursor += sizeof(FrameEntry *) * nentries;
-
-        this->extraArray = (StackEntryExtra *)cursor;
-        cursor += sizeof(StackEntryExtra) * nentries;
-
-        JS_ASSERT(reinterpret_cast<uint8_t *>(this->entries) + totalBytes == cursor);
-
-#if defined JS_NUNBOX32
-        if (!reifier.init(cx, *this, nentries))
-            return false;
-#endif
-
-        this->temporaries = this->temporariesTop = this->entries + nentries - TEMPORARY_LIMIT;
-    }
-
-    /* We should have already checked that argc == nargs */
-    JS_ASSERT_IF(a, argc == script->function()->nargs);
-
-    ActiveFrame *newa = js_new<ActiveFrame>();
-    if (!newa)
-        return false;
-
-    newa->parent = a;
-    newa->depth = a ? (totalDepth() + VALUES_PER_STACK_FRAME) : 0;
-
-    newa->script = script;
-    newa->PC = script->code;
-    newa->analysis = script->analysis();
-
-    /*
-     * The callee/this/args in the new frame reuse the same entries as are on
-     * the stack in the old frame.
-     */
-    FrameEntry *entriesStart = a ? a->sp - (argc + 2) : entries;
-    newa->callee_ = entriesStart + analyze::CalleeSlot();
-    newa->this_   = entriesStart + analyze::ThisSlot();
-    newa->args    = entriesStart + analyze::ArgSlot(0);
-    newa->locals  = entriesStart + analyze::LocalSlot(script, 0);
-    newa->spBase  = entriesStart + analyze::TotalSlots(script);
-    newa->sp      = newa->spBase;
-
-    this->a = newa;
-
-    return true;
-}
-
-void
-FrameState::associateReg(FrameEntry *fe, RematInfo::RematType type, AnyRegisterID reg)
-{
-    freeRegs.takeReg(reg);
-
-    if (type == RematInfo::TYPE)
-        fe->type.setRegister(reg.reg());
-    else if (reg.isReg())
-        fe->data.setRegister(reg.reg());
-    else
-        fe->data.setFPRegister(reg.fpreg());
-    regstate(reg).associate(fe, type);
-}
-
-void
-FrameState::popActiveFrame()
-{
-    a->analysis->clearAllocations();
-
-    if (a->parent) {
-        /* Clear registers and copies used by local variables and stack slots. */
-        for (FrameEntry *fe = a->sp - 1; fe >= a->locals; fe--) {
-            if (!fe->isTracked())
-                continue;
-            forgetAllRegs(fe);
-            fe->clear();
-        }
-    }
-
-    ActiveFrame *parent = a->parent;
-    js_delete(a);
-    a = parent;
-}
-
-void
-FrameState::takeReg(AnyRegisterID reg)
-{
-    modifyReg(reg);
-    if (freeRegs.hasReg(reg)) {
-        freeRegs.takeReg(reg);
-        JS_ASSERT(!regstate(reg).usedBy());
-    } else {
-        JS_ASSERT(regstate(reg).fe());
-        evictReg(reg);
-    }
-}
-
-#ifdef DEBUG
-const char *
-FrameState::entryName(const FrameEntry *fe) const
-{
-    static char bufs[4][50];
-    static unsigned which = 0;
-    which = (which + 1) & 3;
-    char *buf = bufs[which];
-
-    if (isTemporary(fe)) {
-        JS_snprintf(buf, 50, "temp%d", fe - temporaries);
-        return buf;
-    }
-
-    if (fe < a->callee_)
-        return "parent";
-
-    JS_ASSERT(fe >= a->callee_ && fe < a->sp);
-
-    if (fe == a->callee_)
-        return "callee";
-    if (fe == a->this_)
-        return "'this'";
-
-    if (isArg(fe))
-        JS_snprintf(buf, 50, "arg%d", fe - a->args);
-    else if (isLocal(fe))
-        JS_snprintf(buf, 50, "local%d", fe - a->locals);
-    else
-        JS_snprintf(buf, 50, "slot%d", fe - a->spBase);
-    return buf;
-}
-#endif
-
-void
-FrameState::evictReg(AnyRegisterID reg)
-{
-    FrameEntry *fe = regstate(reg).fe();
-
-    JaegerSpew(JSpew_Regalloc, "evicting %s from %s\n", entryName(fe), reg.name());
-
-    if (regstate(reg).type() == RematInfo::TYPE) {
-        syncType(fe);
-        fe->type.setMemory();
-    } else if (reg.isReg()) {
-        syncData(fe);
-        fe->data.setMemory();
-    } else {
-        syncFe(fe);
-        fe->data.setMemory();
-    }
-
-    regstate(reg).forget();
-}
-
-inline Lifetime *
-FrameState::variableLive(FrameEntry *fe, jsbytecode *pc) const
-{
-    /*
-     * Whether an argument, local or 'this' entry is live at pc. Note: this
-     * does not account for the 'this' entry when the script is used as a
-     * constructor, in which case it is live the entire frame.
-     */
-    JS_ASSERT(cx->typeInferenceEnabled());
-    JS_ASSERT(fe > a->callee_ && fe < a->spBase);
-
-    uint32_t offset = pc - a->script->code;
-    return a->analysis->liveness(entrySlot(fe)).live(offset);
-}
-
-AnyRegisterID
-FrameState::bestEvictReg(uint32_t mask, bool includePinned) const
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-
-    /* Must be looking for a specific type of register. */
-    JS_ASSERT((mask & Registers::AvailRegs) != (mask & Registers::AvailFPRegs));
-
-    AnyRegisterID fallback;
-    uint32_t fallbackOffset = UINT32_MAX;
-
-    JaegerSpew(JSpew_Regalloc, "picking best register to evict:\n");
-
-    for (uint32_t i = 0; i < Registers::TotalAnyRegisters; i++) {
-        AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-
-        /* Register is not allocatable, don't bother.  */
-        if (!(Registers::maskReg(reg) & mask))
-            continue;
-
-        /* Register is not owned by the FrameState. */
-        FrameEntry *fe = includePinned ? regstate(reg).usedBy() : regstate(reg).fe();
-        if (!fe)
-            continue;
-
-        /*
-         * Liveness is not tracked for the callee or for stack slot frame entries.
-         * The callee is evicted as early as needed, stack slots are evicted as
-         * late as possible. :XXX: This is unfortunate if the stack slot lives
-         * a long time (especially if it gets spilled anyways when we hit a branch).
-         */
-
-        if (fe == a->callee_) {
-            JaegerSpew(JSpew_Regalloc, "result: %s is callee\n", reg.name());
-            return reg;
-        }
-
-        if (fe >= a->spBase && !isTemporary(fe)) {
-            if (!fallback.isSet()) {
-                fallback = reg;
-                fallbackOffset = 0;
-            }
-            JaegerSpew(JSpew_Regalloc, "    %s is on stack\n", reg.name());
-            continue;
-        }
-
-        /* Prioritize keeping copied entries in registers. */
-        if (fe->isCopied()) {
-            if (!fallback.isSet()) {
-                fallback = reg;
-                fallbackOffset = 0;
-            }
-            JaegerSpew(JSpew_Regalloc, "    %s has copies\n", reg.name());
-            continue;
-        }
-
-        if (isTemporary(fe) || (a->parent && fe < a->locals)) {
-            /*
-             * All temporaries we currently generate are for loop invariants,
-             * which we treat as being live everywhere within the loop.
-             * Additionally, if this is an inlined frame then any entries
-             * belonging to parents are treated as live everywhere in the call.
-             */
-            uint32_t offset = a->parent ? a->script->length : loop->backedgeOffset();
-            if (!fallback.isSet() || offset > fallbackOffset) {
-                fallback = reg;
-                fallbackOffset = offset;
-            }
-            JaegerSpew(JSpew_Regalloc, "    %s is a LICM or inline parent entry\n", reg.name());
-            continue;
-        }
-
-        /*
-         * All entries still in registers should have a lifetime, except 'this'
-         * in constructors which are not accessed later on.
-         */
-        Lifetime *lifetime = variableLive(fe, a->PC);
-
-        /* Evict variables whose value is no longer live. */
-        if (!lifetime) {
-            fallback = reg;
-            fallbackOffset = a->script->length;
-            JaegerSpew(JSpew_Regalloc, "    %s is dead\n", reg.name());
-            continue;
-        }
-
-        /*
-         * Evict variables which are only live in future loop iterations, and are
-         * not carried around the loop in a register.
-         */
-        if (lifetime->loopTail && (!loop || !loop->carriesLoopReg(fe))) {
-            JaegerSpew(JSpew_Regalloc, "result: %s (%s) only live in later iterations\n",
-                       entryName(fe), reg.name());
-            return reg;
-        }
-
-        JaegerSpew(JSpew_Regalloc, "    %s (%s): %u\n", entryName(fe), reg.name(), lifetime->end);
-
-        /*
-         * The best live register to evict is the one that will be live for the
-         * longest time. This may need tweaking for variables that are used in
-         * many places throughout their lifetime. Note that we don't pay attention
-         * to whether the register is synced or not --- it is more efficient to
-         * have things in registers when they're needed than to emit some extra
-         * writes for things that won't be used again for a while.
-         */
-
-        if (!fallback.isSet() || lifetime->end > fallbackOffset) {
-            fallback = reg;
-            fallbackOffset = lifetime->end;
-        }
-    }
-
-    JS_ASSERT(fallback.isSet());
-
-    JaegerSpew(JSpew_Regalloc, "result %s\n", fallback.name());
-    return fallback;
-}
-
-/*
- * Whether we can pretend the payload for a given entry is synced provided that
- * the value in the entry is dead. The contents of dead variables can still be
- * observed during stack scanning, so the payloads of values which might hold
- * objects or strings must be preserved.
- */
-static inline bool
-CanFakeSync(FrameEntry *fe)
-{
-    return fe->isType(JSVAL_TYPE_INT32) || fe->isType(JSVAL_TYPE_BOOLEAN);
-}
-
-void
-FrameState::evictDeadEntries(bool includePinned)
-{
-    for (uint32_t i = 0; i < Registers::TotalAnyRegisters; i++) {
-        AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-
-        /* Follow along with the same filters as bestEvictReg. */
-
-        if (!(Registers::maskReg(reg) & Registers::AvailAnyRegs))
-            continue;
-
-        FrameEntry *fe = includePinned ? regstate(reg).usedBy() : regstate(reg).fe();
-        if (!fe)
-            continue;
-
-        if (fe == a->callee_ || isConstructorThis(fe) ||
-            fe >= a->spBase || fe->isCopied() || (a->parent && fe < a->locals)) {
-            continue;
-        }
-
-        Lifetime *lifetime = variableLive(fe, a->PC);
-        if (lifetime || !CanFakeSync(fe))
-            continue;
-
-        JS_ASSERT(regstate(reg).type() == RematInfo::DATA);
-
-        /*
-         * Mark the entry as synced to avoid emitting a store, we don't need
-         * to keep this value around.
-         */
-        fakeSync(fe);
-        fe->data.setMemory();
-        forgetReg(reg);
-    }
-}
-
-AnyRegisterID
-FrameState::evictSomeReg(uint32_t mask)
-{
-    JS_ASSERT(!freeRegs.hasRegInMask(mask));
-
-    if (cx->typeInferenceEnabled()) {
-        evictDeadEntries(false);
-
-        if (freeRegs.hasRegInMask(mask)) {
-            /* There was a register in use by a dead local variable. */
-            AnyRegisterID reg = freeRegs.takeAnyReg(mask);
-            modifyReg(reg);
-            return reg;
-        }
-
-        AnyRegisterID reg = bestEvictReg(mask, false);
-        evictReg(reg);
-        return reg;
-    }
-
-    /* With inference disabled, only general purpose registers are managed. */
-    JS_ASSERT((mask & ~Registers::AvailRegs) == 0);
-
-    MaybeRegisterID fallback;
-
-    for (uint32_t i = 0; i < JSC::MacroAssembler::TotalRegisters; i++) {
-        RegisterID reg = RegisterID(i);
-
-        /* Register is not allocatable, don't bother.  */
-        if (!(Registers::maskReg(reg) & mask))
-            continue;
-
-        /* Register is not owned by the FrameState. */
-        FrameEntry *fe = regstate(reg).fe();
-        if (!fe)
-            continue;
-
-        /* Try to find a candidate... that doesn't need spilling. */
-        fallback = reg;
-
-        if (regstate(reg).type() == RematInfo::TYPE && fe->type.synced()) {
-            fe->type.setMemory();
-            regstate(reg).forget();
-            return reg;
-        }
-        if (regstate(reg).type() == RematInfo::DATA && fe->data.synced()) {
-            fe->data.setMemory();
-            regstate(reg).forget();
-            return reg;
-        }
-    }
-
-    evictReg(fallback.reg());
-    return fallback.reg();
-}
-
-void
-FrameState::resetInternalState()
-{
-    for (uint32_t i = 0; i < tracker.nentries; i++)
-        tracker[i]->untrack();
-
-    tracker.reset();
-    freeRegs = Registers(Registers::AvailAnyRegs);
-}
-
-void
-FrameState::discardFrame()
-{
-    resetInternalState();
-    PodArrayZero(regstate_);
-}
-
-FrameEntry *
-FrameState::snapshotState()
-{
-    /* Everything can be recovered from a copy of the frame entries. */
-    FrameEntry *snapshot = js_pod_malloc<FrameEntry>(nentries);
-    if (!snapshot)
-        return NULL;
-    PodCopy(snapshot, entries, nentries);
-    return snapshot;
-}
-
-void
-FrameState::restoreFromSnapshot(FrameEntry *snapshot)
-{
-    discardFrame();
-    PodCopy(entries, snapshot, nentries);
-
-    for (unsigned i = 0; i < nentries; i++) {
-        FrameEntry *fe = entries + i;
-        if (!fe->isTracked())
-            continue;
-        tracker.entries[fe->index_] = fe;
-        tracker.nentries = Max(tracker.nentries, fe->index_ + 1);
-        if (fe->isCopy())
-            continue;
-        if (fe->type.inRegister()) {
-            freeRegs.takeReg(fe->type.reg());
-            regstate(fe->type.reg()).associate(fe, RematInfo::TYPE);
-        }
-        if (fe->data.inRegister()) {
-            freeRegs.takeReg(fe->data.reg());
-            regstate(fe->data.reg()).associate(fe, RematInfo::DATA);
-        }
-        if (fe->data.inFPRegister()) {
-            freeRegs.takeReg(fe->data.fpreg());
-            regstate(fe->data.fpreg()).associate(fe, RematInfo::DATA);
-        }
-    }
-}
-
-void
-FrameState::forgetEverything()
-{
-    resetInternalState();
-
-#ifdef DEBUG
-    for (uint32_t i = 0; i < Registers::TotalAnyRegisters; i++) {
-        AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-        JS_ASSERT(!regstate(reg).usedBy());
-    }
-#endif
-}
-
-#ifdef DEBUG
-void
-FrameState::dumpAllocation(RegisterAllocation *alloc)
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-    for (unsigned i = 0; i < Registers::TotalAnyRegisters; i++) {
-        AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-        if (alloc->assigned(reg)) {
-            printf(" (%s: %s%s)", reg.name(), entryName(entries + alloc->index(reg)),
-                   alloc->synced(reg) ? "" : " unsynced");
-        }
-    }
-    printf("\n");
-}
-#endif
-
-RegisterAllocation *
-FrameState::computeAllocation(jsbytecode *target)
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-    RegisterAllocation *alloc = cx->analysisLifoAlloc().new_<RegisterAllocation>(false);
-    if (!alloc) {
-        js_ReportOutOfMemory(cx);
-        return NULL;
-    }
-
-    /*
-     * State must be synced at exception and switch targets, at traps and when
-     * crossing between compilation chunks.
-     */
-    if (a->analysis->getCode(target).safePoint ||
-        (!a->parent && !cc.bytecodeInChunk(target))) {
-#ifdef DEBUG
-        if (IsJaegerSpewChannelActive(JSpew_Regalloc)) {
-            JaegerSpew(JSpew_Regalloc, "allocation at %u:", unsigned(target - a->script->code));
-            dumpAllocation(alloc);
-        }
-#endif
-        return alloc;
-    }
-
-    /*
-     * The allocation to use at the target consists of all parent, temporary
-     * and non-stack entries currently in registers which are live at target.
-     */
-    Registers regs = Registers::AvailAnyRegs;
-    while (!regs.empty()) {
-        AnyRegisterID reg = regs.takeAnyReg();
-        if (freeRegs.hasReg(reg) || regstate(reg).type() == RematInfo::TYPE)
-            continue;
-        FrameEntry *fe = regstate(reg).fe();
-        if (fe < a->callee_ ||
-            isConstructorThis(fe) ||
-            (fe > a->callee_ && fe < a->spBase && variableLive(fe, target)) ||
-            (isTemporary(fe) && (a->parent || uint32_t(target - a->script->code) <= loop->backedgeOffset()))) {
-            /*
-             * For entries currently in floating point registers, check they
-             * are known to be doubles at the target. We don't need to do this
-             * for entries in normal registers, as fixDoubleTypes must have been
-             * called to convert them to floats.
-             */
-            if (!reg.isReg() && !isTemporary(fe) && fe >= a->callee_ && fe < a->spBase) {
-                if (!a->analysis->trackSlot(entrySlot(fe)))
-                    continue;
-                bool nonDoubleTarget = false;
-                const SlotValue *newv = a->analysis->newValues(target);
-                while (newv && newv->slot) {
-                    if (newv->value.kind() == SSAValue::PHI &&
-                        newv->value.phiOffset() == uint32_t(target - a->script->code) &&
-                        newv->slot == entrySlot(fe)) {
-                        types::StackTypeSet *types = a->analysis->getValueTypes(newv->value);
-                        if (types->getKnownTypeTag() != JSVAL_TYPE_DOUBLE)
-                            nonDoubleTarget = true;
-                    }
-                    newv++;
-                }
-                if (nonDoubleTarget)
-                    continue;
-            }
-            alloc->set(reg, fe - entries, fe->data.synced());
-        }
-    }
-
-#ifdef DEBUG
-    if (IsJaegerSpewChannelActive(JSpew_Regalloc)) {
-        JaegerSpew(JSpew_Regalloc, "allocation at %u:", unsigned(target - a->script->code));
-        dumpAllocation(alloc);
-    }
-#endif
-
-    return alloc;
-}
-
-void
-FrameState::relocateReg(AnyRegisterID reg, RegisterAllocation *alloc, Uses uses)
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-
-    /*
-     * The reg needs to be freed to make room for a variable carried across
-     * a branch. Either evict its entry, or try to move it to a different
-     * register if it is needed to test the branch condition. :XXX: could also
-     * watch for variables which are carried across the branch but are in a
-     * the register for a different carried entry, we just spill these for now.
-     */
-    JS_ASSERT(!freeRegs.hasReg(reg));
-
-    for (unsigned i = 0; i < uses.nuses; i++) {
-        FrameEntry *fe = peek(-1 - i);
-        if (fe->isCopy())
-            fe = fe->copyOf();
-        if (reg.isReg() && fe->data.inRegister() && fe->data.reg() == reg.reg()) {
-            pinReg(reg);
-            RegisterID nreg = allocReg();
-            unpinReg(reg);
-
-            JaegerSpew(JSpew_Regalloc, "relocating %s\n", reg.name());
-
-            masm.move(reg.reg(), nreg);
-            regstate(reg).forget();
-            regstate(nreg).associate(fe, RematInfo::DATA);
-            fe->data.setRegister(nreg);
-            freeRegs.putReg(reg);
-            return;
-        }
-    }
-
-    JaegerSpew(JSpew_Regalloc, "could not relocate %s\n", reg.name());
-
-    takeReg(reg);
-    freeRegs.putReg(reg);
-}
-
-bool
-FrameState::syncForBranch(jsbytecode *target, Uses uses)
-{
-    /* There should be no unowned or pinned registers. */
-#ifdef DEBUG
-    Registers checkRegs(Registers::AvailAnyRegs);
-    while (!checkRegs.empty()) {
-        AnyRegisterID reg = checkRegs.takeAnyReg();
-        JS_ASSERT_IF(!freeRegs.hasReg(reg), regstate(reg).fe());
-    }
-#endif
-
-    if (!cx->typeInferenceEnabled()) {
-        syncAndForgetEverything();
-        return true;
-    }
-
-    RegisterAllocation *&alloc = a->analysis->getAllocation(target);
-    if (!alloc) {
-        alloc = computeAllocation(target);
-        if (!alloc)
-            return false;
-    }
-
-    syncForAllocation(alloc, false, uses);
-
-    return true;
-}
-
-void
-FrameState::syncForAllocation(RegisterAllocation *alloc, bool inlineReturn, Uses uses)
-{
-    /*
-     * First pass. Sync all entries which will not be carried in a register,
-     * and uncopy everything except values popped by the branch or before the
-     * call returns.
-     */
-
-    FrameEntry *topEntry = NULL;
-    if (inlineReturn)
-        topEntry = a->parent->sp - (GET_ARGC(a->parent->PC) + 2);
-
-    for (uint32_t i = tracker.nentries - 1; i < tracker.nentries; i--) {
-        FrameEntry *fe = tracker[i];
-
-        if (deadEntry(fe, uses.nuses))
-            continue;
-        if (inlineReturn && fe >= topEntry && !isTemporary(fe)) {
-            /*
-             * The return value has already been stored, so there is no need to
-             * keep any of the entries for this frame or for values popped once
-             * the call returns intact. Forcibly evict any registers for these,
-             * so that we don't emit sync code for them if we need a register
-             * in syncFe below.
-             */
-            forgetAllRegs(fe);
-            fe->resetSynced();
-            continue;
-        }
-
-        /* Force syncs for locals which are dead at the current PC. */
-        if (isLocal(fe) && !fe->copied && !a->analysis->slotEscapes(entrySlot(fe))) {
-            Lifetime *lifetime = a->analysis->liveness(entrySlot(fe)).live(a->PC - a->script->code);
-            if (!lifetime && CanFakeSync(fe))
-                fakeSync(fe);
-        }
-
-        /* If returning from a script, fake syncs for dead locals in the immediate parent. */
-        if (inlineReturn && fe >= a->parent->locals &&
-            fe - a->parent->locals < a->parent->script->nfixed &&
-            !a->parent->analysis->slotEscapes(frameSlot(a->parent, fe))) {
-            const LifetimeVariable &var = a->parent->analysis->liveness(frameSlot(a->parent, fe));
-            Lifetime *lifetime = var.live(a->parent->PC - a->parent->script->code);
-            if (!lifetime && CanFakeSync(fe))
-                fakeSync(fe);
-        }
-
-        if (!fe->isCopy() && alloc->hasAnyReg(fe - entries)) {
-            /* Types are always synced, except for known doubles. */
-            if (!fe->isType(JSVAL_TYPE_DOUBLE))
-                syncType(fe);
-        } else {
-            syncFe(fe);
-            if (fe->isCopy())
-                fe->resetSynced();
-        }
-    }
-
-    /*
-     * Second pass. Move entries carried in registers to the right register
-     * provided no value used in the branch is evicted. After this pass,
-     * everything will either be in the right register or will be in memory.
-     */
-
-    Registers regs = Registers(Registers::AvailAnyRegs);
-    while (!regs.empty()) {
-        AnyRegisterID reg = regs.takeAnyReg();
-        if (!alloc->assigned(reg))
-            continue;
-        FrameEntry *fe = getOrTrack(alloc->index(reg));
-        JS_ASSERT(!fe->isCopy());
-
-        JS_ASSERT_IF(!fe->isType(JSVAL_TYPE_DOUBLE), fe->type.synced());
-        if (!fe->data.synced() && alloc->synced(reg))
-            syncFe(fe);
-
-        if (fe->dataInRegister(reg))
-            continue;
-
-        if (!freeRegs.hasReg(reg))
-            relocateReg(reg, alloc, uses);
-
-        if (reg.isReg()) {
-            RegisterID nreg = reg.reg();
-            if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-                JS_ASSERT(!a->analysis->trackSlot(entrySlot(fe)));
-                syncFe(fe);
-                forgetAllRegs(fe);
-                fe->type.setMemory();
-                fe->data.setMemory();
-            }
-            if (fe->data.inMemory()) {
-                masm.loadPayload(addressOf(fe), nreg);
-            } else if (fe->isConstant()) {
-                masm.loadValuePayload(fe->getValue(), nreg);
-            } else {
-                JS_ASSERT(fe->data.inRegister() && fe->data.reg() != nreg);
-                masm.move(fe->data.reg(), nreg);
-                freeRegs.putReg(fe->data.reg());
-                regstate(fe->data.reg()).forget();
-            }
-            fe->data.setRegister(nreg);
-        } else {
-            FPRegisterID nreg = reg.fpreg();
-            JS_ASSERT(!fe->isNotType(JSVAL_TYPE_DOUBLE));
-            if (!fe->isTypeKnown())
-                learnType(fe, JSVAL_TYPE_DOUBLE, false);
-            if (fe->data.inMemory()) {
-                masm.loadDouble(addressOf(fe), nreg);
-            } else if (fe->isConstant()) {
-                masm.slowLoadConstantDouble(fe->getValue().toDouble(), nreg);
-            } else {
-                JS_ASSERT(fe->data.inFPRegister() && fe->data.fpreg() != nreg);
-                masm.moveDouble(fe->data.fpreg(), nreg);
-                freeRegs.putReg(fe->data.fpreg());
-                regstate(fe->data.fpreg()).forget();
-            }
-            fe->data.setFPRegister(nreg);
-        }
-
-        freeRegs.takeReg(reg);
-        regstate(reg).associate(fe, RematInfo::DATA);
-    }
-}
-
-bool
-FrameState::discardForJoin(RegisterAllocation *&alloc, uint32_t stackDepth)
-{
-    if (!cx->typeInferenceEnabled()) {
-        resetInternalState();
-        PodArrayZero(regstate_);
-        a->sp = a->spBase + stackDepth;
-        return true;
-    }
-
-    if (!alloc) {
-        /*
-         * This shows up for loop entries which are not reachable from the
-         * loop head, and for exception, switch target and trap safe points.
-         */
-        alloc = cx->analysisLifoAlloc().new_<RegisterAllocation>(false);
-        if (!alloc) {
-            js_ReportOutOfMemory(cx);
-            return false;
-        }
-    }
-
-    resetInternalState();
-    PodArrayZero(regstate_);
-
-    Registers regs(Registers::AvailAnyRegs);
-    while (!regs.empty()) {
-        AnyRegisterID reg = regs.takeAnyReg();
-        if (!alloc->assigned(reg))
-            continue;
-        FrameEntry *fe = getOrTrack(alloc->index(reg));
-
-        freeRegs.takeReg(reg);
-
-        /*
-         * We can't look at the type of the fe as we haven't restored analysis types yet,
-         * but if this is an FP reg it will be set to double type.
-         */
-        if (reg.isReg()) {
-            fe->data.setRegister(reg.reg());
-        } else {
-            fe->setType(JSVAL_TYPE_DOUBLE);
-            fe->data.setFPRegister(reg.fpreg());
-        }
-
-        regstate(reg).associate(fe, RematInfo::DATA);
-        if (!alloc->synced(reg)) {
-            fe->data.unsync();
-            if (!reg.isReg())
-                fe->type.unsync();
-        }
-    }
-
-    a->sp = a->spBase + stackDepth;
-
-    for (unsigned i = 0; i < stackDepth; i++)
-        extraArray[a->spBase + i - entries].reset();
-
-    return true;
-}
-
-bool
-FrameState::consistentRegisters(jsbytecode *target)
-{
-    if (!cx->typeInferenceEnabled()) {
-        JS_ASSERT(freeRegs.freeMask == Registers::AvailAnyRegs);
-        return true;
-    }
-
-    /*
-     * Before calling this, either the entire state should have been synced or
-     * syncForBranch should have been called. These will ensure that any FE
-     * which is not consistent with the target's register state has already
-     * been synced, and no stores will need to be issued by prepareForJump.
-     */
-    RegisterAllocation *alloc = a->analysis->getAllocation(target);
-    JS_ASSERT(alloc);
-
-    Registers regs(Registers::AvailAnyRegs);
-    while (!regs.empty()) {
-        AnyRegisterID reg = regs.takeAnyReg();
-        if (alloc->assigned(reg)) {
-            FrameEntry *needed = getOrTrack(alloc->index(reg));
-            if (!freeRegs.hasReg(reg)) {
-                FrameEntry *fe = regstate(reg).fe();
-                if (fe != needed)
-                    return false;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
-void
-FrameState::prepareForJump(jsbytecode *target, Assembler &masm, bool synced)
-{
-    if (!cx->typeInferenceEnabled())
-        return;
-
-    JS_ASSERT_IF(!synced, !consistentRegisters(target));
-
-    RegisterAllocation *alloc = a->analysis->getAllocation(target);
-    JS_ASSERT(alloc);
-
-    Registers regs = 0;
-
-    regs = Registers(Registers::AvailAnyRegs);
-    while (!regs.empty()) {
-        AnyRegisterID reg = regs.takeAnyReg();
-        if (!alloc->assigned(reg))
-            continue;
-
-        const FrameEntry *fe = getOrTrack(alloc->index(reg));
-        if (synced || !fe->backing()->dataInRegister(reg)) {
-            JS_ASSERT_IF(!synced, fe->data.synced());
-            if (reg.isReg())
-                masm.loadPayload(addressOf(fe), reg.reg());
-            else
-                masm.loadDouble(addressOf(fe), reg.fpreg());
-        }
-    }
-}
-
-void
-FrameState::storeTo(FrameEntry *fe, Address address, bool popped)
-{
-    if (fe->isConstant()) {
-        masm.storeValue(fe->getValue(), address);
-        return;
-    }
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!freeRegs.hasReg(address.base));
-
-    /* If loading from memory, ensure destination differs. */
-    JS_ASSERT_IF((fe->type.inMemory() || fe->data.inMemory()),
-                 addressOf(fe).base != address.base ||
-                 addressOf(fe).offset != address.offset);
-
-    if (fe->data.inFPRegister()) {
-        masm.storeDouble(fe->data.fpreg(), address);
-        return;
-    }
-
-    if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-        JS_ASSERT(fe->data.inMemory());
-        masm.loadDouble(addressOf(fe), Registers::FPConversionTemp);
-        masm.storeDouble(Registers::FPConversionTemp, address);
-        return;
-    }
-
-    /* Don't clobber the address's register. */
-    bool pinAddressReg = !!regstate(address.base).fe();
-    if (pinAddressReg)
-        pinReg(address.base);
-
-#if defined JS_PUNBOX64
-    if (fe->type.inMemory() && fe->data.inMemory()) {
-        /* Future optimization: track that the Value is in a register. */
-        RegisterID vreg = Registers::ValueReg;
-        masm.loadPtr(addressOf(fe), vreg);
-        masm.storePtr(vreg, address);
-        if (pinAddressReg)
-            unpinReg(address.base);
-        return;
-    }
-
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    /*
-     * If dreg is obtained via allocReg(), then calling
-     * pinReg() trips an assertion. But in all other cases,
-     * calling pinReg() is necessary in the fe->type.inMemory() path.
-     * Remember whether pinReg() can be safely called.
-     */
-    bool canPinDreg = true;
-    bool wasInRegister = fe->data.inRegister();
-
-    /* Get a register for the payload. */
-    MaybeRegisterID dreg;
-    if (fe->data.inRegister()) {
-        dreg = fe->data.reg();
-    } else {
-        JS_ASSERT(fe->data.inMemory());
-        if (popped) {
-            dreg = allocReg();
-            masm.loadPayload(addressOf(fe), dreg.reg());
-            canPinDreg = false;
-        } else {
-            dreg = allocAndLoadReg(fe, false, RematInfo::DATA).reg();
-            fe->data.setRegister(dreg.reg());
-        }
-    }
-
-    /* Store the Value. */
-    if (fe->type.inRegister()) {
-        masm.storeValueFromComponents(fe->type.reg(), dreg.reg(), address);
-    } else if (fe->isTypeKnown()) {
-        masm.storeValueFromComponents(ImmType(fe->getKnownType()), dreg.reg(), address);
-    } else {
-        JS_ASSERT(fe->type.inMemory());
-        if (canPinDreg)
-            pinReg(dreg.reg());
-
-        RegisterID treg;
-        if (popped) {
-            treg = allocReg();
-            masm.loadTypeTag(addressOf(fe), treg);
-        } else {
-            treg = allocAndLoadReg(fe, false, RematInfo::TYPE).reg();
-        }
-        masm.storeValueFromComponents(treg, dreg.reg(), address);
-
-        if (popped)
-            freeReg(treg);
-        else
-            fe->type.setRegister(treg);
-
-        if (canPinDreg)
-            unpinReg(dreg.reg());
-    }
-
-    /* If register is untracked, free it. */
-    if (!wasInRegister && popped)
-        freeReg(dreg.reg());
-
-#elif defined JS_NUNBOX32
-
-    if (fe->data.inRegister()) {
-        masm.storePayload(fe->data.reg(), address);
-    } else {
-        JS_ASSERT(fe->data.inMemory());
-        RegisterID reg;
-        if (popped) {
-            reg = allocReg();
-            masm.loadPayload(addressOf(fe), reg);
-        } else {
-            reg = allocAndLoadReg(fe, false, RematInfo::DATA).reg();
-        }
-        masm.storePayload(reg, address);
-        if (popped)
-            freeReg(reg);
-        else
-            fe->data.setRegister(reg);
-    }
-
-    if (fe->isTypeKnown()) {
-        masm.storeTypeTag(ImmType(fe->getKnownType()), address);
-    } else if (fe->type.inRegister()) {
-        masm.storeTypeTag(fe->type.reg(), address);
-    } else {
-        JS_ASSERT(fe->type.inMemory());
-        RegisterID reg;
-        if (popped) {
-            reg = allocReg();
-            masm.loadTypeTag(addressOf(fe), reg);
-        } else {
-            reg = allocAndLoadReg(fe, false, RematInfo::TYPE).reg();
-        }
-        masm.storeTypeTag(reg, address);
-        if (popped)
-            freeReg(reg);
-        else
-            fe->type.setRegister(reg);
-    }
-#endif
-    if (pinAddressReg)
-        unpinReg(address.base);
-}
-
-void
-FrameState::loadThisForReturn(RegisterID typeReg, RegisterID dataReg, RegisterID tempReg)
-{
-    return loadForReturn(getThis(), typeReg, dataReg, tempReg);
-}
-
-void FrameState::loadForReturn(FrameEntry *fe, RegisterID typeReg, RegisterID dataReg, RegisterID tempReg)
-{
-    JS_ASSERT(dataReg != typeReg && dataReg != tempReg && typeReg != tempReg);
-
-    if (fe->isConstant()) {
-        masm.loadValueAsComponents(fe->getValue(), typeReg, dataReg);
-        return;
-    }
-
-    if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-        FPRegisterID fpreg = tempFPRegForData(fe);
-        masm.breakDouble(fpreg, typeReg, dataReg);
-        return;
-    }
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    MaybeRegisterID maybeType = maybePinType(fe);
-    MaybeRegisterID maybeData = maybePinData(fe);
-
-    if (fe->isTypeKnown()) {
-        // If the data is in memory, or in the wrong reg, load/move it.
-        if (!maybeData.isSet())
-            masm.loadPayload(addressOf(fe), dataReg);
-        else if (maybeData.reg() != dataReg)
-            masm.move(maybeData.reg(), dataReg);
-        masm.move(ImmType(fe->getKnownType()), typeReg);
-        return;
-    }
-
-    // If both halves of the value are in memory, make this easier and load
-    // both pieces into their respective registers.
-    if (fe->type.inMemory() && fe->data.inMemory()) {
-        masm.loadValueAsComponents(addressOf(fe), typeReg, dataReg);
-        return;
-    }
-
-    // Now, we should be guaranteed that at least one part is in a register.
-    JS_ASSERT(maybeType.isSet() || maybeData.isSet());
-
-    // Make sure we have two registers while making sure not clobber either half.
-    // Here we are allowed to mess up the FrameState invariants, because this
-    // is specialized code for a path that is about to discard the entire frame.
-    if (!maybeType.isSet()) {
-        JS_ASSERT(maybeData.isSet());
-        if (maybeData.reg() != typeReg)
-            maybeType = typeReg;
-        else
-            maybeType = tempReg;
-        masm.loadTypeTag(addressOf(fe), maybeType.reg());
-    } else if (!maybeData.isSet()) {
-        JS_ASSERT(maybeType.isSet());
-        if (maybeType.reg() != dataReg)
-            maybeData = dataReg;
-        else
-            maybeData = tempReg;
-        masm.loadPayload(addressOf(fe), maybeData.reg());
-    }
-
-    RegisterID type = maybeType.reg();
-    RegisterID data = maybeData.reg();
-
-    if (data == typeReg && type == dataReg) {
-        masm.move(type, tempReg);
-        masm.move(data, dataReg);
-        masm.move(tempReg, typeReg);
-    } else if (data != dataReg) {
-        if (type == typeReg) {
-            masm.move(data, dataReg);
-        } else if (type != dataReg) {
-            masm.move(data, dataReg);
-            if (type != typeReg)
-                masm.move(type, typeReg);
-        } else {
-            JS_ASSERT(data != typeReg);
-            masm.move(type, typeReg);
-            masm.move(data, dataReg);
-        }
-    } else if (type != typeReg) {
-        masm.move(type, typeReg);
-    }
-}
-
-#ifdef DEBUG
-void
-FrameState::assertValidRegisterState() const
-{
-    Registers checkedFreeRegs(Registers::AvailAnyRegs);
-
-    /* Check that copied and copy info balance out. */
-    int32_t copyCount = 0;
-
-    for (uint32_t i = 0; i < tracker.nentries; i++) {
-        FrameEntry *fe = tracker[i];
-        if (deadEntry(fe))
-            continue;
-
-        JS_ASSERT(i == fe->trackerIndex());
-
-        if (fe->isCopy()) {
-            JS_ASSERT_IF(!fe->copyOf()->temporary, fe > fe->copyOf());
-            JS_ASSERT(fe->trackerIndex() > fe->copyOf()->trackerIndex());
-            JS_ASSERT(!deadEntry(fe->copyOf()));
-            JS_ASSERT(fe->copyOf()->isCopied());
-            JS_ASSERT(!fe->isCopied());
-            copyCount--;
-            continue;
-        }
-
-        copyCount += fe->copied;
-
-        if (fe->type.inRegister()) {
-            checkedFreeRegs.takeReg(fe->type.reg());
-            JS_ASSERT(regstate(fe->type.reg()).fe() == fe);
-            JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-        }
-        if (fe->data.inRegister()) {
-            checkedFreeRegs.takeReg(fe->data.reg());
-            JS_ASSERT(regstate(fe->data.reg()).fe() == fe);
-            JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-        }
-        if (fe->data.inFPRegister()) {
-            JS_ASSERT(fe->isType(JSVAL_TYPE_DOUBLE));
-            checkedFreeRegs.takeReg(fe->data.fpreg());
-            JS_ASSERT(regstate(fe->data.fpreg()).fe() == fe);
-        }
-    }
-
-    JS_ASSERT(copyCount == 0);
-    JS_ASSERT(checkedFreeRegs == freeRegs);
-
-    for (uint32_t i = 0; i < Registers::TotalRegisters; i++) {
-        AnyRegisterID reg = (RegisterID) i;
-        JS_ASSERT(!regstate(reg).isPinned());
-        JS_ASSERT_IF(regstate(reg).fe(), !freeRegs.hasReg(reg));
-        JS_ASSERT_IF(regstate(reg).fe(), regstate(reg).fe()->isTracked());
-    }
-
-    for (uint32_t i = 0; i < Registers::TotalFPRegisters; i++) {
-        AnyRegisterID reg = (FPRegisterID) i;
-        JS_ASSERT(!regstate(reg).isPinned());
-        JS_ASSERT_IF(regstate(reg).fe(), !freeRegs.hasReg(reg));
-        JS_ASSERT_IF(regstate(reg).fe(), regstate(reg).fe()->isTracked());
-        JS_ASSERT_IF(regstate(reg).fe(), regstate(reg).type() == RematInfo::DATA);
-    }
-}
-#endif
-
-#if defined JS_NUNBOX32
-void
-FrameState::syncFancy(Assembler &masm, Registers avail, int trackerIndex) const
-{
-    reifier.reset(&masm, avail, a->sp, entries);
-
-    for (; trackerIndex >= 0; trackerIndex--) {
-        FrameEntry *fe = tracker[trackerIndex];
-        if (fe >= a->sp)
-            continue;
-
-        reifier.sync(fe);
-    }
-}
-
-#endif
-void
-FrameState::sync(Assembler &masm, Uses uses) const
-{
-    if (!entries)
-        return;
-
-    /* Sync all registers up-front. */
-    Registers allRegs(Registers::AvailAnyRegs);
-    while (!allRegs.empty()) {
-        AnyRegisterID reg = allRegs.takeAnyReg();
-        FrameEntry *fe = regstate(reg).usedBy();
-        if (!fe)
-            continue;
-
-        JS_ASSERT(fe->isTracked());
-
-#if defined JS_PUNBOX64
-        /* Sync entire FE to prevent loads. */
-        ensureFeSynced(fe, masm);
-
-        /* Take the other register in the pair, if one exists. */
-        if (regstate(reg).type() == RematInfo::DATA && fe->type.inRegister())
-            allRegs.takeReg(fe->type.reg());
-        else if (regstate(reg).type() == RematInfo::TYPE && fe->data.inRegister())
-            allRegs.takeReg(fe->data.reg());
-#elif defined JS_NUNBOX32
-        /* Sync register if unsynced. */
-        if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-            ensureFeSynced(fe, masm);
-        } else if (regstate(reg).type() == RematInfo::DATA) {
-            JS_ASSERT(fe->data.reg() == reg.reg());
-            ensureDataSynced(fe, masm);
-        } else {
-            JS_ASSERT(fe->type.reg() == reg.reg());
-            ensureTypeSynced(fe, masm);
-        }
-#endif
-    }
-
-    /*
-     * Keep track of free registers using a bitmask. If we have to drop into
-     * syncFancy(), then this mask will help avoid eviction.
-     */
-    Registers avail(freeRegs.freeMask & Registers::AvailRegs);
-    Registers temp(Registers::TempAnyRegs);
-
-    unsigned nentries = tracker.nentries;
-    for (int trackerIndex = nentries - 1; trackerIndex >= 0; trackerIndex--) {
-        JS_ASSERT(tracker.nentries == nentries);
-        FrameEntry *fe = tracker[trackerIndex];
-        if (fe >= a->sp)
-            continue;
-
-        if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-            /* Copies of in-memory doubles can be synced without spilling. */
-            if (fe->isCopy() || !fe->data.inFPRegister())
-                ensureFeSynced(fe, masm);
-            continue;
-        }
-
-        if (!fe->isCopy()) {
-            if (fe->data.inRegister() && !regstate(fe->data.reg()).isPinned())
-                avail.putReg(fe->data.reg());
-            if (fe->type.inRegister() && !regstate(fe->type.reg()).isPinned())
-                avail.putReg(fe->type.reg());
-        } else {
-            FrameEntry *backing = fe->copyOf();
-            JS_ASSERT(!backing->isConstant() && !fe->isConstant());
-
-#if defined JS_PUNBOX64
-            if ((!fe->type.synced() && backing->type.inMemory()) ||
-                (!fe->data.synced() && backing->data.inMemory())) {
-
-                RegisterID syncReg = Registers::ValueReg;
-
-                /* Load the entire Value into syncReg. */
-                if (backing->type.synced() && backing->data.synced()) {
-                    masm.loadValue(addressOf(backing), syncReg);
-                } else if (backing->type.inMemory()) {
-                    masm.loadTypeTag(addressOf(backing), syncReg);
-                    masm.orPtr(backing->data.reg(), syncReg);
-                } else {
-                    JS_ASSERT(backing->data.inMemory());
-                    masm.loadPayload(addressOf(backing), syncReg);
-                    if (backing->isTypeKnown())
-                        masm.orPtr(ImmType(backing->getKnownType()), syncReg);
-                    else
-                        masm.orPtr(backing->type.reg(), syncReg);
-                }
-
-                masm.storeValue(syncReg, addressOf(fe));
-                continue;
-            }
-#elif defined JS_NUNBOX32
-            /* Fall back to a slower sync algorithm if load required. */
-            if ((!fe->type.synced() && backing->type.inMemory()) ||
-                (!fe->data.synced() && backing->data.inMemory())) {
-                syncFancy(masm, avail, trackerIndex);
-                return;
-            }
-#endif
-        }
-
-        bool copy = fe->isCopy();
-
-        /* If a part still needs syncing, it is either a copy or constant. */
-#if defined JS_PUNBOX64
-        /* All register-backed FEs have been entirely synced up-front. */
-        if (copy || (!fe->type.inRegister() && !fe->data.inRegister()))
-            ensureFeSynced(fe, masm);
-#elif defined JS_NUNBOX32
-        /* All components held in registers have been already synced. */
-        if (copy || !fe->data.inRegister())
-            ensureDataSynced(fe, masm);
-        if (copy || !fe->type.inRegister())
-            ensureTypeSynced(fe, masm);
-#endif
-    }
-}
-
-void
-FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore)
-{
-    if (loop) {
-        /*
-         * Drop any remaining loop registers so we don't do any more after-the-fact
-         * allocation of the initial register state.
-         */
-        loop->clearLoopRegisters();
-    }
-
-    /* Sync all kill-registers up-front. */
-    Registers search(kill.freeMask & ~freeRegs.freeMask);
-    while (!search.empty()) {
-        AnyRegisterID reg = search.takeAnyReg();
-        FrameEntry *fe = regstate(reg).usedBy();
-        if (!fe || deadEntry(fe, ignore.nuses))
-            continue;
-
-        JS_ASSERT(fe->isTracked());
-
-#if defined JS_PUNBOX64
-        /* Don't use syncFe(), since that may clobber more registers. */
-        ensureFeSynced(fe, masm);
-
-        if (!fe->type.synced())
-            fe->type.sync();
-        if (!fe->data.synced())
-            fe->data.sync();
-
-        /* Take the other register in the pair, if one exists. */
-        if (regstate(reg).type() == RematInfo::DATA) {
-            if (!fe->isType(JSVAL_TYPE_DOUBLE)) {
-                JS_ASSERT(fe->data.reg() == reg.reg());
-                if (fe->type.inRegister() && search.hasReg(fe->type.reg()))
-                    search.takeReg(fe->type.reg());
-            }
-        } else {
-            JS_ASSERT(fe->type.reg() == reg.reg());
-            if (fe->data.inRegister() && search.hasReg(fe->data.reg()))
-                search.takeReg(fe->data.reg());
-        }
-#elif defined JS_NUNBOX32
-        /* Sync this register. */
-        if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-            syncFe(fe);
-        } else if (regstate(reg).type() == RematInfo::DATA) {
-            JS_ASSERT(fe->data.reg() == reg.reg());
-            syncData(fe);
-        } else {
-            JS_ASSERT(fe->type.reg() == reg.reg());
-            syncType(fe);
-        }
-#endif
-    }
-
-
-    unsigned nentries = tracker.nentries;
-    for (int trackerIndex = nentries - 1; trackerIndex >= 0; trackerIndex--) {
-        JS_ASSERT(tracker.nentries == nentries);
-        FrameEntry *fe = tracker[trackerIndex];
-
-        if (fe >= a->sp || deadEntry(fe, ignore.nuses))
-            continue;
-
-        syncFe(fe);
-
-        if (fe->isCopy())
-            continue;
-
-        /* Forget registers. */
-        if (fe->data.inRegister() && !regstate(fe->data.reg()).isPinned()) {
-            forgetReg(fe->data.reg());
-            fe->data.setMemory();
-        }
-        if (fe->data.inFPRegister() && !regstate(fe->data.fpreg()).isPinned()) {
-            forgetReg(fe->data.fpreg());
-            fe->data.setMemory();
-        }
-        if (fe->type.inRegister() && !regstate(fe->type.reg()).isPinned()) {
-            forgetReg(fe->type.reg());
-            fe->type.setMemory();
-        }
-    }
-
-    /*
-     * Anything still alive at this point is guaranteed to be synced. However,
-     * it is necessary to evict temporary registers.
-     */
-    search = Registers(kill.freeMask & ~freeRegs.freeMask);
-    while (!search.empty()) {
-        AnyRegisterID reg = search.takeAnyReg();
-        FrameEntry *fe = regstate(reg).usedBy();
-        if (!fe || deadEntry(fe, ignore.nuses))
-            continue;
-
-        JS_ASSERT(fe->isTracked());
-
-        if (regstate(reg).type() == RematInfo::DATA) {
-            JS_ASSERT_IF(reg.isFPReg(), fe->data.fpreg() == reg.fpreg());
-            JS_ASSERT_IF(!reg.isFPReg(), fe->data.reg() == reg.reg());
-            JS_ASSERT(fe->data.synced());
-            fe->data.setMemory();
-        } else {
-            JS_ASSERT(fe->type.reg() == reg.reg());
-            JS_ASSERT(fe->type.synced());
-            fe->type.setMemory();
-        }
-
-        forgetReg(reg);
-    }
-}
-
-void
-FrameState::merge(Assembler &masm, Changes changes) const
-{
-    /*
-     * Note: this should only be called by StubCompiler::rejoin, which will notify
-     * this FrameState about the jump to patch up in case a new loop register is
-     * allocated later.
-     */
-
-    /*
-     * For any changed values we are merging back which we consider to be doubles,
-     * ensure they actually are doubles.  They must be doubles or ints, but we
-     * do not require stub paths to always generate a double when needed.
-     * :FIXME: we check this on OOL stub calls, but not inline stub calls.
-     */
-    if (cx->typeInferenceEnabled()) {
-        for (unsigned i = 0; i < changes.nchanges; i++) {
-            FrameEntry *fe = a->sp - 1 - i;
-            if (fe->isTracked() && fe->isType(JSVAL_TYPE_DOUBLE))
-                masm.ensureInMemoryDouble(addressOf(fe));
-        }
-    }
-
-    uint32_t mask = Registers::AvailAnyRegs & ~freeRegs.freeMask;
-    Registers search(mask);
-
-    while (!search.empty(mask)) {
-        AnyRegisterID reg = search.peekReg(mask);
-        FrameEntry *fe = regstate(reg).usedBy();
-
-        if (!fe) {
-            search.takeReg(reg);
-            continue;
-        }
-
-        if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-            JS_ASSERT(fe->data.fpreg() == reg.fpreg());
-            search.takeReg(fe->data.fpreg());
-            masm.loadDouble(addressOf(fe), fe->data.fpreg());
-        } else if (fe->data.inRegister() && fe->type.inRegister()) {
-            search.takeReg(fe->data.reg());
-            search.takeReg(fe->type.reg());
-            masm.loadValueAsComponents(addressOf(fe), fe->type.reg(), fe->data.reg());
-        } else {
-            if (fe->data.inRegister()) {
-                search.takeReg(fe->data.reg());
-                masm.loadPayload(addressOf(fe), fe->data.reg());
-            }
-            if (fe->type.inRegister()) {
-                search.takeReg(fe->type.reg());
-                masm.loadTypeTag(addressOf(fe), fe->type.reg());
-            }
-        }
-    }
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::copyDataIntoReg(FrameEntry *fe)
-{
-    return copyDataIntoReg(this->masm, fe);
-}
-
-void
-FrameState::copyDataIntoReg(FrameEntry *fe, RegisterID hint)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (!fe->data.inRegister())
-        tempRegForData(fe);
-
-    RegisterID reg = fe->data.reg();
-    if (reg == hint) {
-        if (freeRegs.empty(Registers::AvailRegs)) {
-            ensureDataSynced(fe, masm);
-            fe->data.setMemory();
-        } else {
-            reg = allocReg();
-            masm.move(hint, reg);
-            fe->data.setRegister(reg);
-            regstate(reg).associate(regstate(hint).fe(), RematInfo::DATA);
-        }
-        regstate(hint).forget();
-    } else {
-        pinReg(reg);
-        takeReg(hint);
-        unpinReg(reg);
-        masm.move(reg, hint);
-    }
-
-    modifyReg(hint);
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::copyDataIntoReg(Assembler &masm, FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isConstant());
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    if (fe->data.inRegister()) {
-        RegisterID reg = fe->data.reg();
-        if (freeRegs.empty(Registers::AvailRegs)) {
-            ensureDataSynced(fe, masm);
-            fe->data.setMemory();
-            regstate(reg).forget();
-            modifyReg(reg);
-        } else {
-            RegisterID newReg = allocReg();
-            masm.move(reg, newReg);
-            reg = newReg;
-        }
-        return reg;
-    }
-
-    RegisterID reg = allocReg();
-
-    if (!freeRegs.empty(Registers::AvailRegs))
-        masm.move(tempRegForData(fe), reg);
-    else
-        masm.loadPayload(addressOf(fe),reg);
-
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::copyTypeIntoReg(FrameEntry *fe)
-{
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    JS_ASSERT(!fe->type.isConstant());
-
-    if (fe->type.inRegister()) {
-        RegisterID reg = fe->type.reg();
-        if (freeRegs.empty(Registers::AvailRegs)) {
-            ensureTypeSynced(fe, masm);
-            fe->type.setMemory();
-            regstate(reg).forget();
-            modifyReg(reg);
-        } else {
-            RegisterID newReg = allocReg();
-            masm.move(reg, newReg);
-            reg = newReg;
-        }
-        return reg;
-    }
-
-    RegisterID reg = allocReg();
-
-    if (!freeRegs.empty(Registers::AvailRegs))
-        masm.move(tempRegForType(fe), reg);
-    else
-        masm.loadTypeTag(addressOf(fe), reg);
-
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::copyInt32ConstantIntoReg(FrameEntry *fe)
-{
-    return copyInt32ConstantIntoReg(masm, fe);
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::copyInt32ConstantIntoReg(Assembler &masm, FrameEntry *fe)
-{
-    JS_ASSERT(fe->data.isConstant());
-
-    if (fe->isCopy())
-        fe = fe->copyOf();
-
-    RegisterID reg = allocReg();
-    masm.move(Imm32(fe->getValue().toInt32()), reg);
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::ownRegForType(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isTypeKnown());
-
-    RegisterID reg;
-    if (fe->isCopy()) {
-        /* For now, just do an extra move. The reg must be mutable. */
-        FrameEntry *backing = fe->copyOf();
-        if (!backing->type.inRegister()) {
-            JS_ASSERT(backing->type.inMemory());
-            tempRegForType(backing);
-        }
-
-        if (freeRegs.empty(Registers::AvailRegs)) {
-            /* For now... just steal the register that already exists. */
-            ensureTypeSynced(backing, masm);
-            reg = backing->type.reg();
-            backing->type.setMemory();
-            regstate(reg).forget();
-            modifyReg(reg);
-        } else {
-            reg = allocReg();
-            masm.move(backing->type.reg(), reg);
-        }
-        return reg;
-    }
-
-    if (fe->type.inRegister()) {
-        reg = fe->type.reg();
-
-        /* Remove ownership of this register. */
-        JS_ASSERT(regstate(reg).fe() == fe);
-        JS_ASSERT(regstate(reg).type() == RematInfo::TYPE);
-        regstate(reg).forget();
-        fe->type.setMemory();
-        modifyReg(reg);
-    } else {
-        JS_ASSERT(fe->type.inMemory());
-        reg = allocReg();
-        masm.loadTypeTag(addressOf(fe), reg);
-    }
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-FrameState::ownRegForData(FrameEntry *fe)
-{
-    JS_ASSERT(!fe->isConstant());
-    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
-
-    RegisterID reg;
-    if (fe->isCopy()) {
-        /* For now, just do an extra move. The reg must be mutable. */
-        FrameEntry *backing = fe->copyOf();
-        if (!backing->data.inRegister()) {
-            JS_ASSERT(backing->data.inMemory());
-            tempRegForData(backing);
-        }
-
-        if (freeRegs.empty(Registers::AvailRegs)) {
-            /* For now... just steal the register that already exists. */
-            ensureDataSynced(backing, masm);
-            reg = backing->data.reg();
-            backing->data.setMemory();
-            regstate(reg).forget();
-            modifyReg(reg);
-        } else {
-            reg = allocReg();
-            masm.move(backing->data.reg(), reg);
-        }
-        return reg;
-    }
-
-    if (fe->isCopied())
-        uncopy(fe);
-
-    if (fe->data.inRegister()) {
-        reg = fe->data.reg();
-        /* Remove ownership of this register. */
-        JS_ASSERT(regstate(reg).fe() == fe);
-        JS_ASSERT(regstate(reg).type() == RematInfo::DATA);
-        regstate(reg).forget();
-        fe->data.setMemory();
-        modifyReg(reg);
-    } else {
-        JS_ASSERT(fe->data.inMemory());
-        reg = allocReg();
-        masm.loadPayload(addressOf(fe), reg);
-    }
-    return reg;
-}
-
-void
-FrameState::discardFe(FrameEntry *fe)
-{
-    forgetEntry(fe);
-    fe->type.setMemory();
-    fe->data.setMemory();
-    fe->clear();
-}
-
-void
-FrameState::pushDouble(FPRegisterID fpreg)
-{
-    FrameEntry *fe = rawPush();
-    fe->resetUnsynced();
-    fe->setType(JSVAL_TYPE_DOUBLE);
-    fe->data.setFPRegister(fpreg);
-    regstate(fpreg).associate(fe, RematInfo::DATA);
-}
-
-void
-FrameState::pushDouble(Address address)
-{
-    FPRegisterID fpreg = allocFPReg();
-    masm.loadDouble(address, fpreg);
-    pushDouble(fpreg);
-}
-
-void
-FrameState::ensureDouble(FrameEntry *fe)
-{
-    if (fe->isType(JSVAL_TYPE_DOUBLE))
-        return;
-
-    if (fe->isConstant()) {
-        JS_ASSERT(fe->getValue().isInt32());
-        Value newValue = DoubleValue(double(fe->getValue().toInt32()));
-        fe->setConstant(newValue);
-        return;
-    }
-
-    FrameEntry *backing = fe;
-    if (fe->isCopy()) {
-        /* Forget this entry is a copy.  We are converting this entry, not the backing. */
-        backing = fe->copyOf();
-        fe->clear();
-    } else if (fe->isCopied()) {
-        /* Sync and forget any copies of this entry. */
-        for (uint32_t i = fe->trackerIndex() + 1; i < tracker.nentries; i++) {
-            FrameEntry *nfe = tracker[i];
-            if (!deadEntry(nfe) && nfe->isCopy() && nfe->copyOf() == fe) {
-                syncFe(nfe);
-                nfe->resetSynced();
-            }
-        }
-    }
-
-    FPRegisterID fpreg = allocFPReg();
-
-    if (backing->isType(JSVAL_TYPE_INT32)) {
-        RegisterID data = tempRegForData(backing);
-        masm.convertInt32ToDouble(data, fpreg);
-    } else {
-        syncFe(backing);
-        masm.moveInt32OrDouble(addressOf(backing), fpreg);
-    }
-
-    if (fe == backing)
-        forgetAllRegs(fe);
-    fe->resetUnsynced();
-    fe->setType(JSVAL_TYPE_DOUBLE);
-    fe->data.setFPRegister(fpreg);
-    regstate(fpreg).associate(fe, RematInfo::DATA);
-
-    fe->data.unsync();
-    fe->type.unsync();
-}
-
-void
-FrameState::ensureInteger(FrameEntry *fe)
-{
-    /*
-     * This method is used to revert a previous ensureDouble call made for a
-     * branch. The entry is definitely a double, and has had no copies made.
-     */
-
-    if (fe->isConstant()) {
-        Value newValue = Int32Value(int32_t(fe->getValue().toDouble()));
-        fe->setConstant(newValue);
-        return;
-    }
-
-    JS_ASSERT(!fe->isCopy() && !fe->isCopied());
-    JS_ASSERT_IF(fe->isTypeKnown(), fe->isType(JSVAL_TYPE_DOUBLE));
-
-    if (!fe->isType(JSVAL_TYPE_DOUBLE)) {
-        /*
-         * A normal register may have been allocated after calling
-         * syncAndForgetEverything.
-         */
-        if (fe->data.inRegister()) {
-            syncFe(fe);
-            forgetReg(fe->data.reg());
-            fe->data.setMemory();
-        }
-        learnType(fe, JSVAL_TYPE_DOUBLE, false);
-    }
-
-    RegisterID reg = allocReg();
-    FPRegisterID fpreg = tempFPRegForData(fe);
-    Jump j = masm.branchTruncateDoubleToInt32(fpreg, reg);
-    j.linkTo(masm.label(), &masm);
-
-    forgetAllRegs(fe);
-    fe->resetUnsynced();
-    fe->setType(JSVAL_TYPE_INT32);
-    fe->data.setRegister(reg);
-    regstate(reg).associate(fe, RematInfo::DATA);
-
-    fe->data.unsync();
-    fe->type.unsync();
-}
-
-void
-FrameState::ensureInMemoryDoubles(Assembler &masm)
-{
-    JS_ASSERT(!a->parent);
-    for (uint32_t i = 0; i < tracker.nentries; i++) {
-        FrameEntry *fe = tracker[i];
-        if (!deadEntry(fe) && fe->isType(JSVAL_TYPE_DOUBLE) &&
-            !fe->isCopy() && !fe->isConstant()) {
-            masm.ensureInMemoryDouble(addressOf(fe));
-        }
-    }
-}
-
-void
-FrameState::pushCopyOf(FrameEntry *backing)
-{
-    JS_ASSERT(backing->isTracked());
-    FrameEntry *fe = rawPush();
-    fe->resetUnsynced();
-    if (backing->isConstant()) {
-        fe->setConstant(backing->getValue());
-    } else {
-        if (backing->isCopy())
-            backing = backing->copyOf();
-        fe->setCopyOf(backing);
-
-        /* Maintain tracker ordering guarantees for copies. */
-        JS_ASSERT(backing->isCopied());
-        if (fe->trackerIndex() < backing->trackerIndex())
-            swapInTracker(fe, backing);
-    }
-}
-
-FrameEntry *
-FrameState::walkTrackerForUncopy(FrameEntry *original)
-{
-    uint32_t firstCopy = InvalidIndex;
-    FrameEntry *bestFe = NULL;
-    uint32_t ncopies = 0;
-    for (uint32_t i = original->trackerIndex() + 1; i < tracker.nentries; i++) {
-        FrameEntry *fe = tracker[i];
-        if (deadEntry(fe))
-            continue;
-        if (fe->isCopy() && fe->copyOf() == original) {
-            if (firstCopy == InvalidIndex) {
-                firstCopy = i;
-                bestFe = fe;
-            } else if (fe < bestFe) {
-                bestFe = fe;
-            }
-            ncopies++;
-        }
-    }
-
-    if (!ncopies) {
-        JS_ASSERT(firstCopy == InvalidIndex);
-        JS_ASSERT(!bestFe);
-        return NULL;
-    }
-
-    JS_ASSERT(firstCopy != InvalidIndex);
-    JS_ASSERT(bestFe);
-    JS_ASSERT_IF(!isTemporary(original), bestFe > original);
-
-    /* Mark all extra copies as copies of the new backing index. */
-    bestFe->setCopyOf(NULL);
-    if (ncopies > 1) {
-        for (uint32_t i = firstCopy; i < tracker.nentries; i++) {
-            FrameEntry *other = tracker[i];
-            if (deadEntry(other) || other == bestFe)
-                continue;
-
-            /* The original must be tracked before copies. */
-            JS_ASSERT(other != original);
-
-            if (!other->isCopy() || other->copyOf() != original)
-                continue;
-
-            other->setCopyOf(bestFe);
-
-            /*
-             * This is safe even though we're mutating during iteration. There
-             * are two cases. The first is that both indexes are <= i, and :.
-             * will never be observed. The other case is we're placing the
-             * other FE such that it will be observed later. Luckily, copyOf()
-             * will return != original, so nothing will happen.
-             */
-            if (other->trackerIndex() < bestFe->trackerIndex())
-                swapInTracker(bestFe, other);
-        }
-    }
-
-    return bestFe;
-}
-
-FrameEntry *
-FrameState::walkFrameForUncopy(FrameEntry *original)
-{
-    FrameEntry *bestFe = NULL;
-    uint32_t ncopies = 0;
-
-    /* It's only necessary to visit as many FEs are being tracked. */
-    uint32_t maxvisits = tracker.nentries;
-
-    for (FrameEntry *fe = original + 1; fe < a->sp && maxvisits; fe++) {
-        if (!fe->isTracked())
-            continue;
-
-        maxvisits--;
-
-        if (fe->isCopy() && fe->copyOf() == original) {
-            if (!bestFe) {
-                bestFe = fe;
-                bestFe->setCopyOf(NULL);
-            } else {
-                fe->setCopyOf(bestFe);
-                if (fe->trackerIndex() < bestFe->trackerIndex())
-                    swapInTracker(bestFe, fe);
-            }
-            ncopies++;
-        }
-    }
-
-    return bestFe;
-}
-
-FrameEntry *
-FrameState::uncopy(FrameEntry *original)
-{
-    JS_ASSERT(original->isCopied());
-
-    /*
-     * Copies have three critical invariants:
-     *  1) The backing store precedes all copies in the tracker.
-     *  2) The backing store precedes all copies in the FrameState.
-     *  3) The backing store of a copy cannot be popped from the stack
-     *     while the copy is still live.
-     *
-     * Maintaining this invariant iteratively is kind of hard, so we choose
-     * the "lowest" copy in the frame up-front.
-     *
-     * For example, if the stack is:
-     *    [A, B, C, D]
-     * And the tracker has:
-     *    [A, D, C, B]
-     *
-     * If B, C, and D are copies of A - we will walk the tracker to the end
-     * and select B, not D (see bug 583684).
-     *
-     * Note: |tracker.nentries <= (nslots + nargs)|. However, this walk is
-     * sub-optimal if |tracker.nentries - original->trackerIndex() > sp - original|.
-     * With large scripts this may be a problem worth investigating. Note that
-     * the tracker is walked twice, so we multiply by 2 for pessimism.
-     */
-    FrameEntry *fe;
-    if ((tracker.nentries - original->trackerIndex()) * 2 > uint32_t(a->sp - original))
-        fe = walkFrameForUncopy(original);
-    else
-        fe = walkTrackerForUncopy(original);
-    JS_ASSERT(fe);
-
-    /*
-     * Switch the new backing store to the old backing store. During
-     * this process we also necessarily make sure the copy can be
-     * synced.
-     */
-    if (!original->isTypeKnown()) {
-        /*
-         * If the copy is unsynced, and the original is in memory,
-         * give the original a register. We do this below too; it's
-         * okay if it's spilled.
-         */
-        if (original->type.inMemory() && !fe->type.synced())
-            tempRegForType(original);
-        fe->type.inherit(original->type);
-        if (fe->type.inRegister())
-            regstate(fe->type.reg()).reassociate(fe);
-    } else {
-        fe->setType(original->getKnownType());
-    }
-    if (original->isType(JSVAL_TYPE_DOUBLE)) {
-        if (original->data.inMemory() && !fe->data.synced())
-            tempFPRegForData(original);
-        fe->data.inherit(original->data);
-        if (fe->data.inFPRegister())
-            regstate(fe->data.fpreg()).reassociate(fe);
-    } else {
-        if (fe->type.inRegister())
-            pinReg(fe->type.reg());
-        if (original->data.inMemory() && !fe->data.synced())
-            tempRegForData(original);
-        if (fe->type.inRegister())
-            unpinReg(fe->type.reg());
-        fe->data.inherit(original->data);
-        if (fe->data.inRegister())
-            regstate(fe->data.reg()).reassociate(fe);
-    }
-
-    return fe;
-}
-
-bool
-FrameState::hasOnlyCopy(FrameEntry *backing, FrameEntry *fe)
-{
-    JS_ASSERT(backing->isCopied() && fe->copyOf() == backing);
-
-    for (uint32_t i = backing->trackerIndex() + 1; i < tracker.nentries; i++) {
-        FrameEntry *nfe = tracker[i];
-        if (nfe != fe && !deadEntry(nfe) && nfe->isCopy() && nfe->copyOf() == backing)
-            return false;
-    }
-
-    return true;
-}
-
-void
-FrameState::separateBinaryEntries(FrameEntry *lhs, FrameEntry *rhs)
-{
-    JS_ASSERT(lhs == a->sp - 2 && rhs == a->sp - 1);
-    if (rhs->isCopy() && rhs->copyOf() == lhs) {
-        syncAndForgetFe(rhs);
-        syncAndForgetFe(lhs);
-        uncopy(lhs);
-    }
-}
-
-void
-FrameState::storeLocal(uint32_t n, bool popGuaranteed)
-{
-    FrameEntry *local = getLocal(n);
-
-    if (a->analysis->slotEscapes(entrySlot(local))) {
-        JS_ASSERT(local->data.inMemory());
-        storeTo(peek(-1), addressOf(local), popGuaranteed);
-        return;
-    }
-
-    storeTop(local);
-
-    if (loop)
-        local->lastLoop = loop->headOffset();
-
-    if (inTryBlock)
-        syncFe(local);
-}
-
-void
-FrameState::storeArg(uint32_t n, bool popGuaranteed)
-{
-    // Note that args are always immediately synced, because they can be
-    // aliased (but not written to) via f.arguments.
-    FrameEntry *arg = getArg(n);
-
-    if (a->analysis->slotEscapes(entrySlot(arg))) {
-        JS_ASSERT(arg->data.inMemory());
-        storeTo(peek(-1), addressOf(arg), popGuaranteed);
-        return;
-    }
-
-    storeTop(arg);
-
-    if (loop)
-        arg->lastLoop = loop->headOffset();
-
-    syncFe(arg);
-}
-
-void
-FrameState::forgetEntry(FrameEntry *fe)
-{
-    if (fe->isCopied()) {
-        uncopy(fe);
-        fe->resetUnsynced();
-    } else {
-        forgetAllRegs(fe);
-    }
-
-    extraArray[fe - entries].reset();
-}
-
-void
-FrameState::storeTop(FrameEntry *target)
-{
-    JS_ASSERT(!isTemporary(target));
-
-    /* Detect something like (x = x) which is a no-op. */
-    FrameEntry *top = peek(-1);
-    if (top->isCopy() && top->copyOf() == target) {
-        JS_ASSERT(target->isCopied());
-        return;
-    }
-
-    /*
-     * If this is overwriting a known non-double type with another value of the
-     * same type, then make sure we keep the type marked as synced after doing
-     * the copy.
-     */
-    bool wasSynced = target->type.synced();
-    JSValueType oldType = target->isTypeKnown() ? target->getKnownType() : JSVAL_TYPE_UNKNOWN;
-    bool trySyncType = wasSynced && oldType != JSVAL_TYPE_UNKNOWN && oldType != JSVAL_TYPE_DOUBLE;
-
-    /* Completely invalidate the local variable. */
-    forgetEntry(target);
-    target->resetUnsynced();
-
-    /* Constants are easy to propagate. */
-    if (top->isConstant()) {
-        target->clear();
-        target->setConstant(top->getValue());
-        if (trySyncType && target->isType(oldType))
-            target->type.sync();
-        return;
-    }
-
-    /*
-     * When dealing with copies, there are three important invariants:
-     *
-     * 1) The backing store precedes all copies in the tracker.
-     * 2) The backing store precedes all copies in the FrameState.
-     * 2) The backing store of a local is never a stack slot, UNLESS the local
-     *    variable itself is a stack slot (blocks) that precedes the stack
-     *    slot.
-     *
-     * If the top is a copy, and the second condition holds true, the local
-     * can be rewritten as a copy of the original backing slot. If the first
-     * condition does not hold, force it to hold by swapping in-place.
-     */
-    FrameEntry *backing = top;
-    if (top->isCopy()) {
-        backing = top->copyOf();
-        JS_ASSERT(backing->trackerIndex() < top->trackerIndex());
-
-        if (backing < target || isTemporary(backing)) {
-            /* local.idx < backing.idx means local cannot be a copy yet */
-            if (target->trackerIndex() < backing->trackerIndex())
-                swapInTracker(backing, target);
-            target->setCopyOf(backing);
-            if (trySyncType && target->isType(oldType))
-                target->type.sync();
-            return;
-        }
-
-        /*
-         * If control flow lands here, then there was a bytecode sequence like
-         *
-         *  ENTERBLOCK 2
-         *  GETLOCAL 1
-         *  SETLOCAL 0
-         *
-         * The problem is slot N can't be backed by M if M could be popped
-         * before N. We want a guarantee that when we pop M, even if it was
-         * copied, it has no outstanding copies.
-         *
-         * Because of |let| expressions, it's kind of hard to really know
-         * whether a region on the stack will be popped all at once. Bleh!
-         *
-         * This should be rare except in browser code (and maybe even then),
-         * but even so there's a quick workaround. We take all copies of the
-         * backing fe, and redirect them to be copies of the destination.
-         */
-        for (uint32_t i = backing->trackerIndex() + 1; i < tracker.nentries; i++) {
-            FrameEntry *fe = tracker[i];
-            if (deadEntry(fe))
-                continue;
-            if (fe->isCopy() && fe->copyOf() == backing)
-                fe->setCopyOf(target);
-        }
-    }
-
-    /*
-     * This is valid from the top->isCopy() path because we're guaranteed a
-     * consistent ordering - all copies of |backing| are tracked after
-     * |backing|. Transitively, only one swap is needed.
-     */
-    if (backing->trackerIndex() < target->trackerIndex())
-        swapInTracker(backing, target);
-
-    if (backing->isType(JSVAL_TYPE_DOUBLE)) {
-        FPRegisterID fpreg = tempFPRegForData(backing);
-        target->setType(JSVAL_TYPE_DOUBLE);
-        target->data.setFPRegister(fpreg);
-        regstate(fpreg).reassociate(target);
-    } else {
-        /*
-         * Move the backing store down - we spill registers here, but we could be
-         * smarter and re-use the type reg. If we need registers for both the type
-         * and data in the backing, make sure we keep the other components pinned.
-         * There is nothing else to keep us from evicting the backing's registers.
-         */
-        if (backing->type.inRegister())
-            pinReg(backing->type.reg());
-        RegisterID reg = tempRegForData(backing);
-        if (backing->type.inRegister())
-            unpinReg(backing->type.reg());
-        target->data.setRegister(reg);
-        regstate(reg).reassociate(target);
-
-        if (backing->isTypeKnown()) {
-            target->setType(backing->getKnownType());
-        } else {
-            pinReg(reg);
-            RegisterID typeReg = tempRegForType(backing);
-            unpinReg(reg);
-            target->type.setRegister(typeReg);
-            regstate(typeReg).reassociate(target);
-        }
-    }
-
-    backing->setCopyOf(target);
-    JS_ASSERT(top->copyOf() == target);
-
-    if (trySyncType && target->isType(oldType))
-        target->type.sync();
-}
-
-void
-FrameState::shimmy(uint32_t n)
-{
-    JS_ASSERT(a->sp - n >= a->spBase);
-    int32_t depth = 0 - int32_t(n);
-    storeTop(peek(depth - 1));
-    popn(n);
-}
-
-void
-FrameState::shift(int32_t n)
-{
-    JS_ASSERT(n < 0);
-    JS_ASSERT(a->sp + n - 1 >= a->spBase);
-    storeTop(peek(n - 1));
-    pop();
-}
-
-void
-FrameState::swap()
-{
-    // A B
-
-    dupAt(-2);
-    // A B A
-
-    dupAt(-2);
-    // A B A B
-
-    shift(-3);
-    // B B A
-
-    shimmy(1);
-    // B A
-}
-
-void
-FrameState::forgetKnownDouble(FrameEntry *fe)
-{
-    /*
-     * Forget all information indicating fe is a double, so we can use GPRs for its
-     * contents.  We currently need to do this in order to use the entry in MICs/PICs
-     * or to construct its ValueRemat. :FIXME: this needs to get fixed.
-     */
-    JS_ASSERT(!fe->isConstant() && fe->isType(JSVAL_TYPE_DOUBLE));
-
-    RegisterID typeReg = allocReg();
-    RegisterID dataReg = allocReg();
-
-    /* Copy into a different FP register, as breakDouble can modify fpreg. */
-    FPRegisterID fpreg = allocFPReg();
-    masm.moveDouble(tempFPRegForData(fe), fpreg);
-    masm.breakDouble(fpreg, typeReg, dataReg);
-
-    forgetAllRegs(fe);
-    fe->resetUnsynced();
-    fe->clear();
-
-    regstate(typeReg).associate(fe, RematInfo::TYPE);
-    regstate(dataReg).associate(fe, RematInfo::DATA);
-    fe->type.setRegister(typeReg);
-    fe->data.setRegister(dataReg);
-    freeReg(fpreg);
-}
-
-void
-FrameState::pinEntry(FrameEntry *fe, ValueRemat &vr, bool breakDouble)
-{
-    if (breakDouble && !fe->isConstant() && fe->isType(JSVAL_TYPE_DOUBLE))
-        forgetKnownDouble(fe);
-
-    if (fe->isConstant()) {
-        vr = ValueRemat::FromConstant(fe->getValue());
-    } else if (fe->isType(JSVAL_TYPE_DOUBLE)) {
-        FPRegisterID fpreg = tempFPRegForData(fe);
-        pinReg(fpreg);
-        vr = ValueRemat::FromFPRegister(fpreg);
-    } else {
-        // Pin the type register so it can't spill.
-        MaybeRegisterID maybePinnedType = maybePinType(fe);
-
-        // Get and pin the data register.
-        RegisterID dataReg = tempRegForData(fe);
-        pinReg(dataReg);
-
-        if (fe->isTypeKnown()) {
-            vr = ValueRemat::FromKnownType(fe->getKnownType(), dataReg);
-        } else {
-            // The type might not be loaded yet, so unpin for simplicity.
-            maybeUnpinReg(maybePinnedType);
-
-            vr = ValueRemat::FromRegisters(tempRegForType(fe), dataReg);
-            pinReg(vr.typeReg());
-        }
-    }
-
-    // Set these bits last, since allocation could have caused a sync.
-    vr.isDataSynced = fe->data.synced();
-    vr.isTypeSynced = fe->type.synced();
-}
-
-void
-FrameState::unpinEntry(const ValueRemat &vr)
-{
-    if (vr.isFPRegister()) {
-        unpinReg(vr.fpReg());
-    } else if (!vr.isConstant()) {
-        if (!vr.isTypeKnown())
-            unpinReg(vr.typeReg());
-        unpinReg(vr.dataReg());
-    }
-}
-
-void
-FrameState::ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr)
-{
-#if defined JS_PUNBOX64
-    if (!vr.isDataSynced || !vr.isTypeSynced)
-        masm.storeValue(vr, addressOf(fe));
-#elif defined JS_NUNBOX32
-    if (vr.isConstant() || vr.isFPRegister()) {
-        if (!vr.isDataSynced || !vr.isTypeSynced)
-            masm.storeValue(vr.value(), addressOf(fe));
-    } else {
-        if (!vr.isDataSynced)
-            masm.storePayload(vr.dataReg(), addressOf(fe));
-        if (!vr.isTypeSynced) {
-            if (vr.isTypeKnown())
-                masm.storeTypeTag(ImmType(vr.knownType()), addressOf(fe));
-            else
-                masm.storeTypeTag(vr.typeReg(), addressOf(fe));
-        }
-    }
-#endif
-}
-
-static inline bool
-AllocHelper(RematInfo &info, MaybeRegisterID &maybe)
-{
-    if (info.inRegister()) {
-        maybe = info.reg();
-        return true;
-    }
-    return false;
-}
-
-void
-FrameState::allocForSameBinary(FrameEntry *fe, JSOp op, BinaryAlloc &alloc)
-{
-    alloc.rhsNeedsRemat = false;
-
-    if (!fe->isTypeKnown()) {
-        alloc.lhsType = tempRegForType(fe);
-        pinReg(alloc.lhsType.reg());
-    }
-
-    alloc.lhsData = tempRegForData(fe);
-
-    if (!freeRegs.empty(Registers::AvailRegs)) {
-        alloc.result = allocReg();
-        masm.move(alloc.lhsData.reg(), alloc.result);
-        alloc.lhsNeedsRemat = false;
-    } else {
-        alloc.result = alloc.lhsData.reg();
-        takeReg(alloc.result);
-        alloc.lhsNeedsRemat = true;
-    }
-
-    if (alloc.lhsType.isSet())
-        unpinReg(alloc.lhsType.reg());
-
-    alloc.lhsFP = alloc.rhsFP = allocFPReg();
-}
-
-void
-FrameState::ensureFullRegs(FrameEntry *fe, MaybeRegisterID *type, MaybeRegisterID *data)
-{
-    fe = fe->isCopy() ? fe->copyOf() : fe;
-
-    JS_ASSERT(!data->isSet() && !type->isSet());
-    if (!fe->type.inMemory()) {
-        if (fe->type.inRegister())
-            *type = fe->type.reg();
-        if (fe->data.isConstant())
-            return;
-        if (fe->data.inRegister()) {
-            *data = fe->data.reg();
-            return;
-        }
-        if (fe->type.inRegister())
-            pinReg(fe->type.reg());
-        *data = tempRegForData(fe);
-        if (fe->type.inRegister())
-            unpinReg(fe->type.reg());
-    } else if (!fe->data.inMemory()) {
-        if (fe->data.inRegister())
-            *data = fe->data.reg();
-        if (fe->type.isConstant())
-            return;
-        if (fe->type.inRegister()) {
-            *type = fe->type.reg();
-            return;
-        }
-        if (fe->data.inRegister())
-            pinReg(fe->data.reg());
-        *type = tempRegForType(fe);
-        if (fe->data.inRegister())
-            unpinReg(fe->data.reg());
-    } else {
-        *data = tempRegForData(fe);
-        pinReg(data->reg());
-        *type = tempRegForType(fe);
-        unpinReg(data->reg());
-    }
-}
-
-inline bool
-FrameState::binaryEntryLive(FrameEntry *fe) const
-{
-    /*
-     * Compute whether fe is live after the binary operation performed at the current
-     * bytecode. This is similar to variableLive except that it returns false for the
-     * top two stack entries.
-     */
-    JS_ASSERT(cx->typeInferenceEnabled());
-
-    if (deadEntry(fe, 2))
-        return false;
-
-    JS_ASSERT(fe != a->callee_);
-
-    /* Arguments are always treated as live within inline frames, see bestEvictReg. */
-    if (a->parent && fe < a->locals)
-        return true;
-
-    /* Caller must check that no copies are invalidated by rewriting the entry. */
-    return fe >= a->spBase || variableLive(fe, a->PC);
-}
-
-void
-FrameState::allocForBinary(FrameEntry *lhs, FrameEntry *rhs, JSOp op, BinaryAlloc &alloc,
-                           bool needsResult)
-{
-    FrameEntry *backingLeft = lhs;
-    FrameEntry *backingRight = rhs;
-
-    if (backingLeft->isCopy())
-        backingLeft = backingLeft->copyOf();
-    if (backingRight->isCopy())
-        backingRight = backingRight->copyOf();
-
-    /*
-     * For each remat piece of both FEs, if a register is assigned, get it now
-     * and pin it. This is safe - constants and known types will be avoided.
-     */
-    if (AllocHelper(backingLeft->type, alloc.lhsType))
-        pinReg(alloc.lhsType.reg());
-    if (AllocHelper(backingLeft->data, alloc.lhsData))
-        pinReg(alloc.lhsData.reg());
-    if (AllocHelper(backingRight->type, alloc.rhsType))
-        pinReg(alloc.rhsType.reg());
-    if (AllocHelper(backingRight->data, alloc.rhsData))
-        pinReg(alloc.rhsData.reg());
-
-    /* For each type without a register, give it a register if needed. */
-    if (!alloc.lhsType.isSet() && backingLeft->type.inMemory()) {
-        alloc.lhsType = tempRegForType(lhs);
-        pinReg(alloc.lhsType.reg());
-    }
-    if (!alloc.rhsType.isSet() && backingRight->type.inMemory()) {
-        alloc.rhsType = tempRegForType(rhs);
-        pinReg(alloc.rhsType.reg());
-    }
-
-    /*
-     * Allocate floating point registers.  These are temporaries with no pre-existing data;
-     * floating point registers are only allocated for known doubles, and BinaryAlloc is not
-     * used for such operations.
-     */
-    JS_ASSERT(!backingLeft->isType(JSVAL_TYPE_DOUBLE));
-    JS_ASSERT(!backingRight->isType(JSVAL_TYPE_DOUBLE));
-    alloc.lhsFP = allocFPReg();
-    alloc.rhsFP = allocFPReg();
-
-    bool commu;
-    switch (op) {
-      case JSOP_EQ:
-      case JSOP_GT:
-      case JSOP_GE:
-      case JSOP_LT:
-      case JSOP_LE:
-        /* fall through */
-      case JSOP_ADD:
-      case JSOP_MUL:
-      case JSOP_SUB:
-        commu = true;
-        break;
-
-      case JSOP_DIV:
-        commu = false;
-        break;
-
-      default:
-        JS_NOT_REACHED("unknown op");
-        return;
-    }
-
-    /*
-     * Allocate data registers. If the op is not commutative, the LHS
-     * _must_ be in a register.
-     */
-    JS_ASSERT_IF(lhs->isConstant(), !rhs->isConstant());
-    JS_ASSERT_IF(rhs->isConstant(), !lhs->isConstant());
-
-    if (!alloc.lhsData.isSet()) {
-        if (backingLeft->data.inMemory()) {
-            alloc.lhsData = tempRegForData(lhs);
-            pinReg(alloc.lhsData.reg());
-        } else if (!commu) {
-            JS_ASSERT(lhs->isConstant());
-            alloc.lhsData = allocReg();
-            alloc.extraFree = alloc.lhsData;
-            masm.move(Imm32(lhs->getValue().toInt32()), alloc.lhsData.reg());
-        }
-    }
-    if (!alloc.rhsData.isSet() && backingRight->data.inMemory()) {
-        alloc.rhsData = tempRegForData(rhs);
-        pinReg(alloc.rhsData.reg());
-    }
-
-    alloc.lhsNeedsRemat = false;
-    alloc.rhsNeedsRemat = false;
-    alloc.resultHasRhs = false;
-    alloc.undoResult = false;
-
-    if (!needsResult)
-        goto skip;
-
-    /*
-     * Now a result register is needed. It must contain a mutable copy of the
-     * LHS. For commutative operations, we can opt to use the RHS instead. At
-     * this point, if for some reason either must be in a register, that has
-     * already been guaranteed at this point.
-     */
-
-    /*
-     * Try to reuse operand registers without syncing for ADD and constant SUB,
-     * so long as the backing for the operand is dead.
-     */
-    if (cx->typeInferenceEnabled() &&
-        backingLeft->data.inRegister() && !binaryEntryLive(backingLeft) &&
-        (op == JSOP_ADD || (op == JSOP_SUB && backingRight->isConstant())) &&
-        (lhs == backingLeft || hasOnlyCopy(backingLeft, lhs))) {
-        alloc.result = backingLeft->data.reg();
-        alloc.undoResult = true;
-        alloc.resultHasRhs = false;
-        goto skip;
-    }
-
-    if (cx->typeInferenceEnabled())
-        evictDeadEntries(true);
-
-    if (!freeRegs.empty(Registers::AvailRegs)) {
-        /* Free reg - just grab it. */
-        alloc.result = allocReg();
-        if (!alloc.lhsData.isSet()) {
-            JS_ASSERT(alloc.rhsData.isSet());
-            JS_ASSERT(commu);
-            masm.move(alloc.rhsData.reg(), alloc.result);
-            alloc.resultHasRhs = true;
-        } else {
-            masm.move(alloc.lhsData.reg(), alloc.result);
-            alloc.resultHasRhs = false;
-        }
-    } else if (cx->typeInferenceEnabled()) {
-        /* No free regs. Evict a register or reuse one of the operands. */
-        bool leftInReg = backingLeft->data.inRegister();
-        bool rightInReg = backingRight->data.inRegister();
-
-        /* If the LHS/RHS types are in registers, don't use them for the result. */
-        uint32_t mask = Registers::AvailRegs;
-        if (backingLeft->type.inRegister())
-            mask &= ~Registers::maskReg(backingLeft->type.reg());
-        if (backingRight->type.inRegister())
-            mask &= ~Registers::maskReg(backingRight->type.reg());
-
-        RegisterID result = bestEvictReg(mask, true).reg();
-        if (!commu && rightInReg && backingRight->data.reg() == result) {
-            /* Can't put the result in the RHS for non-commutative operations. */
-            alloc.result = allocReg();
-            masm.move(alloc.lhsData.reg(), alloc.result);
-        } else {
-            alloc.result = result;
-            if (leftInReg && result == backingLeft->data.reg()) {
-                alloc.lhsNeedsRemat = true;
-                unpinReg(result);
-                takeReg(result);
-            } else if (rightInReg && result == backingRight->data.reg()) {
-                alloc.rhsNeedsRemat = true;
-                alloc.resultHasRhs = true;
-                unpinReg(result);
-                takeReg(result);
-            } else {
-                JS_ASSERT(!regstate(result).isPinned());
-                takeReg(result);
-                if (leftInReg) {
-                    masm.move(alloc.lhsData.reg(), result);
-                } else {
-                    masm.move(alloc.rhsData.reg(), result);
-                    alloc.resultHasRhs = true;
-                }
-            }
-        }
-    } else {
-        /*
-         * No free regs. Find a good candidate to re-use. Best candidates don't
-         * require syncs on the inline path.
-         */
-        bool leftInReg = backingLeft->data.inRegister();
-        bool rightInReg = backingRight->data.inRegister();
-        bool leftSynced = backingLeft->data.synced();
-        bool rightSynced = backingRight->data.synced();
-        if (!commu || (leftInReg && (leftSynced || (!rightInReg || !rightSynced)))) {
-            JS_ASSERT(backingLeft->data.inRegister() || !commu);
-            JS_ASSERT_IF(backingLeft->data.inRegister(),
-                         backingLeft->data.reg() == alloc.lhsData.reg());
-            if (backingLeft->data.inRegister()) {
-                alloc.result = backingLeft->data.reg();
-                unpinReg(alloc.result);
-                takeReg(alloc.result);
-                alloc.lhsNeedsRemat = true;
-            } else {
-                /* For now, just spill... */
-                alloc.result = allocReg();
-                masm.move(alloc.lhsData.reg(), alloc.result);
-            }
-            alloc.resultHasRhs = false;
-        } else {
-            JS_ASSERT(commu);
-            JS_ASSERT(!leftInReg || (rightInReg && rightSynced));
-            alloc.result = backingRight->data.reg();
-            unpinReg(alloc.result);
-            takeReg(alloc.result);
-            alloc.resultHasRhs = true;
-            alloc.rhsNeedsRemat = true;
-        }
-    }
-
-  skip:
-    /* Unpin everything that was pinned. */
-    if (backingLeft->type.inRegister())
-        unpinReg(backingLeft->type.reg());
-    if (backingRight->type.inRegister())
-        unpinReg(backingRight->type.reg());
-    if (backingLeft->data.inRegister())
-        unpinReg(backingLeft->data.reg());
-    if (backingRight->data.inRegister())
-        unpinReg(backingRight->data.reg());
-}
-
-void
-FrameState::rematBinary(FrameEntry *lhs, FrameEntry *rhs, const BinaryAlloc &alloc, Assembler &masm)
-{
-    if (alloc.rhsNeedsRemat)
-        masm.loadPayload(addressForDataRemat(rhs), alloc.rhsData.reg());
-    if (alloc.lhsNeedsRemat)
-        masm.loadPayload(addressForDataRemat(lhs), alloc.lhsData.reg());
-}
-
-MaybeRegisterID
-FrameState::maybePinData(FrameEntry *fe)
-{
-    fe = fe->isCopy() ? fe->copyOf() : fe;
-    if (fe->data.inRegister()) {
-        pinReg(fe->data.reg());
-        return fe->data.reg();
-    }
-    return MaybeRegisterID();
-}
-
-MaybeRegisterID
-FrameState::maybePinType(FrameEntry *fe)
-{
-    fe = fe->isCopy() ? fe->copyOf() : fe;
-    if (fe->type.inRegister()) {
-        pinReg(fe->type.reg());
-        return fe->type.reg();
-    }
-    return MaybeRegisterID();
-}
-
-void
-FrameState::maybeUnpinReg(MaybeRegisterID reg)
-{
-    if (reg.isSet())
-        unpinReg(reg.reg());
-}
-
-uint32_t
-FrameState::allocTemporary()
-{
-    if (temporariesTop == temporaries + TEMPORARY_LIMIT)
-        return UINT32_MAX;
-    FrameEntry *fe = temporariesTop++;
-    fe->lastLoop = 0;
-    fe->temporary = true;
-    return fe - temporaries;
-}
-
-void
-FrameState::clearTemporaries()
-{
-    JS_ASSERT(!a->parent);
-
-    for (FrameEntry *fe = temporaries; fe < temporariesTop; fe++) {
-        if (!fe->isTracked())
-            continue;
-        if (fe->isCopied())
-            uncopy(fe);
-        forgetAllRegs(fe);
-        fe->resetSynced();
-    }
-
-    temporariesTop = temporaries;
-}
-
-Vector<TemporaryCopy> *
-FrameState::getTemporaryCopies(Uses uses)
-{
-    /* :XXX: handle OOM */
-    Vector<TemporaryCopy> *res = NULL;
-
-    for (FrameEntry *fe = temporaries; fe < temporariesTop; fe++) {
-        if (!fe->isTracked())
-            continue;
-        if (fe->isCopied()) {
-            for (uint32_t i = fe->trackerIndex() + 1; i < tracker.nentries; i++) {
-                FrameEntry *nfe = tracker[i];
-                if (!deadEntry(nfe, uses.nuses) && nfe->isCopy() && nfe->copyOf() == fe) {
-                    if (!res)
-                        res = js_new< Vector<TemporaryCopy> >(cx);
-                    res->append(TemporaryCopy(addressOf(nfe), addressOf(fe)));
-                }
-            }
-        }
-    }
-
-    return res;
-}
deleted file mode 100644
--- a/js/src/methodjit/FrameState.h
+++ /dev/null
@@ -1,1223 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_framestate_h__ && defined JS_METHODJIT
-#define jsjaeger_framestate_h__
-
-#include "mozilla/PodOperations.h"
-
-#include "jsanalyze.h"
-#include "jsapi.h"
-#include "methodjit/MachineRegs.h"
-#include "methodjit/FrameEntry.h"
-#include "CodeGenIncludes.h"
-#include "ImmutableSync.h"
-#include "jscompartment.h"
-
-namespace js {
-namespace mjit {
-
-struct Uses {
-    explicit Uses(uint32_t nuses)
-      : nuses(nuses)
-    { }
-    uint32_t nuses;
-};
-
-struct Changes {
-    explicit Changes(uint32_t nchanges)
-      : nchanges(nchanges)
-    { }
-    uint32_t nchanges;
-};
-
-struct TemporaryCopy {
-    TemporaryCopy(JSC::MacroAssembler::Address copy, JSC::MacroAssembler::Address temporary)
-        : copy(copy), temporary(temporary)
-    {}
-    JSC::MacroAssembler::Address copy;
-    JSC::MacroAssembler::Address temporary;
-};
-
-class StubCompiler;
-class LoopState;
-
-/*
- * The FrameState keeps track of values on the frame during compilation.
- * The compiler can query FrameState for information about arguments, locals,
- * and stack slots (all hereby referred to as "slots"). Slot information can
- * be requested in constant time. For each slot there is a FrameEntry *. If
- * this is non-NULL, it contains valid information and can be returned.
- *
- * The register allocator keeps track of registers as being in one of two
- * states. These are:
- *
- * 1) Unowned. Some code in the compiler is working on a register.
- * 2) Owned. The FrameState owns the register, and may spill it at any time.
- *
- * ------------------ Implementation Details ------------------
- *
- * Observations:
- *
- * 1) Every time we need a slow call, we must sync everything.
- * 2) Efficient side-exits need to quickly deltize state snapshots.
- * 3) Syncing is limited to constants and registers.
- * 4) Entries are not forgotten unless they are entirely in memory and are
- *    not constants or copies.
- *
- * With these in mind, we want to make sure that the compiler doesn't degrade
- * badly as functions get larger.
- *
- * If the FE is NULL, a new one is allocated, initialized, and stored. They
- * are allocated from a pool such that (fe - pool) can be used to compute
- * the slot's Address.
- *
- * We keep a side vector of all tracked FrameEntry * to quickly generate
- * memory stores and clear the tracker.
- *
- * It is still possible to get really bad behavior with a very large script
- * that doesn't have branches or calls. That's okay, having this code in
- * minimizes damage and lets us introduce a hard cut-off point.
- */
-class FrameState
-{
-    friend class ImmutableSync;
-
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-    typedef JSC::MacroAssembler::Address Address;
-    typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
-    typedef JSC::MacroAssembler::Jump Jump;
-    typedef JSC::MacroAssembler::Imm32 Imm32;
-    typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-
-    static const uint32_t InvalidIndex = 0xFFFFFFFF;
-
-    struct Tracker {
-        Tracker()
-          : entries(NULL), nentries(0)
-        { }
-
-        void add(FrameEntry *fe) {
-            entries[nentries++] = fe;
-        }
-
-        void reset() {
-            nentries = 0;
-        }
-
-        FrameEntry * operator [](uint32_t n) const {
-            JS_ASSERT(n < nentries);
-            return entries[n];
-        }
-
-        FrameEntry **entries;
-        uint32_t nentries;
-    };
-
-    /*
-     * Some RegisterState invariants.
-     *
-     *  If |fe| is non-NULL, |save| is NULL.
-     *  If |save| is non-NULL, |fe| is NULL.
-     *  That is, both |fe| and |save| cannot be non-NULL.
-     *
-     *  If either |fe| or |save| is non-NULL, the register is not in freeRegs.
-     *  If both |fe| and |save| are NULL, the register is either in freeRegs,
-     *  or owned by the compiler.
-     */
-    struct RegisterState {
-        RegisterState() : fe_(NULL), save_(NULL)
-        { }
-
-        RegisterState(FrameEntry *fe, RematInfo::RematType type)
-          : fe_(fe), save_(NULL), type_(type)
-        {
-            JS_ASSERT(!save_);
-        }
-
-        bool isPinned() const {
-            assertConsistency();
-            return !!save_;
-        }
-
-        void assertConsistency() const {
-            JS_ASSERT_IF(fe_, !save_);
-            JS_ASSERT_IF(save_, !fe_);
-        }
-
-        FrameEntry *fe() const {
-            assertConsistency();
-            return fe_;
-        }
-
-        RematInfo::RematType type() const {
-            assertConsistency();
-            return type_;
-        }
-
-        FrameEntry *usedBy() const {
-            if (fe_)
-                return fe_;
-            return save_;
-        }
-
-        void associate(FrameEntry *fe, RematInfo::RematType type) {
-            JS_ASSERT(!fe_);
-            JS_ASSERT(!save_);
-
-            fe_ = fe;
-            type_ = type;
-        }
-
-        /* Change ownership. */
-        void reassociate(FrameEntry *fe) {
-            assertConsistency();
-            JS_ASSERT(fe);
-
-            fe_ = fe;
-        }
-
-        /* Unassociate this register from the FE. */
-        void forget() {
-            JS_ASSERT(fe_);
-            fe_ = NULL;
-            JS_ASSERT(!save_);
-        }
-
-        void pin() {
-            JS_ASSERT(fe_ != NULL);
-            assertConsistency();
-            save_ = fe_;
-            fe_ = NULL;
-        }
-
-        void unpin() {
-            JS_ASSERT(save_ != NULL);
-            assertConsistency();
-            fe_ = save_;
-            save_ = NULL;
-        }
-
-        void unpinUnsafe() {
-            assertConsistency();
-            save_ = NULL;
-        }
-
-      private:
-        /* FrameEntry owning this register, or NULL if not owned by a frame. */
-        FrameEntry *fe_;
-
-        /* Hack - simplifies register allocation for pairs. */
-        FrameEntry *save_;
-
-        /* Part of the FrameEntry that owns the FE. */
-        RematInfo::RematType type_;
-    };
-
-    struct ActiveFrame;
-
-    FrameState *thisFromCtor() { return this; }
-  public:
-    FrameState(JSContext *cx, Compiler &cc, Assembler &masm, StubCompiler &stubcc);
-    ~FrameState();
-
-    /*
-     * Pushes a synced slot that may have a known type.
-     */
-    inline void pushSynced(JSValueType knownType);
-
-    /*
-     * Pushes a slot that has a known, synced type and payload.
-     */
-    inline void pushSynced(JSValueType knownType, RegisterID reg);
-
-    /*
-     * Pushes a constant value.
-     */
-    inline void push(const Value &v);
-
-    /*
-     * Loads a value from memory and pushes it. If reuseBase is set, the
-     * Compiler owns the register and it should be reused if possible.
-     */
-    inline void push(Address address, JSValueType knownType, bool reuseBase = false);
-
-    /*
-     * Loads a word from memory and pushes it. If reuseBase is set, the
-     * Compiler owns the register and it should be reused if possible.
-     * It takes an address and loads/pushes an unboxed word of a given non-double type.
-     */
-    inline void pushWord(Address address, JSValueType knownType, bool reuseBase = false);
-
-    /* Loads a value from memory into a register pair, returning the register. */
-    inline void loadIntoRegisters(Address address, bool reuseBase,
-                                  RegisterID *ptypeReg, RegisterID *pdataReg);
-
-    /*
-     * Pushes a known type and allocated payload onto the operation stack.
-     */
-    inline void pushTypedPayload(JSValueType type, RegisterID payload);
-
-    /*
-     * Clobbers a stack entry with a type register and data register pair,
-     * converting to the specified known type if necessary.  If the type is
-     * JSVAL_TYPE_DOUBLE, the registers are converted into a floating point
-     * register, which is returned.
-     */
-    inline FPRegisterID storeRegs(int32_t depth, RegisterID type, RegisterID data,
-                                  JSValueType knownType);
-    inline FPRegisterID pushRegs(RegisterID type, RegisterID data, JSValueType knownType);
-
-    /*
-     * Load an address into a frame entry in registers. For handling call paths
-     * where merge() would otherwise reload from the wrong address.
-     */
-    inline void reloadEntry(Assembler &masm, Address address, FrameEntry *fe);
-
-    /* Push a value which is definitely a double. */
-    void pushDouble(FPRegisterID fpreg);
-    void pushDouble(Address address);
-
-    /* Ensure that fe is definitely a double. It must already be either int or double. */
-    void ensureDouble(FrameEntry *fe);
-
-    /* Revert an entry just converted to double by ensureDouble. */
-    void ensureInteger(FrameEntry *fe);
-
-    /*
-     * Emit code to masm ensuring that all in memory slots thought to be
-     * doubles are in fact doubles.
-     */
-    void ensureInMemoryDoubles(Assembler &masm);
-
-    /* Forget that fe is definitely a double. */
-    void forgetKnownDouble(FrameEntry *fe);
-
-    /*
-     * Pushes a known type and allocated payload onto the operation stack.
-     * This must be used when the type is known, but cannot be propagated
-     * because it is not known to be correct at a slow-path merge point.
-     *
-     * The caller guarantees that the tag was a fast-path check; that is,
-     * the value it replaces on the stack had the same tag if the fast-path
-     * was taken.
-     */
-    inline void pushUntypedPayload(JSValueType type, RegisterID payload);
-
-    /*
-     * Pushes a value onto the operation stack. This must be used when the
-     * value is known, but its type cannot be propagated because it is not
-     * known to be correct at a slow-path merge point.
-     */
-    inline void pushUntypedValue(const Value &value);
-
-    /*
-     * Pushes a number onto the operation stack.
-     *
-     * If asInt32 is set to true, then the FS will attempt to optimize
-     * syncing the type as int32_t. Only use this parameter when the fast-path
-     * guaranteed that the stack slot was guarded to be an int32_t originally.
-     *
-     * For example, checking LHS and RHS as ints guarantees that if the LHS
-     * was synced, then popping both and pushing a maybe-int32_t does not need
-     * to be synced.
-     */
-    inline void pushNumber(RegisterID payload, bool asInt32 = false);
-
-    /*
-     * Pushes an int32_t onto the operation stack. This is a specialized version
-     * of pushNumber. The caller must guarantee that (a) an int32_t is to be
-     * pushed on the inline path, and (b) if any slow path pushes a double,
-     * the slow path also stores the double to memory.
-     */
-    inline void pushInt32(RegisterID payload);
-
-    /*
-     * Pops a value off the operation stack, freeing any of its resources.
-     */
-    inline void pop();
-
-    /*
-     * Pops a number of values off the operation stack, freeing any of their
-     * resources.
-     */
-    inline void popn(uint32_t n);
-
-    /*
-     * Returns true iff lhs and rhs are copies of the same FrameEntry.
-     */
-    inline bool haveSameBacking(FrameEntry *lhs, FrameEntry *rhs);
-
-    /* If the rhs to a binary operation directly copies the lhs, uncopy the lhs. */
-    void separateBinaryEntries(FrameEntry *lhs, FrameEntry *rhs);
-
-    /*
-     * Temporarily increase and decrease local variable depth.
-     */
-    inline void enterBlock(uint32_t n);
-    inline void leaveBlock(uint32_t n);
-
-    // Pushes a copy of a slot (formal argument, local variable, or stack slot)
-    // onto the operation stack.
-    void pushLocal(uint32_t n);
-    void pushArg(uint32_t n);
-    void pushCallee();
-    void pushThis();
-    void pushCopyOf(FrameEntry *fe);
-    inline void setThis(RegisterID reg);
-    inline void syncThis();
-    inline void learnThisIsObject(bool unsync = true);
-
-    inline FrameEntry *getStack(uint32_t slot);
-    inline FrameEntry *getLocal(uint32_t slot);
-    inline FrameEntry *getArg(uint32_t slot);
-    inline FrameEntry *getSlotEntry(uint32_t slot);
-
-    /*
-     * Allocates a temporary register for a FrameEntry's type. The register
-     * can be spilled or clobbered by the frame. The compiler may only operate
-     * on it temporarily, and must take care not to clobber it.
-     */
-    inline RegisterID tempRegForType(FrameEntry *fe);
-
-    /*
-     * Try to use a register already allocated for fe's type, but if one
-     * is not already available, use fallback.
-     *
-     * Note: this does NOT change fe's type-register remat info. It's supposed
-     * to be a super lightweight/transparent operation.
-     */
-    inline RegisterID tempRegForType(FrameEntry *fe, RegisterID fallback);
-
-    inline void loadTypeIntoReg(const FrameEntry *fe, RegisterID reg);
-    inline void loadDataIntoReg(const FrameEntry *fe, RegisterID reg);
-
-    /*
-     * Returns a register that is guaranteed to contain the frame entry's
-     * data payload. The compiler may not modify the contents of the register.
-     * The compiler should NOT explicitly free it.
-     */
-    inline RegisterID tempRegForData(FrameEntry *fe);
-    inline FPRegisterID tempFPRegForData(FrameEntry *fe);
-
-    /*
-     * Same as above, except register must match identically.
-     */
-    inline AnyRegisterID tempRegInMaskForData(FrameEntry *fe, uint32_t mask);
-
-    /*
-     * Same as above, except loads into reg (using masm) if the entry does not
-     * already have a register, and does not change the frame state in doing so.
-     */
-    inline RegisterID tempRegForData(FrameEntry *fe, RegisterID reg, Assembler &masm) const;
-
-    /*
-     * For opcodes which expect to operate on an object, forget the entry if it
-     * is either a known constant or a non-object. This simplifies path
-     * generation in the Compiler for such unusual cases.
-     */
-    inline void forgetMismatchedObject(FrameEntry *fe);
-
-    /*
-     * Convert an integer to a double without applying
-     * additional Register pressure.
-     */
-    inline void convertInt32ToDouble(Assembler &masm, FrameEntry *fe,
-                                     FPRegisterID fpreg) const;
-
-    /*
-     * Dive into a FrameEntry and check whether it's in a register.
-     */
-    inline bool peekTypeInRegister(FrameEntry *fe) const;
-
-    /*
-     * Allocates a register for a FrameEntry's data, such that the compiler
-     * can modify it in-place.
-     *
-     * The caller guarantees the FrameEntry will not be observed again. This
-     * allows the compiler to avoid spilling. Only call this if the FE is
-     * going to be popped before stubcc joins/guards or the end of the current
-     * opcode.
-     */
-    RegisterID ownRegForData(FrameEntry *fe);
-
-    /*
-     * Allocates a register for a FrameEntry's type, such that the compiler
-     * can modify it in-place.
-     *
-     * The caller guarantees the FrameEntry will not be observed again. This
-     * allows the compiler to avoid spilling. Only call this if the FE is
-     * going to be popped before stubcc joins/guards or the end of the current
-     * opcode.
-     */
-    RegisterID ownRegForType(FrameEntry *fe);
-
-    /*
-     * Allocates a register for a FrameEntry's data, such that the compiler
-     * can modify it in-place. The actual FE is not modified.
-     */
-    RegisterID copyDataIntoReg(FrameEntry *fe);
-    void copyDataIntoReg(FrameEntry *fe, RegisterID exact);
-    RegisterID copyDataIntoReg(Assembler &masm, FrameEntry *fe);
-
-    /*
-     * Allocates a register for a FrameEntry's type, such that the compiler
-     * can modify it in-place. The actual FE is not modified.
-     */
-    RegisterID copyTypeIntoReg(FrameEntry *fe);
-
-    /*
-     * Returns a register that contains the constant Int32 value of the
-     * frame entry's data payload.
-     * Since the register is not bound to a FrameEntry,
-     * it MUST be explicitly freed with freeReg().
-     */
-    RegisterID copyInt32ConstantIntoReg(FrameEntry *fe);
-    RegisterID copyInt32ConstantIntoReg(Assembler &masm, FrameEntry *fe);
-
-    /*
-     * Gets registers for the components of fe where needed, pins them and
-     * stores into vr. If breakDouble is set, vr is guaranteed not to be a
-     * floating point register.
-     */
-    void pinEntry(FrameEntry *fe, ValueRemat &vr, bool breakDouble = true);
-
-    /* Unpins registers from a call to pinEntry. */
-    void unpinEntry(const ValueRemat &vr);
-
-    /* Syncs fe to memory, given its state as constructed by a call to pinEntry. */
-    void ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr);
-
-    struct BinaryAlloc {
-        MaybeRegisterID lhsType;
-        MaybeRegisterID lhsData;
-        MaybeRegisterID rhsType;
-        MaybeRegisterID rhsData;
-        MaybeRegisterID extraFree;
-        RegisterID result;  // mutable result reg
-        FPRegisterID lhsFP; // mutable scratch floating point reg
-        FPRegisterID rhsFP; // mutable scratch floating point reg
-        bool resultHasRhs;  // whether the result has the RHS instead of the LHS
-        bool lhsNeedsRemat; // whether LHS needs memory remat
-        bool rhsNeedsRemat; // whether RHS needs memory remat
-        bool undoResult;    // whether to remat LHS/RHS by undoing operation
-    };
-
-    /*
-     * Ensures that the two given FrameEntries have registers for both their
-     * type and data. The register allocations are returned in a struct.
-     *
-     * One mutable register is allocated as well, holding the LHS payload. If
-     * this would cause a spill that could be avoided by using a mutable RHS,
-     * and the operation is commutative, then the resultHasRhs is set to true.
-     */
-    void allocForBinary(FrameEntry *lhs, FrameEntry *rhs, JSOp op, BinaryAlloc &alloc,
-                        bool resultNeeded = true);
-
-    /*
-     * After the result register in a BinaryAlloc has been clobbered, rematerialize
-     * the left or right side if necessary to restore the original values.
-     */
-    void rematBinary(FrameEntry *lhs, FrameEntry *rhs, const BinaryAlloc &alloc, Assembler &masm);
-
-    /* Ensures that an FE has both type and data remat'd in registers. */
-    void ensureFullRegs(FrameEntry *fe, MaybeRegisterID *typeReg, MaybeRegisterID *dataReg);
-
-    /*
-     * Similar to allocForBinary, except works when the LHS and RHS have the
-     * same backing FE. Only a reduced subset of BinaryAlloc is used:
-     *   lhsType
-     *   lhsData
-     *   result
-     *   lhsNeedsRemat
-     */
-    void allocForSameBinary(FrameEntry *fe, JSOp op, BinaryAlloc &alloc);
-
-    /* Loads an FE into an fp reg. */
-    inline void loadDouble(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) const;
-
-    /*
-     * Slightly more specialized version when more precise register
-     * information is known.
-     */
-    inline void loadDouble(RegisterID type, RegisterID data, FrameEntry *fe, FPRegisterID fpReg,
-                           Assembler &masm) const;
-
-    /*
-     * Types don't always have to be in registers, sometimes the compiler
-     * can use addresses and avoid spilling. If this FrameEntry has a synced
-     * address and no register, this returns true.
-     */
-    inline bool shouldAvoidTypeRemat(FrameEntry *fe);
-
-    /*
-     * Payloads don't always have to be in registers, sometimes the compiler
-     * can use addresses and avoid spilling. If this FrameEntry has a synced
-     * address and no register, this returns true.
-     */
-    inline bool shouldAvoidDataRemat(FrameEntry *fe);
-
-    /*
-     * Frees a temporary register. If this register is being tracked, then it
-     * is not spilled; the backing data becomes invalidated!
-     */
-    inline void freeReg(AnyRegisterID reg);
-
-    /*
-     * Allocates a register. If none are free, one may be spilled from the
-     * tracker. If there are none available for spilling in the tracker,
-     * then this is considered a compiler bug and an assert will fire.
-     */
-    inline RegisterID allocReg();
-    inline FPRegisterID allocFPReg();
-
-    /*
-     * Allocates a register, except using a mask.
-     */
-    inline AnyRegisterID allocReg(uint32_t mask);
-
-    /*
-     * Allocates a specific register, evicting it if it's not avaliable.
-     */
-    void takeReg(AnyRegisterID reg);
-
-    /*
-     * Returns a FrameEntry * for a slot on the operation stack.
-     */
-    inline FrameEntry *peek(int32_t depth);
-
-    /*
-     * Fully stores a FrameEntry at an arbitrary address. popHint specifies
-     * how hard the register allocator should try to keep the FE in registers.
-     */
-    void storeTo(FrameEntry *fe, Address address, bool popHint = false);
-
-    /*
-     * Fully stores a FrameEntry into two arbitrary registers. tempReg may be
-     * used as a temporary.
-     */
-    void loadForReturn(FrameEntry *fe, RegisterID typeReg, RegisterID dataReg, RegisterID tempReg);
-    void loadThisForReturn(RegisterID typeReg, RegisterID dataReg, RegisterID tempReg);
-
-    /* Stores the top stack slot back to a local or slot. */
-    void storeLocal(uint32_t n, bool popGuaranteed = false);
-    void storeArg(uint32_t n, bool popGuaranteed = false);
-    void storeTop(FrameEntry *target);
-
-    /*
-     * Restores state from a slow path.
-     */
-    void merge(Assembler &masm, Changes changes) const;
-
-    /*
-     * Writes unsynced stores to an arbitrary buffer.
-     */
-    void sync(Assembler &masm, Uses uses) const;
-
-    /*
-     * Syncs all outstanding stores to memory and possibly kills regs in the
-     * process.  The top [ignored..uses-1] frame entries will be synced.
-     */
-    void syncAndKill(Registers kill, Uses uses, Uses ignored);
-    void syncAndKill(Registers kill, Uses uses) { syncAndKill(kill, uses, Uses(0)); }
-    void syncAndKill(Uses uses) { syncAndKill(Registers(Registers::AvailAnyRegs), uses, Uses(0)); }
-
-    /* Syncs and kills everything. */
-    void syncAndKillEverything() {
-        syncAndKill(Registers(Registers::AvailAnyRegs), Uses(frameSlots()));
-    }
-
-    /*
-     * Throw away the entire frame state, without syncing anything.
-     * This can only be called after a syncAndKill() against all registers.
-     */
-    void forgetEverything();
-
-    void syncAndForgetEverything()
-    {
-        syncAndKillEverything();
-        forgetEverything();
-    }
-
-    /*
-     * Discard the entire framestate forcefully.
-     */
-    void discardFrame();
-
-    /*
-     * Make a copy of the current frame state, and restore from that snapshot.
-     * The stack depth must match between the snapshot and restore points.
-     */
-    FrameEntry *snapshotState();
-    void restoreFromSnapshot(FrameEntry *snapshot);
-
-    /*
-     * Tries to sync and shuffle registers in accordance with the register state
-     * at target, constructing that state if necessary. Forgets all constants and
-     * copies, and nothing can be pinned. Keeps the top Uses in registers; if Uses
-     * is non-zero the state may not actually be consistent with target.
-     */
-    bool syncForBranch(jsbytecode *target, Uses uses);
-    void syncForAllocation(RegisterAllocation *alloc, bool inlineReturn, Uses uses);
-
-    /* Discards the current frame state and updates to a new register allocation. */
-    bool discardForJoin(RegisterAllocation *&alloc, uint32_t stackDepth);
-
-    RegisterAllocation * computeAllocation(jsbytecode *target);
-
-    /* Return whether the register state is consistent with that at target. */
-    bool consistentRegisters(jsbytecode *target);
-
-    /*
-     * Load all registers to update from either the current register state (if synced
-     * is unset) or a synced state (if synced is set) to target.
-     */
-    void prepareForJump(jsbytecode *target, Assembler &masm, bool synced);
-
-    /*
-     * Mark an existing slot with a type. unsync indicates whether type is already synced.
-     * Do not call this on entries which might be copied.
-     */
-    inline void learnType(FrameEntry *fe, JSValueType type, bool unsync = true);
-    inline void learnType(FrameEntry *fe, JSValueType type, RegisterID payload);
-
-    /*
-     * Forget a type, syncing in the process.
-     */
-    inline void forgetType(FrameEntry *fe);
-
-    /*
-     * Discards a FrameEntry, tricking the FS into thinking it's synced.
-     */
-    void discardFe(FrameEntry *fe);
-
-    /* Compiler-owned metadata about stack entries, reset on push/pop/copy. */
-    struct StackEntryExtra {
-        JSObject *initObject;
-        types::StackTypeSet *types;
-        JSAtom *name;
-        void reset() { mozilla::PodZero(this); }
-    };
-    StackEntryExtra& extra(const FrameEntry *fe) {
-        JS_ASSERT(fe >= a->args && fe < a->sp);
-        return extraArray[fe - entries];
-    }
-    StackEntryExtra& extra(uint32_t slot) { return extra(entries + slot); }
-
-    /*
-     * Helper function. Tests if a slot's type is null. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testNull(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is undefined. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testUndefined(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is an integer. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testInt32(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is a double. Condition must
-     * be Equal or Not Equal.
-     */
-    inline Jump testDouble(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is a boolean. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testBoolean(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is a string. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testString(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is a non-funobj. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testObject(Assembler::Condition cond, FrameEntry *fe);
-
-    inline Jump testGCThing(FrameEntry *fe);
-
-    /*
-     * Helper function. Tests if a slot's type is primitive. Condition must
-     * be Equal or NotEqual.
-     */
-    inline Jump testPrimitive(Assembler::Condition cond, FrameEntry *fe);
-
-    /*
-     * Marks a register such that it cannot be spilled by the register
-     * allocator. Any pinned registers must be unpinned at the end of the op,
-     * no matter what. In addition, pinReg() can only be used on registers
-     * which are associated with FrameEntries.
-     */
-    inline void pinReg(AnyRegisterID reg) { regstate(reg).pin(); }
-
-    /*
-     * Unpins a previously pinned register.
-     */
-    inline void unpinReg(AnyRegisterID reg) { regstate(reg).unpin(); }
-
-    /*
-     * Same as unpinReg(), but does not restore the FrameEntry.
-     */
-    inline void unpinKilledReg(AnyRegisterID reg);
-
-    /* Pins a data or type register if one exists. */
-    MaybeRegisterID maybePinData(FrameEntry *fe);
-    MaybeRegisterID maybePinType(FrameEntry *fe);
-    void maybeUnpinReg(MaybeRegisterID reg);
-
-    /*
-     * Dups the top item on the stack.
-     */
-    inline void dup();
-
-    /*
-     * Dups the top 2 items on the stack.
-     */
-    inline void dup2();
-
-    /*
-     * Dups an item n-deep in the stack. n must be < 0
-     */
-    inline void dupAt(int32_t n);
-
-    /*
-     * Syncs an item n-deep in the stack.
-     */
-    inline void syncAt(int32_t n);
-
-    /*
-     * If the frameentry is a copy, give it its own registers.
-     * This may only be called on the topmost fe.
-     */
-    inline void giveOwnRegs(FrameEntry *fe);
-
-    uint32_t stackDepth() const { return a->sp - a->spBase; }
-
-    /*
-     * The stack depth of the current frame plus any locals and space
-     * for inlined frames, i.e. the difference between the end of the
-     * current fp and sp.
-     */
-    uint32_t totalDepth() const { return a->depth + a->script->nfixed + stackDepth(); }
-
-    // Returns the number of entries in the frame, that is:
-    //   2 for callee, this +
-    //   nargs +
-    //   nfixed +
-    //   currently pushed stack slots
-    uint32_t frameSlots() const { return uint32_t(a->sp - a->callee_); }
-
-#ifdef DEBUG
-    void assertValidRegisterState() const;
-#else
-    inline void assertValidRegisterState() const {}
-#endif
-
-    // Return an address, relative to the StackFrame, that represents where
-    // this FrameEntry is stored in memory. Note that this is its canonical
-    // address, not its backing store. There is no guarantee that the memory
-    // is coherent.
-    Address addressOf(const FrameEntry *fe) const;
-    Address addressOf(uint32_t slot) const { return addressOf(a->callee_ + slot); }
-
-    Address addressOfTop() const { return addressOf(a->sp); }
-
-    // Returns an address, relative to the StackFrame, that represents where
-    // this FrameEntry is backed in memory. This is not necessarily its
-    // canonical address, but the address for which the payload has been synced
-    // to memory. The caller guarantees that the payload has been synced.
-    Address addressForDataRemat(const FrameEntry *fe) const;
-
-    // Inside an inline frame, the address for the return value in the caller.
-    Address addressForInlineReturn();
-
-    inline StateRemat dataRematInfo(const FrameEntry *fe) const;
-
-    /*
-     * This is similar to freeReg(ownRegForData(fe)) - except no movement takes place.
-     * The fe is simply invalidated as if it were popped. This can be used to free
-     * registers in the working area of the stack. Obviously, this can only be called
-     * in infallible code that will pop these entries soon after.
-     */
-    inline void eviscerate(FrameEntry *fe);
-
-    /*
-     * Moves the top of the stack down N slots, popping each item above it.
-     * Caller guarantees the slots below have been observed and eviscerated.
-     */
-    void shimmy(uint32_t n);
-
-    /*
-     * Stores the top item on the stack to a stack slot, count down from the
-     * current stack depth. For example, to move the top (-1) to -3, you would
-     * call shift(-2).
-     */
-    void shift(int32_t n);
-
-    /* Swaps the top two items on the stack. Requires two temp slots. */
-    void swap();
-
-    inline void setInTryBlock(bool inTryBlock) {
-        this->inTryBlock = inTryBlock;
-    }
-
-    inline uint32_t regsInUse() const { return Registers::AvailRegs & ~freeRegs.freeMask; }
-
-    void setPC(jsbytecode *PC) { a->PC = PC; }
-    void setLoop(LoopState *loop) { this->loop = loop; }
-
-    void pruneDeadEntries();
-
-    bool pushActiveFrame(JSScript *script, uint32_t argc);
-    void popActiveFrame();
-
-    uint32_t entrySlot(const FrameEntry *fe) const {
-        return frameSlot(a, fe);
-    }
-
-    uint32_t outerSlot(const FrameEntry *fe) const {
-        ActiveFrame *na = a;
-        while (na->parent) { na = na->parent; }
-        return frameSlot(na, fe);
-    }
-
-    bool isOuterSlot(const FrameEntry *fe) const {
-        if (isTemporary(fe))
-            return true;
-        ActiveFrame *na = a;
-        while (na->parent) { na = na->parent; }
-        return fe < na->spBase && fe != na->callee_;
-    }
-
-#ifdef DEBUG
-    const char * entryName(const FrameEntry *fe) const;
-    void dumpAllocation(RegisterAllocation *alloc);
-#else
-    const char * entryName(const FrameEntry *fe) const { return NULL; }
-#endif
-    const char * entryName(uint32_t slot) { return entryName(entries + slot); }
-
-    /* Maximum number of analysis temporaries the FrameState can track. */
-    static const uint32_t TEMPORARY_LIMIT = 10;
-
-    uint32_t allocTemporary();  /* -1 if limit reached. */
-    void clearTemporaries();
-    inline FrameEntry *getTemporary(uint32_t which);
-
-    /*
-     * Return NULL or a new vector with all current copies of temporaries,
-     * excluding those about to be popped per 'uses'.
-     */
-    Vector<TemporaryCopy> *getTemporaryCopies(Uses uses);
-
-    inline void syncAndForgetFe(FrameEntry *fe, bool markSynced = false);
-    inline void forgetLoopReg(FrameEntry *fe);
-
-  private:
-    inline AnyRegisterID allocAndLoadReg(FrameEntry *fe, bool fp, RematInfo::RematType type);
-    inline void forgetReg(AnyRegisterID reg);
-    AnyRegisterID evictSomeReg(uint32_t mask);
-    void evictReg(AnyRegisterID reg);
-    inline FrameEntry *rawPush();
-    inline void addToTracker(FrameEntry *fe);
-
-    /* Guarantee sync, but do not set any sync flag. */
-    inline void ensureFeSynced(const FrameEntry *fe, Assembler &masm) const;
-    inline void ensureTypeSynced(const FrameEntry *fe, Assembler &masm) const;
-    inline void ensureDataSynced(const FrameEntry *fe, Assembler &masm) const;
-
-    /* Guarantee sync, even if register allocation is required, and set sync. */
-    inline void syncFe(FrameEntry *fe);
-    inline void syncType(FrameEntry *fe);
-    inline void syncData(FrameEntry *fe);
-
-    /* For a frame entry whose value is dead, mark as synced. */
-    inline void fakeSync(FrameEntry *fe);
-
-    inline FrameEntry *getCallee();
-    inline FrameEntry *getThis();
-    inline FrameEntry *getOrTrack(uint32_t index);
-
-    inline void forgetAllRegs(FrameEntry *fe);
-    inline void swapInTracker(FrameEntry *lhs, FrameEntry *rhs);
-#if defined JS_NUNBOX32
-    void syncFancy(Assembler &masm, Registers avail, int trackerIndex) const;
-#endif
-    inline bool tryFastDoubleLoad(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) const;
-    void resetInternalState();
-
-    /*
-     * "Uncopies" the backing store of a FrameEntry that has been copied. The
-     * original FrameEntry is not invalidated; this is the responsibility of
-     * the caller. The caller can check isCopied() to see if the registers
-     * were moved to a copy.
-     *
-     * Later addition: uncopy() returns the first copy found.
-     */
-    FrameEntry *uncopy(FrameEntry *original);
-    FrameEntry *walkTrackerForUncopy(FrameEntry *original);
-    FrameEntry *walkFrameForUncopy(FrameEntry *original);
-
-    /* Whether fe is the only copy of backing. */
-    bool hasOnlyCopy(FrameEntry *backing, FrameEntry *fe);
-
-    /*
-     * All registers in the FE are forgotten. If it is copied, it is uncopied
-     * beforehand.
-     */
-    void forgetEntry(FrameEntry *fe);
-
-    /* Stack and temporary entries whose contents should be disregarded. */
-    bool deadEntry(const FrameEntry *fe, unsigned uses = 0) const {
-        return (fe >= (a->sp - uses) && fe < temporaries) || fe >= temporariesTop;
-    }
-
-    RegisterState & regstate(AnyRegisterID reg) {
-        JS_ASSERT(reg.reg_ < Registers::TotalAnyRegisters);
-        return regstate_[reg.reg_];
-    }
-
-    const RegisterState & regstate(AnyRegisterID reg) const {
-        JS_ASSERT(reg.reg_ < Registers::TotalAnyRegisters);
-        return regstate_[reg.reg_];
-    }
-
-    AnyRegisterID bestEvictReg(uint32_t mask, bool includePinned) const;
-    void evictDeadEntries(bool includePinned);
-
-    inline analyze::Lifetime * variableLive(FrameEntry *fe, jsbytecode *pc) const;
-    inline bool binaryEntryLive(FrameEntry *fe) const;
-    void relocateReg(AnyRegisterID reg, RegisterAllocation *alloc, Uses uses);
-
-    bool isThis(const FrameEntry *fe) const {
-        return fe == a->this_;
-    }
-
-    inline bool isConstructorThis(const FrameEntry *fe) const;
-
-    bool isArg(const FrameEntry *fe) const {
-        return a->script->function() && fe >= a->args && fe - a->args < a->script->function()->nargs;
-    }
-
-    bool isLocal(const FrameEntry *fe) const {
-        return fe >= a->locals && fe - a->locals < a->script->nfixed;
-    }
-
-    bool isTemporary(const FrameEntry *fe) const {
-        JS_ASSERT_IF(fe >= temporaries, fe < temporariesTop);
-        return fe >= temporaries;
-    }
-
-    int32_t frameOffset(const FrameEntry *fe, ActiveFrame *a) const;
-    Address addressOf(const FrameEntry *fe, ActiveFrame *a) const;
-    uint32_t frameSlot(ActiveFrame *a, const FrameEntry *fe) const;
-
-    void associateReg(FrameEntry *fe, RematInfo::RematType type, AnyRegisterID reg);
-
-    inline void modifyReg(AnyRegisterID reg);
-
-    MaybeJump guardArrayLengthBase(FrameEntry *obj, Int32Key key);
-
-  private:
-    JSContext *cx;
-    Assembler &masm;
-    Compiler &cc;
-    StubCompiler &stubcc;
-
-    /* State for the active stack frame. */
-
-    struct ActiveFrame {
-        ActiveFrame() { mozilla::PodZero(this); }
-
-        ActiveFrame *parent;
-
-        /* Number of values between the start of the outer frame and the start of this frame. */
-        uint32_t depth;
-
-        JSScript *script;
-        jsbytecode *PC;
-        analyze::ScriptAnalysis *analysis;
-
-        /* Indexes into the main FrameEntry buffer of entries for this frame. */
-        FrameEntry *callee_;
-        FrameEntry *this_;
-        FrameEntry *args;
-        FrameEntry *locals;
-        FrameEntry *spBase;
-        FrameEntry *sp;
-    };
-    ActiveFrame *a;
-
-    /* Common buffer of frame entries. */
-    FrameEntry *entries;
-    uint32_t nentries;
-
-    /* Compiler-owned metadata for stack contents. */
-    StackEntryExtra *extraArray;
-
-    /* Vector of tracked slot indexes. */
-    Tracker tracker;
-
-#if defined JS_NUNBOX32
-    mutable ImmutableSync reifier;
-#endif
-
-    /*
-     * Register ownership state. This can't be used alone; to find whether an
-     * entry is active, you must check the allocated registers.
-     */
-    RegisterState regstate_[Registers::TotalAnyRegisters];
-
-    /* All unallocated registers. */
-    Registers freeRegs;
-
-    /* Stack of active loops. */
-    LoopState *loop;
-
-    /*
-     * Track state for analysis temporaries. The meaning of these temporaries
-     * is opaque to the frame state, which just tracks where they are stored.
-     */
-    FrameEntry *temporaries;
-    FrameEntry *temporariesTop;
-
-    bool inTryBlock;
-};
-
-/*
- * Register allocation overview. We want to allocate registers at the same time
- * as we emit code, in a single forward pass over the script. This is good both
- * for compilation speed and for design simplicity; we allocate registers for
- * variables and temporaries as the compiler needs them. To get a good allocation,
- * however, we need knowledge of which variables will be used in the future and
- * in what order --- we must prioritize keeping variables in registers which
- * will be used soon, and evict variables after they are no longer needed.
- * We get this from the analyze::LifetimeScript analysis, an initial backwards
- * pass over the script.
- *
- * Combining a backwards lifetime pass with a forward allocation pass in this
- * way produces a Linear-scan register allocator. These can generate code at
- * a speed close to that produced by a graph coloring register allocator,
- * at a fraction of the compilation time.
- */
-
-/* Register allocation to use at a join point. */
-struct RegisterAllocation {
-  private:
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-
-    /* Entry for an unassigned register at the join point. */
-    static const uint32_t UNASSIGNED_REGISTER = UINT32_MAX;
-
-    /*
-     * In the body of a loop, entry for an unassigned register that has not been
-     * used since the start of the loop. We do not finalize the register state
-     * at the start of a loop body until after generating code for the entire loop,
-     * so we can decide on which variables to carry around the loop after seeing
-     * them accessed early on in the body.
-     */
-    static const uint32_t LOOP_REGISTER = uint32_t(-2);
-
-    /*
-     * Assignment of registers to payloads. Type tags are always in memory,
-     * except for known doubles in FP registers. These are indexes into the
-     * frame's entries[] buffer, not slots.
-     */
-    uint32_t regstate_[Registers::TotalAnyRegisters];
-
-    /* Mask for regstate entries indicating if the slot is synced. */
-    static const uint32_t SYNCED = 0x80000000;
-
-    uint32_t & regstate(AnyRegisterID reg) {
-        JS_ASSERT(reg.reg_ < Registers::TotalAnyRegisters);
-        return regstate_[reg.reg_];
-    }
-
-  public:
-    RegisterAllocation(bool forLoop)
-    {
-        uint32_t entry = forLoop ? (uint32_t) LOOP_REGISTER : (uint32_t) UNASSIGNED_REGISTER;
-        for (unsigned i = 0; i < Registers::TotalAnyRegisters; i++) {
-            AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-            bool avail = Registers::maskReg(reg) & Registers::AvailAnyRegs;
-            regstate_[i] = avail ? entry : UNASSIGNED_REGISTER;
-        }
-    }
-
-    bool assigned(AnyRegisterID reg) {
-        return regstate(reg) != UNASSIGNED_REGISTER && regstate(reg) != LOOP_REGISTER;
-    }
-
-    bool loop(AnyRegisterID reg) {
-        return regstate(reg) == LOOP_REGISTER;
-    }
-
-    bool synced(AnyRegisterID reg) {
-        JS_ASSERT(assigned(reg));
-        return regstate(reg) & SYNCED;
-    }
-
-    uint32_t index(AnyRegisterID reg) {
-        JS_ASSERT(assigned(reg));
-        return regstate(reg) & ~SYNCED;
-    }
-
-    void set(AnyRegisterID reg, uint32_t index, bool synced) {
-        JS_ASSERT(index != LOOP_REGISTER && index != UNASSIGNED_REGISTER);
-        regstate(reg) = index | (synced ? SYNCED : 0);
-    }
-
-    void setUnassigned(AnyRegisterID reg) {
-        regstate(reg) = UNASSIGNED_REGISTER;
-    }
-
-    bool synced() {
-        for (unsigned i = 0; i < Registers::TotalAnyRegisters; i++) {
-            if (assigned(AnyRegisterID::fromRaw(i)))
-                return false;
-        }
-        return true;
-    }
-
-    void clearLoops() {
-        for (unsigned i = 0; i < Registers::TotalAnyRegisters; i++) {
-            AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-            if (loop(reg))
-                setUnassigned(reg);
-        }
-    }
-
-    bool hasAnyReg(uint32_t n) {
-        for (unsigned i = 0; i < Registers::TotalAnyRegisters; i++) {
-            AnyRegisterID reg = AnyRegisterID::fromRaw(i);
-            if (assigned(reg) && index(reg) == n)
-                return true;
-        }
-        return false;
-    }
-};
-
-class AutoPreserveAcrossSyncAndKill;
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_framestate_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/ICChecker.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_icchecker_h__ && defined JS_METHODJIT
-#define jsjaeger_icchecker_h__
-
-#include "assembler/assembler/MacroAssembler.h"
-
-namespace js {
-namespace mjit {
-
-#if defined DEBUG && defined JS_CPU_ARM
-static inline void
-CheckInstMask(void *addr, uint32_t mask, uint32_t expected)
-{
-    uint32_t inst = *static_cast<uint32_t *>(addr);
-    JS_ASSERT((inst & mask) == expected);
-}
-
-static inline void
-CheckIsLDR(JSC::CodeLocationLabel label, uint8_t rd)
-{
-    JS_ASSERT((rd & 0xf) == rd);
-    CheckInstMask(label.executableAddress(), 0xfc50f000, 0xe4100000 | (rd << 12));
-}
-
-static inline void
-CheckIsBLX(JSC::CodeLocationLabel label, uint8_t rsrc)
-{
-    JS_ASSERT((rsrc & 0xf) == rsrc);
-    CheckInstMask(label.executableAddress(), 0xfff000ff, 0xe1200030 | rsrc);
-}
-
-static inline void
-CheckIsStubCall(JSC::CodeLocationLabel label)
-{
-    CheckIsLDR(label.labelAtOffset(-4), JSC::ARMRegisters::ip);
-    CheckIsLDR(label.labelAtOffset(0), JSC::ARMRegisters::r8);
-    CheckIsBLX(label.labelAtOffset(4), JSC::ARMRegisters::r8);
-}
-#else
-static inline void CheckIsStubCall(JSC::CodeLocationLabel label) {}
-#endif
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
deleted file mode 100644
--- a/js/src/methodjit/ICLabels.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_ic_labels_h__ && defined JS_METHODJIT
-#define jsjaeger_ic_labels_h__
-
-#include "methodjit/BaseCompiler.h"
-
-class ICOffsetInitializer {
-  public:
-    ICOffsetInitializer();
-};
-
-namespace js {
-namespace mjit {
-namespace ic {
-
-/* GetPropCompiler */
-struct GetPropLabels : MacroAssemblerTypedefs {
-    friend class ::ICOffsetInitializer;
-
-    void setValueLoad(MacroAssembler &masm, Label fastPathRejoin, Label fastValueLoad) {
-        int offset = masm.differenceBetween(fastPathRejoin, fastValueLoad);
-        inlineValueLoadOffset = offset;
-
-        /*
-         * Note: the offset between the type and data loads for x86 is asserted
-         * in NunboxAssembler::loadValueWithAddressOffsetPatch.
-         */
-        JS_ASSERT(offset == inlineValueLoadOffset);
-        (void) offset;
-    }
-
-    CodeLocationLabel getValueLoad(CodeLocationLabel fastPathRejoin) {
-        return fastPathRejoin.labelAtOffset(inlineValueLoadOffset);
-    }
-
-    void setDslotsLoad(MacroAssembler &masm, Label fastPathRejoin, Label dslotsLoad) {
-        int offset = masm.differenceBetween(fastPathRejoin, dslotsLoad);
-        setDslotsLoadOffset(offset);
-    }
-
-    CodeLocationInstruction getDslotsLoad(CodeLocationLabel fastPathRejoin) {
-        return fastPathRejoin.instructionAtOffset(getDslotsLoadOffset());
-    }
-
-    void setInlineShapeData(MacroAssembler &masm, Label shapeGuard, DataLabelPtr inlineShape) {
-        int offset = masm.differenceBetween(shapeGuard, inlineShape);
-        setInlineShapeOffset(offset);
-    }
-
-    CodeLocationDataLabelPtr getInlineShapeData(CodeLocationLabel fastShapeGuard) {
-        return fastShapeGuard.dataLabelPtrAtOffset(getInlineShapeOffset());
-    }
-
-    /*
-     * Note: on x64, the base is the inlineShapeLabel DataLabelPtr, whereas on other
-     * platforms the base is the shapeGuard.
-     */
-    template <typename T>
-    void setInlineShapeJump(MacroAssembler &masm, T base, Label afterJump) {
-        setInlineShapeJumpOffset(masm.differenceBetween(base, afterJump));
-    }
-
-    CodeLocationJump getInlineShapeJump(CodeLocationLabel fastShapeGuard) {
-        return fastShapeGuard.jumpAtOffset(getInlineShapeJumpOffset());
-    }
-
-    void setInlineTypeJump(MacroAssembler &masm, Label fastPathStart, Label afterTypeJump) {
-        int offset = masm.differenceBetween(fastPathStart, afterTypeJump);
-        setInlineTypeJumpOffset(offset);
-    }
-
-    CodeLocationJump getInlineTypeJump(CodeLocationLabel fastPathStart) {
-        return fastPathStart.jumpAtOffset(getInlineTypeJumpOffset());
-    }
-
-    void setStubShapeJump(MacroAssembler &masm, Label stubStart, Label shapeJump) {
-        int offset = masm.differenceBetween(stubStart, shapeJump);
-        setStubShapeJumpOffset(offset);
-    }
-
-    /* Offset-based interface */
-
-    void setDslotsLoadOffset(int offset) {
-        dslotsLoadOffset = offset;
-        JS_ASSERT(offset == dslotsLoadOffset);
-    }
-
-    void setInlineShapeOffset(int offset) {
-        inlineShapeOffset = offset;
-        JS_ASSERT(offset == inlineShapeOffset);
-    }
-
-    void setStubShapeJumpOffset(int offset) {
-        stubShapeJumpOffset = offset;
-        JS_ASSERT(offset == stubShapeJumpOffset);
-    }
-
-    int getInlineShapeJumpOffset() {
-        return POST_INST_OFFSET(inlineShapeJumpOffset);
-    }
-
-    void setInlineShapeJumpOffset(int offset) {
-        inlineShapeJumpOffset = offset;
-        JS_ASSERT(offset == inlineShapeJumpOffset);
-    }
-
-    int getInlineTypeJumpOffset() {
-        return POST_INST_OFFSET(inlineTypeJumpOffset);
-    }
-
-    void setInlineTypeJumpOffset(int offset) {
-        inlineTypeJumpOffset = offset;
-        JS_ASSERT(offset == inlineTypeJumpOffset);
-     }
-
-    int getInlineShapeOffset() {
-        return inlineShapeOffset;
-    }
-    int getDslotsLoadOffset() {
-        return dslotsLoadOffset;
-    }
-    int getStubShapeJumpOffset() {
-        return POST_INST_OFFSET(stubShapeJumpOffset);
-    }
-
-  private:
-    /* Offset from storeBack to beginning of 'mov dslots, addr' */
-    int32_t dslotsLoadOffset : 8;
-
-    /* Offset from shapeGuard to end of shape comparison. */
-    int32_t inlineShapeOffset : 8;
-
-    /* Offset from storeBack to end of value load. */
-    int32_t inlineValueLoadOffset : 8;
-
-    /*
-     * Offset from lastStubStart to end of shape jump.
-     * TODO: We can redefine the location of lastStubStart to be
-     * after the jump -- at which point this is always 0.
-     */
-    int32_t stubShapeJumpOffset : 8;
-
-    /* Offset from the shape guard start to the shape guard jump. */
-    int32_t inlineShapeJumpOffset : 8;
-
-    /* Offset from the fast path to the type guard jump. */
-    int32_t inlineTypeJumpOffset : 8;
-};
-
-/* SetPropCompiler */
-struct SetPropLabels : MacroAssemblerTypedefs {
-    friend class ::ICOffsetInitializer;
-
-    void setInlineValueStore(MacroAssembler &masm, Label fastPathRejoin, DataLabel32 inlineValueStore) {
-        int offset = masm.differenceBetween(fastPathRejoin, inlineValueStore);
-        setInlineValueStoreOffset(offset);
-    }
-
-    CodeLocationLabel getInlineValueStore(CodeLocationLabel fastPathRejoin) {
-        return fastPathRejoin.labelAtOffset(getInlineValueStoreOffset());
-    }
-
-    void setInlineShapeData(MacroAssembler &masm, Label shapeGuard, DataLabelPtr inlineShapeData) {
-        int offset = masm.differenceBetween(shapeGuard, inlineShapeData);
-        setInlineShapeDataOffset(offset);
-    }
-
-    CodeLocationDataLabelPtr getInlineShapeData(CodeLocationLabel fastPathStart, int shapeGuardOffset) {
-        return fastPathStart.dataLabelPtrAtOffset(shapeGuardOffset + getInlineShapeDataOffset());
-    }
-
-    void setDslotsLoad(MacroAssembler &masm, Label fastPathRejoin, Label beforeLoad) {
-        int offset = masm.differenceBetween(fastPathRejoin, beforeLoad);
-        setDslotsLoadOffset(offset);
-    }
-
-    CodeLocationInstruction getDslotsLoad(CodeLocationLabel fastPathRejoin, const ValueRemat &vr) {
-        return fastPathRejoin.instructionAtOffset(getDslotsLoadOffset(vr));
-    }
-
-    void setInlineShapeJump(MacroAssembler &masm, Label shapeGuard, Label afterJump) {
-        setInlineShapeJumpOffset(masm.differenceBetween(shapeGuard, afterJump));
-    }
-
-    CodeLocationJump getInlineShapeJump(CodeLocationLabel shapeGuard) {
-        return shapeGuard.jumpAtOffset(getInlineShapeJumpOffset());
-    }
-
-    void setStubShapeJump(MacroAssembler &masm, Label stubStart, Label afterShapeJump) {
-        int offset = masm.differenceBetween(stubStart, afterShapeJump);
-        setStubShapeJumpOffset(offset);
-    }
-
-    CodeLocationJump getStubShapeJump(CodeLocationLabel stubStart) {
-        return stubStart.jumpAtOffset(getStubShapeJumpOffset());
-    }
-
-  private:
-
-    /* Offset-based interface. */
-
-    void setDslotsLoadOffset(int offset) {
-        dslotsLoadOffset = offset;
-        JS_ASSERT(offset == dslotsLoadOffset);
-    }
-
-    int getDslotsLoadOffset(const ValueRemat &vr) {
-        (void) vr;
-        return dslotsLoadOffset;
-    }
-
-    void setInlineShapeDataOffset(int offset) {
-        inlineShapeDataOffset = offset;
-        JS_ASSERT(offset == inlineShapeDataOffset);
-    }
-
-    void setStubShapeJumpOffset(int offset) {
-        stubShapeJumpOffset = offset;
-        JS_ASSERT(offset == stubShapeJumpOffset);
-    }
-
-    void setInlineValueStoreOffset(int offset) {
-        inlineValueStoreOffset = offset;
-        JS_ASSERT(offset == inlineValueStoreOffset);
-    }
-
-    void setInlineShapeJumpOffset(int offset) {
-        inlineShapeJumpOffset = offset;
-        JS_ASSERT(offset == inlineShapeJumpOffset);
-    }
-
-    int getInlineShapeJumpOffset() {
-        return POST_INST_OFFSET(inlineShapeJumpOffset);
-    }
-
-    int getInlineShapeDataOffset() {
-        return inlineShapeDataOffset;
-    }
-
-    int getStubShapeJumpOffset() {
-        return POST_INST_OFFSET(stubShapeJumpOffset);
-    }
-
-    int getInlineValueStoreOffset() {
-        return inlineValueStoreOffset;
-    }
-
-    /* Offset from storeBack to beginning of 'mov dslots, addr'. */
-    int32_t dslotsLoadOffset : 8;
-
-    /* Offset from shapeGuard to end of shape comparison. */
-    int32_t inlineShapeDataOffset : 8;
-
-    /*
-     * Offset from lastStubStart to end of shape jump.
-     * TODO: We can redefine the location of lastStubStart to be
-     * after the jump -- at which point this is always 0.
-     */
-    int32_t stubShapeJumpOffset : 8;
-
-    int32_t inlineValueStoreOffset : 8;
-
-    /* Offset from shapeGuard to the end of the shape jump. */
-    int32_t inlineShapeJumpOffset : 8;
-};
-
-/* BindNameCompiler */
-struct BindNameLabels : MacroAssemblerTypedefs {
-    friend class ::ICOffsetInitializer;
-
-    void setInlineJumpOffset(int offset) {
-        inlineJumpOffset = offset;
-        JS_ASSERT(offset == inlineJumpOffset);
-    }
-
-    void setInlineJump(MacroAssembler &masm, Label shapeGuard, Jump inlineJump) {
-        int offset = masm.differenceBetween(shapeGuard, inlineJump);
-        setInlineJumpOffset(offset);
-    }
-
-    CodeLocationJump getInlineJump(CodeLocationLabel fastPathStart) {
-        return fastPathStart.jumpAtOffset(getInlineJumpOffset());
-    }
-
-    int getInlineJumpOffset() {
-        return inlineJumpOffset;
-    }
-
-    void setStubJumpOffset(int offset) {
-        stubJumpOffset = offset;
-        JS_ASSERT(offset == stubJumpOffset);
-    }
-
-    void setStubJump(MacroAssembler &masm, Label stubStart, Jump stubJump) {
-        int offset = masm.differenceBetween(stubStart, stubJump);
-        setStubJumpOffset(offset);
-    }
-
-    CodeLocationJump getStubJump(CodeLocationLabel lastStubStart) {
-        return lastStubStart.jumpAtOffset(getStubJumpOffset());
-    }
-
-    int getStubJumpOffset() {
-        return stubJumpOffset;
-    }
-
-  private:
-    /* Offset from shapeGuard to end of shape jump. */
-    int32_t inlineJumpOffset : 8;
-
-    /* Offset from lastStubStart to end of the shape jump. */
-    int32_t stubJumpOffset : 8;
-};
-
-/* ScopeNameCompiler */
-struct ScopeNameLabels : MacroAssemblerTypedefs {
-    friend class ::ICOffsetInitializer;
-
-    void setInlineJumpOffset(int offset) {
-        inlineJumpOffset = offset;
-        JS_ASSERT(offset == inlineJumpOffset);
-    }
-
-    void setInlineJump(MacroAssembler &masm, Label fastPathStart, Jump inlineJump) {
-        int offset = masm.differenceBetween(fastPathStart, inlineJump);
-        setInlineJumpOffset(offset);
-    }
-
-    CodeLocationJump getInlineJump(CodeLocationLabel fastPathStart) {
-        return fastPathStart.jumpAtOffset(getInlineJumpOffset());
-    }
-
-    int getInlineJumpOffset() {
-        return inlineJumpOffset;
-    }
-
-    void setStubJumpOffset(int offset) {
-        stubJumpOffset = offset;
-        JS_ASSERT(offset == stubJumpOffset);
-    }
-
-    void setStubJump(MacroAssembler &masm, Label stubStart, Jump stubJump) {
-        int offset = masm.differenceBetween(stubStart, stubJump);
-        setStubJumpOffset(offset);
-    }
-
-    CodeLocationJump getStubJump(CodeLocationLabel lastStubStart) {
-        return lastStubStart.jumpAtOffset(getStubJumpOffset());
-    }
-
-    int getStubJumpOffset() {
-        return stubJumpOffset;
-    }
-
-  private:
-    /* Offset from fastPathStart to end of shape jump. */
-    int32_t inlineJumpOffset : 8;
-
-    /* Offset from lastStubStart to end of the shape jump. */
-    int32_t stubJumpOffset : 8;
-};
-
-} /* namespace ic */
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_ic_labels_h__ */
deleted file mode 100644
--- a/js/src/methodjit/ICRepatcher.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_icrepatcher_h__ && defined JS_METHODJIT
-#define jsjaeger_icrepatcher_h__
-
-#include "assembler/assembler/RepatchBuffer.h"
-#include "assembler/moco/MocoStubs.h"
-#include "methodjit/ICChecker.h"
-
-namespace js {
-namespace mjit {
-namespace ic {
-
-class Repatcher : public JSC::RepatchBuffer
-{
-    typedef JSC::CodeLocationLabel  CodeLocationLabel;
-    typedef JSC::CodeLocationCall   CodeLocationCall;
-    typedef JSC::FunctionPtr        FunctionPtr;
-
-    CodeLocationLabel label;
-
-  public:
-    explicit Repatcher(JITChunk *js)
-      : JSC::RepatchBuffer(js->code), label(js->code.m_code.executableAddress())
-    { }
-
-    explicit Repatcher(const JSC::JITCode &code)
-      : JSC::RepatchBuffer(code), label(code.start())
-    { }
-
-    using JSC::RepatchBuffer::relink;
-
-    /* Patch a stub call. */
-    void relink(CodeLocationCall call, FunctionPtr stub) {
-#if defined JS_CPU_X64 || defined JS_CPU_X86 || defined JS_CPU_SPARC
-        JSC::RepatchBuffer::relink(call, stub);
-#elif defined JS_CPU_ARM
-        /*
-         * Stub calls on ARM look like this:
-         *
-         *                  ldr     ip, =stub
-         * call label ->    ldr     r8, =JaegerStubVeneer
-         *                  blx     r8
-         *
-         * ARM has to run stub calls through a veneer in order for THROW to
-         * work properly. The address that must be patched is the load into
-         * 'ip', not the load into 'r8'.
-         */
-        CheckIsStubCall(call.labelAtOffset(0));
-        JSC::RepatchBuffer::relink(call.callAtOffset(-4), stub);
-#elif defined JS_CPU_MIPS
-        /*
-         * Stub calls on MIPS look like this:
-         *
-         *                  lui     v0, hi(stub)
-         *                  ori     v0, v0, lo(stub)
-         *                  lui     t9, hi(JaegerStubVeneer)
-         *                  ori     t9, t9, lo(JaegerStubVeneer)
-         *                  jalr    t9
-         *                  nop
-         * call label ->    xxx
-         *
-         * MIPS has to run stub calls through a veneer in order for THROW to
-         * work properly. The address that must be patched is the load into
-         * 'v0', not the load into 't9'.
-         */
-        JSC::RepatchBuffer::relink(call.callAtOffset(-8), stub);
-#else
-# error
-#endif
-    }
-
-    /* Patch the offset of a Value load emitted by loadValueWithAddressOffsetPatch. */
-    void patchAddressOffsetForValueLoad(CodeLocationLabel label, uint32_t offset) {
-#if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC || defined JS_CPU_MIPS
-        repatch(label.dataLabel32AtOffset(0), offset);
-#elif defined JS_CPU_X86
-        static const unsigned LOAD_TYPE_OFFSET = 6;
-        static const unsigned LOAD_DATA_OFFSET = 12;
-
-        /*
-         * We have the following sequence to patch:
-         *
-         *      mov     <offset+4>($base), %<type>
-         *      mov     <offset+0>($base), %<data>
-         */
-        repatch(label.dataLabel32AtOffset(LOAD_DATA_OFFSET), offset);
-        repatch(label.dataLabel32AtOffset(LOAD_TYPE_OFFSET), offset + 4);
-#else
-# error
-#endif
-    }
-
-    void patchAddressOffsetForValueStore(CodeLocationLabel label, uint32_t offset, bool typeConst) {
-#if defined JS_CPU_ARM || defined JS_CPU_X64 || defined JS_CPU_SPARC || defined JS_CPU_MIPS
-        (void) typeConst;
-        repatch(label.dataLabel32AtOffset(0), offset);
-#elif defined JS_CPU_X86
-        static const unsigned STORE_TYPE_OFFSET = 6;
-        static const unsigned STORE_DATA_CONST_TYPE_OFFSET = 16;
-        static const unsigned STORE_DATA_TYPE_OFFSET = 12;
-
-        /*
-         * The type is stored first, then the payload. Both stores can vary in
-         * size, depending on whether or not the data is a constant in the
-         * instruction stream (though only the first store matters for the
-         * purpose of locating both offsets for patching).
-         *
-         * We have one of the following sequences to patch. Offsets are located
-         * before 6B into a given move instruction, but the mov instructions
-         * carrying constant payloads are 10B wide overall.
-         *
-         *  typeConst=false, dataConst=false
-         *      mov     %<type>, <offset+4>($base)  ; Length is 6
-         *      mov     %<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 12
-         *  typeConst=true, dataConst=false
-         *      mov     $<type>, <offset+4>($base)  ; Length is 10
-         *      mov     %<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 16
-         *  typeConst=true, dataConst=true
-         *      mov     $<type>, <offset+4>($base)  ; Length is 10
-         *      mov     $<data>, <offset+0>($base)  ; Offset @ len(prev) + 6 = 16
-         *
-         * Note that we only need to know whether type is const to determine the
-         * correct patch offsets. In all cases, the label points to the start
-         * of the sequence.
-         */
-        repatch(label.dataLabel32AtOffset(STORE_TYPE_OFFSET), offset + 4);
-
-        unsigned payloadOffset = typeConst ? STORE_DATA_CONST_TYPE_OFFSET : STORE_DATA_TYPE_OFFSET;
-        repatch(label.dataLabel32AtOffset(payloadOffset), offset);
-#else
-# error
-#endif
-    }
-};
-
-} /* namespace ic */
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
deleted file mode 100644
--- a/js/src/methodjit/ImmutableSync.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if defined JS_NUNBOX32
-
-#include "FrameEntry.h"
-#include "FrameState.h"
-#include "FrameState-inl.h"
-#include "ImmutableSync.h"
-
-using namespace js;
-using namespace js::mjit;
-
-ImmutableSync::ImmutableSync()
-  : cx(NULL), entries(NULL), frame(NULL), avail(Registers::AvailRegs), generation(0)
-{
-}
-
-ImmutableSync::~ImmutableSync()
-{
-    if (cx)
-        js_free(entries);
-}
-
-bool
-ImmutableSync::init(JSContext *cx, const FrameState &frame, uint32_t nentries)
-{
-    this->cx = cx;
-    this->frame = &frame;
-
-    entries = js_pod_calloc<SyncEntry>(nentries);
-    return !!entries;
-}
-
-void
-ImmutableSync::reset(Assembler *masm, Registers avail, FrameEntry *top, FrameEntry *bottom)
-{
-    this->avail = avail;
-    this->masm = masm;
-    this->top = top;
-    this->bottom = bottom;
-    this->generation++;
-    memset(regs, 0, sizeof(regs));
-}
-
-inline JSC::MacroAssembler::RegisterID
-ImmutableSync::doAllocReg()
-{
-    if (!avail.empty())
-        return avail.takeAnyReg().reg();
-
-    uint32_t lastResort = FrameState::InvalidIndex;
-    uint32_t evictFromFrame = FrameState::InvalidIndex;
-
-    /* Find something to evict. */
-    for (uint32_t i = 0; i < Registers::TotalRegisters; i++) {
-        RegisterID reg = RegisterID(i);
-        if (!(Registers::maskReg(reg) & Registers::AvailRegs))
-            continue;
-
-        if (frame->regstate(reg).isPinned())
-            continue;
-
-        lastResort = i;
-
-        if (!regs[i]) {
-            /* If the frame does not own this register, take it! */
-            FrameEntry *fe = frame->regstate(reg).usedBy();
-            if (!fe)
-                return reg;
-
-            evictFromFrame = i;
-
-            /*
-             * If not copied, we can sync and not have to load again later.
-             * That's about as good as it gets, so just break out now.
-             */
-            if (!fe->isCopied())
-                break;
-        }
-    }
-
-    if (evictFromFrame != FrameState::InvalidIndex) {
-        RegisterID evict = RegisterID(evictFromFrame);
-        FrameEntry *fe = frame->regstate(evict).usedBy();
-        SyncEntry &e = entryFor(fe);
-        if (frame->regstate(evict).type() == RematInfo::TYPE) {
-            JS_ASSERT(!e.typeClobbered);
-            e.typeClobbered = true;
-        } else {
-            JS_ASSERT(!e.dataClobbered);
-            e.dataClobbered = true;
-        }
-        return evict;
-    }
-
-    JS_ASSERT(lastResort != FrameState::InvalidIndex);
-    JS_ASSERT(regs[lastResort]);
-
-    SyncEntry *e = regs[lastResort];
-    RegisterID reg = RegisterID(lastResort);
-    if (e->hasDataReg && e->dataReg == reg) {
-        e->hasDataReg = false;
-    } else if (e->hasTypeReg && e->typeReg == reg) {
-        e->hasTypeReg = false;
-    } else {
-        JS_NOT_REACHED("no way");
-    }
-
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-ImmutableSync::allocReg()
-{
-    RegisterID reg = doAllocReg();
-    JS_ASSERT(!frame->regstate(reg).isPinned());
-    return reg;
-}
-
-void
-ImmutableSync::freeReg(JSC::MacroAssembler::RegisterID reg)
-{
-    if (!frame->regstate(reg).isPinned())
-        avail.putReg(reg);
-}
-
-inline ImmutableSync::SyncEntry &
-ImmutableSync::entryFor(FrameEntry *fe)
-{
-    JS_ASSERT(fe <= top || frame->isTemporary(fe));
-    SyncEntry &e = entries[fe - frame->entries];
-    if (e.generation != generation)
-        e.reset(generation);
-    return e;
-}
-
-void
-ImmutableSync::sync(FrameEntry *fe)
-{
-    if (fe->isCopy())
-        syncCopy(fe);
-    else
-        syncNormal(fe);
-}
-
-bool
-ImmutableSync::shouldSyncType(FrameEntry *fe, SyncEntry &e)
-{
-    /* Registers are synced up-front. */
-    return !fe->type.synced() && !fe->type.inRegister();
-}
-
-bool
-ImmutableSync::shouldSyncData(FrameEntry *fe, SyncEntry &e)
-{
-    /* Registers are synced up-front. */
-    return !fe->data.synced() && !fe->data.inRegister();
-}
-
-JSC::MacroAssembler::RegisterID
-ImmutableSync::ensureTypeReg(FrameEntry *fe, SyncEntry &e)
-{
-    if (fe->type.inRegister() && !e.typeClobbered)
-        return fe->type.reg();
-    if (e.hasTypeReg)
-        return e.typeReg;
-    e.typeReg = allocReg();
-    e.hasTypeReg = true;
-    regs[e.typeReg] = &e;
-    masm->loadTypeTag(frame->addressOf(fe), e.typeReg);
-    return e.typeReg;
-}
-
-JSC::MacroAssembler::RegisterID
-ImmutableSync::ensureDataReg(FrameEntry *fe, SyncEntry &e)
-{
-    if (fe->data.inRegister() && !e.dataClobbered)
-        return fe->data.reg();
-    if (e.hasDataReg)
-        return e.dataReg;
-    e.dataReg = allocReg();
-    e.hasDataReg = true;
-    regs[e.dataReg] = &e;
-    masm->loadPayload(frame->addressOf(fe), e.dataReg);
-    return e.dataReg;
-}
-
-void
-ImmutableSync::syncCopy(FrameEntry *fe)
-{
-    JS_ASSERT(fe >= bottom);
-
-    FrameEntry *backing = fe->copyOf();
-    SyncEntry &e = entryFor(backing);
-
-    JS_ASSERT(!backing->isConstant());
-
-    Address addr = frame->addressOf(fe);
-
-    if (fe->isTypeKnown() && !fe->isType(JSVAL_TYPE_DOUBLE) && !e.learnedType) {
-        e.learnedType = true;
-        e.type = fe->getKnownType();
-    }
-
-    if (!fe->data.synced())
-        masm->storePayload(ensureDataReg(backing, e), addr);
-
-    if (!fe->type.synced()) {
-        if (e.learnedType)
-            masm->storeTypeTag(ImmType(e.type), addr);
-        else
-            masm->storeTypeTag(ensureTypeReg(backing, e), addr);
-    }
-}
-
-void
-ImmutableSync::syncNormal(FrameEntry *fe)
-{
-    SyncEntry &e = entryFor(fe);
-
-    Address addr = frame->addressOf(fe);
-
-    if (fe->isTypeKnown() && !fe->isType(JSVAL_TYPE_DOUBLE)) {
-        e.learnedType = true;
-        e.type = fe->getKnownType();
-    }
-
-    if (shouldSyncData(fe, e)) {
-        if (fe->isConstant()) {
-            masm->storeValue(fe->getValue(), addr);
-            return;
-        }
-        masm->storePayload(ensureDataReg(fe, e), addr);
-    }
-
-    if (shouldSyncType(fe, e)) {
-        if (e.learnedType)
-            masm->storeTypeTag(ImmType(e.type), addr);
-        else
-            masm->storeTypeTag(ensureTypeReg(fe, e), addr);
-    }
-
-    if (e.hasDataReg) {
-        freeReg(e.dataReg);
-        regs[e.dataReg] = NULL;
-    } else if (!e.dataClobbered &&
-               fe->data.inRegister() &&
-               frame->regstate(fe->data.reg()).usedBy()) {
-        freeReg(fe->data.reg());
-    }
-
-    if (e.hasTypeReg) {
-        freeReg(e.typeReg);
-        regs[e.typeReg] = NULL;
-    } else if (!e.typeClobbered &&
-               fe->type.inRegister() &&
-               frame->regstate(fe->type.reg()).usedBy()) {
-        freeReg(fe->type.reg());
-    }
-}
-
-#endif /* JS_NUNBOX32 */
-
deleted file mode 100644
--- a/js/src/methodjit/ImmutableSync.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_imm_sync_h__ && defined JS_METHODJIT && defined JS_NUNBOX32
-#define jsjaeger_imm_sync_h__
-
-#include "methodjit/MachineRegs.h"
-#include "methodjit/FrameEntry.h"
-#include "CodeGenIncludes.h"
-
-namespace js {
-namespace mjit {
-
-class FrameState;
-
-/*
- * This is a structure nestled within the FrameState used for safely syncing
- * registers to memory during transitions from the fast path into a slow path
- * stub call. During this process, the frame itself is immutable, and we may
- * run out of registers needed to remat copies.
- *
- * This structure maintains a mapping of the tracker used to perform ad-hoc
- * register allocation.
- */
-class ImmutableSync
-{
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::Address Address;
-
-    struct SyncEntry {
-        /*
-         * NB: clobbered and sync mean the same thing: the register associated
-         * in the FrameEntry is no longer valid, and has been written back.
-         *
-         * They are separated for readability.
-         */
-        uint32_t generation;
-        bool dataClobbered;
-        bool typeClobbered;
-        bool hasDataReg;
-        bool hasTypeReg;
-        bool learnedType;
-        RegisterID dataReg;
-        RegisterID typeReg;
-        JSValueType type;
-
-        void reset(uint32_t gen) {
-            dataClobbered = false;
-            typeClobbered = false;
-            hasDataReg = false;
-            hasTypeReg = false;
-            learnedType = false;
-            generation = gen;
-        }
-    };
-
-  public:
-    ImmutableSync();
-    ~ImmutableSync();
-    bool init(JSContext *cx, const FrameState &frame, uint32_t nentries);
-
-    void reset(Assembler *masm, Registers avail, FrameEntry *top, FrameEntry *bottom);
-    void sync(FrameEntry *fe);
-
-  private:
-    void syncCopy(FrameEntry *fe);
-    void syncNormal(FrameEntry *fe);
-    RegisterID ensureDataReg(FrameEntry *fe, SyncEntry &e);
-    RegisterID ensureTypeReg(FrameEntry *fe, SyncEntry &e);
-
-    RegisterID allocReg();
-    void freeReg(RegisterID reg);
-
-    /* To be called only by allocReg. */
-    RegisterID doAllocReg();
-
-    inline SyncEntry &entryFor(FrameEntry *fe);
-
-    bool shouldSyncType(FrameEntry *fe, SyncEntry &e);
-    bool shouldSyncData(FrameEntry *fe, SyncEntry &e);
-
-  private:
-    JSContext *cx;
-    SyncEntry *entries;
-    const FrameState *frame;
-    uint32_t nentries;
-    Registers avail;
-    Assembler *masm;
-    SyncEntry *regs[Assembler::TotalRegisters];
-    FrameEntry *top;
-    FrameEntry *bottom;
-    uint32_t generation;
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_imm_sync_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/InlineFrameAssembler.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_inl_frame_asm_h__ && defined JS_METHODJIT && defined JS_MONOIC
-#define jsjaeger_inl_frame_asm_h__
-
-#include "assembler/assembler/MacroAssembler.h"
-#include "assembler/assembler/CodeLocation.h"
-#include "methodjit/MethodJIT.h"
-#include "CodeGenIncludes.h"
-
-namespace js {
-namespace mjit {
-
-struct AdjustedFrame {
-    AdjustedFrame(uint32_t baseOffset)
-     : baseOffset(baseOffset)
-    { }
-
-    uint32_t baseOffset;
-
-    JSC::MacroAssembler::Address addrOf(uint32_t offset) {
-        return JSC::MacroAssembler::Address(JSFrameReg, baseOffset + offset);
-    }
-};
-
-/*
- * This is used for emitting code to inline callee-side frame creation and
- * should jit code equivalent to StackFrame::initCallFrameCallerHalf.
- *
- * Once finished, JSFrameReg is advanced to be the new fp.
- */
-class InlineFrameAssembler {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::Address Address;
-    typedef JSC::MacroAssembler::Imm32 Imm32;
-    typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-    typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
-
-    Assembler &masm;
-    FrameSize  frameSize;       // size of the caller's frame
-    RegisterID funObjReg;       // register containing the function object (callee)
-    uint32_t   flags;           // frame flags
-
-  public:
-    /*
-     * Register state, so consumers of this class can restrict which registers
-     * can and can't be clobbered.
-     */
-    Registers  tempRegs;
-
-    InlineFrameAssembler(Assembler &masm, ic::CallICInfo &ic, uint32_t flags)
-      : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
-    {
-        frameSize = ic.frameSize;
-        funObjReg = ic.funObjReg;
-        tempRegs.takeReg(funObjReg);
-    }
-
-    InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, uint32_t flags)
-      : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
-    {
-        frameSize = gen.frameSize;
-        funObjReg = gen.funObjReg;
-        tempRegs.takeReg(funObjReg);
-    }
-
-    DataLabelPtr assemble(void *ncode, jsbytecode *pc)
-    {
-        JS_ASSERT((flags & ~StackFrame::CONSTRUCTING) == 0);
-
-        /* Generate StackFrame::initCallFrameCallerHalf. */
-
-        /* Get the actual flags to write. */
-        JS_ASSERT(!(flags & ~StackFrame::CONSTRUCTING));
-        uint32_t flags = this->flags | StackFrame::FUNCTION;
-        if (frameSize.lowered(pc))
-            flags |= StackFrame::LOWERED_CALL_APPLY;
-
-        DataLabelPtr ncodePatch;
-        if (frameSize.isStatic()) {
-            uint32_t frameDepth = frameSize.staticLocalSlots();
-            AdjustedFrame newfp(sizeof(StackFrame) + frameDepth * sizeof(Value));
-
-            Address flagsAddr = newfp.addrOf(StackFrame::offsetOfFlags());
-            masm.store32(Imm32(flags), flagsAddr);
-            Address prevAddr = newfp.addrOf(StackFrame::offsetOfPrev());
-            masm.storePtr(JSFrameReg, prevAddr);
-            Address ncodeAddr = newfp.addrOf(StackFrame::offsetOfNcode());
-            ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
-
-            masm.addPtr(Imm32(sizeof(StackFrame) + frameDepth * sizeof(Value)), JSFrameReg);
-        } else {
-            /*
-             * If the frame size is dynamic, then the fast path generated by
-             * generateFullCallStub must be used. Thus, this code is executed
-             * after stubs::SplatApplyArgs has been called. SplatApplyArgs
-             * stores the dynamic stack pointer (i.e., regs.sp after pushing a
-             * dynamic number of arguments) to VMFrame.regs, so we just load it
-             * here to get the new frame pointer.
-             */
-            RegisterID newfp = tempRegs.takeAnyReg().reg();
-            masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), newfp);
-
-            Address flagsAddr(newfp, StackFrame::offsetOfFlags());
-            masm.store32(Imm32(flags), flagsAddr);
-            Address prevAddr(newfp, StackFrame::offsetOfPrev());
-            masm.storePtr(JSFrameReg, prevAddr);
-            Address ncodeAddr(newfp, StackFrame::offsetOfNcode());
-            ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
-
-            masm.move(newfp, JSFrameReg);
-            tempRegs.putReg(newfp);
-        }
-
-        return ncodePatch;
-    }
-};
-
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_inl_frame_asm_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ /dev/null
@@ -1,1114 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/DebugOnly.h"
-
-#include "jsanalyze.h"
-#include "jscntxt.h"
-#include "jsobj.h"
-#include "jslibmath.h"
-#include "jsiter.h"
-#include "jsnum.h"
-#include "jsbool.h"
-#include "jstypes.h"
-
-#include "assembler/assembler/MacroAssemblerCodeRef.h"
-#include "assembler/assembler/CodeLocation.h"
-#include "builtin/Eval.h"
-#include "methodjit/StubCalls.h"
-#include "methodjit/MonoIC.h"
-#include "methodjit/BaseCompiler.h"
-#include "methodjit/ICRepatcher.h"
-#include "vm/Debugger.h"
-#include "vm/Shape.h"
-
-#include "jsinterpinlines.h"
-#include "jsscriptinlines.h"
-#include "jsobjinlines.h"
-#include "jscntxtinlines.h"
-#include "jsatominlines.h"
-
-#include "StubCalls-inl.h"
-
-#include "vm/Shape-inl.h"
-
-#include "jsautooplen.h"
-
-#include "ion/Ion.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace JSC;
-
-using mozilla::DebugOnly;
-
-using ic::Repatcher;
-
-static jsbytecode *
-FindExceptionHandler(JSContext *cx)
-{
-    StackFrame *fp = cx->fp();
-    RootedScript script(cx, fp->script());
-
-    if (!script->hasTrynotes())
-        return NULL;
-
-  error:
-    if (cx->isExceptionPending()) {
-        for (TryNoteIter tni(cx, cx->regs()); !tni.done(); ++tni) {
-            JSTryNote *tn = *tni;
-
-            UnwindScope(cx, cx->fp(), tn->stackDepth);
-
-            /*
-             * Set pc to the first bytecode after the the try note to point
-             * to the beginning of catch or finally or to [enditer] closing
-             * the for-in loop.
-             */
-            jsbytecode *pc = script->main() + tn->start + tn->length;
-            cx->regs().pc = pc;
-            cx->regs().sp = cx->regs().spForStackDepth(tn->stackDepth);
-
-            switch (tn->kind) {
-                case JSTRY_CATCH:
-                  JS_ASSERT(JSOp(*pc) == JSOP_ENTERBLOCK);
-
-#if JS_HAS_GENERATORS
-                  /* Catch cannot intercept the closing of a generator. */
-                  if (JS_UNLIKELY(cx->getPendingException().isMagic(JS_GENERATOR_CLOSING)))
-                      break;
-#endif
-
-                  /*
-                   * Don't clear cx->throwing to save cx->exception from GC
-                   * until it is pushed to the stack via [exception] in the
-                   * catch block.
-                   */
-                  return pc;
-
-                case JSTRY_FINALLY:
-                  /*
-                   * Push (true, exception) pair for finally to indicate that
-                   * [retsub] should rethrow the exception.
-                   */
-                  cx->regs().sp[0].setBoolean(true);
-                  cx->regs().sp[1] = cx->getPendingException();
-                  cx->regs().sp += 2;
-                  cx->clearPendingException();
-                  return pc;
-
-                case JSTRY_ITER:
-                {
-                  /*
-                   * This is similar to JSOP_ENDITER in the interpreter loop,
-                   * except the code now uses the stack slot normally used by
-                   * JSOP_NEXTITER, namely regs.sp[-1] before the regs.sp -= 2
-                   * adjustment and regs.sp[1] after, to save and restore the
-                   * pending exception.
-                   */
-                  JS_ASSERT(JSOp(*pc) == JSOP_ENDITER);
-                  RootedObject obj(cx, &cx->regs().sp[-1].toObject());
-                  bool ok = UnwindIteratorForException(cx, obj);
-                  cx->regs().sp -= 1;
-                  if (!ok)
-                      goto error;
-                  break;
-                }
-
-                case JSTRY_LOOP:
-                  break;
-            }
-        }
-    } else {
-        UnwindForUncatchableException(cx, cx->regs());
-    }
-
-    return NULL;
-}
-
-/*
- * Clean up a frame and return.
- */
-
-static inline bool
-MaybeCloneAndPatchCallee(JSContext *cx, CallArgs args, HandleScript script, jsbytecode *pc)
-{
-    if (cx->typeInferenceEnabled() && !args.calleev().isPrimitive() &&
-        args.callee().isFunction() && args.callee().toFunction()->hasScript() &&
-        args.callee().toFunction()->nonLazyScript()->shouldCloneAtCallsite)
-    {
-        RootedFunction fun(cx, args.callee().toFunction());
-        fun = CloneFunctionAtCallsite(cx, fun, script, pc);
-        if (!fun)
-            return false;
-        args.setCallee(ObjectValue(*fun));
-    }
-
-    return true;
-}
-
-void JS_FASTCALL
-stubs::SlowCall(VMFrame &f, uint32_t argc)
-{
-    if (*f.regs.pc == JSOP_FUNAPPLY && !GuardFunApplyArgumentsOptimization(f.cx))
-        THROW();
-
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-    RootedScript fscript(f.cx, f.script());
-
-    if (!MaybeCloneAndPatchCallee(f.cx, args, fscript, f.pc()))
-        THROW();
-    if (!Invoke(f.cx, args))
-        THROW();
-
-    types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-}
-
-void JS_FASTCALL
-stubs::SlowNew(VMFrame &f, uint32_t argc)
-{
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-    RootedScript fscript(f.cx, f.script());
-
-    if (!MaybeCloneAndPatchCallee(f.cx, args, fscript, f.pc()))
-        THROW();
-    if (!InvokeConstructor(f.cx, args))
-        THROW();
-
-    types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-}
-
-static inline bool
-CheckStackQuota(VMFrame &f)
-{
-    JS_ASSERT(f.regs.stackDepth() == 0);
-
-    f.stackLimit = f.cx->stack.space().getStackLimit(f.cx, DONT_REPORT_ERROR);
-    if (f.stackLimit)
-        return true;
-
-    /* Remove the current partially-constructed frame before throwing. */
-    f.cx->stack.popFrameAfterOverflow();
-    js_ReportOverRecursed(f.cx);
-
-    return false;
-}
-
-/*
- * HitStackQuota is called after the early prologue pushing the new frame would
- * overflow f.stackLimit.
- */
-void JS_FASTCALL
-stubs::HitStackQuota(VMFrame &f)
-{
-    if (!CheckStackQuota(f))
-        THROW();
-}
-
-/*
- * This function must only be called after the early prologue, since it depends
- * on fp->exec.fun.
- */
-void * JS_FASTCALL
-stubs::FixupArity(VMFrame &f, uint32_t nactual)
-{
-    JSContext *cx = f.cx;
-    StackFrame *oldfp = f.fp();
-
-    JS_ASSERT(nactual != oldfp->numFormalArgs());
-
-    /*
-     * Grossssss! *move* the stack frame. If this ends up being perf-critical,
-     * we can figure out how to spot-optimize it. Be careful to touch only the
-     * members that have been initialized by the caller and early prologue.
-     */
-    InitialFrameFlags initial = oldfp->initialFlags();
-    RootedFunction fun(cx, oldfp->fun());
-    RootedScript script(cx, fun->nonLazyScript());
-    void *ncode = oldfp->nativeReturnAddress();
-
-    /* Pop the inline frame. */
-    f.regs.popPartialFrame((Value *)oldfp);
-
-    /* Reserve enough space for a callee frame. */
-    CallArgs args = CallArgsFromSp(nactual, f.regs.sp);
-    if (script->isCallsiteClone) {
-        JS_ASSERT(args.callee().toFunction() == script->originalFunction());
-        args.setCallee(ObjectValue(*fun));
-    }
-    StackFrame *fp = cx->stack.getFixupFrame(cx, DONT_REPORT_ERROR, args, fun,
-                                             script, ncode, initial, &f.stackLimit);
-
-    if (!fp) {
-        f.regs.updateForNcode(f.jit(), ncode);
-        js_ReportOverRecursed(cx);
-        THROWV(NULL);
-    }
-
-    /* The caller takes care of assigning fp to regs. */
-    return fp;
-}
-
-struct ResetStubRejoin {
-    VMFrame &f;
-    ResetStubRejoin(VMFrame &f) : f(f) {}
-    ~ResetStubRejoin() { f.stubRejoin = 0; }
-};
-
-void * JS_FASTCALL
-stubs::CompileFunction(VMFrame &f, uint32_t argc)
-{
-    /*
-     * Note: the stubRejoin kind for the frame was written before the call, and
-     * needs to be cleared out on all return paths (doing this directly in the
-     * IC stub will not handle cases where we recompiled or threw).
-     */
-    JS_ASSERT_IF(f.cx->typeInferenceEnabled(), f.stubRejoin);
-    ResetStubRejoin reset(f);
-
-    InitialFrameFlags initial = f.fp()->initialFlags();
-    f.regs.popPartialFrame((Value *)f.fp());
-
-    if (InitialFrameFlagsAreConstructing(initial))
-        return UncachedNew(f, argc);
-    else if (InitialFrameFlagsAreLowered(initial))
-        return UncachedLoweredCall(f, argc);
-    else
-        return UncachedCall(f, argc);
-}
-
-// Heuristics to decide whether a JM function call should invoke JM or Ion. Calling
-// into Ion may be faster, especially if the function contains loops, but JM -> Ion
-// calls are slower than JM -> JM calls.
-static inline bool
-ShouldJaegerCompileCallee(JSContext *cx, JSScript *caller, JSScript *callee, JITScript *callerJit)
-{
-#ifdef JS_ION
-    if (!ion::IsEnabled(cx))
-        return true;
-
-    // If we know Ion cannot compile either the caller or callee, use JM.
-    if (!callee->canIonCompile())
-        return true;
-
-    // Use JM if the callee has no loops. In this case calling into Ion
-    // is likely not worth the overhead.
-    if (!callee->hasAnalysis())
-        return true;
-
-    if (callee->isShortRunning())
-        return true;
-
-    return false;
-#endif
-    return true;
-}
-
-static inline bool
-UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
-                   void **pret, bool *unjittable, uint32_t argc)
-{
-    JSContext *cx = f.cx;
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-    RootedFunction newfun(cx, args.callee().toFunction());
-
-    RootedScript newscript(cx, newfun->nonLazyScript());
-    if (!newscript)
-        return false;
-
-    bool construct = InitialFrameFlagsAreConstructing(initial);
-
-    RootedScript fscript(cx, f.script());
-    bool newType = construct && cx->typeInferenceEnabled() &&
-        types::UseNewType(cx, fscript, f.pc());
-
-    if (!types::TypeMonitorCall(cx, args, construct))
-        return false;
-
-    /* Try to compile if not already compiled. */
-    if (ShouldJaegerCompileCallee(cx, f.script(), newscript, f.jit())) {
-        CompileStatus status = CanMethodJIT(cx, newscript, newscript->code, construct,
-                                            CompileRequest_JIT, f.fp());
-        if (status == Compile_Error) {
-            /* A runtime exception was thrown, get out. */
-            return false;
-        }
-        if (status == Compile_Abort)
-            *unjittable = true;
-    }
-
-    /*
-     * Make sure we are not calling from an inline frame if we need to make a
-     * call object for the callee, as doing so could trigger GC and cause
-     * jitcode discarding / frame expansion.
-     */
-    if (f.regs.inlined() && newfun->isHeavyweight()) {
-        ExpandInlineFrames(cx->zone());
-        JS_ASSERT(!f.regs.inlined());
-    }
-
-    /*
-     * Preserve f.regs.fp while pushing the new frame, for the invariant that
-     * f.regs reflects the state when we entered the stub call. This handoff is
-     * tricky: we need to make sure that f.regs is not updated to the new
-     * frame, and we also need to ensure that cx->regs still points to f.regs
-     * when space is reserved, in case doing so throws an exception.
-     */
-    FrameRegs regs = f.regs;
-
-    /* Get pointer to new frame/slots, prepare arguments. */
-    if (!cx->stack.pushInlineFrame(cx, regs, args, newfun, newscript, initial, &f.stackLimit))
-        return false;
-
-    /* Finish the handoff to the new frame regs. */
-    PreserveRegsGuard regsGuard(cx, regs);
-
-    /*
-     * If newscript was successfully compiled, run it. Skip for calls which
-     * will be constructing a new type object for 'this'.
-     */
-    if (!newType) {
-        if (JITScript *jit = newscript->getJIT(regs.fp()->isConstructing(), cx->zone()->compileBarriers())) {
-            if (jit->invokeEntry) {
-                *pret = jit->invokeEntry;
-
-                /* Restore the old fp around and let the JIT code repush the new fp. */
-                regs.popFrame((Value *) regs.fp());
-                return true;
-            }
-        }
-    }
-
-    /*
-     * Otherwise, run newscript in the interpreter. Expand any inlined frame we
-     * are calling from, as the new frame is not associated with the VMFrame
-     * and will not have its prevpc info updated if frame expansion is
-     * triggered while interpreting.
-     */
-    if (f.regs.inlined()) {
-        ExpandInlineFrames(cx->zone());
-        JS_ASSERT(!f.regs.inlined());
-        regs.fp()->resetInlinePrev(f.fp(), f.regs.pc);
-    }
-
-    JS_CHECK_RECURSION(cx, return false);
-
-    bool ok = RunScript(cx, cx->fp());
-    f.cx->stack.popInlineFrame(regs);
-
-    if (ok) {
-        RootedScript fscript(cx, f.script());
-        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-    }
-
-    *pret = NULL;
-    return ok;
-}
-
-void * JS_FASTCALL
-stubs::UncachedNew(VMFrame &f, uint32_t argc)
-{
-    UncachedCallResult ucr(f.cx);
-    UncachedNewHelper(f, argc, ucr);
-    return ucr.codeAddr;
-}
-
-void
-stubs::UncachedNewHelper(VMFrame &f, uint32_t argc, UncachedCallResult &ucr)
-{
-    ucr.init();
-    JSContext *cx = f.cx;
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-    RootedScript fscript(cx, f.script());
-
-    if (!ucr.setFunction(cx, args, fscript, f.pc()))
-        THROW();
-
-    /* Try to do a fast inline call before the general Invoke path. */
-    if (ucr.fun && ucr.fun->isInterpretedConstructor()) {
-        if (!UncachedInlineCall(f, INITIAL_CONSTRUCT, &ucr.codeAddr, &ucr.unjittable, argc))
-            THROW();
-    } else {
-        if (!InvokeConstructor(cx, args))
-            THROW();
-        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-    }
-}
-
-void * JS_FASTCALL
-stubs::UncachedCall(VMFrame &f, uint32_t argc)
-{
-    UncachedCallResult ucr(f.cx);
-    UncachedCallHelper(f, argc, false, ucr);
-    return ucr.codeAddr;
-}
-
-void * JS_FASTCALL
-stubs::UncachedLoweredCall(VMFrame &f, uint32_t argc)
-{
-    UncachedCallResult ucr(f.cx);
-    UncachedCallHelper(f, argc, true, ucr);
-    return ucr.codeAddr;
-}
-
-void JS_FASTCALL
-stubs::Eval(VMFrame &f, uint32_t argc)
-{
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-
-    if (!IsBuiltinEvalForScope(f.fp()->scopeChain(), args.calleev())) {
-        if (!Invoke(f.cx, args))
-            THROW();
-
-        RootedScript fscript(f.cx, f.script());
-        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-        return;
-    }
-
-    JS_ASSERT(f.fp() == f.cx->fp());
-    if (!DirectEval(f.cx, args))
-        THROW();
-
-    RootedScript fscript(f.cx, f.script());
-    types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-}
-
-void
-stubs::UncachedCallHelper(VMFrame &f, uint32_t argc, bool lowered, UncachedCallResult &ucr)
-{
-    ucr.init();
-
-    JSContext *cx = f.cx;
-    CallArgs args = CallArgsFromSp(argc, f.regs.sp);
-    RootedScript fscript(cx, f.script());
-
-    if (!ucr.setFunction(cx, args, fscript, f.pc()))
-        THROW();
-
-    if (ucr.fun) {
-        if (ucr.fun->isInterpreted()) {
-            InitialFrameFlags initial = lowered ? INITIAL_LOWERED : INITIAL_NONE;
-            if (!UncachedInlineCall(f, initial, &ucr.codeAddr, &ucr.unjittable, argc))
-                THROW();
-            return;
-        }
-
-        if (ucr.fun->isNative()) {
-            if (!CallJSNative(cx, ucr.fun->native(), args))
-                THROW();
-            RootedScript fscript(cx, f.script());
-            types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-            return;
-        }
-    }
-
-    if (!Invoke(f.cx, args))
-        THROW();
-
-    types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-    return;
-}
-
-static void
-RemoveOrphanedNative(JSContext *cx, StackFrame *fp)
-{
-    /*
-     * Remove fp from the list of frames holding a reference on the orphaned
-     * native pools. If all the references have been removed, release all the
-     * pools. We don't release pools piecemeal as a pool can be referenced by
-     * multiple frames.
-     */
-    JaegerRuntime &jr = cx->jaegerRuntime();
-    if (jr.orphanedNativeFrames.empty())
-        return;
-    for (unsigned i = 0; i < jr.orphanedNativeFrames.length(); i++) {
-        if (fp == jr.orphanedNativeFrames[i]) {
-            jr.orphanedNativeFrames[i] = jr.orphanedNativeFrames.back();
-            jr.orphanedNativeFrames.popBack();
-            break;
-        }
-    }
-    if (jr.orphanedNativeFrames.empty()) {
-        for (unsigned i = 0; i < jr.orphanedNativePools.length(); i++)
-            jr.orphanedNativePools[i]->release();
-        jr.orphanedNativePools.clear();
-    }
-}
-
-extern "C" void *
-js_InternalThrow(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-
-    ExpandInlineFrames(cx->zone());
-
-    // The current frame may have an associated orphaned native, if the native
-    // or SplatApplyArgs threw an exception.
-    RemoveOrphanedNative(cx, f.fp());
-
-    JS_ASSERT(!f.fp()->finishedInInterpreter());
-
-    // Make sure sp is up to date.
-    JS_ASSERT(&cx->regs() == &f.regs);
-
-    jsbytecode *pc = NULL;
-    for (;;) {
-        if (cx->isExceptionPending()) {
-            // Call the throw hook if necessary
-            JSThrowHook handler = cx->runtime->debugHooks.throwHook;
-            if (handler || !cx->compartment->getDebuggees().empty()) {
-                RootedValue rval(cx);
-                JSTrapStatus st = Debugger::onExceptionUnwind(cx, &rval);
-                if (st == JSTRAP_CONTINUE && handler) {
-                    RootedScript fscript(cx, cx->fp()->script());
-                    st = handler(cx, fscript, cx->regs().pc, rval.address(),
-                                 cx->runtime->debugHooks.throwHookData);
-                }
-
-                switch (st) {
-                case JSTRAP_ERROR:
-                    cx->clearPendingException();
-                    break;
-
-                case JSTRAP_CONTINUE:
-                    break;
-
-                case JSTRAP_RETURN:
-                    cx->clearPendingException();
-                    cx->fp()->setReturnValue(rval);
-                    return cx->jaegerRuntime().forceReturnFromExternC();
-
-                case JSTRAP_THROW:
-                    cx->setPendingException(rval);
-                    break;
-
-                default:
-                    JS_NOT_REACHED("bad onExceptionUnwind status");
-                }
-            }
-        }
-
-        pc = FindExceptionHandler(cx);
-        if (pc)
-            break;
-
-        // The JIT guarantees that ScriptDebugEpilogue() and ScriptEpilogue()
-        // have always been run upon exiting to its caller. This is important
-        // for consistency, where execution modes make similar guarantees about
-        // prologues and epilogues. Interpret(), and Invoke() all rely on this
-        // property.
-        JS_ASSERT(!f.fp()->finishedInInterpreter());
-        UnwindScope(cx, cx->fp(), 0);
-        f.regs.setToEndOfScript();
-
-        if (cx->compartment->debugMode()) {
-            // This can turn a throw or error into a healthy return. Note that
-            // we will run ScriptDebugEpilogue again (from AnyFrameEpilogue);
-            // ScriptDebugEpilogue is prepared for this eventuality.
-            if (js::ScriptDebugEpilogue(cx, f.fp(), false))
-                return cx->jaegerRuntime().forceReturnFromExternC();
-        }
-
-
-        f.fp()->epilogue(f.cx);
-
-        // Don't remove the last frame, this is the responsibility of
-        // JaegerShot()'s caller. We only guarantee that ScriptEpilogue()
-        // has been run.
-        if (f.entryfp == f.fp())
-            break;
-
-        f.cx->stack.popInlineFrame(f.regs);
-        DebugOnly<JSOp> op = JSOp(*f.regs.pc);
-        JS_ASSERT(op == JSOP_CALL ||
-                  op == JSOP_NEW ||
-                  op == JSOP_EVAL ||
-                  op == JSOP_FUNCALL ||
-                  op == JSOP_FUNAPPLY);
-        f.regs.pc += JSOP_CALL_LENGTH;
-    }
-
-    JS_ASSERT(&cx->regs() == &f.regs);
-
-    if (!pc)
-        return NULL;
-
-    StackFrame *fp = cx->fp();
-    RootedScript script(cx, fp->script());
-
-    /*
-     * Fall back to EnterMethodJIT and finish the frame in the interpreter.
-     * With type inference enabled, we may wipe out all JIT code on the
-     * stack without patching ncode values to jump to the interpreter, and
-     * thus can only enter JIT code via EnterMethodJIT (which overwrites
-     * its entry frame's ncode). See ClearAllFrames.
-     */
-    cx->jaegerRuntime().setLastUnfinished(Jaeger_Unfinished);
-
-    if (!script->ensureRanAnalysis(cx)) {
-        js_ReportOutOfMemory(cx);
-        return NULL;
-    }
-
-    types::AutoEnterAnalysis enter(cx);
-
-    /*
-     * Interpret the ENTERBLOCK and EXCEPTION opcodes, so that we don't go
-     * back into the interpreter with a pending exception. This will cause
-     * it to immediately rethrow.
-     */
-    if (cx->isExceptionPending()) {
-        JS_ASSERT(JSOp(*pc) == JSOP_ENTERBLOCK);
-        StaticBlockObject &blockObj = script->getObject(GET_UINT32_INDEX(pc))->asStaticBlock();
-        Value *vp = cx->regs().sp + blockObj.slotCount();
-        SetValueRangeToUndefined(cx->regs().sp, vp);
-        cx->regs().sp = vp;
-        if (!cx->regs().fp()->pushBlock(cx, blockObj))
-            return NULL;
-
-        JS_ASSERT(JSOp(pc[JSOP_ENTERBLOCK_LENGTH]) == JSOP_EXCEPTION);
-        cx->regs().sp[0] = cx->getPendingException();
-        cx->clearPendingException();
-        cx->regs().sp++;
-
-        cx->regs().pc = pc + JSOP_ENTERBLOCK_LENGTH + JSOP_EXCEPTION_LENGTH;
-    }
-
-    *f.oldregs = f.regs;
-
-    return NULL;
-}
-
-void JS_FASTCALL
-stubs::CreateThis(VMFrame &f, JSObject *proto)
-{
-    JSContext *cx = f.cx;
-    StackFrame *fp = f.fp();
-    RootedObject callee(cx, &fp->callee());
-    JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto);
-    if (!obj)
-        THROW();
-    fp->thisValue() = ObjectValue(*obj);
-}
-
-void JS_FASTCALL
-stubs::ScriptDebugPrologue(VMFrame &f)
-{
-    Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
-    JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
-    switch (status) {
-      case JSTRAP_CONTINUE:
-        break;
-      case JSTRAP_RETURN:
-        *f.returnAddressLocation() = f.cx->jaegerRuntime().forceReturnFromFastCall();
-        return;
-      case JSTRAP_ERROR:
-      case JSTRAP_THROW:
-        THROW();
-      default:
-        JS_NOT_REACHED("bad ScriptDebugPrologue status");
-    }
-}
-
-void JS_FASTCALL
-stubs::ScriptDebugEpilogue(VMFrame &f)
-{
-    if (!js::ScriptDebugEpilogue(f.cx, f.fp(), JS_TRUE))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::ScriptProbeOnlyPrologue(VMFrame &f)
-{
-    Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
-}
-
-void JS_FASTCALL
-stubs::ScriptProbeOnlyEpilogue(VMFrame &f)
-{
-    Probes::exitScript(f.cx, f.script(), f.script()->function(), f.fp());
-}
-
-void JS_FASTCALL
-stubs::CrossChunkShim(VMFrame &f, void *edge_)
-{
-    DebugOnly<CrossChunkEdge*> edge = (CrossChunkEdge *) edge_;
-
-    mjit::ExpandInlineFrames(f.cx->zone());
-
-    RootedScript script(f.cx, f.script());
-    JS_ASSERT(edge->target < script->length);
-    JS_ASSERT(script->code + edge->target == f.pc());
-
-    CompileStatus status = CanMethodJIT(f.cx, script, f.pc(),
-                                        f.fp()->isConstructing(),
-                                        CompileRequest_Interpreter, f.fp());
-    if (status == Compile_Error)
-        THROW();
-
-    void **addr = f.returnAddressLocation();
-    *addr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
-
-    f.fp()->setRejoin(StubRejoin(REJOIN_RESUME));
-}
-
-JS_STATIC_ASSERT(JSOP_NOP == 0);
-
-/* :XXX: common out with identical copy in Compiler.cpp */
-#if defined(JS_METHODJIT_SPEW)
-static const char *OpcodeNames[] = {
-# define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) #name,
-# include "jsopcode.tbl"
-# undef OPDEF
-};
-#endif
-
-extern "C" void *
-js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VMFrame &f)
-{
-    FrameRejoinState jsrejoin = f.fp()->rejoin();
-    RejoinState rejoin;
-    if (jsrejoin & 0x1) {
-        /* Rejoin after a scripted call finished. Restore f.regs.pc and f.regs.inlined (NULL) */
-        uint32_t pcOffset = jsrejoin >> 1;
-        f.regs.pc = f.fp()->script()->code + pcOffset;
-        f.regs.clearInlined();
-        rejoin = REJOIN_SCRIPTED;
-    } else {
-        rejoin = (RejoinState) (jsrejoin >> 1);
-    }
-
-    JSContext *cx = f.cx;
-    StackFrame *fp = f.regs.fp();
-    RootedScript script(cx, fp->script());
-
-    jsbytecode *pc = f.regs.pc;
-
-    JSOp op = JSOp(*pc);
-
-    if (!script->ensureRanAnalysis(cx)) {
-        js_ReportOutOfMemory(cx);
-        return js_InternalThrow(f);
-    }
-
-    mozilla::Maybe<types::AutoEnterAnalysis> enter;
-    enter.construct(cx);
-
-    analyze::ScriptAnalysis *analysis = script->analysis();
-
-    /*
-     * f.regs.sp is not normally maintained by stubs (except for call prologues
-     * where it indicates the new frame), so is not expected to be coherent
-     * here. Update it to its value at the start of the opcode.
-     */
-    Value *oldsp = f.regs.sp;
-    f.regs.sp = f.regs.spForStackDepth(analysis->getCode(pc).stackDepth);
-
-    jsbytecode *nextpc = pc + GetBytecodeLength(pc);
-    Value *nextsp = NULL;
-    if (nextpc != script->code + script->length && analysis->maybeCode(nextpc))
-        nextsp = f.regs.spForStackDepth(analysis->getCode(nextpc).stackDepth);
-
-    JS_ASSERT(&cx->regs() == &f.regs);
-
-#ifdef JS_METHODJIT_SPEW
-    JaegerSpew(JSpew_Recompile, "interpreter rejoin (file \"%s\") (line \"%d\") (op %s) (opline \"%d\")\n",
-               script->filename(), script->lineno, OpcodeNames[op], PCToLineNumber(script, pc));
-#endif
-
-    uint32_t nextDepth = UINT32_MAX;
-    bool skipTrap = false;
-
-    switch (rejoin) {
-      case REJOIN_SCRIPTED: {
-        jsval_layout rval;
-#ifdef JS_NUNBOX32
-        rval.asBits = ((uint64_t)returnType << 32) | (uint32_t)returnData;
-#elif JS_PUNBOX64
-        rval.asBits = (uint64_t)returnType | (uint64_t)returnData;
-#else
-#error "Unknown boxing format"
-#endif
-
-        nextsp[-1] = IMPL_TO_JSVAL(rval);
-
-        /*
-         * When making a scripted call at monitored sites, it is the caller's
-         * responsibility to update the pushed type set.
-         */
-        types::TypeScript::Monitor(cx, script, pc, nextsp[-1]);
-        f.regs.pc = nextpc;
-        break;
-      }
-
-      case REJOIN_NONE:
-        JS_NOT_REACHED("Unpossible rejoin!");
-        break;
-
-      case REJOIN_RESUME:
-        break;
-
-      case REJOIN_TRAP:
-        /*
-         * Make sure when resuming in the interpreter we do not execute the
-         * trap again. Watch out for the case where the trap removed itself.
-         */
-        if (script->hasBreakpointsAt(pc))
-            skipTrap = true;
-        break;
-
-      case REJOIN_FALLTHROUGH:
-        f.regs.pc = nextpc;
-        break;
-
-      case REJOIN_NATIVE:
-      case REJOIN_NATIVE_LOWERED:
-      case REJOIN_NATIVE_GETTER: {
-        /*
-         * We don't rejoin until after the native stub finishes execution, in
-         * which case the return value will be in memory. For lowered natives,
-         * the return value will be in the 'this' value's slot.
-         */
-        if (rejoin != REJOIN_NATIVE)
-            nextsp[-1] = nextsp[0];
-
-        /* Release this reference on the orphaned native stub. */
-        RemoveOrphanedNative(cx, fp);
-
-        f.regs.pc = nextpc;
-        break;
-      }
-
-      case REJOIN_PUSH_BOOLEAN:
-        nextsp[-1].setBoolean((JSBool)(uintptr_t)returnReg);
-        f.regs.pc = nextpc;
-        break;
-
-      case REJOIN_PUSH_OBJECT:
-        nextsp[-1].setObject(* (JSObject *) returnReg);
-        f.regs.pc = nextpc;
-        break;
-
-      case REJOIN_THIS_PROTOTYPE: {
-        RootedObject callee(cx, &fp->callee());
-        JSObject *proto = f.regs.sp[0].isObject() ? &f.regs.sp[0].toObject() : NULL;
-        JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto);
-        if (!obj)
-            return js_InternalThrow(f);
-        fp->thisValue() = ObjectValue(*obj);
-        /* FALLTHROUGH */
-      }
-
-      case REJOIN_THIS_CREATED: {
-        Probes::enterScript(f.cx, f.script(), f.script()->function(), fp);
-
-        if (script->debugMode) {
-            JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
-            switch (status) {
-              case JSTRAP_CONTINUE:
-                break;
-              case JSTRAP_RETURN: {
-                /* Advance to the JSOP_STOP at the end of the script. */
-                f.regs.pc = script->code + script->length - 1;
-                nextDepth = 0;
-                JS_ASSERT(*f.regs.pc == JSOP_STOP);
-                break;
-              }
-              case JSTRAP_THROW:
-              case JSTRAP_ERROR:
-                return js_InternalThrow(f);
-              default:
-                JS_NOT_REACHED("bad ScriptDebugPrologue status");
-            }
-        }
-
-        break;
-      }
-
-      /*
-       * Each of these cases indicates a point of progress through
-       * generatePrologue. Execute the rest of the prologue here.
-       */
-      case REJOIN_CHECK_ARGUMENTS:
-        if (!CheckStackQuota(f))
-            return js_InternalThrow(f);
-        fp->initVarsToUndefined();
-        fp->scopeChain();
-        if (types::UseNewTypeAtEntry(cx, fp))
-            fp->setUseNewType();
-        if (!fp->prologue(cx))
-            return js_InternalThrow(f);
-
-        /*
-         * We would normally call ScriptDebugPrologue here. But in debug mode,
-         * we only use JITted functions' invokeEntry entry point, whereas
-         * CheckArgumentTypes (REJOIN_CHECK_ARGUMENTS) is only reachable via
-         * the other entry points.
-         *
-         * If we fix bug 699196 ("Debug mode code could use inline caches
-         * now"), then this case will become reachable again.
-         */
-        JS_ASSERT(!cx->compartment->debugMode());
-        break;
-
-      /* Finish executing the tail of generatePrologue. */
-      case REJOIN_FUNCTION_PROLOGUE:
-        if (fp->isConstructing()) {
-            RootedObject callee(cx, &fp->callee());
-            JSObject *obj = CreateThisForFunction(cx, callee, types::UseNewTypeAtEntry(cx, fp));
-            if (!obj)
-                return js_InternalThrow(f);
-            fp->functionThis() = ObjectValue(*obj);
-        }
-        /* FALLTHROUGH */
-      case REJOIN_EVAL_PROLOGUE:
-        Probes::enterScript(cx, f.script(), f.script()->function(), fp);
-        if (cx->compartment->debugMode()) {
-            JSTrapStatus status = ScriptDebugPrologue(cx, fp);
-            switch (status) {
-              case JSTRAP_CONTINUE:
-                break;
-              case JSTRAP_RETURN:
-                return f.cx->jaegerRuntime().forceReturnFromFastCall();
-              case JSTRAP_ERROR:
-              case JSTRAP_THROW:
-                return js_InternalThrow(f);
-              default:
-                JS_NOT_REACHED("bad ScriptDebugPrologue status");
-            }
-        }
-        break;
-
-      case REJOIN_CALL_PROLOGUE:
-      case REJOIN_CALL_PROLOGUE_LOWERED_CALL:
-      case REJOIN_CALL_PROLOGUE_LOWERED_APPLY:
-        if (returnReg) {
-            uint32_t argc = 0;
-            if (rejoin == REJOIN_CALL_PROLOGUE)
-                argc = GET_ARGC(pc);
-            else if (rejoin == REJOIN_CALL_PROLOGUE_LOWERED_CALL)
-                argc = GET_ARGC(pc) - 1;
-            else
-                argc = f.u.call.dynamicArgc;
-
-            /*
-             * The caller frame's code was discarded, but we still need to
-             * execute the callee and have a JIT code pointer to do so.
-             * Set the argc and frame registers as the call path does, but set
-             * the callee frame's return address to jump back into the
-             * Interpoline, and change the caller frame's rejoin to reflect the
-             * state after the call.
-             */
-            f.regs.restorePartialFrame(oldsp); /* f.regs.sp stored the new frame */
-            f.scratch = (void *) uintptr_t(argc); /* The interpoline will load f.scratch into argc */
-            f.fp()->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolineScripted));
-            fp->setRejoin(REJOIN_SCRIPTED | ((pc - script->code) << 1));
-            return returnReg;
-        } else {
-            /*
-             * The call has already finished, and the return value is on the
-             * stack. For lowered call/apply, the return value has been stored
-             * in the wrong slot, so adjust it here.
-             */
-            f.regs.pc = nextpc;
-            if (rejoin != REJOIN_CALL_PROLOGUE) {
-                /* Same offset return value as for lowered native calls. */
-                nextsp[-1] = nextsp[0];
-            }
-        }
-        break;
-
-      case REJOIN_CALL_SPLAT: {
-        /* Leave analysis early and do the Invoke which SplatApplyArgs prepared. */
-        nextDepth = analysis->getCode(nextpc).stackDepth;
-        enter.destroy();
-        f.regs.sp = nextsp + 2 + f.u.call.dynamicArgc;
-        if (!Invoke(cx, CallArgsFromSp(f.u.call.dynamicArgc, f.regs.sp)))
-            return js_InternalThrow(f);
-        nextsp[-1] = nextsp[0];
-        f.regs.pc = nextpc;
-        break;
-      }
-
-      case REJOIN_GETTER:
-        /*
-         * Match the PC to figure out whether this property fetch is part of a
-         * fused opcode which needs to be finished.
-         */
-        switch (op) {
-          case JSOP_INSTANCEOF: {
-            /*
-             * If we recompiled from a getprop used within JSOP_INSTANCEOF,
-             * the stack looks like 'LHS RHS protov'. Inline the remaining
-             * portion of fun_hasInstance.
-             */
-            if (f.regs.sp[0].isPrimitive()) {
-                RootedValue val(cx, f.regs.sp[-1]);
-                js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
-                return js_InternalThrow(f);
-            }
-            bool isDelegate;
-            RootedObject obj(cx, &f.regs.sp[0].toObject());
-            if (!IsDelegate(cx, obj, f.regs.sp[-2], &isDelegate))
-                return js_InternalThrow(f);
-            nextsp[-1].setBoolean(isDelegate);
-            f.regs.pc = nextpc;
-            break;
-          }
-
-          default:
-            f.regs.pc = nextpc;
-            break;
-        }
-        break;
-
-      case REJOIN_BRANCH: {
-        /*
-         * This must be an opcode fused with IFNE/IFEQ. Unfused IFNE/IFEQ are
-         * implemented in terms of ValueToBoolean, which is infallible and
-         * cannot trigger recompilation.
-         */
-        bool takeBranch = false;
-        switch (JSOp(*nextpc)) {
-          case JSOP_IFNE:
-            takeBranch = (JSBool)(uintptr_t)returnReg;
-            break;
-          case JSOP_IFEQ:
-            takeBranch = !(JSBool)(uintptr_t)returnReg;
-            break;
-          default:
-            JS_NOT_REACHED("Bad branch op");
-        }
-        if (takeBranch)
-            f.regs.pc = nextpc + GET_JUMP_OFFSET(nextpc);
-        else
-            f.regs.pc = nextpc + GetBytecodeLength(nextpc);
-        break;
-      }
-
-      default:
-        JS_NOT_REACHED("Missing rejoin");
-    }
-
-    if (nextDepth == UINT32_MAX)
-        nextDepth = analysis->getCode(f.regs.pc).stackDepth;
-    f.regs.sp = f.regs.spForStackDepth(nextDepth);
-
-    /*
-     * Monitor the result of the previous op when finishing a JOF_TYPESET op.
-     * The result may not have been marked if we bailed out while inside a stub
-     * for the op.
-     */
-    if (f.regs.pc == nextpc && (js_CodeSpec[op].format & JOF_TYPESET))
-        types::TypeScript::Monitor(cx, script, pc, f.regs.sp[-1]);
-
-    /* Mark the entry frame as unfinished, and update the regs to resume at. */
-    JaegerStatus status = skipTrap ? Jaeger_UnfinishedAtTrap : Jaeger_Unfinished;
-    cx->jaegerRuntime().setLastUnfinished(status);
-    *f.oldregs = f.regs;
-
-    return NULL;
-}
deleted file mode 100644
--- a/js/src/methodjit/Logging.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "jsutil.h"
-#include "MethodJIT.h"
-#include "Logging.h"
-
-#include "jsobjinlines.h"
-
-#if defined(JS_METHODJIT_SPEW)
-
-static bool LoggingChecked = false;
-static uint32_t LoggingBits = 0;
-
-static const char *ChannelNames[] =
-{
-#define _(name) #name,
-    JSPEW_CHAN_MAP(_)
-#undef  _
-};
-
-void
-js::JMCheckLogging()
-{
-    /* Not MT safe; races on Logging{Checked,Bits}. */
-    if (LoggingChecked)
-        return;
-    LoggingChecked = true;
-    const char *env = getenv("JMFLAGS");
-    if (!env)
-        return;
-    if (strstr(env, "help")) {
-        fflush(NULL);
-        printf(
-            "\n"
-            "usage: JMFLAGS=option,option,option,... where options can be:\n"
-            "\n"
-            "  help          show this message\n"
-            "  abort/aborts  ???\n"
-            "  scripts       ???\n"
-            "  profile       ???\n"
-#ifdef DEBUG
-            "  pcprofile     Runtime hit counts of every JS opcode executed\n"
-            "  jsops         JS opcodes\n"
-#endif
-            "  insns         JS opcodes and generated insns\n"
-            "  vmframe       VMFrame contents\n"
-            "  pics          PIC patching activity\n"
-            "  slowcalls     Calls to slow path functions\n"
-            "  analysis      LICM and other analysis behavior\n"
-            "  regalloc      Register allocation behavior\n"
-            "  inlin         Call inlining behavior\n"
-            "  recompile     Dynamic recompilations\n"
-            "  full          everything not affecting codegen\n"
-            "\n"
-        );
-        exit(0);
-        /*NOTREACHED*/
-    }
-    if (strstr(env, "abort") || strstr(env, "aborts"))
-        LoggingBits |= (1 << uint32_t(JSpew_Abort));
-    if (strstr(env, "scripts"))
-        LoggingBits |= (1 << uint32_t(JSpew_Scripts));
-    if (strstr(env, "profile"))
-        LoggingBits |= (1 << uint32_t(JSpew_Prof));
-#ifdef DEBUG
-    if (strstr(env, "jsops"))
-        LoggingBits |= (1 << uint32_t(JSpew_JSOps));
-#endif
-    if (strstr(env, "insns"))
-        LoggingBits |= (1 << uint32_t(JSpew_Insns) | (1 << uint32_t(JSpew_JSOps)));
-    if (strstr(env, "vmframe"))
-        LoggingBits |= (1 << uint32_t(JSpew_VMFrame));
-    if (strstr(env, "pics"))
-        LoggingBits |= (1 << uint32_t(JSpew_PICs));
-    if (strstr(env, "slowcalls"))
-        LoggingBits |= (1 << uint32_t(JSpew_SlowCalls));
-    if (strstr(env, "analysis"))
-        LoggingBits |= (1 << uint32_t(JSpew_Analysis));
-    if (strstr(env, "regalloc"))
-        LoggingBits |= (1 << uint32_t(JSpew_Regalloc));
-    if (strstr(env, "recompile"))
-        LoggingBits |= (1 << uint32_t(JSpew_Recompile));
-    if (strstr(env, "inlin"))
-        LoggingBits |= (1 << uint32_t(JSpew_Inlining));
-    if (strstr(env, "full"))
-        LoggingBits |= 0xFFFFFFFF;
-}
-
-js::ConditionalLog::ConditionalLog(bool logging)
-    : oldBits(LoggingBits), logging(logging)
-{
-    if (logging)
-        LoggingBits = 0xFFFFFFFF;
-}
-
-js::ConditionalLog::~ConditionalLog() {
-    if (logging)
-        LoggingBits = oldBits;
-}
-
-bool
-js::IsJaegerSpewChannelActive(JaegerSpewChannel channel)
-{
-    JS_ASSERT(LoggingChecked);
-    return !!(LoggingBits & (1 << uint32_t(channel)));
-}
-
-void
-js::JaegerSpew(JaegerSpewChannel channel, const char *fmt, ...)
-{
-    JS_ASSERT(LoggingChecked);
-
-    if (!(LoggingBits & (1 << uint32_t(channel))))
-        return;
-
-    fprintf(stderr, "[jaeger] %-7s  ", ChannelNames[channel]);
-
-    va_list ap;
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-
-    /* fprintf(stdout, "\n"); */
-}
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/Logging.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_logging_h__
-#define jsjaeger_logging_h__
-
-#include "assembler/wtf/Platform.h"
-#include "prmjtime.h"
-
-namespace js {
-
-#define JSPEW_CHAN_MAP(_)   \
-    _(Abort)                \
-    _(Scripts)              \
-    _(Prof)                 \
-    _(JSOps)                \
-    _(Insns)                \
-    _(VMFrame)              \
-    _(PICs)                 \
-    _(SlowCalls)            \
-    _(Analysis)             \
-    _(Regalloc)             \
-    _(Inlining)             \
-    _(Recompile)
-
-enum JaegerSpewChannel {
-#define _(name) JSpew_##name,
-    JSPEW_CHAN_MAP(_)
-#undef  _
-    JSpew_Terminator
-};
-
-#ifdef JS_METHODJIT_SPEW
-
-void JMCheckLogging();
-bool IsJaegerSpewChannelActive(JaegerSpewChannel channel);
-
-#ifdef __GNUC__
-void JaegerSpew(JaegerSpewChannel channel, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-#else
-void JaegerSpew(JaegerSpewChannel channel, const char *fmt, ...);
-#endif
-
-#else
-
-static inline void JMCheckLogging() {}
-static inline bool IsJaegerSpewChannelActive(JaegerSpewChannel channel) { return false; }
-static inline void JaegerSpew(JaegerSpewChannel channel, const char *fmt, ...) {}
-
-#endif // JS_METHODJIT_SPEW
-
-#if defined(JS_METHODJIT_SPEW)
-
-struct ConditionalLog {
-    uint32_t oldBits;
-    bool logging;
-    ConditionalLog(bool logging);
-    ~ConditionalLog();
-};
-
-struct Profiler {
-    int64_t t_start;
-    int64_t t_stop;
-
-    static inline int64_t now() {
-        return PRMJ_Now();
-    }
-
-    inline void start() {
-        t_start = now();
-    }
-
-    inline void stop() {
-        t_stop = now();
-    }
-
-    inline uint32_t time_ms() {
-        return uint32_t((t_stop - t_start) / PRMJ_USEC_PER_MSEC);
-    }
-
-    inline uint32_t time_us() {
-        return uint32_t(t_stop - t_start);
-    }
-};
-
-#endif // JS_METHODJIT_SPEW
-
-} // namespace js
-
-#endif
deleted file mode 100644
--- a/js/src/methodjit/LoopState.cpp
+++ /dev/null
@@ -1,2084 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/MathAlgorithms.h"
-
-#include "methodjit/Compiler.h"
-#include "methodjit/LoopState.h"
-#include "methodjit/FrameState-inl.h"
-#include "methodjit/StubCalls.h"
-
-#include "jstypedarrayinlines.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::analyze;
-using namespace js::types;
-
-using mozilla::Abs;
-
-LoopState::LoopState(JSContext *cx, analyze::CrossScriptSSA *ssa,
-                     mjit::Compiler *cc, FrameState *frame)
-    : cx(cx), ssa(ssa),
-      outerScript(ssa->outerScript()), outerAnalysis(outerScript->analysis()),
-      cc(*cc), frame(*frame),
-      lifetime(NULL), alloc(NULL), reachedEntryPoint(false), loopRegs(0), skipAnalysis(false),
-      loopJoins(CompilerAllocPolicy(cx, *cc)),
-      loopPatches(CompilerAllocPolicy(cx, *cc)),
-      restoreInvariantCalls(CompilerAllocPolicy(cx, *cc)),
-      invariantEntries(CompilerAllocPolicy(cx, *cc)),
-      outer(NULL), temporariesStart(0),
-      testLHS(UNASSIGNED), testRHS(UNASSIGNED),
-      testConstant(0), testLessEqual(false),
-      increments(CompilerAllocPolicy(cx, *cc)), unknownModset(false),
-      growArrays(CompilerAllocPolicy(cx, *cc)),
-      modifiedProperties(CompilerAllocPolicy(cx, *cc)),
-      constrainedLoop(true)
-{
-    JS_ASSERT(cx->typeInferenceEnabled());
-}
-
-bool
-LoopState::init(jsbytecode *head, Jump entry, jsbytecode *entryTarget)
-{
-    this->lifetime = outerAnalysis->getLoop(head);
-    JS_ASSERT(lifetime);
-    JS_ASSERT(lifetime->head == uint32_t(head - outerScript->code));
-    JS_ASSERT(lifetime->entry == uint32_t(entryTarget - outerScript->code));
-
-    this->entry = entry;
-
-    for (unsigned i = 0; i < ssa->numFrames(); i++) {
-        /* Only analyze this frame if it is nested within the loop itself. */
-        uint32_t index = ssa->iterFrame(i).index;
-        if (index != CrossScriptSSA::OUTER_FRAME) {
-            unsigned pframe = index;
-            while (ssa->getFrame(pframe).parent != CrossScriptSSA::OUTER_FRAME)
-                pframe = ssa->getFrame(pframe).parent;
-            uint32_t offset = ssa->getFrame(pframe).parentpc - outerScript->code;
-            JS_ASSERT(offset < outerScript->length);
-            if (offset < lifetime->head || offset > lifetime->backedge)
-                continue;
-        }
-        analyzeLoopBody(index);
-    }
-
-    if (testLHS != UNASSIGNED) {
-        JaegerSpew(JSpew_Analysis, "loop test at %u: %s %s %s + %d\n", lifetime->head,
-                   frame.entryName(testLHS),
-                   testLessEqual ? "<=" : ">=",
-                   (testRHS == UNASSIGNED) ? "" : frame.entryName(testRHS),
-                   testConstant);
-    }
-
-    for (unsigned i = 0; i < increments.length(); i++) {
-        JaegerSpew(JSpew_Analysis, "loop increment at %u for %s: %u\n", lifetime->head,
-                   frame.entryName(increments[i].slot),
-                   increments[i].offset);
-    }
-
-    for (unsigned i = 0; i < growArrays.length(); i++) {
-        JaegerSpew(JSpew_Analysis, "loop grow array at %u: %s\n", lifetime->head,
-                   types::TypeString(types::Type::ObjectType(growArrays[i])));
-    }
-
-    for (unsigned i = 0; i < modifiedProperties.length(); i++) {
-        JaegerSpew(JSpew_Analysis, "loop modified property at %u: %s %s\n", lifetime->head,
-                   types::TypeString(types::Type::ObjectType(modifiedProperties[i].object)),
-                   TypeIdString(modifiedProperties[i].id));
-    }
-
-    RegisterAllocation *&alloc = outerAnalysis->getAllocation(head);
-    JS_ASSERT(!alloc);
-
-    alloc = cx->analysisLifoAlloc().new_<RegisterAllocation>(true);
-    if (!alloc) {
-        js_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    this->alloc = alloc;
-    this->loopRegs = Registers::AvailAnyRegs;
-
-    /*
-     * Don't hoist bounds checks or loop invariant code in scripts that have
-     * had indirect modification of their arguments.
-     */
-    if (outerScript->function()) {
-        if (HeapTypeSet::HasObjectFlags(cx, outerScript->function()->getType(cx), OBJECT_FLAG_UNINLINEABLE))
-            this->skipAnalysis = true;
-    }
-
-    /*
-     * Don't hoist bounds checks or loop invariant code in loops with safe
-     * points in the middle, which the interpreter can join at directly without
-     * performing hoisted bounds checks or doing initial computation of loop
-     * invariant terms.
-     */
-    if (lifetime->hasSafePoints)
-        this->skipAnalysis = true;
-
-    return true;
-}
-
-void
-LoopState::addJoin(unsigned index, bool script)
-{
-    StubJoin r;
-    r.index = index;
-    r.script = script;
-    loopJoins.append(r);
-}
-
-void
-LoopState::addInvariantCall(Jump jump, Label label, bool ool, bool entry, unsigned patchIndex, Uses uses)
-{
-    RestoreInvariantCall call;
-    call.jump = jump;
-    call.label = label;
-    call.ool = ool;
-    call.entry = entry;
-    call.patchIndex = patchIndex;
-    call.temporaryCopies = frame.getTemporaryCopies(uses);
-
-    restoreInvariantCalls.append(call);
-}
-
-void
-LoopState::flushLoop(StubCompiler &stubcc)
-{
-    clearLoopRegisters();
-
-    /*
-     * Patch stub compiler rejoins with loads of loop carried registers
-     * discovered after the fact.
-     */
-    for (unsigned i = 0; i < loopPatches.length(); i++) {
-        const StubJoinPatch &p = loopPatches[i];
-        stubcc.patchJoin(p.join.index, p.join.script, p.address, p.reg);
-    }
-    loopJoins.clear();
-    loopPatches.clear();
-
-    if (hasInvariants()) {
-        for (unsigned i = 0; i < restoreInvariantCalls.length(); i++) {
-            RestoreInvariantCall &call = restoreInvariantCalls[i];
-            Assembler &masm = cc.getAssembler(true);
-            Vector<Jump> failureJumps(cx);
-
-            jsbytecode *pc = cc.getInvariantPC(call.patchIndex);
-
-            if (call.ool) {
-                call.jump.linkTo(masm.label(), &masm);
-                restoreInvariants(pc, masm, call.temporaryCopies, &failureJumps);
-                masm.jump().linkTo(call.label, &masm);
-            } else {
-                stubcc.linkExitDirect(call.jump, masm.label());
-                restoreInvariants(pc, masm, call.temporaryCopies, &failureJumps);
-                stubcc.crossJump(masm.jump(), call.label);
-            }
-
-            if (!failureJumps.empty()) {
-                for (unsigned i = 0; i < failureJumps.length(); i++)
-                    failureJumps[i].linkTo(masm.label(), &masm);
-
-                /*
-                 * Call InvariantFailure, setting up the return address to
-                 * patch and any value for the call to return.
-                 */
-                InvariantCodePatch *patch = cc.getInvariantPatch(call.patchIndex);
-                patch->hasPatch = true;
-                patch->codePatch = masm.storePtrWithPatch(ImmPtr(NULL),
-                                                          FrameAddress(offsetof(VMFrame, scratch)));
-                JS_STATIC_ASSERT(Registers::ReturnReg != Registers::ArgReg1);
-                masm.move(Registers::ReturnReg, Registers::ArgReg1);
-
-                if (call.entry) {
-                    masm.fallibleVMCall(true, JS_FUNC_TO_DATA_PTR(void *, stubs::InvariantFailure),
-                                        pc, NULL, 0);
-                } else {
-                    /* f.regs are already coherent, don't write new values to them. */
-                    masm.infallibleVMCall(JS_FUNC_TO_DATA_PTR(void *, stubs::InvariantFailure), -1);
-                }
-            }
-        }
-    } else {
-        for (unsigned i = 0; i < restoreInvariantCalls.length(); i++) {
-            RestoreInvariantCall &call = restoreInvariantCalls[i];
-            Assembler &masm = cc.getAssembler(call.ool);
-            call.jump.linkTo(call.label, &masm);
-        }
-    }
-    restoreInvariantCalls.clear();
-}
-
-void
-LoopState::clearLoopRegisters()
-{
-    alloc->clearLoops();
-    loopRegs = 0;
-}
-
-bool
-LoopState::loopInvariantEntry(uint32_t slot)
-{
-    if (slot == UNASSIGNED)
-        return true;
-
-    /* Watch for loop temporaries. :XXX: this is really gross. */
-    if (slot >= analyze::LocalSlot(outerScript, outerScript->nslots))
-        return true;
-
-    if (slot == analyze::CalleeSlot() || outerAnalysis->slotEscapes(slot))
-        return false;
-    return outerAnalysis->liveness(slot).firstWrite(lifetime) == UINT32_MAX;
-}
-
-inline bool
-LoopState::entryRedundant(const InvariantEntry &e0, const InvariantEntry &e1)
-{
-    JS_ASSERT(e0.isCheck() && e1.isCheck());
-
-    uint32_t array0 = e0.u.check.arraySlot;
-    uint32_t array1 = e1.u.check.arraySlot;
-
-    uint32_t value01 = e0.u.check.valueSlot1;
-    uint32_t value02 = e0.u.check.valueSlot2;
-
-    uint32_t value11 = e1.u.check.valueSlot1;
-    uint32_t value12 = e1.u.check.valueSlot2;
-
-    int32_t c0 = e0.u.check.constant;
-    int32_t c1 = e1.u.check.constant;
-
-    /*
-     * initialized lengths are always <= JSObject::NELEMENTS_LIMIT, check for
-     * integer overflow checks redundant given initialized length checks.
-     * If Y <= c0 and Y + c1 < initlen(array):
-     *
-     * Y <= c0
-     * initlen(array) - c1 <= c0
-     * NSLOTS_LIMIT <= c0 + c1
-     */
-    if (e0.kind == InvariantEntry::RANGE_CHECK && e1.isBoundsCheck() &&
-        value01 == value11 && value02 == value12) {
-        int32_t constant;
-        if (c1 >= 0)
-            constant = c0;
-        else if (!SafeAdd(c0, c1, &constant))
-            return false;
-        return constant >= (int32_t) JSObject::NELEMENTS_LIMIT;
-    }
-
-    /* Look for matching tests that differ only in their constants. */
-    if (e0.kind == e1.kind && array0 == array1 && value01 == value11 && value02 == value12) {
-        if (e0.isBoundsCheck()) {
-            /* If e0 is X >= Y + c0 and e1 is X >= Y + c1, e0 is redundant if c0 <= c1 */
-            return (c0 <= c1);
-        } else {
-            /* If e0 is c0 >= Y and e1 is c1 >= Y, e0 is redundant if c0 >= c1 */
-            return (c0 >= c1);
-        }
-    }
-
-    return false;
-}
-
-bool
-LoopState::checkRedundantEntry(const InvariantEntry &entry)
-{
-    /*
-     * Return true if entry is implied by an existing entry, otherwise filter
-     * out any existing entries which entry implies.
-     */
-    JS_ASSERT(entry.isCheck());
-
-    /* Maintain this separately, GCC miscompiles if the loop test is invariantEntries.length(). */
-    unsigned length = invariantEntries.length();
-
-    for (unsigned i = 0; i < length; i++) {
-        InvariantEntry &baseEntry = invariantEntries[i];
-        if (!baseEntry.isCheck())
-            continue;
-        if (entryRedundant(entry, baseEntry))
-            return true;
-        if (entryRedundant(baseEntry, entry)) {
-            /*
-             * Make sure to maintain the existing ordering on how invariant
-             * entries are generated, this is required for e.g. entries which
-             * use temporaries or slot computations which appear before any
-             * bounds checks on the arrays.
-             */
-            for (unsigned j = i; j < length - 1; j++)
-                invariantEntries[j] = invariantEntries[j + 1];
-            invariantEntries.popBack();
-            i--;
-            length--;
-        }
-    }
-
-    return false;
-}
-
-bool
-LoopState::addHoistedCheck(InvariantArrayKind arrayKind, uint32_t arraySlot,
-                           uint32_t valueSlot1, uint32_t valueSlot2, int32_t constant)
-{
-#ifdef DEBUG
-    JS_ASSERT_IF(valueSlot1 == UNASSIGNED, valueSlot2 == UNASSIGNED);
-    const char *field = (arrayKind == DENSE_ARRAY) ? "initlen" : "length";
-    if (valueSlot1 == UNASSIGNED) {
-        JaegerSpew(JSpew_Analysis, "Hoist %s > %d\n", field, constant);
-    } else if (valueSlot2 == UNASSIGNED) {
-        JaegerSpew(JSpew_Analysis, "Hoisted as %s > %s + %d\n", field,
-                   frame.entryName(valueSlot1), constant);
-    } else {
-        JaegerSpew(JSpew_Analysis, "Hoisted as %s > %s + %s + %d\n", field,
-                   frame.entryName(valueSlot1), frame.entryName(valueSlot2), constant);
-    }
-#endif
-
-    InvariantEntry entry;
-    entry.kind = (arrayKind == DENSE_ARRAY)
-                 ? InvariantEntry::DENSE_ARRAY_BOUNDS_CHECK
-                 : InvariantEntry::TYPED_ARRAY_BOUNDS_CHECK;
-    entry.u.check.arraySlot = arraySlot;
-    entry.u.check.valueSlot1 = valueSlot1;
-    entry.u.check.valueSlot2 = valueSlot2;
-    entry.u.check.constant = constant;
-
-    if (checkRedundantEntry(entry))
-        return true;
-
-    /*
-     * Maintain an invariant that for any array with a hoisted bounds check,
-     * we also have a loop invariant slot to hold the array's slots pointer.
-     * The compiler gets invariant array slots only for accesses with a hoisted
-     * bounds check, so this makes invariantSlots infallible.
-     */
-    bool hasInvariantSlots = false;
-    InvariantEntry::EntryKind slotsKind = (arrayKind == DENSE_ARRAY)
-                                          ? InvariantEntry::DENSE_ARRAY_SLOTS
-                                          : InvariantEntry::TYPED_ARRAY_SLOTS;
-    for (unsigned i = 0; !hasInvariantSlots && i < invariantEntries.length(); i++) {
-        InvariantEntry &entry = invariantEntries[i];
-        if (entry.kind == slotsKind && entry.u.array.arraySlot == arraySlot)
-            hasInvariantSlots = true;
-    }
-    if (!hasInvariantSlots) {
-        uint32_t which = frame.allocTemporary();
-        if (which == UINT32_MAX)
-            return false;
-        FrameEntry *fe = frame.getTemporary(which);
-
-        JaegerSpew(JSpew_Analysis, "Using %s for loop invariant slots of %s\n",
-                   frame.entryName(fe), frame.entryName(arraySlot));
-
-        InvariantEntry slotsEntry;
-        slotsEntry.kind = slotsKind;
-        slotsEntry.u.array.arraySlot = arraySlot;
-        slotsEntry.u.array.temporary = which;
-        invariantEntries.append(slotsEntry);
-    }
-
-    invariantEntries.append(entry);
-    return true;
-}
-
-void
-LoopState::addNegativeCheck(uint32_t valueSlot, int32_t constant)
-{
-    JaegerSpew(JSpew_Analysis, "Nonnegative check %s + %d >= 0\n",
-               frame.entryName(valueSlot), constant);
-
-    InvariantEntry entry;
-    entry.kind = InvariantEntry::NEGATIVE_CHECK;
-    entry.u.check.valueSlot1 = valueSlot;
-    entry.u.check.constant = constant;
-
-    if (!checkRedundantEntry(entry))
-        invariantEntries.append(entry);
-}
-
-void
-LoopState::addRangeCheck(uint32_t valueSlot1, uint32_t valueSlot2, int32_t constant)
-{
-    JaegerSpew(JSpew_Analysis, "Range check %d >= %s + %s\n",
-               constant, frame.entryName(valueSlot1),
-               valueSlot2 == UINT32_MAX ? "" : frame.entryName(valueSlot2));
-
-    InvariantEntry entry;
-    entry.kind = InvariantEntry::RANGE_CHECK;
-    entry.u.check.valueSlot1 = valueSlot1;
-    entry.u.check.valueSlot2 = valueSlot2;
-    entry.u.check.constant = constant;
-
-    if (!checkRedundantEntry(entry))
-        invariantEntries.append(entry);
-}
-
-void
-LoopState::setLoopReg(AnyRegisterID reg, FrameEntry *fe)
-{
-    JS_ASSERT(alloc->loop(reg));
-    loopRegs.takeReg(reg);
-
-    uint32_t slot = frame.outerSlot(fe);
-    JaegerSpew(JSpew_Regalloc, "allocating loop register %s for %s\n",
-               reg.name(), frame.entryName(fe));
-
-    alloc->set(reg, slot, true);
-
-    /*
-     * Mark pending rejoins to patch up with the load. We don't do this now as that would
-     * cause us to emit into the slow path, which may be in progress.
-     */
-    for (unsigned i = 0; i < loopJoins.length(); i++) {
-        StubJoinPatch p;
-        p.join = loopJoins[i];
-        p.address = frame.addressOf(fe);
-        p.reg = reg;
-        loopPatches.append(p);
-    }
-
-    if (reachedEntryPoint) {
-        /*
-         * We've advanced past the entry point of the loop (we're analyzing the condition),
-         * so need to update the register state at that entry point so that the right
-         * things get loaded when we enter the loop.
-         */
-        RegisterAllocation *alloc = outerAnalysis->getAllocation(lifetime->entry);
-        JS_ASSERT(alloc && !alloc->assigned(reg));
-        alloc->set(reg, slot, true);
-    }
-}
-
-bool
-LoopState::hoistArrayLengthCheck(InvariantArrayKind arrayKind, const CrossSSAValue &obj,
-                                 const CrossSSAValue &index)
-{
-    /*
-     * Note: this method requires that the index is definitely an integer, and
-     * that obj is either a dense array, a typed array or not an object.
-     */
-    if (skipAnalysis)
-        return false;
-
-    uint32_t objSlot;
-    int32_t objConstant;
-    if (!getEntryValue(obj, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0)
-        return false;
-
-    JaegerSpew(JSpew_Analysis, "Trying to hoist bounds check on %s\n",
-               frame.entryName(objSlot));
-
-    if (!loopInvariantEntry(objSlot)) {
-        JaegerSpew(JSpew_Analysis, "Object is not loop invariant\n");
-        return false;
-    }
-
-    /*
-     * Check for an overlap with the arrays we think might grow in this loop.
-     * This information is only a guess; if we don't think the array can grow
-     * but it actually can, we will probably recompile after the hoisted
-     * bounds check fails.
-     */
-    TypeSet *objTypes = ssa->getValueTypes(obj);
-    if (arrayKind == DENSE_ARRAY && !growArrays.empty()) {
-        unsigned count = objTypes->getObjectCount();
-        for (unsigned i = 0; i < count; i++) {
-            if (objTypes->getSingleObject(i) != NULL) {
-                JaegerSpew(JSpew_Analysis, "Object might be a singleton");
-                return false;
-            }
-            TypeObject *object = objTypes->getTypeObject(i);
-            if (object && hasGrowArray(object)) {
-                JaegerSpew(JSpew_Analysis, "Object might grow inside loop\n");
-                return false;
-            }
-        }
-    }
-
-    /*
-     * Get an expression for the index 'index + indexConstant', where index
-     * is the value of a slot at loop entry.
-     */
-    uint32_t indexSlot;
-    int32_t indexConstant;
-    if (!getEntryValue(index, &indexSlot, &indexConstant)) {
-        JaegerSpew(JSpew_Analysis, "Could not compute index in terms of loop entry state\n");
-        return false;
-    }
-
-    if (indexSlot == UNASSIGNED) {
-        /* Hoist checks on x[n] accesses for constant n. */
-        if (indexConstant < 0) {
-            JaegerSpew(JSpew_Analysis, "Constant index is negative\n");
-            return false;
-        }
-        return addHoistedCheck(arrayKind, objSlot, UNASSIGNED, UNASSIGNED, indexConstant);
-    }
-
-    if (loopInvariantEntry(indexSlot)) {
-        /* Hoist checks on x[y] accesses when y is loop invariant. */
-        addNegativeCheck(indexSlot, indexConstant);
-        return addHoistedCheck(arrayKind, objSlot, indexSlot, UNASSIGNED, indexConstant);
-    }
-
-    /*
-     * If the LHS can decrease in the loop, it could become negative and
-     * underflow the array. We currently only hoist bounds checks for loops
-     * which walk arrays going forward.
-     */
-    if (!outerAnalysis->liveness(indexSlot).nonDecreasing(outerScript, lifetime)) {
-        JaegerSpew(JSpew_Analysis, "Index may decrease in future iterations\n");
-        return false;
-    }
-
-    /*
-     * If the access is of the form x[y + a] where we know that y <= z + b
-     * (both in terms of state at the head of the loop), hoist as follows:
-     *
-     * y + a < initlen(x)
-     * y < initlen(x) - a
-     * z + b < initlen(x) - a
-     * z + b + a < initlen(x)
-     */
-    if (indexSlot == testLHS && testLessEqual) {
-        int32_t constant;
-        if (!SafeAdd(testConstant, indexConstant, &constant))
-            return false;
-
-        /*
-         * Check that the LHS is nonnegative every time we rejoin the loop.
-         * This is only really necessary on initial loop entry. Note that this
-         * test is not sensitive to changes to the LHS between when we make
-         * the test and the start of the next iteration, as we've ensured the
-         * LHS is nondecreasing within the body of the loop.
-         */
-        addNegativeCheck(indexSlot, indexConstant);
-
-        return addHoistedCheck(arrayKind, objSlot, testRHS, UNASSIGNED, constant);
-    }
-
-    /*
-     * If the access is of the form x[y + a] where we know that z >= b at the
-     * head of the loop and y has a linear relationship with z such that
-     * (y + z) always has the same value at the head of the loop, hoist as
-     * follows:
-     *
-     * y + a < initlen(x)
-     * y + z < initlen(x) + z - a
-     * y + z < initlen(x) + b - a
-     * y + z + a - b < initlen(x)
-     */
-    if (hasTestLinearRelationship(indexSlot)) {
-        int32_t constant;
-        if (!SafeSub(indexConstant, testConstant, &constant))
-            return false;
-
-        addNegativeCheck(indexSlot, indexConstant);
-        return addHoistedCheck(arrayKind, objSlot, indexSlot, testLHS, constant);
-    }
-
-    JaegerSpew(JSpew_Analysis, "No match found\n");
-    return false;
-}
-
-bool
-LoopState::hoistArgsLengthCheck(const CrossSSAValue &index)
-{
-    if (skipAnalysis)
-        return false;
-
-    JaegerSpew(JSpew_Analysis, "Trying to hoist argument range check\n");
-
-    uint32_t indexSlot;
-    int32_t indexConstant;
-    if (!getEntryValue(index, &indexSlot, &indexConstant)) {
-        JaegerSpew(JSpew_Analysis, "Could not compute index in terms of loop entry state\n");
-        return false;
-    }
-
-    /*
-     * We only hoist arguments checks which can be completely eliminated, for
-     * now just tests with 'i < arguments.length' or similar in the condition.
-     */
-
-    if (indexSlot == UNASSIGNED || loopInvariantEntry(indexSlot)) {
-        JaegerSpew(JSpew_Analysis, "Index is constant or loop invariant\n");
-        return false;
-    }
-
-    if (!outerAnalysis->liveness(indexSlot).nonDecreasing(outerScript, lifetime)) {
-        JaegerSpew(JSpew_Analysis, "Index may decrease in future iterations\n");
-        return false;
-    }
-
-    if (indexSlot == testLHS && indexConstant == 0 && testConstant == -1 && testLessEqual) {
-        bool found = false;
-        for (unsigned i = 0; i < invariantEntries.length(); i++) {
-            const InvariantEntry &entry = invariantEntries[i];
-            if (entry.kind == InvariantEntry::INVARIANT_ARGS_LENGTH) {
-                uint32_t slot = frame.outerSlot(frame.getTemporary(entry.u.array.temporary));
-                if (slot == testRHS)
-                    found = true;
-                break;
-            }
-        }
-        if (found) {
-            addNegativeCheck(indexSlot, indexConstant);
-            JaegerSpew(JSpew_Analysis, "Access implied by loop test\n");
-            return true;
-        }
-    }
-
-    JaegerSpew(JSpew_Analysis, "No match found\n");
-    return false;
-}
-
-bool
-LoopState::hasTestLinearRelationship(uint32_t slot)
-{
-    /*
-     * Determine whether slot has a linear relationship with the loop test
-     * variable 'test', such that (slot + test) always has the same value at
-     * the head of the loop.
-     */
-
-    if (testLHS == UNASSIGNED || testRHS != UNASSIGNED || testLessEqual)
-        return false;
-
-    uint32_t incrementOffset = getIncrement(slot);
-    if (incrementOffset == UINT32_MAX) {
-        /*
-         * Variable is not always incremented in the loop, or is incremented
-         * multiple times. Note that the nonDecreasing test done earlier
-         * ensures that if there is a single write, it is an increment.
-         */
-        return false;
-    }
-
-    uint32_t decrementOffset = getIncrement(testLHS);
-    if (decrementOffset == UINT32_MAX)
-        return false;
-
-    JSOp op = JSOp(outerScript->code[decrementOffset]);
-    switch (op) {
-      case JSOP_DECLOCAL:
-      case JSOP_LOCALDEC:
-      case JSOP_DECARG:
-      case JSOP_ARGDEC:
-        return true;
-      default:
-        return false;
-    }
-}
-
-FrameEntry *
-LoopState::invariantArraySlots(const CrossSSAValue &obj)
-{
-    JS_ASSERT(!skipAnalysis);
-
-    uint32_t objSlot;
-    int32_t objConstant;
-    if (!getEntryValue(obj, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0) {
-        JS_NOT_REACHED("Bad value");
-        return NULL;
-    }
-
-    /*
-     * Note: we don't have to check arrayKind (dense array or typed array) here,
-     * because an array cannot have entries for both dense array slots and typed
-     * array slots.
-     */
-    for (unsigned i = 0; i < invariantEntries.length(); i++) {
-        InvariantEntry &entry = invariantEntries[i];
-        if ((entry.kind == InvariantEntry::DENSE_ARRAY_SLOTS ||
-             entry.kind == InvariantEntry::TYPED_ARRAY_SLOTS) &&
-            entry.u.array.arraySlot == objSlot) {
-            return frame.getTemporary(entry.u.array.temporary);
-        }
-    }
-
-    /* addHoistedCheck should have ensured there is an entry for the slots. */
-    JS_NOT_REACHED("Missing invariant slots");
-    return NULL;
-}
-
-FrameEntry *
-LoopState::invariantArguments()
-{
-    if (skipAnalysis)
-        return NULL;
-
-    for (unsigned i = 0; i < invariantEntries.length(); i++) {
-        InvariantEntry &entry = invariantEntries[i];
-        if (entry.kind == InvariantEntry::INVARIANT_ARGS_BASE)
-            return frame.getTemporary(entry.u.array.temporary);
-    }
-
-    uint32_t which = frame.allocTemporary();
-    if (which == UINT32_MAX)
-        return NULL;
-    FrameEntry *fe = frame.getTemporary(which);
-
-    InvariantEntry entry;
-    entry.kind = InvariantEntry::INVARIANT_ARGS_BASE;
-    entry.u.array.temporary = which;
-    invariantEntries.append(entry);
-
-    JaegerSpew(JSpew_Analysis, "Using %s for loop invariant args base\n",
-               frame.entryName(fe));
-    return fe;
-}
-
-FrameEntry *
-LoopState::invariantLength(const CrossSSAValue &obj)
-{
-    if (skipAnalysis)
-        return NULL;
-
-    uint32_t objSlot;
-    int32_t objConstant;
-    if (!getEntryValue(obj, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0)
-        return NULL;
-    StackTypeSet *objTypes = ssa->getValueTypes(obj);
-
-    /* Check for 'length' on the lazy arguments for the current frame. */
-    if (objTypes->isMagicArguments()) {
-        JS_ASSERT(obj.frame == CrossScriptSSA::OUTER_FRAME);
-
-        for (unsigned i = 0; i < invariantEntries.length(); i++) {
-            InvariantEntry &entry = invariantEntries[i];
-            if (entry.kind == InvariantEntry::INVARIANT_ARGS_LENGTH)
-                return frame.getTemporary(entry.u.array.temporary);
-        }
-
-        uint32_t which = frame.allocTemporary();
-        if (which == UINT32_MAX)
-            return NULL;
-        FrameEntry *fe = frame.getTemporary(which);
-
-        InvariantEntry entry;
-        entry.kind = InvariantEntry::INVARIANT_ARGS_LENGTH;
-        entry.u.array.temporary = which;
-        invariantEntries.append(entry);
-
-        JaegerSpew(JSpew_Analysis, "Using %s for loop invariant args length\n",
-                   frame.entryName(fe));
-        return fe;
-    }
-
-    /*
-     * Note: we don't have to check arrayKind (dense array or typed array) here,
-     * because an array cannot have entries for both dense array length and typed
-     * array length.
-     */
-    for (unsigned i = 0; i < invariantEntries.length(); i++) {
-        InvariantEntry &entry = invariantEntries[i];
-        if ((entry.kind == InvariantEntry::DENSE_ARRAY_LENGTH ||
-             entry.kind == InvariantEntry::TYPED_ARRAY_LENGTH) &&
-            entry.u.array.arraySlot == objSlot) {
-            return frame.getTemporary(entry.u.array.temporary);
-        }
-    }
-
-    if (!loopInvariantEntry(objSlot))
-        return NULL;
-
-    /* Hoist 'length' access on typed arrays. */
-    if (objTypes->getTypedArrayType() != TypedArray::TYPE_MAX) {
-        uint32_t which = frame.allocTemporary();
-        if (which == UINT32_MAX)
-            return NULL;
-        FrameEntry *fe = frame.getTemporary(which);
-
-        JaegerSpew(JSpew_Analysis, "Using %s for loop invariant typed array length of %s\n",
-                   frame.entryName(fe), frame.entryName(objSlot));
-
-        InvariantEntry entry;
-        entry.kind = InvariantEntry::TYPED_ARRAY_LENGTH;
-        entry.u.array.arraySlot = objSlot;
-        entry.u.array.temporary = which;
-        invariantEntries.append(entry);
-
-        return fe;
-    }
-
-    if (objTypes->getKnownClass() != &ArrayClass)
-        return NULL;
-    if (objTypes->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                 types::OBJECT_FLAG_LENGTH_OVERFLOW))
-        return NULL;
-
-    /*
-     * Don't make 'length' loop invariant if the loop might directly write
-     * to the elements of any of the accessed arrays. This could invoke an
-     * inline path which updates the length. There is no need to check the
-     * modset for direct 'length' writes, as we don't generate inline paths
-     * updating array lengths.
-     */
-    for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
-        if (objTypes->getSingleObject(i) != NULL)
-            return NULL;
-        TypeObject *object = objTypes->getTypeObject(i);
-        if (object && hasModifiedProperty(object, JSID_VOID))
-            return NULL;
-    }
-
-    uint32_t which = frame.allocTemporary();
-    if (which == UINT32_MAX)
-        return NULL;
-    FrameEntry *fe = frame.getTemporary(which);
-
-    JaegerSpew(JSpew_Analysis, "Using %s for loop invariant dense array length of %s\n",
-               frame.entryName(fe), frame.entryName(objSlot));
-
-    InvariantEntry entry;
-    entry.kind = InvariantEntry::DENSE_ARRAY_LENGTH;
-    entry.u.array.arraySlot = objSlot;
-    entry.u.array.temporary = which;
-    invariantEntries.append(entry);
-
-    return fe;
-}
-
-FrameEntry *
-LoopState::invariantProperty(const CrossSSAValue &obj, jsid id)
-{
-    if (skipAnalysis)
-        return NULL;
-
-    if (id == NameToId(cx->names().length))
-        return NULL;
-
-    uint32_t objSlot;
-    int32_t objConstant;
-    if (!getEntryValue(obj, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0)
-        return NULL;
-
-    for (unsigned i = 0; i < invariantEntries.length(); i++) {
-        InvariantEntry &entry = invariantEntries[i];
-        if (entry.kind == InvariantEntry::INVARIANT_PROPERTY &&
-            entry.u.property.objectSlot == objSlot &&
-            entry.u.property.id == id) {
-            return frame.getTemporary(entry.u.property.temporary);
-        }
-    }
-
-    if (!loopInvariantEntry(objSlot))
-        return NULL;
-
-    /* Check that the property is definite and not written anywhere in the loop. */
-    TypeSet *objTypes = ssa->getValueTypes(obj);
-    if (objTypes->unknownObject() || objTypes->getObjectCount() != 1)
-        return NULL;
-    TypeObject *object = objTypes->getTypeObject(0);
-    if (!object || object->unknownProperties() || hasModifiedProperty(object, id) || id != IdToTypeId(id))
-        return NULL;
-    HeapTypeSet *propertyTypes = object->getProperty(cx, id, false);
-    if (!propertyTypes)
-        return NULL;
-    if (!propertyTypes->definiteProperty() || propertyTypes->isOwnProperty(cx, object, true))
-        return NULL;
-
-    uint32_t which = frame.allocTemporary();
-    if (which == UINT32_MAX)
-        return NULL;
-    FrameEntry *fe = frame.getTemporary(which);
-
-    JaegerSpew(JSpew_Analysis, "Using %s for loop invariant property of %s\n",
-               frame.entryName(fe), frame.entryName(objSlot));
-
-    InvariantEntry entry;
-    entry.kind = InvariantEntry::INVARIANT_PROPERTY;
-    entry.u.property.objectSlot = objSlot;
-    entry.u.property.propertySlot = propertyTypes->definiteSlot();
-    entry.u.property.temporary = which;
-    entry.u.property.id = id;
-    invariantEntries.append(entry);
-
-    return fe;
-}
-
-bool
-LoopState::cannotIntegerOverflow(const CrossSSAValue &pushed)
-{
-    if (skipAnalysis)
-        return false;
-
-    int32_t min, max;
-    if (computeInterval(pushed, &min, &max)) {
-        JaegerSpew(JSpew_Analysis, "Integer operation fits in range [%d, %d]\n", min, max);
-        return true;
-    }
-
-    /*
-     * Compute a slot and constant such that the result of the binary op is
-     * 'slot + constant', where slot is expressed in terms of its value at
-     * the head of the loop.
-     */
-    JS_ASSERT(pushed.v.kind() == SSAValue::PUSHED);
-    jsbytecode *PC = ssa->getFrame(pushed.frame).script->code + pushed.v.pushedOffset();
-    ScriptAnalysis *analysis = ssa->getFrame(pushed.frame).script->analysis();
-
-    if (!analysis->integerOperation(PC))
-        return false;
-
-    uint32_t baseSlot = UNASSIGNED;
-    int32_t baseConstant = 0;
-    JSOp op = JSOp(*PC);
-    switch (op) {
-
-      case JSOP_INCLOCAL:
-      case JSOP_LOCALINC:
-      case JSOP_INCARG:
-      case JSOP_ARGINC: {
-        CrossSSAValue cv(pushed.frame, analysis->poppedValue(PC, 0));
-        if (!getEntryValue(cv, &baseSlot, &baseConstant))
-            return false;
-        if (!SafeAdd(baseConstant, 1, &baseConstant))
-            return false;
-        break;
-      }
-
-      case JSOP_DECLOCAL:
-      case JSOP_LOCALDEC:
-      case JSOP_DECARG:
-      case JSOP_ARGDEC: {
-        CrossSSAValue cv(pushed.frame, analysis->poppedValue(PC, 0));
-        if (!getEntryValue(cv, &baseSlot, &baseConstant))
-            return false;
-        if (!SafeSub(baseConstant, 1, &baseConstant))
-            return false;
-        break;
-      }
-
-      case JSOP_ADD:
-      case JSOP_SUB: {
-        uint32_t lhs = UNASSIGNED, rhs = UNASSIGNED;
-        int32_t lhsconstant = 0, rhsconstant = 0;
-        CrossSSAValue lcv(pushed.frame, analysis->poppedValue(PC, 1));
-        CrossSSAValue rcv(pushed.frame, analysis->poppedValue(PC, 0));
-        if (!getEntryValue(lcv, &lhs, &lhsconstant))
-            return false;
-        if (!getEntryValue(rcv, &rhs, &rhsconstant))
-            return false;
-        if (op == JSOP_ADD) {
-            if (!SafeAdd(lhsconstant, rhsconstant, &baseConstant))
-                return false;
-            if (lhs != UNASSIGNED && rhs != UNASSIGNED)
-                return false;
-            baseSlot = (lhs == UNASSIGNED) ? rhs : lhs;
-        } else {
-            if (!SafeSub(lhsconstant, rhsconstant, &baseConstant))
-                return false;
-            if (rhs != UNASSIGNED)
-                return false;
-            baseSlot = lhs;
-        }
-        break;
-      }
-
-      default:
-        return false;
-    }
-
-    if (baseSlot == UNASSIGNED)
-        return false;
-
-    JaegerSpew(JSpew_Analysis, "Trying to hoist integer overflow check on %s + %d\n",
-               frame.entryName(baseSlot), baseConstant);
-
-    if (baseConstant == 0) {
-        JaegerSpew(JSpew_Analysis, "Vacuously holds\n");
-        return true;
-    }
-
-    if (baseConstant < 0) {
-        /*
-         * If the access is of the form 'y + a' where a is negative and we know
-         * that y >= b at the head of the loop, we can eliminate as follows:
-         *
-         * y + a >= INT_MIN
-         * b + a >= INT_MIN
-         */
-        if (baseSlot == testLHS && !testLessEqual && testRHS == UNASSIGNED) {
-            int32_t constant;
-            if (!SafeAdd(testConstant, baseConstant, &constant))
-                return false;
-
-            JaegerSpew(JSpew_Analysis, "Loop test comparison must hold\n");
-            return true;
-        }
-
-        JaegerSpew(JSpew_Analysis, "No match found\n");
-        return false;
-    }
-
-    /*
-     * If the access is of the form 'y + a' where we know that y <= z + b
-     * (both in terms of state at the head of the loop), hoist as follows:
-     *
-     * y + a <= INT_MAX
-     * y <= INT_MAX - a
-     * z + b <= INT_MAX - a
-     * z <= INT_MAX - (a + b)
-     */
-    if (baseSlot == testLHS && testLessEqual) {
-        int32_t constant;
-        if (!SafeAdd(testConstant, baseConstant, &constant))
-            return false;
-
-        if (testRHS == UNASSIGNED || constant <= 0) {
-            /*
-             * Reduces to '(a + b) <= INT_MAX', which SafeAdd ensures,
-             * or 'z <= INT_MAX', which integer checks on z ensure.
-             */
-            JaegerSpew(JSpew_Analysis, "Loop test comparison must hold\n");
-            return true;
-        }
-
-        constant = JSVAL_INT_MAX - constant;
-
-        addRangeCheck(testRHS, UNASSIGNED, constant);
-        return true;
-    }
-
-    /*
-     * If the access is of the form 'y + a' where we know that z >= b at the
-     * head of the loop and y has a linear relationship with z such that
-     * (y + z) always has the same value at the head of the loop, hoist as
-     * follows:
-     *
-     * y + a <= INT_MAX
-     * y + z <= INT_MAX + z - a
-     * y + z <= INT_MAX + b - a
-     */
-    if (hasTestLinearRelationship(baseSlot)) {
-        int32_t constant;
-        if (!SafeSub(testConstant, baseConstant, &constant))
-            return false;
-
-        if (constant >= 0)
-            constant = 0;
-        constant = JSVAL_INT_MAX + constant;
-
-        addRangeCheck(baseSlot, testLHS, constant);
-        return true;
-    }
-
-    JaegerSpew(JSpew_Analysis, "No match found\n");
-    return false;
-}
-
-bool
-LoopState::ignoreIntegerOverflow(const CrossSSAValue &pushed)
-{
-    if (skipAnalysis || unknownModset || !constrainedLoop)
-        return false;
-
-    /*
-     * Under certain circumstances, we can ignore arithmetic overflow in adds
-     * and multiplies. As long as the result of the add/mul is either only used
-     * in bitwise arithmetic or is only used in additions whose result is only
-     * used in bitwise arithmetic, then the conversion to integer performed by
-     * the bitop will undo the effect of the earlier overflow. There are two
-     * additional things to watch for before performing this transformation:
-     *
-     * 1. If the overflowing double is sufficiently large that it loses
-     * precision in its lower bits (with a 48 bit mantissa, this may happen for
-     * values of N >= 2^48), the resulting rounding could change the result.
-     * We don't ignore overflow on multiplications without range information,
-     * though assume that no amount of integer additions we perform in a single
-     * loop iteration will overflow 2^48.
-     *
-     * 2. If used in an addition with a string, the overflowing and truncated
-     * results may produce different values (e.g. '(x + "e3") & y'). We must
-     * restrict the loop body in such a way that no string operand is possible
-     * or becomes possible due to dynamic type changes for such additions.
-     * constrainedLoop indicates whether the only operations which can happen
-     * in the loop body are int/double arithmetic and bitops, and reads/writes
-     * from known dense arrays which can only produce ints and doubles.
-     */
-
-    /* This value must be in the outer loop: loops with inline calls are not constrained. */
-    JS_ASSERT(pushed.frame == CrossScriptSSA::OUTER_FRAME);
-
-    JS_ASSERT(pushed.v.kind() == SSAValue::PUSHED);
-    jsbytecode *PC = outerScript->code + pushed.v.pushedOffset();
-
-    JSOp op = JSOp(*PC);
-    if (op != JSOP_MUL && op != JSOP_ADD)
-        return false;
-
-    if (valueFlowsToBitops(pushed.v)) {
-        JaegerSpew(JSpew_Analysis, "Integer result flows to bitops\n");
-        return true;
-    }
-
-    if (op == JSOP_MUL) {
-        /*
-         * If the multiply will only be used in an addition, negative zero can
-         * be ignored as long as the other operand in the addition cannot be
-         * negative zero.
-         */
-        if (!outerAnalysis->trackUseChain(pushed.v))
-            return false;
-
-        SSAUseChain *use = outerAnalysis->useChain(pushed.v);
-        if (!use || use->next || !use->popped || outerScript->code[use->offset] != JSOP_ADD)
-            return false;
-
-        if (use->u.which == 1) {
-            /*
-             * Only ignore negative zero if this is the RHS of an addition.
-             * Otherwise the result of the other side could change to a double
-             * after the first LHS has been computed, and be affected by a
-             * negative zero LHS.
-             */
-            return false;
-        }
-
-        StackTypeSet *lhsTypes = outerAnalysis->poppedTypes(use->offset, 1);
-        if (lhsTypes->getKnownTypeTag() != JSVAL_TYPE_INT32)
-            return false;
-
-        JaegerSpew(JSpew_Analysis, "Integer result is RHS in integer addition\n");
-        return true;
-    }
-
-    return false;
-}
-
-bool
-LoopState::valueFlowsToBitops(const analyze::SSAValue &v)
-{
-    /*
-     * Determine whether v can only be used in a bitop later in the same
-     * iteration of this loop, or in additions whose result is also only
-     * used in such a bitop.
-     */
-    if (!outerAnalysis->trackUseChain(v))
-        return false;
-
-    SSAUseChain *use = outerAnalysis->useChain(v);
-    while (use) {
-        if (!use->popped) {
-            /*
-             * Ignore variables used in phi nodes, so long as the variable is
-             * dead at the phi. We don't track live variables across back edges
-             * or complex control flow.
-             */
-            if (v.kind() == SSAValue::VAR) {
-                analyze::Lifetime *lifetime = outerAnalysis->liveness(v.varSlot()).live(use->offset);
-                if (!lifetime) {
-                    use = use->next;
-                    continue;
-                }
-            }
-            return false;
-        }
-
-        if (use->offset > lifetime->backedge)
-            return false;
-
-        jsbytecode *pc = outerScript->code + use->offset;
-        JSOp op = JSOp(*pc);
-        switch (op) {
-          case JSOP_ADD:
-          case JSOP_GETLOCAL: {
-            SSAValue pushv;
-            pushv.initPushed(use->offset, 0);
-            if (!valueFlowsToBitops(pushv))
-                return false;
-            break;
-          }
-
-          case JSOP_SETLOCAL: {
-            uint32_t slot = GetBytecodeSlot(outerScript, pc);
-            if (!outerAnalysis->trackSlot(slot))
-                return false;
-            SSAValue writev;
-            writev.initWritten(slot, use->offset);
-            if (!valueFlowsToBitops(writev))
-                return false;
-            break;
-          }
-
-          case JSOP_BITAND:
-          case JSOP_BITOR:
-          case JSOP_BITXOR:
-          case JSOP_RSH:
-          case JSOP_LSH:
-          case JSOP_URSH:
-          case JSOP_BITNOT:
-            break;
-
-          default:
-            return false;
-        }
-
-        use = use->next;
-    }
-
-    return true;
-}
-
-void
-LoopState::restoreInvariants(jsbytecode *pc, Assembler &masm,
-                             Vector<TemporaryCopy> *temporaryCopies, Vector<Jump> *jumps)
-{
-    /*
-     * Restore all invariants in memory when entering the loop or after any
-     * scripted or C++ call, and check that all hoisted conditions still hold.
-     * Care should be taken not to clobber the return register or callee-saved
-     * registers, which may still be live after some calls.
-     */
-
-    Registers regs(Registers::TempRegs);
-    regs.takeReg(Registers::ReturnReg);
-    if (regs.hasReg(JSReturnReg_Data))
-        regs.takeReg(JSReturnReg_Data);
-    if (regs.hasReg(JSReturnReg_Type))
-        regs.takeReg(JSReturnReg_Type);
-
-    RegisterID T0 = regs.takeAnyReg().reg();
-    RegisterID T1 = regs.takeAnyReg().reg();
-
-    for (unsigned i = 0; i < invariantEntries.length(); i++) {
-        const InvariantEntry &entry = invariantEntries[i];
-        switch (entry.kind) {
-
-          case InvariantEntry::DENSE_ARRAY_BOUNDS_CHECK:
-          case InvariantEntry::TYPED_ARRAY_BOUNDS_CHECK: {
-            /*
-             * Hoisted bounds checks always have preceding invariant slots
-             * in the invariant list, so don't recheck this is an object.
-             */
-            masm.loadPayload(frame.addressOf(entry.u.check.arraySlot), T0);
-            if (entry.kind == InvariantEntry::DENSE_ARRAY_BOUNDS_CHECK) {
-                masm.loadPtr(Address(T0, JSObject::offsetOfElements()), T0);
-                masm.load32(Address(T0, ObjectElements::offsetOfInitializedLength()), T0);
-            } else {
-                masm.loadPayload(Address(T0, TypedArray::lengthOffset()), T0);
-            }
-
-            int32_t constant = entry.u.check.constant;
-
-            if (entry.u.check.valueSlot1 != UINT32_MAX) {
-                constant += adjustConstantForIncrement(pc, entry.u.check.valueSlot1);
-                masm.loadPayload(frame.addressOf(entry.u.check.valueSlot1), T1);
-                if (entry.u.check.valueSlot2 != UINT32_MAX) {
-                    constant += adjustConstantForIncrement(pc, entry.u.check.valueSlot2);
-                    Jump overflow = masm.branchAdd32(Assembler::Overflow,
-                                                     frame.addressOf(entry.u.check.valueSlot2), T1);
-                    jumps->append(overflow);
-                }
-                if (constant != 0) {
-                    Jump overflow = masm.branchAdd32(Assembler::Overflow,
-                                                     Imm32(constant), T1);
-                    jumps->append(overflow);
-                }
-                Jump j = masm.branch32(Assembler::LessThanOrEqual, T0, T1);
-                jumps->append(j);
-            } else {
-                Jump j = masm.branch32(Assembler::LessThanOrEqual, T0,
-                                       Imm32(constant));
-                jumps->append(j);
-            }
-            break;
-          }
-
-          case InvariantEntry::RANGE_CHECK: {
-            int32_t constant = 0;
-
-            constant += adjustConstantForIncrement(pc, entry.u.check.valueSlot1);
-            masm.loadPayload(frame.addressOf(entry.u.check.valueSlot1), T0);
-            if (entry.u.check.valueSlot2 != UINT32_MAX) {
-                constant += adjustConstantForIncrement(pc, entry.u.check.valueSlot2);
-                Jump overflow = masm.branchAdd32(Assembler::Overflow,
-                                                 frame.addressOf(entry.u.check.valueSlot2), T0);
-                jumps->append(overflow);
-            }
-            if (constant != 0) {
-                Jump overflow = masm.branchAdd32(Assembler::Overflow, Imm32(constant), T0);
-                jumps->append(overflow);
-            }
-            Jump j = masm.branch32(Assembler::GreaterThan, T0, Imm32(entry.u.check.constant));
-            jumps->append(j);
-            break;
-          }
-
-          case InvariantEntry::NEGATIVE_CHECK: {
-            masm.loadPayload(frame.addressOf(entry.u.check.valueSlot1), T0);
-            if (entry.u.check.constant != 0) {
-                Jump overflow = masm.branchAdd32(Assembler::Overflow,
-                                                 Imm32(entry.u.check.constant), T0);
-                jumps->append(overflow);
-            }
-            Jump j = masm.branch32(Assembler::LessThan, T0, Imm32(0));
-            jumps->append(j);
-            break;
-          }
-
-          case InvariantEntry::DENSE_ARRAY_SLOTS:
-          case InvariantEntry::DENSE_ARRAY_LENGTH: {
-            uint32_t array = entry.u.array.arraySlot;
-            Jump notObject = masm.testObject(Assembler::NotEqual, frame.addressOf(array));
-            jumps->append(notObject);
-            masm.loadPayload(frame.addressOf(array), T0);
-            masm.loadPtr(Address(T0, JSObject::offsetOfElements()), T0);
-
-            Address address = frame.addressOf(frame.getTemporary(entry.u.array.temporary));
-
-            if (entry.kind == InvariantEntry::DENSE_ARRAY_LENGTH) {
-                masm.load32(Address(T0, ObjectElements::offsetOfLength()), T0);
-                masm.storeValueFromComponents(ImmType(JSVAL_TYPE_INT32), T0, address);
-            } else {
-                masm.storePayload(T0, address);
-            }
-            break;
-          }
-
-          case InvariantEntry::TYPED_ARRAY_SLOTS:
-          case InvariantEntry::TYPED_ARRAY_LENGTH: {
-            uint32_t array = entry.u.array.arraySlot;
-            Jump notObject = masm.testObject(Assembler::NotEqual, frame.addressOf(array));
-            jumps->append(notObject);
-            masm.loadPayload(frame.addressOf(array), T0);
-
-            Address address = frame.addressOf(frame.getTemporary(entry.u.array.temporary));
-
-            if (entry.kind == InvariantEntry::TYPED_ARRAY_LENGTH) {
-                masm.loadPayload(Address(T0, TypedArray::lengthOffset()), T0);
-                masm.storeValueFromComponents(ImmType(JSVAL_TYPE_INT32), T0, address);
-            } else {
-                masm.loadPtr(Address(T0, js::TypedArray::dataOffset()), T0);
-                masm.storePayload(T0, address);
-            }
-            break;
-          }
-
-          case InvariantEntry::INVARIANT_ARGS_BASE: {
-            Address address = frame.addressOf(frame.getTemporary(entry.u.array.temporary));
-            masm.loadFrameActuals(outerScript->function(), T0);
-            masm.storePayload(T0, address);
-            break;
-          }
-
-          case InvariantEntry::INVARIANT_ARGS_LENGTH: {
-            Address address = frame.addressOf(frame.getTemporary(entry.u.array.temporary));
-            masm.load32(Address(JSFrameReg, StackFrame::offsetOfNumActual()), T0);
-            masm.storeValueFromComponents(ImmType(JSVAL_TYPE_INT32), T0, address);
-            break;
-          }
-
-          case InvariantEntry::INVARIANT_PROPERTY: {
-            uint32_t object = entry.u.property.objectSlot;
-            Jump notObject = masm.testObject(Assembler::NotEqual, frame.addressOf(object));
-            jumps->append(notObject);
-            masm.loadPayload(frame.addressOf(object), T0);
-
-            masm.loadInlineSlot(T0, entry.u.property.propertySlot, T1, T0);
-            masm.storeValueFromComponents(T1, T0,
-                frame.addressOf(frame.getTemporary(entry.u.property.temporary)));
-            break;
-          }
-
-          default:
-            JS_NOT_REACHED("Bad invariant kind");
-        }
-    }
-
-    /*
-     * If there were any copies of temporaries on the stack, make sure the
-     * value we just reconstructed matches the stored value of that temporary.
-     * We sync the entire stack before calls, so the copy's slot holds the old
-     * value, but in future code we will assume the copy is valid and use the
-     * changed value of the invariant.
-     */
-
-    for (unsigned i = 0; temporaryCopies && i < temporaryCopies->length(); i++) {
-        const TemporaryCopy &copy = (*temporaryCopies)[i];
-        masm.compareValue(copy.copy, copy.temporary, T0, T1, jumps);
-    }
-
-    if (temporaryCopies)
-        js_delete(temporaryCopies);
-}
-
-/* Loop analysis methods. */
-
-bool
-LoopState::definiteArrayAccess(const SSAValue &obj, const SSAValue &index)
-{
-    /*
-     * Check that an index on obj is definitely accessing a dense array, giving
-     * either a value modelled by the pushed types or a hole. This needs to be
-     * robust against recompilations that could be triggered inside the loop:
-     * the array must be loop invariant, and the index must definitely be an
-     * integer.
-     *
-     * This is used to determine if we can ignore possible integer overflow in
-     * an operation; if this site could read a non-integer element out of the
-     * array or invoke a scripted getter/setter, it could produce a string or
-     * other value by which the overflow could be observed.
-     */
-
-    StackTypeSet *objTypes = outerAnalysis->getValueTypes(obj);
-    StackTypeSet *elemTypes = outerAnalysis->getValueTypes(index);
-
-    if (objTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT ||
-        elemTypes->getKnownTypeTag() != JSVAL_TYPE_INT32) {
-        return false;
-    }
-
-    if (objTypes->getKnownClass() != &ArrayClass)
-        return false;
-    if (objTypes->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES |
-                                 types::OBJECT_FLAG_LENGTH_OVERFLOW))
-        return false;
-
-    RootedScript rOuterScript(cx, outerScript);
-    if (ArrayPrototypeHasIndexedProperty(cx, rOuterScript))
-        return false;
-
-    uint32_t objSlot;
-    int32_t objConstant;
-    CrossSSAValue objv(CrossScriptSSA::OUTER_FRAME, obj);
-    if (!getEntryValue(objv, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0)
-        return false;
-    if (!loopInvariantEntry(objSlot))
-        return false;
-
-    /* Bitops must produce integers. */
-    if (index.kind() == SSAValue::PUSHED) {
-        JSOp op = JSOp(outerScript->code[index.pushedOffset()]);
-        switch (op) {
-          case JSOP_BITAND:
-          case JSOP_BITOR:
-          case JSOP_BITXOR:
-          case JSOP_BITNOT:
-          case JSOP_RSH:
-          case JSOP_LSH:
-          case JSOP_URSH:
-            return true;
-          default:;
-        }
-    }
-
-    uint32_t indexSlot;
-    int32_t indexConstant;
-    CrossSSAValue indexv(CrossScriptSSA::OUTER_FRAME, index);
-    if (!getEntryValue(indexv, &indexSlot, &indexConstant))
-        return false;
-
-    /*
-     * The index is determined from a variable's value at loop entry. We don't
-     * carry values with ignored overflows around loop back edges, so will know
-     * the index is a non-integer before such overflows are ignored.
-     */
-    return true;
-}
-
-void
-LoopState::analyzeLoopBody(unsigned frame)
-{
-    if (cc.debugMode()) {
-        skipAnalysis = true;
-        return;
-    }
-
-    JSScript *script = ssa->getFrame(frame).script;
-    analyze::ScriptAnalysis *analysis = script->analysis();
-    JS_ASSERT(analysis && !analysis->failed() && analysis->ranInference());
-
-    /*
-     * The temporaries need to be positioned after all values in the deepest
-     * inlined frame plus another stack frame pushed by, e.g. ic::Call.
-     * This new frame will have been partially initialized by the call, and
-     * we don't want to scribble on that frame when restoring invariants.
-     */
-    temporariesStart =
-        Max<uint32_t>(temporariesStart,
-                    ssa->getFrame(frame).depth + VALUES_PER_STACK_FRAME * 2 + script->nslots);
-
-    if (script->failedBoundsCheck || analysis->localsAliasStack())
-        skipAnalysis = true;
-
-    /* Analyze the entire script for frames inlined in the loop body. */
-    unsigned start = (frame == CrossScriptSSA::OUTER_FRAME) ? lifetime->head + JSOP_LOOPHEAD_LENGTH : 0;
-    unsigned end = (frame == CrossScriptSSA::OUTER_FRAME) ? lifetime->backedge : script->length;
-
-    unsigned offset = start;
-    while (offset < end) {
-        jsbytecode *pc = script->code + offset;
-        uint32_t successorOffset = offset + GetBytecodeLength(pc);
-
-        analyze::Bytecode *opinfo = analysis->maybeCode(offset);
-        if (!opinfo) {
-            offset = successorOffset;
-            continue;
-        }
-
-        JSOp op = JSOp(*pc);
-
-        /* Don't do any hoisting for outer loops in case of nesting. */
-        if (op == JSOP_LOOPHEAD)
-            skipAnalysis = true;
-
-        switch (op) {
-
-          case JSOP_CALL: {
-            /*
-             * Don't hoist within this loop unless calls at this site are inlined.
-             * :XXX: also recognize native calls which will be inlined.
-             */
-            bool foundInline = false;
-            for (unsigned i = 0; !foundInline && i < ssa->numFrames(); i++) {
-                if (ssa->iterFrame(i).parent == frame && ssa->iterFrame(i).parentpc == pc)
-                    foundInline = true;
-            }
-            if (!foundInline)
-                skipAnalysis = true;
-            break;
-          }
-
-          case JSOP_EVAL:
-          case JSOP_FUNCALL:
-          case JSOP_FUNAPPLY:
-          case JSOP_NEW:
-            skipAnalysis = true;
-            break;
-
-          case JSOP_SETELEM: {
-            SSAValue objValue = analysis->poppedValue(pc, 2);
-            SSAValue elemValue = analysis->poppedValue(pc, 1);
-
-            StackTypeSet *objTypes = analysis->getValueTypes(objValue);
-            StackTypeSet *elemTypes = analysis->getValueTypes(elemValue);
-
-            /*
-             * Mark the modset as unknown if the index might be non-integer,
-             * we don't want to consider the SETELEM PIC here.
-             */
-            if (objTypes->unknownObject() || elemTypes->getKnownTypeTag() != JSVAL_TYPE_INT32) {
-                unknownModset = true;
-                break;
-            }
-
-            for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
-                TypeObject *object = objTypes->getTypeObject(i);
-                if (!object)
-                    continue;
-                if (!addModifiedProperty(object, JSID_VOID))
-                    return;
-                if (analysis->getCode(pc).arrayWriteHole && !addGrowArray(object))
-                    return;
-            }
-
-            if (constrainedLoop && !definiteArrayAccess(objValue, elemValue))
-                constrainedLoop = false;
-            break;
-          }
-
-          case JSOP_GETELEM: {
-            SSAValue objValue = analysis->poppedValue(pc, 1);
-            SSAValue elemValue = analysis->poppedValue(pc, 0);
-
-            if (constrainedLoop && !definiteArrayAccess(objValue, elemValue))
-                constrainedLoop = false;
-            break;
-          }
-
-          case JSOP_SETPROP: {
-            PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
-            jsid id = IdToTypeId(NameToId(name));
-
-            TypeSet *objTypes = analysis->poppedTypes(pc, 1);
-            if (objTypes->unknownObject()) {
-                unknownModset = true;
-                break;
-            }
-
-            for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
-                TypeObject *object = objTypes->getTypeObject(i);
-                if (!object)
-                    continue;
-                if (!addModifiedProperty(object, id))
-                    continue;
-            }
-
-            constrainedLoop = false;
-            break;
-          }
-
-          case JSOP_ENUMELEM:
-          case JSOP_ENUMCONSTELEM:
-            unknownModset = true;
-            break;
-
-          case JSOP_LOOPHEAD:
-          case JSOP_LOOPENTRY:
-          case JSOP_POP:
-          case JSOP_ZERO:
-          case JSOP_ONE:
-          case JSOP_INT8:
-          case JSOP_INT32:
-          case JSOP_UINT16:
-          case JSOP_UINT24:
-          case JSOP_FALSE:
-          case JSOP_TRUE:
-          case JSOP_GETARG:
-          case JSOP_SETARG:
-          case JSOP_INCARG:
-          case JSOP_DECARG:
-          case JSOP_ARGINC:
-          case JSOP_ARGDEC:
-          case JSOP_THIS:
-          case JSOP_GETLOCAL:
-          case JSOP_SETLOCAL:
-          case JSOP_INCLOCAL:
-          case JSOP_DECLOCAL:
-          case JSOP_LOCALINC:
-          case JSOP_LOCALDEC:
-          case JSOP_IFEQ:
-          case JSOP_IFNE:
-          case JSOP_AND:
-          case JSOP_OR:
-          case JSOP_GOTO:
-            break;
-
-          case JSOP_ADD:
-          case JSOP_SUB:
-          case JSOP_MUL:
-          case JSOP_MOD:
-          case JSOP_DIV:
-          case JSOP_BITAND:
-          case JSOP_BITOR:
-          case JSOP_BITXOR:
-          case JSOP_RSH:
-          case JSOP_LSH:
-          case JSOP_URSH:
-          case JSOP_EQ:
-          case JSOP_NE:
-          case JSOP_LT:
-          case JSOP_LE:
-          case JSOP_GT:
-          case JSOP_GE:
-          case JSOP_STRICTEQ:
-          case JSOP_STRICTNE: {
-            JSValueType type = analysis->poppedTypes(pc, 1)->getKnownTypeTag();
-            if (type != JSVAL_TYPE_INT32 && type != JSVAL_TYPE_DOUBLE)
-                constrainedLoop = false;
-          }
-          /* FALLTHROUGH */
-
-          case JSOP_POS:
-          case JSOP_NEG:
-          case JSOP_BITNOT: {
-            JSValueType type = analysis->poppedTypes(pc, 0)->getKnownTypeTag();
-            if (type != JSVAL_TYPE_INT32 && type != JSVAL_TYPE_DOUBLE)
-                constrainedLoop = false;
-            break;
-          }
-
-          default:
-            constrainedLoop = false;
-            break;
-        }
-
-        offset = successorOffset;
-    }
-}
-
-bool
-LoopState::addGrowArray(TypeObject *object)
-{
-    static const uint32_t MAX_SIZE = 10;
-    for (unsigned i = 0; i < growArrays.length(); i++) {
-        if (growArrays[i] == object)
-            return true;
-    }
-    if (growArrays.length() >= MAX_SIZE) {
-        unknownModset = true;
-        return false;
-    }
-    growArrays.append(object);
-
-    return true;
-}
-
-bool
-LoopState::addModifiedProperty(TypeObject *object, jsid id)
-{
-    static const uint32_t MAX_SIZE = 20;
-    for (unsigned i = 0; i < modifiedProperties.length(); i++) {
-        if (modifiedProperties[i].object == object && modifiedProperties[i].id == id)
-            return true;
-    }
-    if (modifiedProperties.length() >= MAX_SIZE) {
-        unknownModset = true;
-        return false;
-    }
-
-    ModifiedProperty property;
-    property.object = object;
-    property.id = id;
-    modifiedProperties.append(property);
-
-    return true;
-}
-
-bool
-LoopState::hasGrowArray(TypeObject *object)
-{
-    if (unknownModset)
-        return true;
-    for (unsigned i = 0; i < growArrays.length(); i++) {
-        if (growArrays[i] == object)
-            return true;
-    }
-    return false;
-}
-
-bool
-LoopState::hasModifiedProperty(TypeObject *object, jsid id)
-{
-    if (unknownModset)
-        return true;
-    id = IdToTypeId(id);
-    for (unsigned i = 0; i < modifiedProperties.length(); i++) {
-        if (modifiedProperties[i].object == object && modifiedProperties[i].id == id)
-            return true;
-    }
-    return false;
-}
-
-uint32_t
-LoopState::getIncrement(uint32_t slot)
-{
-    for (unsigned i = 0; i < increments.length(); i++) {
-        if (increments[i].slot == slot)
-            return increments[i].offset;
-    }
-    return UINT32_MAX;
-}
-
-int32_t
-LoopState::adjustConstantForIncrement(jsbytecode *pc, uint32_t slot)
-{
-    /*
-     * The only terms that can appear in a hoisted bounds check are either
-     * loop invariant or are incremented or decremented exactly once in each
-     * iteration of the loop. Depending on the current pc in the body of the
-     * loop, return a constant adjustment if an increment/decrement for slot
-     * has not yet happened, such that 'slot + n' at this point is the value
-     * of slot at the start of the next iteration.
-     */
-    uint32_t offset = getIncrement(slot);
-
-    /*
-     * Note the '<' here. If this PC is at one of the increment opcodes, then
-     * behave as if the increment has not happened yet. This is needed for loop
-     * entry points, which can be directly at an increment. We won't rejoin
-     * after the increment, as we only take stub calls in such situations on
-     * integer overflow, which will disable hoisted conditions involving the
-     * variable anyways.
-     */
-    if (offset == UINT32_MAX || offset < uint32_t(pc - outerScript->code))
-        return 0;
-
-    switch (JSOp(outerScript->code[offset])) {
-      case JSOP_INCLOCAL:
-      case JSOP_LOCALINC:
-      case JSOP_INCARG:
-      case JSOP_ARGINC:
-        return 1;
-      case JSOP_DECLOCAL:
-      case JSOP_LOCALDEC:
-      case JSOP_DECARG:
-      case JSOP_ARGDEC:
-        return -1;
-      default:
-        JS_NOT_REACHED("Bad op");
-        return 0;
-    }
-}
-
-bool
-LoopState::getEntryValue(const CrossSSAValue &iv, uint32_t *pslot, int32_t *pconstant)
-{
-    *pslot = UNASSIGNED;
-    *pconstant = 1;
-
-    CrossSSAValue cv = ssa->foldValue(iv);
-
-    JSScript *script = ssa->getFrame(cv.frame).script;
-    ScriptAnalysis *analysis = script->analysis();
-    const SSAValue &v = cv.v;
-
-    /*
-     * For a stack value popped by the bytecode at offset, try to get an
-     * expression 'slot + constant' with the same value as the stack value
-     * and expressed in terms of the state at loop entry.
-     */
-
-    if (v.kind() == SSAValue::PHI) {
-        if (cv.frame != CrossScriptSSA::OUTER_FRAME)
-            return false;
-        if (v.phiSlot() >= TotalSlots(script))
-            return false;
-        if (v.phiOffset() > lifetime->head &&
-            outerAnalysis->liveness(v.phiSlot()).firstWrite(lifetime) < v.phiOffset()) {
-            return false;
-        }
-        *pslot = v.phiSlot();
-        *pconstant = 0;
-        return true;
-    }
-
-    if (v.kind() == SSAValue::VAR) {
-        if (cv.frame != CrossScriptSSA::OUTER_FRAME)
-            return false;
-        if (v.varInitial() || v.varOffset() < lifetime->head) {
-            *pslot = v.varSlot();
-            *pconstant = 0;
-            return true;
-        }
-    }
-
-    if (v.kind() != SSAValue::PUSHED)
-        return false;
-
-    jsbytecode *pc = script->code + v.pushedOffset();
-    JSOp op = (JSOp)*pc;
-
-    switch (op) {
-
-      case JSOP_GETLOCAL:
-      case JSOP_LOCALINC:
-      case JSOP_INCLOCAL:
-      case JSOP_GETARG:
-      case JSOP_ARGINC:
-      case JSOP_INCARG: {
-        if (cv.frame != CrossScriptSSA::OUTER_FRAME || !analysis->integerOperation(pc))
-            return false;
-        uint32_t slot = GetBytecodeSlot(outerScript, pc);
-        if (outerAnalysis->slotEscapes(slot))
-            return false;
-        uint32_t write = outerAnalysis->liveness(slot).firstWrite(lifetime);
-        if (write != UINT32_MAX && write < v.pushedOffset()) {
-            /* Variable has been modified since the start of the loop. */
-            return false;
-        }
-        *pslot = slot;
-        *pconstant = (op == JSOP_INCLOCAL || op == JSOP_INCARG) ? 1 : 0;
-        return true;
-      }
-
-      case JSOP_THIS:
-        if (cv.frame != CrossScriptSSA::OUTER_FRAME)
-            return false;
-        *pslot = ThisSlot();
-        *pconstant = 0;
-        return true;
-
-      case JSOP_ZERO:
-      case JSOP_ONE:
-      case JSOP_UINT16:
-      case JSOP_UINT24:
-      case JSOP_INT8:
-      case JSOP_INT32:
-        *pslot = UNASSIGNED;
-        *pconstant = GetBytecodeInteger(pc);
-        return true;
-
-      case JSOP_LENGTH: {
-        CrossSSAValue lengthcv(cv.frame, analysis->poppedValue(v.pushedOffset(), 0));
-        FrameEntry *tmp = invariantLength(lengthcv);
-        if (!tmp)
-            return false;
-        *pslot = frame.outerSlot(tmp);
-        *pconstant = 0;
-        return true;
-      }
-
-      case JSOP_GETPROP: {
-        PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
-        jsid id = NameToId(name);
-        CrossSSAValue objcv(cv.frame, analysis->poppedValue(v.pushedOffset(), 0));
-        FrameEntry *tmp = invariantProperty(objcv, id);
-        if (!tmp)
-            return false;
-        *pslot = frame.outerSlot(tmp);
-        *pconstant = 0;
-        return true;
-      }
-
-      default:
-        return false;
-    }
-}
-
-bool
-LoopState::computeInterval(const CrossSSAValue &cv, int32_t *pmin, int32_t *pmax)
-{
-    JSScript *script = ssa->getFrame(cv.frame).script;
-    ScriptAnalysis *analysis = script->analysis();
-    const SSAValue &v = cv.v;
-
-    if (v.kind() == SSAValue::VAR && !v.varInitial()) {
-        jsbytecode *pc = script->code + v.varOffset();
-        switch (JSOp(*pc)) {
-          case JSOP_SETLOCAL:
-          case JSOP_SETARG: {
-            CrossSSAValue ncv(cv.frame, analysis->poppedValue(pc, 0));
-            return computeInterval(ncv, pmin, pmax);
-          }
-
-          default:
-            return false;
-        }
-    }
-
-    if (v.kind() != SSAValue::PUSHED)
-        return false;
-
-    jsbytecode *pc = script->code + v.pushedOffset();
-    JSOp op = (JSOp)*pc;
-
-    /* Note: this was adapted from similar code in nanojit/LIR.cpp */
-    switch (op) {
-
-      case JSOP_ZERO:
-      case JSOP_ONE:
-      case JSOP_UINT16:
-      case JSOP_UINT24:
-      case JSOP_INT8:
-      case JSOP_INT32: {
-        int32_t constant = GetBytecodeInteger(pc);
-        *pmin = constant;
-        *pmax = constant;
-        return true;
-      }
-
-      case JSOP_BITAND: {
-        int32_t lhsmin, lhsmax, rhsmin, rhsmax;
-        CrossSSAValue lhsv(cv.frame, analysis->poppedValue(pc, 1));
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        bool haslhs = computeInterval(lhsv, &lhsmin, &lhsmax);
-        bool hasrhs = computeInterval(rhsv, &rhsmin, &rhsmax);
-
-        /* Only handle bitand with a constant operand. */
-        haslhs = haslhs && lhsmin == lhsmax && lhsmin >= 0;
-        hasrhs = hasrhs && rhsmin == rhsmax && rhsmin >= 0;
-
-        if (haslhs && hasrhs) {
-            *pmin = 0;
-            *pmax = Min(lhsmax, rhsmax);
-        } else if (haslhs) {
-            *pmin = 0;
-            *pmax = lhsmax;
-        } else if (hasrhs) {
-            *pmin = 0;
-            *pmax = rhsmax;
-        } else {
-            return false;
-        }
-        return true;
-      }
-
-      case JSOP_RSH: {
-        int32_t rhsmin, rhsmax;
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(rhsv, &rhsmin, &rhsmax) || rhsmin != rhsmax)
-            return false;
-
-        /* Only use the bottom 5 bits. */
-        int32_t shift = rhsmin & 0x1f;
-        *pmin = -(1 << (31 - shift));
-        *pmax = (1 << (31 - shift)) - 1;
-        return true;
-      }
-
-      case JSOP_URSH: {
-        int32_t rhsmin, rhsmax;
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(rhsv, &rhsmin, &rhsmax) || rhsmin != rhsmax)
-            return false;
-
-        /* Only use the bottom 5 bits. */
-        int32_t shift = rhsmin & 0x1f;
-        if (shift == 0)
-            return false;
-        *pmin = 0;
-        *pmax = (1 << (31 - shift)) - 1;
-        return true;
-      }
-
-      case JSOP_MOD: {
-        int32_t rhsmin, rhsmax;
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(rhsv, &rhsmin, &rhsmax) || rhsmin != rhsmax)
-            return false;
-
-        uint32_t absRHS = Abs(rhsmax);
-        *pmin = -int32_t(absRHS - 1);
-        *pmax = int32_t(absRHS - 1);
-        return true;
-      }
-
-      case JSOP_ADD: {
-        int32_t lhsmin, lhsmax, rhsmin, rhsmax;
-        CrossSSAValue lhsv(cv.frame, analysis->poppedValue(pc, 1));
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(lhsv, &lhsmin, &lhsmax) || !computeInterval(rhsv, &rhsmin, &rhsmax))
-            return false;
-        return SafeAdd(lhsmin, rhsmin, pmin) && SafeAdd(lhsmax, rhsmax, pmax);
-      }
-
-      case JSOP_SUB: {
-        int32_t lhsmin, lhsmax, rhsmin, rhsmax;
-        CrossSSAValue lhsv(cv.frame, analysis->poppedValue(pc, 1));
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(lhsv, &lhsmin, &lhsmax) || !computeInterval(rhsv, &rhsmin, &rhsmax))
-            return false;
-        return SafeSub(lhsmin, rhsmax, pmin) && SafeSub(lhsmax, rhsmin, pmax);
-      }
-
-      case JSOP_MUL: {
-        int32_t lhsmin, lhsmax, rhsmin, rhsmax;
-        CrossSSAValue lhsv(cv.frame, analysis->poppedValue(pc, 1));
-        CrossSSAValue rhsv(cv.frame, analysis->poppedValue(pc, 0));
-        if (!computeInterval(lhsv, &lhsmin, &lhsmax) || !computeInterval(rhsv, &rhsmin, &rhsmax))
-            return false;
-
-        if (lhsmin == INT32_MIN || rhsmin == INT32_MIN)
-            return false;
-
-        int32_t nlhs = int32_t(Max(Abs(lhsmin), Abs(lhsmax)));
-        int32_t nrhs = int32_t(Max(Abs(rhsmin), Abs(rhsmax)));
-
-        if (!SafeMul(nlhs, nrhs, pmax))
-            return false;
-
-        if (lhsmin < 0 || rhsmin < 0) {
-            /* pmax is nonnegative, so can be negated without overflow. */
-            *pmin = -*pmax;
-        } else {
-            *pmin = 0;
-        }
-
-        return true;
-      }
-
-      default:
-        return false;
-    }
-}
deleted file mode 100644
--- a/js/src/methodjit/LoopState.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_loopstate_h__ && defined JS_METHODJIT
-#define jsjaeger_loopstate_h__
-
-#include "mozilla/PodOperations.h"
-
-#include "jsanalyze.h"
-#include "methodjit/Compiler.h"
-
-namespace js {
-namespace mjit {
-
-/*
- * The LoopState keeps track of register and analysis state within the loop
- * currently being processed by the Compiler.
- *
- * There are several analyses we do that are specific to loops: loop carried
- * registers, bounds check hoisting, and loop invariant code motion. Brief
- * descriptions of these analyses:
- *
- * Loop carried registers. We allocate registers as we emit code, in a single
- * forward pass over the script. Normally this would mean we need to pick the
- * register allocation at the head of the loop before any of the body has been
- * processed. Instead, while processing the loop body we retroactively mark
- * registers as holding the payload of certain entries at the head (being
- * carried around the loop), so that the head's allocation ends up holding
- * registers that are likely to be used shortly. This can be done provided that
- * (a) the register has not been touched since the loop head, (b) the slot
- * has not been modified or separately assigned a different register, and (c)
- * all prior slow path rejoins in the loop are patched with reloads of the
- * register. The register allocation at the loop head must have all entries
- * synced, so that prior slow path syncs do not also need patching.
- *
- * Bounds check hoisting. If we can determine a loop invariant test which
- * implies the bounds check at one or more array accesses, we hoist that and
- * check it when initially entering the loop (from JIT code or the
- * interpreter) and after every stub or C++ call.
- *
- * Loop invariant code motion. If we can determine a computation (arithmetic,
- * array slot pointer or property access) is loop invariant, we give it a slot
- * on the stack and preserve its value throughout the loop. We can allocate
- * and carry registers for loop invariant slots as for normal slots. These
- * slots sit above the frame's normal slots, and are transient --- they are
- * clobbered whenever a new frame is pushed. We thus regenerate the loop
- * invariant slots after every C++ and scripted call, and avoid doing LICM on
- * loops which have such calls. This has a nice property that the slots only
- * need to be loop invariant wrt the side effects that happen directly in the
- * loop; if C++ calls a getter which scribbles on the object properties
- * involved in an 'invariant' then we will reload the invariant's new value
- * after the call finishes.
- */
-
-struct TemporaryCopy;
-
-enum InvariantArrayKind { DENSE_ARRAY, TYPED_ARRAY };
-
-class LoopState : public MacroAssemblerTypedefs
-{
-    JSContext *cx;
-    analyze::CrossScriptSSA *ssa;
-    JSScript *outerScript;
-    analyze::ScriptAnalysis *outerAnalysis;
-
-    Compiler &cc;
-    FrameState &frame;
-
-    /* Basic information about this loop. */
-    analyze::LoopAnalysis *lifetime;
-
-    /* Allocation at the head of the loop, has all loop carried variables. */
-    RegisterAllocation *alloc;
-
-    /*
-     * Set if this is not a do-while loop and the compiler has advanced past
-     * the loop's entry point.
-     */
-    bool reachedEntryPoint;
-
-    /*
-     * Jump which initially enters the loop. The state is synced when this jump
-     * occurs, and needs a trampoline generated to load the right registers
-     * before going to entryTarget.
-     */
-    Jump entry;
-
-    /* Registers available for loop variables. */
-    Registers loopRegs;
-
-    /* Whether to skip all bounds check hoisting and loop invariant code analysis. */
-    bool skipAnalysis;
-
-    /* Prior stub rejoins to patch when new loop registers are allocated. */
-    struct StubJoin {
-        unsigned index;
-        bool script;
-    };
-    Vector<StubJoin,16,CompilerAllocPolicy> loopJoins;
-
-    /* Pending loads to patch for stub rejoins. */
-    struct StubJoinPatch {
-        StubJoin join;
-        Address address;
-        AnyRegisterID reg;
-    };
-    Vector<StubJoinPatch,16,CompilerAllocPolicy> loopPatches;
-
-    /*
-     * Pair of a jump/label immediately after each call in the loop, to patch
-     * with restores of the loop invariant stack values.
-     */
-    struct RestoreInvariantCall {
-        Jump jump;
-        Label label;
-        bool ool;
-        bool entry;
-        unsigned patchIndex;  /* Index into Compiler's callSites. */
-
-        /* Any copies of temporaries on the stack */
-        Vector<TemporaryCopy> *temporaryCopies;
-    };
-    Vector<RestoreInvariantCall> restoreInvariantCalls;
-
-    /*
-     * Aggregate structure for all loop invariant code and hoisted checks we
-     * can perform. These are all stored in the same vector as they may depend
-     * on each other and we need to emit code restoring them in order.
-     */
-    struct InvariantEntry {
-        enum EntryKind {
-            /*
-             * initializedLength(array) > value1 + value2 + constant.
-             * Unsigned comparison, so will fail if value + constant < 0
-             */
-            DENSE_ARRAY_BOUNDS_CHECK,
-            TYPED_ARRAY_BOUNDS_CHECK,
-
-            /* value1 + constant >= 0 */
-            NEGATIVE_CHECK,
-
-            /* constant >= value1 + value2 */
-            RANGE_CHECK,
-
-            /* For dense arrays */
-            DENSE_ARRAY_SLOTS,
-            DENSE_ARRAY_LENGTH,
-
-            /* For typed arrays */
-            TYPED_ARRAY_SLOTS,
-            TYPED_ARRAY_LENGTH,
-
-            /* For lazy arguments */
-            INVARIANT_ARGS_BASE,
-            INVARIANT_ARGS_LENGTH,
-
-            /* For definite properties */
-            INVARIANT_PROPERTY
-        } kind;
-        union {
-            struct {
-                uint32_t arraySlot;
-                uint32_t valueSlot1;
-                uint32_t valueSlot2;
-                int32_t constant;
-            } check;
-            struct {
-                uint32_t arraySlot;
-                uint32_t temporary;
-            } array;
-            struct {
-                uint32_t objectSlot;
-                uint32_t propertySlot;
-                uint32_t temporary;
-                jsid id;
-            } property;
-        } u;
-        InvariantEntry() { mozilla::PodZero(this); }
-        bool isBoundsCheck() const {
-            return kind == DENSE_ARRAY_BOUNDS_CHECK || kind == TYPED_ARRAY_BOUNDS_CHECK;
-        }
-        bool isCheck() const {
-            return isBoundsCheck() || kind == NEGATIVE_CHECK || kind == RANGE_CHECK;
-        }
-    };
-    Vector<InvariantEntry, 4, CompilerAllocPolicy> invariantEntries;
-
-    static inline bool entryRedundant(const InvariantEntry &e0, const InvariantEntry &e1);
-    bool checkRedundantEntry(const InvariantEntry &entry);
-
-    bool loopInvariantEntry(uint32_t slot);
-    bool addHoistedCheck(InvariantArrayKind arrayKind, uint32_t arraySlot,
-                         uint32_t valueSlot1, uint32_t valueSlot2, int32_t constant);
-    void addNegativeCheck(uint32_t valueSlot, int32_t constant);
-    void addRangeCheck(uint32_t valueSlot1, uint32_t valueSlot2, int32_t constant);
-    bool hasTestLinearRelationship(uint32_t slot);
-
-    bool hasInvariants() { return !invariantEntries.empty(); }
-    void restoreInvariants(jsbytecode *pc, Assembler &masm,
-                           Vector<TemporaryCopy> *temporaryCopies, Vector<Jump> *jumps);
-
-  public:
-
-    /* Outer loop to this one, in case of loop nesting. */
-    LoopState *outer;
-
-    /* Offset from the outermost frame at which temporaries should be allocated. */
-    uint32_t temporariesStart;
-
-    LoopState(JSContext *cx, analyze::CrossScriptSSA *ssa,
-              Compiler *cc, FrameState *frame);
-    bool init(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
-
-    void setOuterPC(jsbytecode *pc)
-    {
-        if (uint32_t(pc - outerScript->code) == lifetime->entry && lifetime->entry != lifetime->head)
-            reachedEntryPoint = true;
-    }
-
-    bool generatingInvariants() { return !skipAnalysis; }
-
-    /* Add a call with trailing jump/label, after which invariants need to be restored. */
-    void addInvariantCall(Jump jump, Label label, bool ool, bool entry, unsigned patchIndex, Uses uses);
-
-    uint32_t headOffset() { return lifetime->head; }
-    uint32_t getLoopRegs() { return loopRegs.freeMask; }
-
-    Jump entryJump() { return entry; }
-    uint32_t entryOffset() { return lifetime->entry; }
-    uint32_t backedgeOffset() { return lifetime->backedge; }
-
-    /* Whether the payload of slot is carried around the loop in a register. */
-    bool carriesLoopReg(FrameEntry *fe) { return alloc->hasAnyReg(frame.entrySlot(fe)); }
-
-    void setLoopReg(AnyRegisterID reg, FrameEntry *fe);
-
-    void clearLoopReg(AnyRegisterID reg)
-    {
-        /*
-         * Mark reg as having been modified since the start of the loop; it
-         * cannot subsequently be marked to carry a register around the loop.
-         */
-        JS_ASSERT(loopRegs.hasReg(reg) == alloc->loop(reg));
-        if (loopRegs.hasReg(reg)) {
-            loopRegs.takeReg(reg);
-            alloc->setUnassigned(reg);
-            JaegerSpew(JSpew_Regalloc, "clearing loop register %s\n", reg.name());
-        }
-    }
-
-    void addJoin(unsigned index, bool script);
-    void clearLoopRegisters();
-
-    void flushLoop(StubCompiler &stubcc);
-
-    /*
-     * These should only be used for entries which are known to be dense arrays
-     * (if they are objects at all).
-     */
-    bool hoistArrayLengthCheck(InvariantArrayKind arrayKind,
-                               const analyze::CrossSSAValue &obj,
-                               const analyze::CrossSSAValue &index);
-    FrameEntry *invariantArraySlots(const analyze::CrossSSAValue &obj);
-
-    /* Methods for accesses on lazy arguments. */
-    bool hoistArgsLengthCheck(const analyze::CrossSSAValue &index);
-    FrameEntry *invariantArguments();
-
-    FrameEntry *invariantLength(const analyze::CrossSSAValue &obj);
-    FrameEntry *invariantProperty(const analyze::CrossSSAValue &obj, jsid id);
-
-    /* Whether a binary or inc/dec op's result cannot overflow. */
-    bool cannotIntegerOverflow(const analyze::CrossSSAValue &pushed);
-
-    /*
-     * Whether integer overflow in addition or negative zeros in multiplication
-     * at a binary op can be safely ignored.
-     */
-    bool ignoreIntegerOverflow(const analyze::CrossSSAValue &pushed);
-
-  private:
-    /* Analysis information for the loop. */
-
-    /*
-     * Any inequality known to hold at the head of the loop. This has the
-     * form 'lhs <= rhs + constant' or 'lhs >= rhs + constant', depending on
-     * lessEqual. The lhs may be modified within the loop body (the test is
-     * invalid afterwards), and the rhs is invariant. This information is only
-     * valid if the LHS/RHS are known integers.
-     */
-    enum { UNASSIGNED = UINT32_MAX };
-    uint32_t testLHS;
-    uint32_t testRHS;
-    int32_t testConstant;
-    bool testLessEqual;
-
-    /*
-     * A variable which will be incremented or decremented exactly once in each
-     * iteration of the loop. The offset of the operation is indicated, which
-     * may or may not run after the initial entry into the loop.
-     */
-    struct Increment {
-        uint32_t slot;
-        uint32_t offset;
-    };
-    Vector<Increment, 4, CompilerAllocPolicy> increments;
-
-    /* It is unknown which arrays grow or which objects are modified in this loop. */
-    bool unknownModset;
-
-    /*
-     * Arrays which might grow during this loop. This is a guess, and may
-     * underapproximate the actual set of such arrays.
-     */
-    Vector<types::TypeObject *, 4, CompilerAllocPolicy> growArrays;
-
-    /* Properties which might be modified during this loop. */
-    struct ModifiedProperty {
-        types::TypeObject *object;
-        jsid id;
-    };
-    Vector<ModifiedProperty, 4, CompilerAllocPolicy> modifiedProperties;
-
-    /*
-     * Whether this loop only performs integer and double arithmetic and dense
-     * array accesses. Integer overflows in this loop which only flow to bitops
-     * can be ignored.
-     */
-    bool constrainedLoop;
-
-    void analyzeLoopBody(unsigned frame);
-
-    bool definiteArrayAccess(const analyze::SSAValue &obj, const analyze::SSAValue &index);
-
-    bool addGrowArray(types::TypeObject *object);
-    bool addModifiedProperty(types::TypeObject *object, jsid id);
-
-    bool hasGrowArray(types::TypeObject *object);
-    bool hasModifiedProperty(types::TypeObject *object, jsid id);
-
-    uint32_t getIncrement(uint32_t slot);
-    int32_t adjustConstantForIncrement(jsbytecode *pc, uint32_t slot);
-
-    bool getEntryValue(const analyze::CrossSSAValue &v, uint32_t *pslot, int32_t *pconstant);
-    bool computeInterval(const analyze::CrossSSAValue &v, int32_t *pmin, int32_t *pmax);
-    bool valueFlowsToBitops(const analyze::SSAValue &v);
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_loopstate_h__ */
deleted file mode 100644
--- a/js/src/methodjit/MachineRegs.h
+++ /dev/null
@@ -1,589 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_regstate_h__ && defined JS_METHODJIT
-#define jsjaeger_regstate_h__
-
-#include "mozilla/Util.h"
-
-#include "assembler/assembler/MacroAssembler.h"
-
-namespace js {
-
-namespace mjit {
-
-/* Common handling for both general purpose and floating point registers. */
-
-struct AnyRegisterID {
-    unsigned reg_;
-
-    AnyRegisterID()
-        : reg_((unsigned)-1)
-    { pin(); }
-
-    AnyRegisterID(const AnyRegisterID &o)
-        : reg_(o.reg_)
-    { pin(); }
-
-    AnyRegisterID(JSC::MacroAssembler::RegisterID reg)
-        : reg_((unsigned)reg)
-    { pin(); }
-
-    AnyRegisterID(JSC::MacroAssembler::FPRegisterID reg)
-        : reg_(JSC::MacroAssembler::TotalRegisters + (unsigned)reg)
-    { pin(); }
-
-    static inline AnyRegisterID fromRaw(unsigned reg);
-
-    inline JSC::MacroAssembler::RegisterID reg();
-    inline JSC::MacroAssembler::FPRegisterID fpreg();
-
-    bool isSet() { return reg_ != unsigned(-1); }
-    bool isReg() { return reg_ < JSC::MacroAssembler::TotalRegisters; }
-    bool isFPReg() { return isSet() && !isReg(); }
-
-    inline const char * name();
-
-  private:
-    unsigned * pin() {
-        /*
-         * Workaround for apparent compiler bug in GCC 4.2. If GCC thinks that reg_
-         * cannot escape then it compiles isReg() and other accesses to reg_ incorrectly.
-         */
-        static unsigned *v;
-        v = &reg_;
-        return v;
-    }
-};
-
-struct Registers {
-
-    /* General purpose registers. */
-
-    static const uint32_t TotalRegisters = JSC::MacroAssembler::TotalRegisters;
-
-    enum CallConvention {
-        NormalCall,
-        FastCall
-    };
-
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    // Homed and scratch registers for working with Values on x64.
-#if defined(JS_CPU_X64)
-    static const RegisterID TypeMaskReg = JSC::X86Registers::r13;
-    static const RegisterID PayloadMaskReg = JSC::X86Registers::r14;
-    static const RegisterID ValueReg = JSC::X86Registers::r10;
-    static const RegisterID ScratchReg = JSC::X86Registers::r11;
-#endif
-
-    // Register that homes the current JSStackFrame.
-#if defined(JS_CPU_X86)
-    static const RegisterID JSFrameReg = JSC::X86Registers::ebp;
-#elif defined(JS_CPU_X64)
-    static const RegisterID JSFrameReg = JSC::X86Registers::ebx;
-#elif defined(JS_CPU_ARM)
-    static const RegisterID JSFrameReg = JSC::ARMRegisters::r10;
-#elif defined(JS_CPU_SPARC)
-    static const RegisterID JSFrameReg = JSC::SparcRegisters::l0;
-#elif defined(JS_CPU_MIPS)
-    static const RegisterID JSFrameReg = JSC::MIPSRegisters::s0;
-#endif
-
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    static const RegisterID ReturnReg = JSC::X86Registers::eax;
-# if defined(JS_CPU_X86) || defined(_WIN64)
-    static const RegisterID ArgReg0 = JSC::X86Registers::ecx;
-    static const RegisterID ArgReg1 = JSC::X86Registers::edx;
-#  if defined(JS_CPU_X64)
-    static const RegisterID ArgReg2 = JSC::X86Registers::r8;
-    static const RegisterID ArgReg3 = JSC::X86Registers::r9;
-#  endif
-# else
-    static const RegisterID ArgReg0 = JSC::X86Registers::edi;
-    static const RegisterID ArgReg1 = JSC::X86Registers::esi;
-    static const RegisterID ArgReg2 = JSC::X86Registers::edx;
-    static const RegisterID ArgReg3 = JSC::X86Registers::ecx;
-# endif
-#elif JS_CPU_ARM
-    static const RegisterID ReturnReg = JSC::ARMRegisters::r0;
-    static const RegisterID ArgReg0 = JSC::ARMRegisters::r0;
-    static const RegisterID ArgReg1 = JSC::ARMRegisters::r1;
-    static const RegisterID ArgReg2 = JSC::ARMRegisters::r2;
-#elif JS_CPU_SPARC
-    static const RegisterID ReturnReg = JSC::SparcRegisters::o0;
-    static const RegisterID ArgReg0 = JSC::SparcRegisters::o0;
-    static const RegisterID ArgReg1 = JSC::SparcRegisters::o1;
-    static const RegisterID ArgReg2 = JSC::SparcRegisters::o2;
-    static const RegisterID ArgReg3 = JSC::SparcRegisters::o3;
-    static const RegisterID ArgReg4 = JSC::SparcRegisters::o4;
-    static const RegisterID ArgReg5 = JSC::SparcRegisters::o5;
-#elif JS_CPU_MIPS
-    static const RegisterID ReturnReg = JSC::MIPSRegisters::v0;
-    static const RegisterID ArgReg0 = JSC::MIPSRegisters::a0;
-    static const RegisterID ArgReg1 = JSC::MIPSRegisters::a1;
-    static const RegisterID ArgReg2 = JSC::MIPSRegisters::a2;
-    static const RegisterID ArgReg3 = JSC::MIPSRegisters::a3;
-#endif
-
-    static const RegisterID StackPointer = JSC::MacroAssembler::stackPointerRegister;
-
-    static inline uint32_t maskReg(RegisterID reg) {
-        return (1 << reg);
-    }
-
-    static inline uint32_t mask2Regs(RegisterID reg1, RegisterID reg2) {
-        return maskReg(reg1) | maskReg(reg2);
-    }
-
-    static inline uint32_t mask3Regs(RegisterID reg1, RegisterID reg2, RegisterID reg3) {
-        return maskReg(reg1) | maskReg(reg2) | maskReg(reg3);
-    }
-
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    static const uint32_t TempRegs =
-          (1 << JSC::X86Registers::eax)
-# if defined(JS_CPU_X86)
-        | (1 << JSC::X86Registers::ebx)
-# endif
-        | (1 << JSC::X86Registers::ecx)
-        | (1 << JSC::X86Registers::edx)
-# if defined(JS_CPU_X64)
-        | (1 << JSC::X86Registers::r8)
-        | (1 << JSC::X86Registers::r9)
-#  if !defined(_WIN64)
-        | (1 << JSC::X86Registers::esi)
-        | (1 << JSC::X86Registers::edi)
-#  endif
-# endif
-        ;
-
-# if defined(JS_CPU_X64)
-    static const uint32_t SavedRegs =
-        /* r11 is scratchRegister, used by JSC. */
-          (1 << JSC::X86Registers::r12)
-    // r13 is TypeMaskReg.
-    // r14 is PayloadMaskReg.
-        | (1 << JSC::X86Registers::r15)
-#  if defined(_WIN64)
-        | (1 << JSC::X86Registers::esi)
-        | (1 << JSC::X86Registers::edi)
-#  endif
-# else
-    static const uint32_t SavedRegs =
-          (1 << JSC::X86Registers::esi)
-        | (1 << JSC::X86Registers::edi)
-# endif
-        ;
-
-# if defined(JS_CPU_X86)
-    static const uint32_t SingleByteRegs = (TempRegs | SavedRegs) &
-        ~((1 << JSC::X86Registers::esi) |
-          (1 << JSC::X86Registers::edi) |
-          (1 << JSC::X86Registers::ebp) |
-          (1 << JSC::X86Registers::esp));
-# elif defined(JS_CPU_X64)
-    static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
-# endif
-
-#elif defined(JS_CPU_ARM)
-    static const uint32_t TempRegs =
-          (1 << JSC::ARMRegisters::r0)
-        | (1 << JSC::ARMRegisters::r1)
-        | (1 << JSC::ARMRegisters::r2);
-    // r3 is reserved as a scratch register for the assembler.
-    // r12 is IP, and is used for stub calls.
-
-    static const uint32_t SavedRegs =
-          (1 << JSC::ARMRegisters::r4)
-        | (1 << JSC::ARMRegisters::r5)
-        | (1 << JSC::ARMRegisters::r6)
-        | (1 << JSC::ARMRegisters::r7)
-    // r8 is reserved as a scratch register for the assembler.
-        | (1 << JSC::ARMRegisters::r9);
-    // r10 is reserved for JSFrameReg.
-    // r13 is SP and must always point to VMFrame whilst in generated code.
-    // r14 is LR and is used for return sequences.
-    // r15 is PC (program counter).
-
-    static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
-#elif defined(JS_CPU_SPARC)
-    static const uint32_t TempRegs =
-          (1 << JSC::SparcRegisters::o0)
-        | (1 << JSC::SparcRegisters::o1)
-        | (1 << JSC::SparcRegisters::o2)
-        | (1 << JSC::SparcRegisters::o3)
-        | (1 << JSC::SparcRegisters::o4)
-        | (1 << JSC::SparcRegisters::o5);
-
-    static const uint32_t SavedRegs =
-          (1 << JSC::SparcRegisters::l2)
-        | (1 << JSC::SparcRegisters::l3)
-        | (1 << JSC::SparcRegisters::l4)
-        | (1 << JSC::SparcRegisters::l5)
-        | (1 << JSC::SparcRegisters::l6)
-        | (1 << JSC::SparcRegisters::l7);
-
-    static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
-#elif defined(JS_CPU_MIPS)
-    static const uint32_t TempRegs =
-          (1 << JSC::MIPSRegisters::at)
-        | (1 << JSC::MIPSRegisters::v0)
-        | (1 << JSC::MIPSRegisters::v1)
-        | (1 << JSC::MIPSRegisters::a0)
-        | (1 << JSC::MIPSRegisters::a1)
-        | (1 << JSC::MIPSRegisters::a2)
-        | (1 << JSC::MIPSRegisters::a3)
-        | (1 << JSC::MIPSRegisters::t5)
-        | (1 << JSC::MIPSRegisters::t6)
-        | (1 << JSC::MIPSRegisters::t7);
-    /* t0-t4,t9 is reserved as a scratch register for the assembler.
-       We don't use t8 ($24), as we limit ourselves within $0 to $23 to
-       leave the bitmask for 8 FP registers. */
-
-    static const uint32_t SavedRegs =
-          (1 << JSC::MIPSRegisters::s1)
-        | (1 << JSC::MIPSRegisters::s2)
-        | (1 << JSC::MIPSRegisters::s3)
-        | (1 << JSC::MIPSRegisters::s4)
-        | (1 << JSC::MIPSRegisters::s5)
-        | (1 << JSC::MIPSRegisters::s6)
-        | (1 << JSC::MIPSRegisters::s7);
-    // s0 is reserved for JSFrameReg.
-
-    static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
-#else
-# error "Unsupported platform"
-#endif
-
-    static const uint32_t AvailRegs = SavedRegs | TempRegs;
-
-    static bool isAvail(RegisterID reg) {
-        uint32_t mask = maskReg(reg);
-        return bool(mask & AvailRegs);
-    }
-
-    static bool isSaved(RegisterID reg) {
-        uint32_t mask = maskReg(reg);
-        JS_ASSERT(mask & AvailRegs);
-        return bool(mask & SavedRegs);
-    }
-
-    static inline uint32_t numArgRegs(CallConvention convention) {
-#if defined(JS_CPU_X86)
-# if defined(JS_NO_FASTCALL)
-        return 0;
-# else
-        return (convention == FastCall) ? 2 : 0;
-# endif
-#elif defined(JS_CPU_X64)
-# ifdef _WIN64
-        return 4;
-# else
-        return 6;
-# endif
-#elif defined(JS_CPU_ARM)
-        return 4;
-#elif defined(JS_CPU_SPARC)
-        return 6;
-#elif defined(JS_CPU_MIPS)
-        return 4;
-#endif
-    }
-
-    static inline bool regForArg(CallConvention conv, uint32_t i, RegisterID *reg) {
-#if defined(JS_CPU_X86)
-        static const RegisterID regs[] = {
-            JSC::X86Registers::ecx,
-            JSC::X86Registers::edx
-        };
-
-# if defined(JS_NO_FASTCALL)
-        return false;
-# else
-        if (conv == NormalCall)
-            return false;
-# endif
-#elif defined(JS_CPU_X64)
-# ifdef _WIN64
-        static const RegisterID regs[] = {
-            JSC::X86Registers::ecx,
-            JSC::X86Registers::edx,
-            JSC::X86Registers::r8,
-            JSC::X86Registers::r9
-        };
-# else
-        static const RegisterID regs[] = {
-            JSC::X86Registers::edi,
-            JSC::X86Registers::esi,
-            JSC::X86Registers::edx,
-            JSC::X86Registers::ecx,
-            JSC::X86Registers::r8,
-            JSC::X86Registers::r9
-        };
-# endif
-#elif defined(JS_CPU_ARM)
-        static const RegisterID regs[] = {
-            JSC::ARMRegisters::r0,
-            JSC::ARMRegisters::r1,
-            JSC::ARMRegisters::r2,
-            JSC::ARMRegisters::r3
-        };
-#elif defined(JS_CPU_SPARC)
-        static const RegisterID regs[] = {
-            JSC::SparcRegisters::o0,
-            JSC::SparcRegisters::o1,
-            JSC::SparcRegisters::o2,
-            JSC::SparcRegisters::o3,
-            JSC::SparcRegisters::o4,
-            JSC::SparcRegisters::o5
-        };
-#elif defined(JS_CPU_MIPS)
-        static const RegisterID regs[] = {
-            JSC::MIPSRegisters::a0,
-            JSC::MIPSRegisters::a1,
-            JSC::MIPSRegisters::a2,
-            JSC::MIPSRegisters::a3,
-        };
-#endif
-        JS_ASSERT(numArgRegs(conv) == mozilla::ArrayLength(regs));
-        if (i > mozilla::ArrayLength(regs))
-            return false;
-        *reg = regs[i];
-        return true;
-    }
-
-    /* Floating point registers. */
-
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-#ifdef _WIN64
-    /* xmm0-xmm5 are scratch register on Win64 ABI */
-    static const uint32_t TotalFPRegisters = 5;
-    static const FPRegisterID FPConversionTemp = JSC::X86Registers::xmm5;
-#else
-    static const uint32_t TotalFPRegisters = 7;
-    static const FPRegisterID FPConversionTemp = JSC::X86Registers::xmm7;
-#endif
-    static const uint32_t TempFPRegs = (
-          (1 << JSC::X86Registers::xmm0)
-        | (1 << JSC::X86Registers::xmm1)
-        | (1 << JSC::X86Registers::xmm2)
-        | (1 << JSC::X86Registers::xmm3)
-        | (1 << JSC::X86Registers::xmm4)
-#ifndef _WIN64
-        | (1 << JSC::X86Registers::xmm5)
-        | (1 << JSC::X86Registers::xmm6)
-#endif
-        ) << TotalRegisters;
-#elif defined(JS_CPU_ARM)
-    static const uint32_t TotalFPRegisters = 3;
-    static const uint32_t TempFPRegs = (
-          (1 << JSC::ARMRegisters::d0)
-        | (1 << JSC::ARMRegisters::d1)
-        | (1 << JSC::ARMRegisters::d2)
-        ) << TotalRegisters;
-    static const FPRegisterID FPConversionTemp = JSC::ARMRegisters::d3;
-#elif defined(JS_CPU_SPARC)
-    static const uint32_t TotalFPRegisters = 8;
-    static const uint32_t TempFPRegs = (uint32_t)(
-          (1 << JSC::SparcRegisters::f0)
-        | (1 << JSC::SparcRegisters::f2)
-        | (1 << JSC::SparcRegisters::f4)
-        | (1 << JSC::SparcRegisters::f6)
-        ) << TotalRegisters;
-    static const FPRegisterID FPConversionTemp = JSC::SparcRegisters::f8;
-#elif defined(JS_CPU_MIPS)
-    /* TotalRegisters is 24, so TotalFPRegisters can be 8 to have a 32-bit
-       bit mask.
-       Note that the O32 ABI can access only even FP registers. */
-    static const uint32_t TotalFPRegisters = 8;
-    static const uint32_t TempFPRegs = (uint32_t)(
-          (1 << JSC::MIPSRegisters::f0)
-        | (1 << JSC::MIPSRegisters::f2)
-        | (1 << JSC::MIPSRegisters::f4)
-        | (1 << JSC::MIPSRegisters::f6)
-        ) << TotalRegisters;
-    // f16 is reserved as a scratch register for the assembler.
-    static const FPRegisterID FPConversionTemp = JSC::MIPSRegisters::f18;
-#else
-# error "Unsupported platform"
-#endif
-
-    /* Temp reg that can be clobbered when setting up a fallible fast or ABI call. */
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    static const RegisterID ClobberInCall = JSC::X86Registers::ecx;
-#elif defined(JS_CPU_ARM)
-    static const RegisterID ClobberInCall = JSC::ARMRegisters::r2;
-#elif defined(JS_CPU_SPARC)
-    static const RegisterID ClobberInCall = JSC::SparcRegisters::l1;
-#elif defined(JS_CPU_MIPS)
-    static const RegisterID ClobberInCall = JSC::MIPSRegisters::at;
-#endif
-
-    static const uint32_t AvailFPRegs = TempFPRegs;
-
-    static inline uint32_t maskReg(FPRegisterID reg) {
-        return (1 << reg) << TotalRegisters;
-    }
-
-    /* Common code. */
-
-    static const uint32_t TotalAnyRegisters = TotalRegisters + TotalFPRegisters;
-    static const uint32_t TempAnyRegs = TempRegs | TempFPRegs;
-    static const uint32_t AvailAnyRegs = AvailRegs | AvailFPRegs;
-
-    static inline uint32_t maskReg(AnyRegisterID reg) {
-        return (1 << reg.reg_);
-    }
-
-    /* Get a register which is not live before a FASTCALL. */
-    static inline RegisterID tempCallReg() {
-        Registers regs(TempRegs);
-        regs.takeReg(Registers::ArgReg0);
-        regs.takeReg(Registers::ArgReg1);
-        return regs.takeAnyReg().reg();
-    }
-
-    /* Get a register which is not live before a normal ABI call with at most four args. */
-    static inline Registers tempCallRegMask() {
-        Registers regs(AvailRegs);
-#ifndef JS_CPU_X86
-        regs.takeReg(ArgReg0);
-        regs.takeReg(ArgReg1);
-        regs.takeReg(ArgReg2);
-#if defined(JS_CPU_SPARC) || defined(JS_CPU_X64)
-        regs.takeReg(ArgReg3);
-#endif
-#endif
-        return regs;
-    }
-
-    Registers(uint32_t freeMask)
-      : freeMask(freeMask)
-    { }
-
-    Registers(const Registers &other)
-      : freeMask(other.freeMask)
-    { }
-
-    Registers & operator =(const Registers &other)
-    {
-        freeMask = other.freeMask;
-        return *this;
-    }
-
-    bool empty(uint32_t mask) const {
-        return !(freeMask & mask);
-    }
-
-    bool empty() const {
-        return !freeMask;
-    }
-
-    AnyRegisterID peekReg(uint32_t mask) {
-        JS_ASSERT(!empty(mask));
-        unsigned ireg;
-        JS_FLOOR_LOG2(ireg, freeMask & mask);
-        return AnyRegisterID::fromRaw(ireg);
-    }
-
-    AnyRegisterID peekReg() {
-        return peekReg(freeMask);
-    }
-
-    AnyRegisterID takeAnyReg(uint32_t mask) {
-        AnyRegisterID reg = peekReg(mask);
-        takeReg(reg);
-        return reg;
-    }
-
-    AnyRegisterID takeAnyReg() {
-        return takeAnyReg(freeMask);
-    }
-
-    bool hasReg(AnyRegisterID reg) const {
-        return !!(freeMask & (1 << reg.reg_));
-    }
-
-    bool hasRegInMask(uint32_t mask) const {
-        return !!(freeMask & mask);
-    }
-
-    bool hasAllRegs(uint32_t mask) const {
-        return (freeMask & mask) == mask;
-    }
-
-    void putRegUnchecked(AnyRegisterID reg) {
-        freeMask |= (1 << reg.reg_);
-    }
-
-    void putReg(AnyRegisterID reg) {
-        JS_ASSERT(!hasReg(reg));
-        putRegUnchecked(reg);
-    }
-
-    void takeReg(AnyRegisterID reg) {
-        JS_ASSERT(hasReg(reg));
-        takeRegUnchecked(reg);
-    }
-
-    void takeRegUnchecked(AnyRegisterID reg) {
-        freeMask &= ~(1 << reg.reg_);
-    }
-
-    bool operator ==(const Registers &other) {
-        return freeMask == other.freeMask;
-    }
-
-    uint32_t freeMask;
-};
-
-static const JSC::MacroAssembler::RegisterID JSFrameReg = Registers::JSFrameReg;
-
-AnyRegisterID
-AnyRegisterID::fromRaw(unsigned reg_)
-{
-    JS_ASSERT(reg_ < Registers::TotalAnyRegisters);
-    AnyRegisterID reg;
-    reg.reg_ = reg_;
-    return reg;
-}
-
-JSC::MacroAssembler::RegisterID
-AnyRegisterID::reg()
-{
-    JS_ASSERT(reg_ < Registers::TotalRegisters);
-    return (JSC::MacroAssembler::RegisterID) reg_;
-}
-
-JSC::MacroAssembler::FPRegisterID
-AnyRegisterID::fpreg()
-{
-    JS_ASSERT(reg_ >= Registers::TotalRegisters &&
-              reg_ < Registers::TotalAnyRegisters);
-    return (JSC::MacroAssembler::FPRegisterID) (reg_ - Registers::TotalRegisters);
-}
-
-const char *
-AnyRegisterID::name()
-{
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-    return isReg() ? JSC::X86Registers::nameIReg(reg()) : JSC::X86Registers::nameFPReg(fpreg());
-#elif defined(JS_CPU_ARM)
-    return isReg() ? JSC::ARMAssembler::nameGpReg(reg()) : JSC::ARMAssembler::nameFpRegD(fpreg());
-#else
-    return "???";
-#endif
-}
-
-} /* namespace mjit */
-
-} /* namespace js */
-
-#endif /* jsjaeger_regstate_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/MethodJIT.cpp
+++ /dev/null
@@ -1,1735 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "BaseAssembler.h"
-#include "Compiler.h"
-#include "jscntxtinlines.h"
-#include "jscompartment.h"
-#include "Logging.h"
-#include "MethodJIT.h"
-#include "MonoIC.h"
-#include "PolyIC.h"
-#include "Retcon.h"
-#include "TrampolineCompiler.h"
-
-#include "assembler/assembler/RepatchBuffer.h"
-#include "assembler/jit/ExecutableAllocator.h"
-#include "gc/Marking.h"
-#include "ion/Ion.h"
-#include "ion/IonCode.h"
-#include "ion/IonCompartment.h"
-#include "js/MemoryMetrics.h"
-#include "vm/Shape.h"
-
-#include "jsgcinlines.h"
-#include "jsinterpinlines.h"
-
-#if JS_TRACE_LOGGING
-#include "TraceLogging.h"
-#endif
-
-using namespace js;
-using namespace js::mjit;
-
-#ifdef __GCC_HAVE_DWARF2_CFI_ASM
-# define CFI(str) str
-#else
-# define CFI(str)
-#endif
-
-js::mjit::CompilerAllocPolicy::CompilerAllocPolicy(JSContext *cx, Compiler &compiler)
-: TempAllocPolicy(cx),
-  oomFlag(&compiler.oomInVector)
-{
-}
-void
-StackFrame::methodjitStaticAsserts()
-{
-        /* Static assert for x86 trampolines in MethodJIT.cpp. */
-#if defined(JS_CPU_X86)
-        JS_STATIC_ASSERT(offsetof(StackFrame, rval_)     == 0x18);
-        JS_STATIC_ASSERT(offsetof(StackFrame, rval_) + 4 == 0x1C);
-        JS_STATIC_ASSERT(offsetof(StackFrame, ncode_)    == 0x14);
-        /* ARM uses decimal literals. */
-        JS_STATIC_ASSERT(offsetof(StackFrame, rval_)     == 24);
-        JS_STATIC_ASSERT(offsetof(StackFrame, rval_) + 4 == 28);
-        JS_STATIC_ASSERT(offsetof(StackFrame, ncode_)    == 20);
-#elif defined(JS_CPU_X64)
-        JS_STATIC_ASSERT(offsetof(StackFrame, rval_)     == 0x30);
-        JS_STATIC_ASSERT(offsetof(StackFrame, ncode_)    == 0x28);
-#endif
-}
-
-/*
- * Explanation of VMFrame activation and various helper thunks below.
- *
- * JaegerTrampoline  - Executes a method JIT-compiled JSFunction. This function
- *    creates a VMFrame on the machine stack and jumps into JIT'd code. The JIT'd
- *    code will eventually jump back to JaegerTrampolineReturn, clean up the
- *    VMFrame and return into C++.
- *
- *  - Called from C++ function EnterMethodJIT.
- *  - Parameters: cx, fp, code, stackLimit
- *
- * JaegerThrowpoline - Calls into an exception handler from JIT'd code, and if a
- *    scripted exception handler is not found, unwinds the VMFrame and returns
- *    to C++.
- *
- *  - To start exception handling, we return from a stub call to the throwpoline.
- *  - On entry to the throwpoline, the normal conditions of the jit-code ABI
- *    are satisfied.
- *  - To do the unwinding and find out where to continue executing, we call
- *    js_InternalThrow.
- *  - js_InternalThrow may return 0, which means the place to continue, if any,
- *    is above this JaegerShot activation, so we just return, in the same way
- *    the trampoline does.
- *  - Otherwise, js_InternalThrow returns a jit-code address to continue execution
- *    at. Because the jit-code ABI conditions are satisfied, we can just jump to
- *    that point.
- *
- * JaegerInterpoline - After returning from a stub or scripted call made by JIT'd
- *    code, calls into Interpret and has it finish execution of the JIT'd script.
- *    If we have to throw away the JIT code for a script for some reason (either
- *    a new trap is added for debug code, or assumptions made by the JIT code
- *    have broken and forced its invalidation), the call returns into the
- *    Interpoline which calls Interpret to finish the JIT frame. The Interpret
- *    call may eventually recompile the script, in which case it will join into
- *    that code with a new VMFrame activation and JaegerTrampoline.
- *
- *  - Returned into from stub calls originally made from JIT code.
- *  - An alternate version, JaegerInterpolineScripted, returns from scripted
- *    calls originally made from JIT code, and fixes up state to match the
- *    stub call ABI.
- */
-
-#ifdef JS_METHODJIT_PROFILE_STUBS
-static const size_t STUB_CALLS_FOR_OP_COUNT = 255;
-static uint32_t StubCallsForOp[STUB_CALLS_FOR_OP_COUNT];
-#endif
-
-// Called from JaegerTrampoline only
-extern "C" void JS_FASTCALL
-PushActiveVMFrame(VMFrame &f)
-{
-    f.oldregs = &f.cx->stack.regs();
-    f.cx->stack.repointRegs(&f.regs);
-    f.cx->jaegerRuntime().pushActiveFrame(&f);
-    f.entryfp->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void*, JaegerTrampolineReturn));
-    f.regs.clearInlined();
-}
-
-// Called from JaegerTrampolineReturn, JaegerThrowpoline, JaegerInterpoline
-extern "C" void JS_FASTCALL
-PopActiveVMFrame(VMFrame &f)
-{
-    f.cx->jaegerRuntime().popActiveFrame();
-    f.cx->stack.repointRegs(f.oldregs);
-}
-
-#if defined(__APPLE__) || (defined(XP_WIN) && !defined(JS_CPU_X64)) || defined(XP_OS2)
-# define SYMBOL_STRING(name) "_" #name
-#else
-# define SYMBOL_STRING(name) #name
-#endif
-
-JS_STATIC_ASSERT(offsetof(FrameRegs, sp) == 0);
-
-#if defined(__linux__) && defined(JS_CPU_X64)
-# define SYMBOL_STRING_RELOC(name) #name "@plt"
-#else
-# define SYMBOL_STRING_RELOC(name) SYMBOL_STRING(name)
-#endif
-
-#if (defined(XP_WIN) || defined(XP_OS2)) && defined(JS_CPU_X86)
-# define SYMBOL_STRING_VMFRAME(name) "@" #name "@4"
-#else
-# define SYMBOL_STRING_VMFRAME(name) SYMBOL_STRING_RELOC(name)
-#endif
-
-#if defined(XP_MACOSX)
-# define HIDE_SYMBOL(name) ".private_extern _" #name
-#elif defined(__linux__)
-# define HIDE_SYMBOL(name) ".hidden" #name
-#else
-# define HIDE_SYMBOL(name)
-#endif
-
-/*
- * Notes about DWARF Call Frame Information (CFI) annotations:
- *
- * A .cfi directive placed in assembly code describes how to recover the
- * caller's registers when control is at or after that directive. That is,
- * they describe the states that hold between one instruction and the next,
- * not the instructions themselves. Later directives override earlier
- * directives.
- *
- * In DWARF CFI, each stack frame has a Canonical Frame Address (CFA) that
- * remains constant throughout the frame's lifetime. Exactly where it is is
- * a matter of convention; on the x86 and x86_64, for example, the CFA
- * points just after the end of the current stack frame: the address of the
- * next word after the return address. The CFI annotations describe 1) how
- * to compute the CFA at each point in the function, and 2) given the CFA,
- * where the caller's value of each register has been saved. (CFI specifies
- * saved registers' locations relative to the CFA, instead of the stack
- * pointer, so that when we push or pop the stack, we need only adjust our
- * rule for computing the CFA, not the rule for each saved register.)
- *
- * Quick reference:
- *
- * .cfi_startproc, .cfi_endproc
- *   Put these at the beginning and end of the block of code you're
- *   annotating.
- *
- * (The following directives apply starting at the point they appear until
- * they are overridden or until the .cfi_endproc.)
- *
- * .cfi_def_cfa REGISTER, OFFSET
- *   The CFA is the value of REGISTER plus OFFSET.
- *
- * .cfi_def_cfa_offset OFFSET
- *   The CFA is the value of the same register as before, but now adding OFFSET.
- *
- * .cfi_def_cfa_register REGISTER
- *   The CFA is now the value of REGISTER, adding the same offset as before.
- *
- * .cfi_offset REGISTER, OFFSET
- *   The caller's value of REGISTER is saved at OFFSET from the current CFA.
- *   (This is the directive that actually says something interesting.)
- *
- * There are other directives that compute the CFA, a saved register's address,
- * or a saved register's value, in more complex ways, but the above are the ones
- * we use here.
- *
- * Special rules for JaegerThrowpoline and friends:
- *
- * In ordinary code, return addresses always point directly after a call
- * instruction. When GDB looks up the CFI for a return address it got from the
- * stack (as opposed to the current PC), it uses the CFI just before the return
- * address --- the CFI associated with the call instruction --- to do the
- * unwinding. However, JaegerMonkey uses hacks that edit return addresses to
- * point directly at the first instruction of JaegerThrowpoline,
- * JaegerInterpoline, and their ilk, so GDB ends up trying to use the CFI
- * associated with whatever instruction lies immediately *before* the given
- * entry point.
- *
- * We make sure our CFI covers the code address GDB will actually use, by
- * placing a 'nop' *before* the entry point --- it is never executed --- and
- * having our CFI apply starting at that nop.
- */
-
-#if defined(__GNUC__) && !defined(_WIN64)
-
-/* If this assert fails, you need to realign VMFrame to 16 bytes. */
-#if defined(JS_CPU_ARM) || defined(JS_CPU_MIPS) || defined(JS_CPU_SPARC)
-JS_STATIC_ASSERT(sizeof(VMFrame) % 8 == 0);
-#else
-JS_STATIC_ASSERT(sizeof(VMFrame) % 16 == 0);
-#endif
-
-# if defined(JS_CPU_X64)
-
-/*
- *    *** DANGER ***
- * If these assertions break, update the constants below.
- *    *** DANGER ***
- */
-JS_STATIC_ASSERT(offsetof(VMFrame, savedRBX) == 0x68);
-JS_STATIC_ASSERT(offsetof(VMFrame, scratch) == 0x18);
-JS_STATIC_ASSERT(VMFrame::offsetOfFp == 0x38);
-
-JS_STATIC_ASSERT(JSVAL_TAG_MASK == 0xFFFF800000000000LL);
-JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
-
-asm (
-".text\n"
-".globl " SYMBOL_STRING(JaegerTrampoline) "\n"
-SYMBOL_STRING(JaegerTrampoline) ":"       "\n"
-    /* Prologue. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa rsp, 8"            "\n")
-    "pushq %rbp"                         "\n"
-    CFI(".cfi_def_cfa_offset 16"         "\n")
-    CFI(".cfi_offset rbp, -16"           "\n")
-    "movq %rsp, %rbp"                    "\n"
-    CFI(".cfi_def_cfa_register rbp"      "\n")
-    /* Save non-volatile registers. */
-    "pushq %r12"                         "\n"
-    CFI(".cfi_offset r12, -24"           "\n")
-    "pushq %r13"                         "\n"
-    CFI(".cfi_offset r13, -32"           "\n")
-    "pushq %r14"                         "\n"
-    CFI(".cfi_offset r14, -40"           "\n")
-    "pushq %r15"                         "\n"
-    CFI(".cfi_offset r15, -48"           "\n")
-    "pushq %rbx"                         "\n"
-    CFI(".cfi_offset rbx, -56"           "\n")
-
-    /* Load mask registers. */
-    "movq $0xFFFF800000000000, %r13"     "\n"
-    "movq $0x00007FFFFFFFFFFF, %r14"     "\n"
-
-    /* Build the JIT frame.
-     * rdi = cx
-     * rsi = fp
-     * rcx = inlineCallCount
-     * fp must go into rbx
-     */
-    "pushq $0x0"                         "\n" /* stubRejoin */
-    "pushq %rsi"                         "\n" /* entryncode */
-    "pushq %rsi"                         "\n" /* entryfp */
-    "pushq %rcx"                         "\n" /* inlineCallCount */
-    "pushq %rdi"                         "\n" /* cx */
-    "pushq %rsi"                         "\n" /* fp */
-    "movq  %rsi, %rbx"                   "\n"
-
-    /* Space for the rest of the VMFrame. */
-    "subq  $0x28, %rsp"                  "\n"
-
-    /* This is actually part of the VMFrame. */
-    "pushq %r8"                          "\n"
-
-    /* Set cx->regs and set the active frame. Save rdx and align frame in one. */
-    "pushq %rdx"                         "\n"
-    "movq  %rsp, %rdi"                   "\n"
-    "call " SYMBOL_STRING_VMFRAME(PushActiveVMFrame) "\n"
-
-    /* Jump into the JIT'd code. */
-    "jmp *0(%rsp)"                      "\n"
-    CFI(".cfi_endproc"                  "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa rbp, 16"           "\n")
-    CFI(".cfi_offset rbp, -16"           "\n")
-    CFI(".cfi_offset r12, -24"           "\n")
-    CFI(".cfi_offset r13, -32"           "\n")
-    CFI(".cfi_offset r14, -40"           "\n")
-    CFI(".cfi_offset r15, -48"           "\n")
-    CFI(".cfi_offset rbx, -56"           "\n")
-    CFI("nop"                            "\n")
-".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n"
-SYMBOL_STRING(JaegerTrampolineReturn) ":"       "\n"
-    "or   %rdi, %rsi"                    "\n"
-    "movq %rsi, 0x30(%rbx)"              "\n"
-    "movq %rsp, %rdi"                    "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-
-    "addq $0x68, %rsp"                   "\n"
-    "popq %rbx"                          "\n"
-    "popq %r15"                          "\n"
-    "popq %r14"                          "\n"
-    "popq %r13"                          "\n"
-    "popq %r12"                          "\n"
-    "popq %rbp"                          "\n"
-    CFI(".cfi_def_cfa rsp, 8"            "\n")
-    "movq $1, %rax"                      "\n"
-    "ret"                                "\n"
-    CFI(".cfi_endproc"                   "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                    "\n")
-    CFI(".cfi_def_cfa rbp, 16"              "\n")
-    CFI(".cfi_offset rbp, -16"              "\n")
-    CFI(".cfi_offset r12, -24"              "\n")
-    CFI(".cfi_offset r13, -32"              "\n")
-    CFI(".cfi_offset r14, -40"              "\n")
-    CFI(".cfi_offset r15, -48"              "\n")
-    CFI(".cfi_offset rbx, -56"              "\n")
-    CFI("nop"                               "\n")
-".globl " SYMBOL_STRING(JaegerThrowpoline)  "\n"
-SYMBOL_STRING(JaegerThrowpoline) ":"        "\n"
-    "movq %rsp, %rdi"                       "\n"
-    "call " SYMBOL_STRING_RELOC(js_InternalThrow) "\n"
-    "testq %rax, %rax"                      "\n"
-    "je   throwpoline_exit"                 "\n"
-    "jmp  *%rax"                            "\n"
-  "throwpoline_exit:"                       "\n"
-    "movq %rsp, %rdi"                       "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-    "addq $0x68, %rsp"                      "\n"
-    "popq %rbx"                             "\n"
-    "popq %r15"                             "\n"
-    "popq %r14"                             "\n"
-    "popq %r13"                             "\n"
-    "popq %r12"                             "\n"
-    "popq %rbp"                             "\n"
-    CFI(".cfi_def_cfa rsp, 8"               "\n")
-    "xorq %rax,%rax"                        "\n"
-    "ret"                                   "\n"
-    CFI(".cfi_endproc"                      "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                    "\n")
-    CFI(".cfi_def_cfa rbp, 16"              "\n")
-    CFI(".cfi_offset rbp, -16"              "\n")
-    CFI(".cfi_offset r12, -24"              "\n")
-    CFI(".cfi_offset r13, -32"              "\n")
-    CFI(".cfi_offset r14, -40"              "\n")
-    CFI(".cfi_offset r15, -48"              "\n")
-    CFI(".cfi_offset rbx, -56"              "\n")
-    CFI("nop"                               "\n")
-".globl " SYMBOL_STRING(JaegerInterpoline)  "\n"
-SYMBOL_STRING(JaegerInterpoline) ":"        "\n"
-    "movq %rsp, %rcx"                       "\n"
-    "movq %rax, %rdx"                       "\n"
-    "call " SYMBOL_STRING_RELOC(js_InternalInterpret) "\n"
-    "movq 0x38(%rsp), %rbx"                 "\n" /* Load frame */
-    "movq 0x30(%rbx), %rsi"                 "\n" /* Load rval payload */
-    "and %r14, %rsi"                        "\n" /* Mask rval payload */
-    "movq 0x30(%rbx), %rdi"                 "\n" /* Load rval type */
-    "and %r13, %rdi"                        "\n" /* Mask rval type */
-    "movq 0x18(%rsp), %rcx"                 "\n" /* Load scratch -> argc */
-    "testq %rax, %rax"                      "\n"
-    "je   interpoline_exit"                 "\n"
-    "jmp  *%rax"                            "\n"
-  "interpoline_exit:"                       "\n"
-    "movq %rsp, %rdi"                       "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-    "addq $0x68, %rsp"                      "\n"
-    "popq %rbx"                             "\n"
-    "popq %r15"                             "\n"
-    "popq %r14"                             "\n"
-    "popq %r13"                             "\n"
-    "popq %r12"                             "\n"
-    "popq %rbp"                             "\n"
-    CFI(".cfi_def_cfa rsp, 8"               "\n")
-    "xorq %rax,%rax"                        "\n"
-    "ret"                                   "\n"
-    CFI(".cfi_endproc"                      "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                            "\n")
-    CFI(".cfi_def_cfa rbp, 16"                      "\n")
-    CFI(".cfi_offset rbp, -16"                      "\n")
-    CFI(".cfi_offset r12, -24"                      "\n")
-    CFI(".cfi_offset r13, -32"                      "\n")
-    CFI(".cfi_offset r14, -40"                      "\n")
-    CFI(".cfi_offset r15, -48"                      "\n")
-    CFI(".cfi_offset rbx, -56"                      "\n")
-    CFI("nop"                                       "\n")
-".globl " SYMBOL_STRING(JaegerInterpolineScripted)  "\n"
-SYMBOL_STRING(JaegerInterpolineScripted) ":"        "\n"
-    "movq 0x20(%rbx), %rbx"                         "\n" /* load prev */
-    "movq %rbx, 0x38(%rsp)"                         "\n"
-    "jmp " SYMBOL_STRING_RELOC(JaegerInterpoline)   "\n"
-    CFI(".cfi_endproc"                              "\n")
-);
-
-# elif defined(JS_CPU_X86)
-
-/*
- *    *** DANGER ***
- * If these assertions break, update the constants below. The throwpoline
- * should have the offset of savedEBX plus 4, because it needs to clean
- * up the argument.
- *    *** DANGER ***
- */
-JS_STATIC_ASSERT(offsetof(VMFrame, savedEBX) == 0x3C);
-JS_STATIC_ASSERT(offsetof(VMFrame, scratch) == 0xC);
-JS_STATIC_ASSERT(VMFrame::offsetOfFp == 0x1C);
-
-asm (
-".text\n"
-".globl " SYMBOL_STRING(JaegerTrampoline) "\n"
-SYMBOL_STRING(JaegerTrampoline) ":"       "\n"
-    /* Prologue. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa esp, 4"            "\n")
-    "pushl %ebp"                         "\n"
-    CFI(".cfi_def_cfa_offset 8"          "\n")
-    CFI(".cfi_offset ebp, -8"            "\n")
-    "movl %esp, %ebp"                    "\n"
-    CFI(".cfi_def_cfa_register ebp"      "\n")
-    /* Save non-volatile registers. */
-    "pushl %esi"                         "\n"
-    CFI(".cfi_offset esi, -12"           "\n")
-    "pushl %edi"                         "\n"
-    CFI(".cfi_offset edi, -16"           "\n")
-    "pushl %ebx"                         "\n"
-    CFI(".cfi_offset ebx, -20"           "\n")
-
-    /* Build the JIT frame. Push fields in order,
-     * then align the stack to form esp == VMFrame. */
-    "movl  12(%ebp), %ebx"               "\n"   /* load fp */
-    "pushl %ebx"                         "\n"   /* unused1 */
-    "pushl %ebx"                         "\n"   /* unused0 */
-    "pushl $0x0"                         "\n"   /* stubRejoin */
-    "pushl %ebx"                         "\n"   /* entryncode */
-    "pushl %ebx"                         "\n"   /* entryfp */
-    "pushl 20(%ebp)"                     "\n"   /* stackLimit */
-    "pushl 8(%ebp)"                      "\n"   /* cx */
-    "pushl %ebx"                         "\n"   /* fp */
-    "subl $0x1C, %esp"                   "\n"
-
-    /* Jump into the JIT'd code. */
-    "movl  %esp, %ecx"                   "\n"
-    "call " SYMBOL_STRING_VMFRAME(PushActiveVMFrame) "\n"
-
-    "movl 28(%esp), %ebp"                "\n"   /* load fp for JIT code */
-    "jmp *88(%esp)"                      "\n"
-    CFI(".cfi_endproc"                   "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa ebp, 8"            "\n")
-    CFI(".cfi_offset ebp, -8"            "\n")
-    CFI(".cfi_offset esi, -12"           "\n")
-    CFI(".cfi_offset edi, -16"           "\n")
-    CFI(".cfi_offset ebx, -20"           "\n")
-    CFI("nop"                            "\n")
-".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n"
-SYMBOL_STRING(JaegerTrampolineReturn) ":" "\n"
-    "movl  %esi, 0x18(%ebp)"             "\n"
-    "movl  %edi, 0x1C(%ebp)"             "\n"
-    "movl  %esp, %ebp"                   "\n"
-    "addl  $0x48, %ebp"                  "\n" /* Restore stack at STACK_BASE_DIFFERENCE */
-    "movl  %esp, %ecx"                   "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-
-    "addl $0x3C, %esp"                   "\n"
-    "popl %ebx"                          "\n"
-    "popl %edi"                          "\n"
-    "popl %esi"                          "\n"
-    "popl %ebp"                          "\n"
-    CFI(".cfi_def_cfa esp, 4"            "\n")
-    "movl $1, %eax"                      "\n"
-    "ret"                                "\n"
-    CFI(".cfi_endproc"                   "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa ebp, 8"            "\n")
-    CFI(".cfi_offset ebp, -8"            "\n")
-    CFI(".cfi_offset esi, -12"           "\n")
-    CFI(".cfi_offset edi, -16"           "\n")
-    CFI(".cfi_offset ebx, -20"           "\n")
-    CFI("nop"                            "\n")
-".globl " SYMBOL_STRING(JaegerThrowpoline)  "\n"
-SYMBOL_STRING(JaegerThrowpoline) ":"        "\n"
-    /* Align the stack to 16 bytes. */
-    "pushl %esp"                         "\n"
-    "pushl (%esp)"                       "\n"
-    "pushl (%esp)"                       "\n"
-    "pushl (%esp)"                       "\n"
-    "call " SYMBOL_STRING_RELOC(js_InternalThrow) "\n"
-    /* Bump the stack by 0x2c, as in the basic trampoline, but
-     * also one more word to clean up the stack for js_InternalThrow,
-     * and another to balance the alignment above. */
-    "addl $0x10, %esp"                   "\n"
-    "testl %eax, %eax"                   "\n"
-    "je   throwpoline_exit"              "\n"
-    "jmp  *%eax"                         "\n"
-  "throwpoline_exit:"                    "\n"
-    "movl %esp, %ecx"                    "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-    "addl $0x3c, %esp"                   "\n"
-    "popl %ebx"                          "\n"
-    "popl %edi"                          "\n"
-    "popl %esi"                          "\n"
-    "popl %ebp"                          "\n"
-    CFI(".cfi_def_cfa esp, 4"            "\n")
-    "xorl %eax, %eax"                    "\n"
-    "ret"                                "\n"
-    CFI(".cfi_endproc"                   "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                 "\n")
-    CFI(".cfi_def_cfa ebp, 8"            "\n")
-    CFI(".cfi_offset ebp, -8"            "\n")
-    CFI(".cfi_offset esi, -12"           "\n")
-    CFI(".cfi_offset edi, -16"           "\n")
-    CFI(".cfi_offset ebx, -20"           "\n")
-    CFI("nop"                            "\n")
-".globl " SYMBOL_STRING(JaegerInterpoline)  "\n"
-SYMBOL_STRING(JaegerInterpoline) ":"        "\n"
-    /* Align the stack to 16 bytes. */
-    "pushl %esp"                         "\n"
-    "pushl %eax"                         "\n"
-    "pushl %edi"                         "\n"
-    "pushl %esi"                         "\n"
-    "call " SYMBOL_STRING_RELOC(js_InternalInterpret) "\n"
-    "addl $0x10, %esp"                   "\n"
-    "movl 0x1C(%esp), %ebp"              "\n" /* Load frame */
-    "movl 0x18(%ebp), %esi"              "\n" /* Load rval payload */
-    "movl 0x1C(%ebp), %edi"              "\n" /* Load rval type */
-    "movl 0xC(%esp), %ecx"               "\n" /* Load scratch -> argc, for any scripted call */
-    "testl %eax, %eax"                   "\n"
-    "je   interpoline_exit"              "\n"
-    "jmp  *%eax"                         "\n"
-  "interpoline_exit:"                    "\n"
-    "movl %esp, %ecx"                    "\n"
-    "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
-    "addl $0x3c, %esp"                   "\n"
-    "popl %ebx"                          "\n"
-    "popl %edi"                          "\n"
-    "popl %esi"                          "\n"
-    "popl %ebp"                          "\n"
-    CFI(".cfi_def_cfa esp, 4"            "\n")
-    "xorl %eax, %eax"                    "\n"
-    "ret"                                "\n"
-    CFI(".cfi_endproc"                   "\n")
-);
-
-asm (
-".text\n"
-    /* See "Special rules for JaegerThrowpoline and friends", above. */
-    CFI(".cfi_startproc"                            "\n")
-    CFI(".cfi_def_cfa ebp, 8"                       "\n")
-    CFI(".cfi_offset ebp, -8"                       "\n")
-    CFI(".cfi_offset esi, -12"                      "\n")
-    CFI(".cfi_offset edi, -16"                      "\n")
-    CFI(".cfi_offset ebx, -20"                      "\n")
-    CFI("nop"                                       "\n")
-".globl " SYMBOL_STRING(JaegerInterpolineScripted)  "\n"
-SYMBOL_STRING(JaegerInterpolineScripted) ":"        "\n"
-    "movl 0x10(%ebp), %ebp"                         "\n" /* load prev. :XXX: STATIC_ASSERT this */
-    "movl  %ebp, 0x1C(%esp)"                        "\n"
-    "jmp " SYMBOL_STRING_RELOC(JaegerInterpoline)   "\n"
-    CFI(".cfi_endproc"                              "\n")
-);
-
-# elif defined(JS_CPU_ARM)
-
-JS_STATIC_ASSERT(sizeof(VMFrame) == 88);
-JS_STATIC_ASSERT(sizeof(VMFrame)%8 == 0);   /* We need 8-byte stack alignment for EABI. */
-JS_STATIC_ASSERT(offsetof(VMFrame, savedLR) ==          (4*21));
-JS_STATIC_ASSERT(offsetof(VMFrame, entryfp) ==          (4*10));
-JS_STATIC_ASSERT(offsetof(VMFrame, stackLimit) ==       (4*9));
-JS_STATIC_ASSERT(offsetof(VMFrame, cx) ==               (4*8));
-JS_STATIC_ASSERT(VMFrame::offsetOfFp ==                 (4*7));
-JS_STATIC_ASSERT(offsetof(VMFrame, scratch) ==          (4*3));
-JS_STATIC_ASSERT(offsetof(VMFrame, previous) ==         (4*2));
-
-JS_STATIC_ASSERT(JSFrameReg == JSC::ARMRegisters::r10);
-JS_STATIC_ASSERT(JSReturnReg_Type == JSC::ARMRegisters::r5);
-JS_STATIC_ASSERT(JSReturnReg_Data == JSC::ARMRegisters::r4);
-
-#ifdef MOZ_THUMB2
-#define FUNCTION_HEADER_EXTRA \
-  ".align 2\n" \
-  ".thumb\n" \
-  ".thumb_func\n"
-#define BRANCH_AND_LINK(x) "blx " x
-#else
-#define FUNCTION_HEADER_EXTRA
-#define BRANCH_AND_LINK(x) "bl " x
-#endif
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerTrampoline)   "\n"
-SYMBOL_STRING(JaegerTrampoline) ":"         "\n"
-    /*
-     * On entry to JaegerTrampoline:
-     *         r0 = cx
-     *         r1 = fp
-     *         r2 = code
-     *         r3 = stackLimit
-     *
-     * The VMFrame for ARM looks like this:
-     *  [ lr           ]   \
-     *  [ r11          ]   |
-     *  [ r10          ]   |
-     *  [ r9           ]   | Callee-saved registers.
-     *  [ r8           ]   | VFP registers d8-d15 may be required here too, but
-     *  [ r7           ]   | unconditionally preserving them might be expensive
-     *  [ r6           ]   | considering that we might not use them anyway.
-     *  [ r5           ]   |
-     *  [ r4           ]   /
-     *  [ stubRejoin   ]
-     *  [ entryncode   ]
-     *  [ entryfp      ]
-     *  [ stkLimit     ]
-     *  [ cx           ]
-     *  [ regs.fp      ]
-     *  [ regs.inlined ]
-     *  [ regs.pc      ]
-     *  [ regs.sp      ]
-     *  [ scratch      ]
-     *  [ previous     ]
-     *  [ args.ptr2    ]  [ dynamicArgc ]  (union)
-     *  [ args.ptr     ]  [ lazyArgsObj ]  (union)
-     */
-
-    /* Push callee-saved registers. */
-"   push    {r4-r11,lr}"                        "\n"
-    /* Push interesting VMFrame content. */
-"   mov     ip, #0"                             "\n"
-"   push    {ip}"                               "\n"    /* stubRejoin */
-"   push    {r1}"                               "\n"    /* entryncode */
-"   push    {r1}"                               "\n"    /* entryfp */
-"   push    {r3}"                               "\n"    /* stackLimit */
-"   push    {r0}"                               "\n"    /* cx */
-"   push    {r1}"                               "\n"    /* regs.fp */
-    /* Remaining fields are set elsewhere, but we need to leave space for them. */
-"   sub     sp, sp, #(4*7)"                     "\n"
-
-    /* Preserve 'code' (r2) in an arbitrary callee-saved register. */
-"   mov     r4, r2"                             "\n"
-    /* Preserve 'fp' (r1) in r10 (JSFrameReg). */
-"   mov     r10, r1"                            "\n"
-
-"   mov     r0, sp"                             "\n"
-"   " BRANCH_AND_LINK(SYMBOL_STRING_VMFRAME(PushActiveVMFrame)) "\n"
-
-    /* Call the compiled JavaScript function. */
-"   bx     r4"                                  "\n"
-);
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerTrampolineReturn)   "\n"
-SYMBOL_STRING(JaegerTrampolineReturn) ":"         "\n"
-"   strd    r4, r5, [r10, #24]"             "\n" /* fp->rval type,data */
-
-    /* Tidy up. */
-"   mov     r0, sp"                         "\n"
-"   " BRANCH_AND_LINK(SYMBOL_STRING_VMFRAME(PopActiveVMFrame)) "\n"
-
-    /* Skip past the parameters we pushed (such as cx and the like). */
-"   add     sp, sp, #(4*7 + 4*6)"           "\n"
-
-    /* Set a 'true' return value to indicate successful completion. */
-"   mov     r0, #1"                         "\n"
-"   pop     {r4-r11,pc}"                    "\n"
-);
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerThrowpoline)  "\n"
-SYMBOL_STRING(JaegerThrowpoline) ":"        "\n"
-    /* Find the VMFrame pointer for js_InternalThrow. */
-"   mov     r0, sp"                         "\n"
-
-    /* Call the utility function that sets up the internal throw routine. */
-"   " BRANCH_AND_LINK(SYMBOL_STRING_RELOC(js_InternalThrow)) "\n"
-
-    /* If js_InternalThrow found a scripted handler, jump to it. Otherwise, tidy
-     * up and return. */
-"   cmp     r0, #0"                         "\n"
-"   it      ne"                             "\n"
-"   bxne    r0"                             "\n"
-
-    /* Tidy up, then return '0' to represent an unhandled exception. */
-"   mov     r0, sp"                         "\n"
-"   " BRANCH_AND_LINK(SYMBOL_STRING_VMFRAME(PopActiveVMFrame)) "\n"
-"   add     sp, sp, #(4*7 + 4*6)"           "\n"
-"   mov     r0, #0"                         "\n"
-"   pop     {r4-r11,pc}"                    "\n"
-);
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerInterpolineScripted)  "\n"
-SYMBOL_STRING(JaegerInterpolineScripted) ":"        "\n"
-    /* The only difference between JaegerInterpoline and JaegerInpolineScripted is that the
-     * scripted variant has to walk up to the previous StackFrame first. */
-"   ldr     r10, [r10, #(4*4)]"             "\n"    /* Load f->prev_ */
-"   str     r10, [sp, #(4*7)]"              "\n"    /* Update f->regs->fp_ */
-    /* Fall through into JaegerInterpoline. */
-
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerInterpoline)  "\n"
-SYMBOL_STRING(JaegerInterpoline) ":"        "\n"
-"   mov     r3, sp"                         "\n"    /* f */
-"   mov     r2, r0"                         "\n"    /* returnReg */
-"   mov     r1, r5"                         "\n"    /* returnType */
-"   mov     r0, r4"                         "\n"    /* returnData */
-"   " BRANCH_AND_LINK(SYMBOL_STRING_RELOC(js_InternalInterpret)) "\n"
-"   cmp     r0, #0"                         "\n"
-"   ldr     r10, [sp, #(4*7)]"              "\n"    /* Load (StackFrame*)f->regs->fp_ */
-"   ldrd    r4, r5, [r10, #(4*6)]"          "\n"    /* Load rval payload and type. */
-"   ldr     r1, [sp, #(4*3)]"               "\n"    /* Load scratch. */
-"   it      ne"                             "\n"
-"   bxne    r0"                             "\n"
-    /* Tidy up, then return 0. */
-"   mov     r0, sp"                         "\n"
-"   " BRANCH_AND_LINK(SYMBOL_STRING_VMFRAME(PopActiveVMFrame)) "\n"
-"   add     sp, sp, #(4*7 + 4*6)"           "\n"
-"   mov     r0, #0"                         "\n"
-"   pop     {r4-r11,pc}"                    "\n"
-);
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(JaegerStubVeneer)   "\n"
-SYMBOL_STRING(JaegerStubVeneer) ":"         "\n"
-    /* We enter this function as a veneer between a compiled method and one of the js_ stubs. We
-     * need to store the LR somewhere (so it can be modified in case on an exception) and then
-     * branch to the js_ stub as if nothing had happened.
-     * The arguments are identical to those for js_* except that the target function should be in
-     * 'ip'. */
-"   push    {ip,lr}"                        "\n"
-"   blx     ip"                             "\n"
-"   pop     {ip,pc}"                        "\n"
-);
-
-asm (
-".text\n"
-FUNCTION_HEADER_EXTRA
-".globl " SYMBOL_STRING(IonVeneer)          "\n"
-SYMBOL_STRING(IonVeneer) ":"                "\n"
-    /* We enter this function as a veneer between a compiled method and one of the js_ stubs. We
-     * need to store the LR somewhere (so it can be modified in case on an exception) and then
-     * branch to the js_ stub as if nothing had happened.
-     * The arguments are identical to those for js_* except that the target function should be in
-     * 'ip'. */
-"   push    {lr}"                           "\n"
-"   blx     ip"                             "\n"
-"   pop     {pc}"                           "\n"
-);
-
-# elif defined(JS_CPU_SPARC)
-# elif defined(JS_CPU_MIPS)
-# else
-#  error "Unsupported CPU!"
-# endif
-#elif defined(_MSC_VER) && defined(JS_CPU_X86)
-
-/*
- *    *** DANGER ***
- * If these assertions break, update the constants below. The throwpoline
- * should have the offset of savedEBX plus 4, because it needs to clean
- * up the argument.
- *    *** DANGER ***
- */
-JS_STATIC_ASSERT(offsetof(VMFrame, savedEBX) == 0x3C);
-JS_STATIC_ASSERT(offsetof(VMFrame, scratch) == 0xC);
-JS_STATIC_ASSERT(VMFrame::offsetOfFp == 0x1C);
-
-extern "C" {
-
-    __declspec(naked) JSBool JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code,
-                                              Value *stackLimit)
-    {
-        __asm {
-            /* Prologue. */
-            push ebp;
-            mov ebp, esp;
-            /* Save non-volatile registers. */
-            push esi;
-            push edi;
-            push ebx;
-
-            /* Build the JIT frame. Push fields in order,
-             * then align the stack to form esp == VMFrame. */
-            mov  ebx, [ebp + 12];
-            push ebx;
-            push ebx;
-            push 0x0;
-            push ebx;
-            push ebx;
-            push [ebp + 20];
-            push [ebp + 8];
-            push ebx;
-            sub  esp, 0x1C;
-
-            /* Jump into into the JIT'd code. */
-            mov  ecx, esp;
-            call PushActiveVMFrame;
-
-            mov ebp, [esp + 28];  /* load fp for JIT code */
-            jmp dword ptr [esp + 88];
-        }
-    }
-
-    __declspec(naked) void JaegerTrampolineReturn()
-    {
-        __asm {
-            mov [ebp + 0x18], esi;
-            mov [ebp + 0x1C], edi;
-            mov  ebp, esp;
-            add  ebp, 0x48; /* Restore stack at STACK_BASE_DIFFERENCE */
-            mov  ecx, esp;
-            call PopActiveVMFrame;
-
-            add esp, 0x3C;
-
-            pop ebx;
-            pop edi;
-            pop esi;
-            pop ebp;
-            mov eax, 1;
-            ret;
-        }
-    }
-
-    extern "C" void *js_InternalThrow(js::VMFrame &f);
-
-    __declspec(naked) void *JaegerThrowpoline(js::VMFrame *vmFrame) {
-        __asm {
-            /* Align the stack to 16 bytes. */
-            push esp;
-            push [esp];
-            push [esp];
-            push [esp];
-            call js_InternalThrow;
-            /* Bump the stack by 0x2c, as in the basic trampoline, but
-             * also one more word to clean up the stack for js_InternalThrow,
-             * and another to balance the alignment above. */
-            add esp, 0x10;
-            test eax, eax;
-            je throwpoline_exit;
-            jmp eax;
-        throwpoline_exit:
-            mov ecx, esp;
-            call PopActiveVMFrame;
-            add esp, 0x3c;
-            pop ebx;
-            pop edi;
-            pop esi;
-            pop ebp;
-            xor eax, eax
-            ret;
-        }
-    }
-
-    extern "C" void *
-    js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VMFrame &f);
-
-    __declspec(naked) void JaegerInterpoline() {
-        __asm {
-            /* Align the stack to 16 bytes. */
-            push esp;
-            push eax;
-            push edi;
-            push esi;
-            call js_InternalInterpret;
-            add esp, 0x10;
-            mov ebp, [esp + 0x1C];  /* Load frame */
-            mov esi, [ebp + 0x18];  /* Load rval payload */
-            mov edi, [ebp + 0x1C];  /* Load rval type */
-            mov ecx, [esp + 0xC];   /* Load scratch -> argc */
-            test eax, eax;
-            je interpoline_exit;
-            jmp eax;
-        interpoline_exit:
-            mov ecx, esp;
-            call PopActiveVMFrame;
-            add esp, 0x3c;
-            pop ebx;
-            pop edi;
-            pop esi;
-            pop ebp;
-            xor eax, eax
-            ret;
-        }
-    }
-
-    __declspec(naked) void JaegerInterpolineScripted() {
-        __asm {
-            mov ebp, [ebp + 0x10];  /* Load prev */
-            mov [esp + 0x1C], ebp;  /* fp -> regs.fp */
-            jmp JaegerInterpoline;
-        }
-    }
-}
-
-// Windows x64 uses assembler version since compiler doesn't support
-// inline assembler
-#elif defined(_WIN64)
-
-/*
- *    *** DANGER ***
- * If these assertions break, update the constants below.
- *    *** DANGER ***
- */
-JS_STATIC_ASSERT(offsetof(VMFrame, savedRBX) == 0x68);
-JS_STATIC_ASSERT(offsetof(VMFrame, scratch) == 0x18);
-JS_STATIC_ASSERT(VMFrame::offsetOfFp == 0x38);
-JS_STATIC_ASSERT(JSVAL_TAG_MASK == 0xFFFF800000000000LL);
-JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
-
-#endif                   /* _WIN64 */
-
-JaegerRuntime::JaegerRuntime()
-    : orphanedNativeFrames(SystemAllocPolicy()), orphanedNativePools(SystemAllocPolicy())
-{}
-
-bool
-JaegerRuntime::init(JSContext *cx)
-{
-    JSC::ExecutableAllocator *execAlloc = cx->runtime->getExecAlloc(cx);
-    if (!execAlloc)
-        return false;
-
-    TrampolineCompiler tc(execAlloc, &trampolines);
-    if (!tc.compile())
-        return false;
-
-#ifdef JS_METHODJIT_PROFILE_STUBS
-    for (size_t i = 0; i < STUB_CALLS_FOR_OP_COUNT; ++i)
-        StubCallsForOp[i] = 0;
-#endif
-
-    activeFrame_ = NULL;
-    lastUnfinished_ = (JaegerStatus) 0;
-
-    return true;
-}
-
-void
-JaegerRuntime::finish()
-{
-    TrampolineCompiler::release(&trampolines);
-#ifdef JS_METHODJIT_PROFILE_STUBS
-    FILE *fp = fopen("/tmp/stub-profiling", "wt");
-# define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) \
-    fprintf(fp, "%03d %s %d\n", val, #op, StubCallsForOp[val]);
-# include "jsopcode.tbl"
-# undef OPDEF
-    fclose(fp);
-#endif
-}
-
-extern "C" JSBool
-JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code, Value *stackLimit);
-
-JaegerStatus
-mjit::EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimit, bool partial)
-{
-#ifdef JS_METHODJIT_SPEW
-    JaegerSpew(JSpew_Prof, "%s jaeger script, line %d\n",
-               fp->script()->filename(), fp->script()->lineno);
-    Profiler prof;
-    prof.start();
-#endif
-
-    JS_ASSERT(cx->fp() == fp);
-
-    JSBool ok;
-    {
-        AssertCompartmentUnchanged pcc(cx);
-
-#ifdef JS_ION
-        ion::IonContext ictx(cx, NULL);
-        ion::IonActivation activation(cx, NULL);
-        ion::AutoFlushInhibitor afi(cx->compartment->ionCompartment());
-#endif
-
-        JSAutoResolveFlags rf(cx, RESOLVE_INFER);
-
-        ok = JaegerTrampoline(cx, fp, code, stackLimit);
-    }
-
-#ifdef JS_METHODJIT_SPEW
-    prof.stop();
-    JaegerSpew(JSpew_Prof, "script run took %d ms\n", prof.time_ms());
-#endif
-
-    JaegerStatus status = cx->jaegerRuntime().lastUnfinished();
-    if (status) {
-        if (partial) {
-            /*
-             * Being called from the interpreter, which will resume execution
-             * where the JIT left off.
-             */
-            return status;
-        }
-
-        /*
-         * Call back into the interpreter to finish the initial frame. This may
-         * invoke EnterMethodJIT again, but will allow partial execution for
-         * that recursive invocation, so we can have at most two VM frames for
-         * a range of inline frames.
-         */
-        InterpMode mode = (status == Jaeger_UnfinishedAtTrap)
-            ? JSINTERP_SKIP_TRAP
-            : JSINTERP_REJOIN;
-        InterpretStatus status = Interpret(cx, fp, mode);
-
-        return (status != Interpret_Error) ? Jaeger_Returned : Jaeger_Throwing;
-    }
-
-    cx->regs().refreshFramePointer(fp);
-    cx->regs().setToEndOfScript();
-
-    /* The entry frame should have finished. */
-    JS_ASSERT(fp == cx->fp());
-
-    if (ok) {
-        /* The trampoline wrote the return value but did not set the HAS_RVAL flag. */
-        fp->markReturnValue();
-    }
-
-    return ok ? Jaeger_Returned : Jaeger_Throwing;
-}
-
-static inline JaegerStatus
-CheckStackAndEnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, bool partial)
-{
-    JS_CHECK_RECURSION(cx, return Jaeger_ThrowBeforeEnter);
-
-    JS_ASSERT(!cx->compartment->activeAnalysis);
-    JS_ASSERT(code);
-
-    Value *stackLimit = cx->stack.space().getStackLimit(cx, REPORT_ERROR);
-    if (!stackLimit)
-        return Jaeger_ThrowBeforeEnter;
-
-    return EnterMethodJIT(cx, fp, code, stackLimit, partial);
-}
-
-JaegerStatus
-mjit::JaegerShot(JSContext *cx, bool partial)
-{
-    StackFrame *fp = cx->fp();
-    JITScript *jit = fp->script()->getJIT(fp->isConstructing(), cx->zone()->compileBarriers());
-
-    JS_ASSERT(cx->regs().pc == fp->script()->code);
-
-#if JS_TRACE_LOGGING
-    AutoTraceLog logger(TraceLogging::defaultLogger(),
-                        TraceLogging::JM_START,
-                        TraceLogging::JM_STOP,
-                        fp->script().unsafeGet());
-#endif
-
-    return CheckStackAndEnterMethodJIT(cx, cx->fp(), jit->invokeEntry, partial);
-}
-
-JaegerStatus
-js::mjit::JaegerShotAtSafePoint(JSContext *cx, void *safePoint, bool partial)
-{
-#if JS_TRACE_LOGGING
-    AutoTraceLog logger(TraceLogging::defaultLogger(),
-                        TraceLogging::JM_SAFEPOINT_START,
-                        TraceLogging::JM_SAFEPOINT_STOP,
-                        cx->fp()->script().unsafeGet());
-#endif
-    return CheckStackAndEnterMethodJIT(cx, cx->fp(), safePoint, partial);
-}
-
-NativeMapEntry *
-JITChunk::nmap() const
-{
-    return (NativeMapEntry *)((char*)this + sizeof(*this));
-}
-
-js::mjit::InlineFrame *
-JITChunk::inlineFrames() const
-{
-    return (js::mjit::InlineFrame *)((char *)nmap() + sizeof(NativeMapEntry) * nNmapPairs);
-}
-
-js::mjit::CallSite *
-JITChunk::callSites() const
-{
-    return (js::mjit::CallSite *)&inlineFrames()[nInlineFrames];
-}
-
-js::mjit::CompileTrigger *
-JITChunk::compileTriggers() const
-{
-    return (CompileTrigger *)&callSites()[nCallSites];
-}
-
-JSObject **
-JITChunk::rootedTemplates() const
-{
-    return (JSObject **)&compileTriggers()[nCompileTriggers];
-}
-
-RegExpShared **
-JITChunk::rootedRegExps() const
-{
-    return (RegExpShared **)&rootedTemplates()[nRootedTemplates];
-}
-
-uint32_t *
-JITChunk::monitoredBytecodes() const
-{
-    return (uint32_t *)&rootedRegExps()[nRootedRegExps];
-}
-
-uint32_t *
-JITChunk::typeBarrierBytecodes() const
-{
-    return (uint32_t *)&monitoredBytecodes()[nMonitoredBytecodes];
-}
-
-char *
-JITChunk::commonSectionLimit() const
-{
-    return (char *)&typeBarrierBytecodes()[nTypeBarrierBytecodes];
-}
-
-#ifdef JS_MONOIC
-ic::GetGlobalNameIC *
-JITChunk::getGlobalNames() const
-{
-    return (ic::GetGlobalNameIC *) commonSectionLimit();
-}
-
-ic::SetGlobalNameIC *
-JITChunk::setGlobalNames() const
-{
-    return (ic::SetGlobalNameIC *)((char *)getGlobalNames() +
-            sizeof(ic::GetGlobalNameIC) * nGetGlobalNames);
-}
-
-ic::CallICInfo *
-JITChunk::callICs() const
-{
-    return (ic::CallICInfo *)&setGlobalNames()[nSetGlobalNames];
-}
-
-ic::EqualityICInfo *
-JITChunk::equalityICs() const
-{
-    return (ic::EqualityICInfo *)&callICs()[nCallICs];
-}
-
-char *
-JITChunk::monoICSectionsLimit() const
-{
-    return (char *)&equalityICs()[nEqualityICs];
-}
-#else   // JS_MONOIC
-char *
-JITChunk::monoICSectionsLimit() const
-{
-    return commonSectionLimit();
-}
-#endif  // JS_MONOIC
-
-#ifdef JS_POLYIC
-ic::GetElementIC *
-JITChunk::getElems() const
-{
-    return (ic::GetElementIC *)monoICSectionsLimit();
-}
-
-ic::SetElementIC *
-JITChunk::setElems() const
-{
-    return (ic::SetElementIC *)((char *)getElems() + sizeof(ic::GetElementIC) * nGetElems);
-}
-
-ic::PICInfo *
-JITChunk::pics() const
-{
-    return (ic::PICInfo *)((char *)setElems() + sizeof(ic::SetElementIC) * nSetElems);
-}
-
-char *
-JITChunk::polyICSectionsLimit() const
-{
-    return (char *)pics() + sizeof(ic::PICInfo) * nPICs;
-}
-#else   // JS_POLYIC
-char *
-JITChunk::polyICSectionsLimit() const
-{
-    return monoICSectionsLimit();
-}
-#endif  // JS_POLYIC
-
-void
-JITScript::patchEdge(const CrossChunkEdge &edge, void *label)
-{
-    if (edge.sourceJump1 || edge.sourceJump2) {
-        JITChunk *sourceChunk = chunk(script->code + edge.source);
-        ic::Repatcher repatch(sourceChunk);
-
-#ifdef JS_CPU_X64
-        JS_ASSERT(edge.sourceTrampoline);
-
-        static const uint32_t JUMP_LENGTH = 10;
-
-        if (edge.sourceJump1) {
-            JSC::CodeLocationLabel targetLabel(VerifyRange(edge.sourceJump1, JUMP_LENGTH, label, 0)
-                                               ? label
-                                               : edge.sourceTrampoline);
-            repatch.relink(JSC::CodeLocationJump(edge.sourceJump1), targetLabel);
-        }
-        if (edge.sourceJump2) {
-            JSC::CodeLocationLabel targetLabel(VerifyRange(edge.sourceJump2, JUMP_LENGTH, label, 0)
-                                               ? label
-                                               : edge.sourceTrampoline);
-            repatch.relink(JSC::CodeLocationJump(edge.sourceJump2), targetLabel);
-        }
-        JSC::CodeLocationDataLabelPtr sourcePatch((char*)edge.sourceTrampoline + JUMP_LENGTH);
-        repatch.repatch(sourcePatch, label);
-#else
-        JSC::CodeLocationLabel targetLabel(label);
-        if (edge.sourceJump1)
-            repatch.relink(JSC::CodeLocationJump(edge.sourceJump1), targetLabel);
-        if (edge.sourceJump2)
-            repatch.relink(JSC::CodeLocationJump(edge.sourceJump2), targetLabel);
-#endif
-    }
-    if (edge.jumpTableEntries) {
-        for (unsigned i = 0; i < edge.jumpTableEntries->length(); i++)
-            *(*edge.jumpTableEntries)[i] = label;
-    }
-}
-
-JITChunk::~JITChunk()
-{
-    purgeCaches();
-    code.release();
-
-    for (size_t i = 0; i < nRootedRegExps; i++)
-        rootedRegExps()[i]->decRef();
-
-    if (pcLengths)
-        js_free(pcLengths);
-}
-
-void
-JITScript::destroy(FreeOp *fop)
-{
-    for (unsigned i = 0; i < nchunks; i++)
-        destroyChunk(fop, i);
-
-    if (liveness)
-        fop->free_(liveness);
-
-    if (shimPool)
-        shimPool->release();
-}
-
-void
-JITScript::destroyChunk(FreeOp *fop, unsigned chunkIndex, bool resetUses)
-{
-    ChunkDescriptor &desc = chunkDescriptor(chunkIndex);
-
-    if (desc.chunk) {
-        // Invalidates the CompilerOutput of the chunk.
-        types::TypeCompartment &types = script->compartment()->types;
-        desc.chunk->recompileInfo.compilerOutput(types)->invalidate();
-
-        /*
-         * Write barrier: Before we destroy the chunk, trace through the objects
-         * it holds.
-         */
-        if (script->zone()->needsBarrier())
-            desc.chunk->trace(script->zone()->barrierTracer());
-
-        Probes::discardMJITCode(fop, this, desc.chunk, desc.chunk->code.m_code.executableAddress());
-        fop->delete_(desc.chunk);
-        desc.chunk = NULL;
-
-        CrossChunkEdge *edges = this->edges();
-        for (unsigned i = 0; i < nedges; i++) {
-            CrossChunkEdge &edge = edges[i];
-            if (edge.source >= desc.begin && edge.source < desc.end) {
-                edge.sourceJump1 = edge.sourceJump2 = NULL;
-#ifdef JS_CPU_X64
-                edge.sourceTrampoline = NULL;
-#endif
-                if (edge.jumpTableEntries) {
-                    fop->delete_(edge.jumpTableEntries);
-                    edge.jumpTableEntries = NULL;
-                }
-            } else if (edge.target >= desc.begin && edge.target < desc.end) {
-                edge.targetLabel = NULL;
-                patchEdge(edge, edge.shimLabel);
-            }
-        }
-    }
-
-    if (resetUses)
-        desc.counter = 0;
-
-    if (chunkIndex == 0) {
-        if (argsCheckPool) {
-            argsCheckPool->release();
-            argsCheckPool = NULL;
-        }
-
-        disableScriptEntry();
-    }
-}
-
-void
-JITScript::trace(JSTracer *trc)
-{
-    for (unsigned i = 0; i < nchunks; i++) {
-        ChunkDescriptor &desc = chunkDescriptor(i);
-        if (desc.chunk)
-            desc.chunk->trace(trc);
-    }
-}
-
-static ic::PICInfo *
-GetPIC(JSContext *cx, JSScript *script, jsbytecode *pc, bool constructing)
-{
-    JITScript *jit = script->getJIT(constructing, cx->zone()->needsBarrier());
-    if (!jit)
-        return NULL;
-
-    JITChunk *chunk = jit->chunk(pc);
-    if (!chunk)
-        return NULL;
-
-    ic::PICInfo *pics = chunk->pics();
-    for (uint32_t i = 0; i < chunk->nPICs; i++) {
-        if (pics[i].pc == pc)
-            return &pics[i];
-    }
-
-    return NULL;
-}
-
-Shape *
-mjit::GetPICSingleShape(JSContext *cx, JSScript *script, jsbytecode *pc, bool constructing)
-{
-    ic::PICInfo *pic = GetPIC(cx, script, pc, constructing);
-    if (!pic)
-        return NULL;
-    return pic->getSingleShape();
-}
-
-void
-JITScript::purgeCaches()
-{
-    for (unsigned i = 0; i < nchunks; i++) {
-        ChunkDescriptor &desc = chunkDescriptor(i);
-        if (desc.chunk)
-            desc.chunk->purgeCaches();
-    }
-}
-
-void
-JITScript::disableScriptEntry()
-{
-    invokeEntry = NULL;
-    fastEntry = NULL;
-    argsCheckEntry = NULL;
-    arityCheckEntry = NULL;
-
-    // Fixup any ICs still referring to this script.
-    while (!JS_CLIST_IS_EMPTY(&callers)) {
-        JS_STATIC_ASSERT(offsetof(ic::CallICInfo, links) == 0);
-        ic::CallICInfo *ic = (ic::CallICInfo *) callers.next;
-
-        uint8_t *start = (uint8_t *)ic->funGuard.executableAddress();
-        JSC::RepatchBuffer repatch(JSC::JITCode(start - 32, 64));
-
-        repatch.repatch(ic->funGuard, NULL);
-        repatch.relink(ic->funJump, ic->slowPathStart);
-        ic->purgeGuardedObject();
-    }
-}
-
-const js::mjit::JITScript *JSScript::JITScriptHandle::UNJITTABLE =
-    reinterpret_cast<js::mjit::JITScript *>(1);
-
-void
-JSScript::JITScriptHandle::staticAsserts()
-{
-    // JITScriptHandle's memory layout must match that of JITScript *.
-    JS_STATIC_ASSERT(sizeof(JSScript::JITScriptHandle) == sizeof(js::mjit::JITScript *));
-    JS_STATIC_ASSERT(JS_ALIGNMENT_OF(JSScript::JITScriptHandle) ==
-                     JS_ALIGNMENT_OF(js::mjit::JITScript *));
-    JS_STATIC_ASSERT(offsetof(JSScript::JITScriptHandle, value) == 0);
-}
-
-size_t
-JSScript::sizeOfJitScripts(JSMallocSizeOfFun mallocSizeOf)
-{
-    if (!hasMJITInfo())
-        return 0;
-
-    size_t n = mallocSizeOf(mJITInfo);
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            JITScript *jit = getJIT((bool) constructing, (bool) barriers);
-            if (jit)
-                n += jit->sizeOfIncludingThis(mallocSizeOf);
-        }
-    }
-    return n;
-}
-
-size_t
-mjit::JITScript::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
-{
-    size_t n = mallocSizeOf(this);
-    if (liveness)
-        n += mallocSizeOf(liveness);
-    for (unsigned i = 0; i < nchunks; i++) {
-        const ChunkDescriptor &desc = chunkDescriptor(i);
-        if (desc.chunk)
-            n += desc.chunk->sizeOfIncludingThis(mallocSizeOf);
-    }
-    return n;
-}
-
-/* Please keep in sync with Compiler::finishThisUp! */
-size_t
-mjit::JITChunk::computedSizeOfIncludingThis()
-{
-    return sizeof(JITChunk) +
-           sizeof(NativeMapEntry) * nNmapPairs +
-           sizeof(InlineFrame) * nInlineFrames +
-           sizeof(CallSite) * nCallSites +
-           sizeof(CompileTrigger) * nCompileTriggers +
-           sizeof(JSObject*) * nRootedTemplates +
-           sizeof(RegExpShared*) * nRootedRegExps +
-           sizeof(uint32_t) * nMonitoredBytecodes +
-           sizeof(uint32_t) * nTypeBarrierBytecodes +
-#if defined JS_MONOIC
-           sizeof(ic::GetGlobalNameIC) * nGetGlobalNames +
-           sizeof(ic::SetGlobalNameIC) * nSetGlobalNames +
-           sizeof(ic::CallICInfo) * nCallICs +
-           sizeof(ic::EqualityICInfo) * nEqualityICs +
-#endif
-#if defined JS_POLYIC
-           sizeof(ic::PICInfo) * nPICs +
-           sizeof(ic::GetElementIC) * nGetElems +
-           sizeof(ic::SetElementIC) * nSetElems +
-#endif
-           0;
-}
-
-/* Please keep in sync with Compiler::finishThisUp! */
-size_t
-mjit::JITChunk::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
-{
-    return mallocSizeOf(this);
-}
-
-void
-JSScript::ReleaseCode(FreeOp *fop, JITScriptHandle *jith)
-{
-    // NB: The recompiler may call ReleaseScriptCode, in which case it
-    // will get called again when the script is destroyed, so we
-    // must protect against calling ReleaseScriptCode twice.
-
-    if (jith->isValid()) {
-        JITScript *jit = jith->getValid();
-        jit->destroy(fop);
-        fop->free_(jit);
-        jith->setEmpty();
-    }
-}
-
-static void
-DisableScriptAtPC(JITScript *jit, jsbytecode *pc)
-{
-    JS_ASSERT(jit->script->hasIonScript());
-
-    JITChunk *chunk = jit->chunk(pc);
-    if (!chunk)
-        return;
-
-    CompileTrigger *triggers = chunk->compileTriggers();
-    for (size_t i = 0; i < chunk->nCompileTriggers; i++) {
-        const CompileTrigger &trigger = triggers[i];
-        if (trigger.pcOffset != pc - jit->script->code)
-            continue;
-
-        // The inline jump in the trigger is 'script->useCount >= threshold',
-        // which should hold at the specified pc because the script has been
-        // compiled for Ion. Normally, if this jump passes it will then take
-        // a second jump to test for !script->ion. Patch the first jump to
-        // bypass the second jump and directly call TriggerIonCompile, which
-        // will recognize this case and destroy the chunk.
-        ic::Repatcher repatcher(chunk);
-        repatcher.relink(trigger.inlineJump, trigger.stubLabel);
-    }
-}
-
-void
-mjit::DisableScriptCodeForIon(JSScript *script, jsbytecode *osrPC)
-{
-    if (!script->hasMJITInfo())
-        return;
-
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            JITScript *jit = script->getJIT((bool) constructing, (bool) barriers);
-            if (jit) {
-                DisableScriptAtPC(jit, script->code);
-                if (osrPC)
-                    DisableScriptAtPC(jit, osrPC);
-            }
-        }
-    }
-}
-
-#ifdef JS_METHODJIT_PROFILE_STUBS
-void JS_FASTCALL
-mjit::ProfileStubCall(VMFrame &f)
-{
-    JSOp op = JSOp(*f.regs.pc);
-    StubCallsForOp[op]++;
-}
-#endif
-
-JITChunk *
-JITScript::findCodeChunk(void *addr)
-{
-    for (unsigned i = 0; i < nchunks; i++) {
-        ChunkDescriptor &desc = chunkDescriptor(i);
-        if (desc.chunk && desc.chunk->isValidCode(addr))
-            return desc.chunk;
-    }
-    return NULL;
-}
-
-jsbytecode *
-JITScript::nativeToPC(void *returnAddress, CallSite **pinline)
-{
-    JITChunk *chunk = findCodeChunk(returnAddress);
-    JS_ASSERT(chunk);
-
-    JS_ASSERT(chunk->isValidCode(returnAddress));
-
-    size_t low = 0;
-    size_t high = chunk->nCallICs;
-    js::mjit::ic::CallICInfo *callICs_ = chunk->callICs();
-    while (high > low + 1) {
-        /* Could overflow here on a script with 2 billion calls. Oh well. */
-        size_t mid = (high + low) / 2;
-        void *entry = callICs_[mid].funGuard.executableAddress();
-
-        /*
-         * Use >= here as the return address of the call is likely to be
-         * the start address of the next (possibly IC'ed) operation.
-         */
-        if (entry >= returnAddress)
-            high = mid;
-        else
-            low = mid;
-    }
-
-    js::mjit::ic::CallICInfo &ic = callICs_[low];
-    JS_ASSERT((uint8_t*)ic.funGuard.executableAddress() + ic.joinPointOffset == returnAddress);
-
-    if (ic.call->inlineIndex != UINT32_MAX) {
-        if (pinline)
-            *pinline = ic.call;
-        InlineFrame *frame = &chunk->inlineFrames()[ic.call->inlineIndex];
-        while (frame && frame->parent)
-            frame = frame->parent;
-        return frame->parentpc;
-    }
-
-    if (pinline)
-        *pinline = NULL;
-    return script->code + ic.call->pcOffset;
-}
-
-jsbytecode *
-mjit::NativeToPC(JITScript *jit, void *ncode, mjit::CallSite **pinline)
-{
-    return jit->nativeToPC(ncode, pinline);
-}
-
-/* static */ const double mjit::Assembler::oneDouble = 1.0;
-
-void
-JITChunk::trace(JSTracer *trc)
-{
-    JSObject **rootedTemplates_ = rootedTemplates();
-    for (size_t i = 0; i < nRootedTemplates; i++) {
-        /* We use a manual write barrier in destroyChunk. */
-        MarkObjectUnbarriered(trc, &rootedTemplates_[i], "jitchunk_template");
-    }
-
-    /* RegExpShared objects require the RegExp source string. */
-    RegExpShared **rootedRegExps_ = rootedRegExps();
-    for (size_t i = 0; i < nRootedRegExps; i++)
-        rootedRegExps_[i]->trace(trc);
-}
-
-void
-JITChunk::purgeCaches()
-{
-    ic::Repatcher repatch(this);
-
-#if defined JS_MONOIC
-    uint32_t releasedExecPools = 0;
-
-    ic::EqualityICInfo *equalityICs_ = equalityICs();
-    for (uint32_t i = 0; i < nEqualityICs; i++) {
-        ic::EqualityICInfo &ic = equalityICs_[i];
-        if (!ic.generated)
-            continue;
-
-        JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, ic::Equality));
-        repatch.relink(ic.stubCall, fptr);
-        repatch.relink(ic.jumpToStub, ic.stubEntry);
-
-        ic.generated = false;
-        releasedExecPools++;
-    }
-
-    JS_ASSERT(releasedExecPools == execPools.length());
-    for (JSC::ExecutablePool **pExecPool = execPools.begin();
-         pExecPool != execPools.end();
-         ++pExecPool)
-    {
-        (*pExecPool)->release();
-    }
-    execPools.clear();
-
-    for (unsigned i = 0; i < nativeCallStubs.length(); i++) {
-        JSC::ExecutablePool *pool = nativeCallStubs[i].pool;
-        if (pool)
-            pool->release();
-    }
-    nativeCallStubs.clear();
-
-    ic::GetGlobalNameIC *getGlobalNames_ = getGlobalNames();
-    for (uint32_t i = 0; i < nGetGlobalNames; i++) {
-        ic::GetGlobalNameIC &ic = getGlobalNames_[i];
-        repatch.repatch(ic.fastPathStart.dataLabelPtrAtOffset(ic.shapeOffset), NULL);
-    }
-
-    ic::SetGlobalNameIC *setGlobalNames_ = setGlobalNames();
-    for (uint32_t i = 0; i < nSetGlobalNames; i++) {
-        ic::SetGlobalNameIC &ic = setGlobalNames_[i];
-        ic.patchInlineShapeGuard(repatch, NULL);
-    }
-
-    ic::CallICInfo *callICs_ = callICs();
-    for (uint32_t i = 0; i < nCallICs; i++)
-        callICs_[i].reset(repatch);
-#endif
-
-#if defined JS_POLYIC
-    ic::GetElementIC *getElems_ = getElems();
-    ic::SetElementIC *setElems_ = setElems();
-    ic::PICInfo *pics_ = pics();
-    for (uint32_t i = 0; i < nGetElems; i++)
-        getElems_[i].purge(repatch);
-    for (uint32_t i = 0; i < nSetElems; i++)
-        setElems_[i].purge(repatch);
-    for (uint32_t i = 0; i < nPICs; i++)
-        pics_[i].purge(repatch);
-#endif
-}
deleted file mode 100644
--- a/js/src/methodjit/MethodJIT.h
+++ /dev/null
@@ -1,1113 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_h__ && defined JS_METHODJIT
-#define jsjaeger_h__
-
-#include "mozilla/PodOperations.h"
-
-#ifdef JSGC_INCREMENTAL
-#define JSGC_INCREMENTAL_MJ
-#endif
-
-#include "jscntxt.h"
-#include "jscompartment.h"
-
-#include "assembler/assembler/MacroAssemblerCodeRef.h"
-#include "assembler/assembler/CodeLocation.h"
-
-#if !defined JS_CPU_X64 && \
-    !defined JS_CPU_X86 && \
-    !defined JS_CPU_SPARC && \
-    !defined JS_CPU_ARM && \
-    !defined JS_CPU_MIPS
-# error "Oh no, you should define a platform so this compiles."
-#endif
-
-#if !defined(JS_NUNBOX32) && !defined(JS_PUNBOX64)
-# error "No boxing format selected."
-#endif
-
-namespace js {
-
-namespace mjit {
-    struct JITChunk;
-    struct JITScript;
-}
-
-namespace analyze {
-    struct ScriptLiveness;
-}
-
-struct VMFrame
-{
-#if defined(JS_CPU_SPARC)
-    void *savedL0;
-    void *savedL1;
-    void *savedL2;
-    void *savedL3;
-    void *savedL4;
-    void *savedL5;
-    void *savedL6;
-    void *savedL7;
-    void *savedI0;
-    void *savedI1;
-    void *savedI2;
-    void *savedI3;
-    void *savedI4;
-    void *savedI5;
-    void *savedI6;
-    void *savedI7;
-
-    void *str_p;
-
-    void *outgoing_p0;
-    void *outgoing_p1;
-    void *outgoing_p2;
-    void *outgoing_p3;
-    void *outgoing_p4;
-    void *outgoing_p5;
-
-    void *outgoing_p6;
-
-    void *reserve_0;
-    void *reserve_1;
-
-#elif defined(JS_CPU_MIPS)
-    /* Reserved 16 bytes for a0-a3 space in MIPS O32 ABI */
-    void         *unused0;
-    void         *unused1;
-    void         *unused2;
-    void         *unused3;
-#endif
-
-    union Arguments {
-        struct {
-            void *ptr;
-            void *ptr2;
-        } x;
-        struct {
-            uint32_t dynamicArgc;
-        } call;
-    } u;
-
-    static size_t offsetOfDynamicArgc() {
-        return offsetof(VMFrame, u.call.dynamicArgc);
-    }
-
-    VMFrame      *previous;
-    void         *scratch;
-    FrameRegs    regs;
-
-    static size_t offsetOfRegsSp() {
-        return offsetof(VMFrame, regs.sp);
-    }
-
-    static size_t offsetOfRegsPc() {
-        return offsetof(VMFrame, regs.pc);
-    }
-
-    JSContext    *cx;
-    Value        *stackLimit;
-    StackFrame   *entryfp;
-    FrameRegs    *oldregs;
-    FrameRejoinState stubRejoin;  /* How to rejoin if inside a call from an IC stub. */
-
-#if defined(JS_CPU_X86)
-    void         *unused0, *unused1;  /* For 16 byte alignment */
-#endif
-
-#if defined(JS_CPU_X86)
-    void *savedEBX;
-    void *savedEDI;
-    void *savedESI;
-    void *savedEBP;
-    void *savedEIP;
-
-# ifdef JS_NO_FASTCALL
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 5;
-    }
-# else
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 1;
-    }
-# endif
-
-    /* The gap between ebp and esp in JaegerTrampoline frames on X86 platforms. */
-    static const uint32_t STACK_BASE_DIFFERENCE = 0x38;
-
-#elif defined(JS_CPU_X64)
-    void *savedRBX;
-# ifdef _WIN64
-    void *savedRSI;
-    void *savedRDI;
-# endif
-    void *savedR15;
-    void *savedR14;
-    void *savedR13;
-    void *savedR12;
-    void *savedRBP;
-    void *savedRIP;
-
-# ifdef _WIN64
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 5;
-    }
-# else
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 1;
-    }
-# endif
-
-#elif defined(JS_CPU_ARM)
-    void *savedR4;
-    void *savedR5;
-    void *savedR6;
-    void *savedR7;
-    void *savedR8;
-    void *savedR9;
-    void *savedR10;
-    void *savedR11;
-    void *savedLR;
-
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 1;
-    }
-#elif defined(JS_CPU_SPARC)
-    JSStackFrame *topRetrunAddr;
-    void* veneerReturn;
-    void* _align;
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(&this->veneerReturn);
-    }
-#elif defined(JS_CPU_MIPS)
-    void *savedS0;
-    void *savedS1;
-    void *savedS2;
-    void *savedS3;
-    void *savedS4;
-    void *savedS5;
-    void *savedS6;
-    void *savedS7;
-    void *savedGP;
-    void *savedRA;
-    void *unused4;  // For alignment.
-
-    inline void** returnAddressLocation() {
-        return reinterpret_cast<void**>(this) - 1;
-    }
-#else
-# error "The VMFrame layout isn't defined for your processor architecture!"
-#endif
-
-    JSRuntime *runtime() { return cx->runtime; }
-
-    /*
-     * Get the current frame and JIT. Note that these are NOT stable in case
-     * of recompilations; all code which expects these to be stable should
-     * check that cx->recompilations() has not changed across a call that could
-     * trigger recompilation (pretty much any time the VM is called into).
-     */
-    StackFrame *fp() { return regs.fp(); }
-    mjit::JITScript *jit() { return fp()->jit(); }
-
-    inline mjit::JITChunk *chunk();
-    inline unsigned chunkIndex();
-
-    /* Get the inner script/PC in case of inlining. */
-    inline JSScript *script();
-    inline jsbytecode *pc();
-
-#if defined(JS_CPU_SPARC)
-    static const size_t offsetOfFp = 30 * sizeof(void *) + FrameRegs::offsetOfFp;
-    static const size_t offsetOfInlined = 30 * sizeof(void *) + FrameRegs::offsetOfInlined;
-#elif defined(JS_CPU_MIPS)
-    static const size_t offsetOfFp = 8 * sizeof(void *) + FrameRegs::offsetOfFp;
-    static const size_t offsetOfInlined = 8 * sizeof(void *) + FrameRegs::offsetOfInlined;
-#else
-    static const size_t offsetOfFp = 4 * sizeof(void *) + FrameRegs::offsetOfFp;
-    static const size_t offsetOfInlined = 4 * sizeof(void *) + FrameRegs::offsetOfInlined;
-#endif
-
-    static void staticAssert() {
-        JS_STATIC_ASSERT(offsetOfFp == offsetof(VMFrame, regs) + FrameRegs::offsetOfFp);
-        JS_STATIC_ASSERT(offsetOfInlined == offsetof(VMFrame, regs) + FrameRegs::offsetOfInlined);
-    }
-};
-
-#if defined(JS_CPU_ARM) || defined(JS_CPU_SPARC) || defined(JS_CPU_MIPS)
-// WARNING: Do not call this function directly from C(++) code because it is not ABI-compliant.
-extern "C" void JaegerStubVeneer(void);
-# if defined(JS_CPU_ARM)
-extern "C" void IonVeneer(void);
-# endif
-#endif
-
-namespace mjit {
-
-/*
- * For a C++ or scripted call made from JIT code, indicates properties of the
- * register and stack state after the call finishes, which js_InternalInterpret
- * must use to construct a coherent state for rejoining into the interpreter.
- */
-enum RejoinState {
-    /*
-     * Return value of call at this bytecode is held in ReturnReg_{Data,Type}
-     * and needs to be restored before starting the next bytecode. f.regs.pc
-     * is *not* intact when rejoining from a scripted call (unlike all other
-     * rejoin states). The pc's offset into the script is stored in the upper
-     * 31 bits of the rejoin state, and the remaining values for RejoinState
-     * are shifted left by one in stack frames to leave the lower bit set only
-     * for scripted calls.
-     */
-    REJOIN_SCRIPTED = 1,
-
-    /* Recompilations and frame expansion are impossible for this call. */
-    REJOIN_NONE,
-
-    /* State is coherent for the start of the current bytecode. */
-    REJOIN_RESUME,
-
-    /*
-     * State is coherent for the start of the current bytecode, which is a TRAP
-     * that has already been invoked and should not be invoked again.
-     */
-    REJOIN_TRAP,
-
-    /* State is coherent for the start of the next (fallthrough) bytecode. */
-    REJOIN_FALLTHROUGH,
-
-    /*
-     * As for REJOIN_FALLTHROUGH, but holds a reference on the compartment's
-     * orphaned native pools which needs to be reclaimed by InternalInterpret.
-     * The return value needs to be adjusted if REJOIN_NATIVE_LOWERED, and
-     * REJOIN_NATIVE_GETTER is for ABI calls made for property accesses.
-     */
-    REJOIN_NATIVE,
-    REJOIN_NATIVE_LOWERED,
-    REJOIN_NATIVE_GETTER,
-
-    /*
-     * Dummy rejoin stored in VMFrames to indicate they return into a native
-     * stub (and their FASTCALL return address should not be observed) but
-     * that they have already been patched and can be ignored.
-     */
-    REJOIN_NATIVE_PATCHED,
-
-    /* Call returns a payload, which should be pushed before starting next bytecode. */
-    REJOIN_PUSH_BOOLEAN,
-    REJOIN_PUSH_OBJECT,
-
-    /*
-     * During the prologue of constructing scripts, after the function's
-     * .prototype property has been fetched.
-     */
-    REJOIN_THIS_PROTOTYPE,
-
-    /* As above, after the 'this' object has been created. */
-    REJOIN_THIS_CREATED,
-
-    /*
-     * Type check on arguments failed during prologue, need stack check and
-     * the rest of the JIT prologue before the script can execute.
-     */
-    REJOIN_CHECK_ARGUMENTS,
-
-    /*
-     * The script's jitcode was discarded during one of the following steps of
-     * a frame's prologue.
-     */
-    REJOIN_EVAL_PROLOGUE,
-    REJOIN_FUNCTION_PROLOGUE,
-
-    /*
-     * State after calling a stub which returns a JIT code pointer for a call
-     * or NULL for an already-completed call.
-     */
-    REJOIN_CALL_PROLOGUE,
-    REJOIN_CALL_PROLOGUE_LOWERED_CALL,
-    REJOIN_CALL_PROLOGUE_LOWERED_APPLY,
-
-    /* Triggered a recompilation while placing the arguments to an apply on the stack. */
-    REJOIN_CALL_SPLAT,
-
-    /* Like REJOIN_FALLTHROUGH, but handles getprop used as part of JSOP_INSTANCEOF. */
-    REJOIN_GETTER,
-
-    /*
-     * For an opcode fused with IFEQ/IFNE, call returns a boolean indicating
-     * the result of the comparison and whether to take or not take the branch.
-     */
-    REJOIN_BRANCH
-};
-
-/* Get the rejoin state for a StackFrame after returning from a scripted call. */
-static inline FrameRejoinState
-ScriptedRejoin(uint32_t pcOffset)
-{
-    return REJOIN_SCRIPTED | (pcOffset << 1);
-}
-
-/* Get the rejoin state for a StackFrame after returning from a stub call. */
-static inline FrameRejoinState
-StubRejoin(RejoinState rejoin)
-{
-    return rejoin << 1;
-}
-
-/* Helper to watch for recompilation and frame expansion activity on a compartment. */
-struct RecompilationMonitor
-{
-    JSContext *cx;
-
-    /*
-     * If either inline frame expansion or recompilation occurs, then ICs and
-     * stubs should not depend on the frame or JITs being intact. The two are
-     * separated for logging.
-     */
-    unsigned recompilations;
-    unsigned frameExpansions;
-
-    /* If a GC occurs it may discard jit code on the stack. */
-    uint64_t gcNumber;
-
-    RecompilationMonitor(JSContext *cx)
-        : cx(cx),
-          recompilations(cx->compartment->types.recompilations),
-          frameExpansions(cx->compartment->types.frameExpansions),
-          gcNumber(cx->runtime->gcNumber)
-    {}
-
-    bool recompiled() {
-        return cx->compartment->types.recompilations != recompilations
-            || cx->compartment->types.frameExpansions != frameExpansions
-            || cx->runtime->gcNumber != gcNumber;
-    }
-};
-
-/*
- * Trampolines to force returns from jit code.
- * See also TrampolineCompiler::generateForceReturn(Fast).
- */
-struct Trampolines {
-    typedef void (*TrampolinePtr)();
-
-    TrampolinePtr       forceReturn;
-    JSC::ExecutablePool *forceReturnPool;
-
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-    TrampolinePtr       forceReturnFast;
-    JSC::ExecutablePool *forceReturnFastPool;
-#endif
-};
-
-/* Result status of executing mjit code on a frame. */
-enum JaegerStatus
-{
-    /* Entry frame finished, and is throwing an exception. */
-    Jaeger_Throwing = 0,
-
-    /* Entry frame finished, and is returning. */
-    Jaeger_Returned = 1,
-
-    /*
-     * Entry frame did not finish. cx->regs reflects where to resume execution.
-     * This result is only possible if 'partial' is passed as true below.
-     */
-    Jaeger_Unfinished = 2,
-
-    /*
-     * As for Unfinished, but stopped after a TRAP triggered recompilation.
-     * The trap has been reinstalled, but should not execute again when
-     * resuming execution.
-     */
-    Jaeger_UnfinishedAtTrap = 3,
-
-    /*
-     * An exception was thrown before entering jit code, so the caller should
-     * 'goto error'.
-     */
-    Jaeger_ThrowBeforeEnter = 4
-};
-
-static inline bool
-JaegerStatusToSuccess(JaegerStatus status)
-{
-    JS_ASSERT(status != Jaeger_Unfinished);
-    JS_ASSERT(status != Jaeger_UnfinishedAtTrap);
-    return status == Jaeger_Returned;
-}
-
-/* Method JIT data associated with the JSRuntime. */
-class JaegerRuntime
-{
-    Trampolines              trampolines;    // force-return trampolines
-    VMFrame                  *activeFrame_;  // current active VMFrame
-    JaegerStatus             lastUnfinished_;// result status of last VM frame,
-                                             // if unfinished
-
-    void finish();
-
-  public:
-    bool init(JSContext *cx);
-
-    JaegerRuntime();
-    ~JaegerRuntime() { finish(); }
-
-    VMFrame *activeFrame() {
-        return activeFrame_;
-    }
-
-    void pushActiveFrame(VMFrame *f) {
-        JS_ASSERT(!lastUnfinished_);
-        f->previous = activeFrame_;
-        f->scratch = NULL;
-        activeFrame_ = f;
-    }
-
-    void popActiveFrame() {
-        JS_ASSERT(activeFrame_);
-        activeFrame_ = activeFrame_->previous;
-    }
-
-    void setLastUnfinished(JaegerStatus status) {
-        JS_ASSERT(!lastUnfinished_);
-        lastUnfinished_ = status;
-    }
-
-    JaegerStatus lastUnfinished() {
-        JaegerStatus result = lastUnfinished_;
-        lastUnfinished_ = (JaegerStatus) 0;
-        return result;
-    }
-
-    /*
-     * To force the top StackFrame in a VMFrame to return, when that VMFrame
-     * has called an extern "C" function (say, js_InternalThrow or
-     * js_InternalInterpret), change the extern "C" function's return address
-     * to the value this method returns.
-     */
-    void *forceReturnFromExternC() const {
-        return JS_FUNC_TO_DATA_PTR(void *, trampolines.forceReturn);
-    }
-
-    /*
-     * To force the top StackFrame in a VMFrame to return, when that VMFrame has
-     * called a fastcall function (say, most stubs:: functions), change the
-     * fastcall function's return address to the value this method returns.
-     */
-    void *forceReturnFromFastCall() const {
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-        return JS_FUNC_TO_DATA_PTR(void *, trampolines.forceReturnFast);
-#else
-        return JS_FUNC_TO_DATA_PTR(void *, trampolines.forceReturn);
-#endif
-    }
-
-    /*
-     * References held on pools created for native ICs, where the IC was
-     * destroyed and we are waiting for the pool to finish use and jump
-     * into the interpoline.
-     */
-    Vector<StackFrame *, 8, SystemAllocPolicy> orphanedNativeFrames;
-    Vector<JSC::ExecutablePool *, 8, SystemAllocPolicy> orphanedNativePools;
-};
-
-/*
- * Allocation policy for compiler jstl objects. The goal is to free the
- * compiler from having to check and propagate OOM after every time we
- * append to a vector. We do this by reporting OOM to the engine and
- * setting a flag on the compiler when OOM occurs. The compiler is required
- * to check for OOM only before trying to use the contents of the list.
- */
-class CompilerAllocPolicy : public TempAllocPolicy
-{
-    bool *oomFlag;
-
-    void *checkAlloc(void *p) {
-        if (!p)
-            *oomFlag = true;
-        return p;
-    }
-
-  public:
-    CompilerAllocPolicy(JSContext *cx, bool *oomFlag)
-    : TempAllocPolicy(cx), oomFlag(oomFlag) {}
-    CompilerAllocPolicy(JSContext *cx, Compiler &compiler);
-
-    void *malloc_(size_t bytes) { return checkAlloc(TempAllocPolicy::malloc_(bytes)); }
-    void *realloc_(void *p, size_t oldBytes, size_t bytes) {
-        return checkAlloc(TempAllocPolicy::realloc_(p, oldBytes, bytes));
-    }
-};
-
-namespace ic {
-# if defined JS_POLYIC
-    struct PICInfo;
-    struct GetElementIC;
-    struct SetElementIC;
-# endif
-# if defined JS_MONOIC
-    struct GetGlobalNameIC;
-    struct SetGlobalNameIC;
-    struct EqualityICInfo;
-    struct CallICInfo;
-# endif
-}
-}
-
-typedef void (JS_FASTCALL *VoidStub)(VMFrame &);
-typedef void (JS_FASTCALL *VoidVpStub)(VMFrame &, Value *);
-typedef void (JS_FASTCALL *VoidStubUInt32)(VMFrame &, uint32_t);
-typedef void (JS_FASTCALL *VoidStubInt32)(VMFrame &, int32_t);
-typedef JSBool (JS_FASTCALL *BoolStub)(VMFrame &);
-typedef void * (JS_FASTCALL *VoidPtrStub)(VMFrame &);
-typedef void * (JS_FASTCALL *VoidPtrStubPC)(VMFrame &, jsbytecode *);
-typedef void * (JS_FASTCALL *VoidPtrStubUInt32)(VMFrame &, uint32_t);
-typedef JSObject * (JS_FASTCALL *JSObjStub)(VMFrame &);
-typedef JSObject * (JS_FASTCALL *JSObjStubUInt32)(VMFrame &, uint32_t);
-typedef JSObject * (JS_FASTCALL *JSObjStubFun)(VMFrame &, JSFunction *);
-typedef void (JS_FASTCALL *VoidStubFun)(VMFrame &, JSFunction *);
-typedef JSObject * (JS_FASTCALL *JSObjStubJSObj)(VMFrame &, JSObject *);
-typedef void (JS_FASTCALL *VoidStubName)(VMFrame &, PropertyName *);
-typedef JSString * (JS_FASTCALL *JSStrStub)(VMFrame &);
-typedef JSString * (JS_FASTCALL *JSStrStubUInt32)(VMFrame &, uint32_t);
-typedef void (JS_FASTCALL *VoidStubJSObj)(VMFrame &, JSObject *);
-typedef void (JS_FASTCALL *VoidStubPC)(VMFrame &, jsbytecode *);
-typedef JSBool (JS_FASTCALL *BoolStubUInt32)(VMFrame &f, uint32_t);
-#ifdef JS_MONOIC
-typedef void (JS_FASTCALL *VoidStubCallIC)(VMFrame &, js::mjit::ic::CallICInfo *);
-typedef void * (JS_FASTCALL *VoidPtrStubCallIC)(VMFrame &, js::mjit::ic::CallICInfo *);
-typedef void (JS_FASTCALL *VoidStubGetGlobal)(VMFrame &, js::mjit::ic::GetGlobalNameIC *);
-typedef void (JS_FASTCALL *VoidStubSetGlobal)(VMFrame &, js::mjit::ic::SetGlobalNameIC *);
-typedef JSBool (JS_FASTCALL *BoolStubEqualityIC)(VMFrame &, js::mjit::ic::EqualityICInfo *);
-#endif
-#ifdef JS_POLYIC
-typedef void (JS_FASTCALL *VoidStubPIC)(VMFrame &, js::mjit::ic::PICInfo *);
-typedef void (JS_FASTCALL *VoidStubGetElemIC)(VMFrame &, js::mjit::ic::GetElementIC *);
-typedef void (JS_FASTCALL *VoidStubSetElemIC)(VMFrame &f, js::mjit::ic::SetElementIC *);
-#endif
-
-namespace mjit {
-
-struct InlineFrame;
-struct CallSite;
-struct CompileTrigger;
-
-struct NativeMapEntry {
-    size_t          bcOff;  /* bytecode offset in script */
-    void            *ncode; /* pointer to native code */
-};
-
-/* Per-op counts of performance metrics. */
-struct PCLengthEntry {
-    double          inlineLength; /* amount of inline code generated */
-    double          picsLength;   /* amount of PIC stub code generated */
-    double          stubLength;   /* amount of stubcc code generated */
-    double          codeLengthAugment; /* augment to inlineLength to be added
-                                          at runtime, represents instrumentation
-                                          taken out or common stubcc accounted
-                                          for (instead of just adding inlineLength) */
-};
-
-/*
- * Pools and patch locations for managing stubs for non-FASTCALL C++ calls made
- * from native call and PropertyOp stubs. Ownership of these may be transferred
- * into the orphanedNativePools for the compartment.
- */
-struct NativeCallStub {
-    /* PC for the stub. Native call stubs cannot be added for inline frames. */
-    jsbytecode *pc;
-
-    /* Pool for the stub, NULL if it has been removed from the script. */
-    JSC::ExecutablePool *pool;
-
-    /*
-     * Fallthrough jump returning to jitcode which may be patched during
-     * recompilation. On x64 this is an indirect jump to avoid issues with far
-     * jumps on relative branches.
-     */
-#ifdef JS_CPU_X64
-    JSC::CodeLocationDataLabelPtr jump;
-#else
-    JSC::CodeLocationJump jump;
-#endif
-};
-
-struct JITChunk
-{
-    typedef JSC::MacroAssemblerCodeRef CodeRef;
-    CodeRef         code;       /* pool & code addresses */
-
-    PCLengthEntry   *pcLengths;         /* lengths for outer and inline frames */
-
-    /*
-     * This struct has several variable-length sections that are allocated on
-     * the end:  nmaps, MICs, callICs, etc.  To save space -- worthwhile
-     * because JITScripts are common -- we only record their lengths.  We can
-     * find any of the sections from the lengths because we know their order.
-     * Therefore, do not change the section ordering in finishThisUp() without
-     * changing nMICs() et al as well.
-     */
-    uint32_t        nNmapPairs : 31;    /* The NativeMapEntrys are sorted by .bcOff.
-                                           .ncode values may not be NULL. */
-    uint32_t        nInlineFrames;
-    uint32_t        nCallSites;
-    uint32_t        nCompileTriggers;
-    uint32_t        nRootedTemplates;
-    uint32_t        nRootedRegExps;
-    uint32_t        nMonitoredBytecodes;
-    uint32_t        nTypeBarrierBytecodes;
-#ifdef JS_MONOIC
-    uint32_t        nGetGlobalNames;
-    uint32_t        nSetGlobalNames;
-    uint32_t        nCallICs;
-    uint32_t        nEqualityICs;
-#endif
-#ifdef JS_POLYIC
-    uint32_t        nGetElems;
-    uint32_t        nSetElems;
-    uint32_t        nPICs;
-#endif
-
-#ifdef JS_MONOIC
-    // Additional ExecutablePools that IC stubs were generated into.
-    typedef Vector<JSC::ExecutablePool *, 0, SystemAllocPolicy> ExecPoolVector;
-    ExecPoolVector execPools;
-#endif
-
-    types::RecompileInfo recompileInfo;
-
-    // Additional ExecutablePools for native call and getter stubs.
-    Vector<NativeCallStub, 0, SystemAllocPolicy> nativeCallStubs;
-
-    NativeMapEntry *nmap() const;
-    js::mjit::InlineFrame *inlineFrames() const;
-    js::mjit::CallSite *callSites() const;
-    js::mjit::CompileTrigger *compileTriggers() const;
-    JSObject **rootedTemplates() const;
-    RegExpShared **rootedRegExps() const;
-
-    /*
-     * Offsets of bytecodes which were monitored or had type barriers at the
-     * point of compilation. Used to avoid unnecessary recompilation after
-     * analysis purges.
-     */
-    uint32_t *monitoredBytecodes() const;
-    uint32_t *typeBarrierBytecodes() const;
-
-#ifdef JS_MONOIC
-    ic::GetGlobalNameIC *getGlobalNames() const;
-    ic::SetGlobalNameIC *setGlobalNames() const;
-    ic::CallICInfo *callICs() const;
-    ic::EqualityICInfo *equalityICs() const;
-#endif
-#ifdef JS_POLYIC
-    ic::GetElementIC *getElems() const;
-    ic::SetElementIC *setElems() const;
-    ic::PICInfo     *pics() const;
-#endif
-
-    bool isValidCode(void *ptr) {
-        char *jitcode = (char *)code.m_code.executableAddress();
-        char *jcheck = (char *)ptr;
-        return jcheck >= jitcode && jcheck < jitcode + code.m_size;
-    }
-
-    size_t computedSizeOfIncludingThis();
-    size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf);
-
-    ~JITChunk();
-
-    void trace(JSTracer *trc);
-    void purgeCaches();
-
-  private:
-    /* Helpers used to navigate the variable-length sections. */
-    char *commonSectionLimit() const;
-    char *monoICSectionsLimit() const;
-    char *polyICSectionsLimit() const;
-};
-
-void
-SetChunkLimit(uint32_t limit);
-
-/* Information about a compilation chunk within a script. */
-struct ChunkDescriptor
-{
-    /* Bytecode range of the chunk: [begin,end) */
-    uint32_t begin;
-    uint32_t end;
-
-    /* Use counter for the chunk. */
-    uint32_t counter;
-
-    /* Optional compiled code for the chunk. */
-    JITChunk *chunk;
-
-    ChunkDescriptor() { mozilla::PodZero(this); }
-};
-
-/* Jump or fallthrough edge in the bytecode which crosses a chunk boundary. */
-struct CrossChunkEdge
-{
-    /* Bytecode offsets of the source and target of the edge. */
-    uint32_t source;
-    uint32_t target;
-
-    /* Locations of the jump(s) for the source, NULL if not compiled. */
-    void *sourceJump1;
-    void *sourceJump2;
-
-#ifdef JS_CPU_X64
-    /*
-     * Location of a trampoline for the edge to perform an indirect jump if
-     * out of range, NULL if the source is not compiled.
-     */
-    void *sourceTrampoline;
-#endif
-
-    /* Any jump table entries along this edge. */
-    typedef Vector<void**,4,SystemAllocPolicy> JumpTableEntryVector;
-    JumpTableEntryVector *jumpTableEntries;
-
-    /* Location of the label for the target, NULL if not compiled. */
-    void *targetLabel;
-
-    /*
-     * Location of a shim which will transfer control to the interpreter at the
-     * target bytecode. The source jumps are patched to jump to this label if
-     * the source is compiled but not the target.
-     */
-    void *shimLabel;
-
-    CrossChunkEdge() { mozilla::PodZero(this); }
-};
-
-struct JITScript
-{
-    JSScript        *script;
-
-    void            *invokeEntry;       /* invoke address */
-    void            *fastEntry;         /* cached entry, fastest */
-    void            *arityCheckEntry;   /* arity check address */
-    void            *argsCheckEntry;    /* arguments check address */
-
-    /* List of inline caches jumping to the fastEntry. */
-    JSCList         callers;
-
-    uint32_t        nchunks;
-    uint32_t        nedges;
-
-    /*
-     * Pool for shims which transfer control to the interpreter on cross chunk
-     * edges to chunks which do not have compiled code.
-     */
-    JSC::ExecutablePool *shimPool;
-
-    /*
-     * Optional liveness information attached to the JITScript if the analysis
-     * information is purged while retaining JIT info.
-     */
-    analyze::ScriptLiveness *liveness;
-
-    /*
-     * Number of calls made to IonMonkey functions, used to avoid slow
-     * JM -> Ion calls.
-     */
-    uint32_t        ionCalls;
-
-    /*
-     * If set, we decided to keep the JITChunk so that Ion can access its caches.
-     * The chunk has to be destroyed the next time the script runs in JM.
-     * Note that this flag implies nchunks == 1.
-     */
-    bool mustDestroyEntryChunk;
-
-#ifdef JS_MONOIC
-    /* Inline cache at function entry for checking this/argument types. */
-    JSC::CodeLocationLabel argsCheckStub;
-    JSC::CodeLocationLabel argsCheckFallthrough;
-    JSC::CodeLocationJump  argsCheckJump;
-    JSC::ExecutablePool *argsCheckPool;
-    void resetArgsCheck();
-#endif
-
-    ChunkDescriptor &chunkDescriptor(unsigned i) {
-        JS_ASSERT(i < nchunks);
-        ChunkDescriptor *descs = (ChunkDescriptor *) ((char *) this + sizeof(JITScript));
-        return descs[i];
-    }
-
-    unsigned chunkIndex(jsbytecode *pc) {
-        unsigned offset = pc - script->code;
-        JS_ASSERT(offset < script->length);
-        for (unsigned i = 0; i < nchunks; i++) {
-            const ChunkDescriptor &desc = chunkDescriptor(i);
-            JS_ASSERT(desc.begin <= offset);
-            if (offset < desc.end)
-                return i;
-        }
-        JS_NOT_REACHED("Bad chunk layout");
-        return 0;
-    }
-
-    JITChunk *chunk(jsbytecode *pc) {
-        return chunkDescriptor(chunkIndex(pc)).chunk;
-    }
-
-    JITChunk *findCodeChunk(void *addr);
-
-    CrossChunkEdge *edges() {
-        return (CrossChunkEdge *) (&chunkDescriptor(0) + nchunks);
-    }
-
-    /* Patch any compiled sources in edge to jump to label. */
-    void patchEdge(const CrossChunkEdge &edge, void *label);
-
-    jsbytecode *nativeToPC(void *returnAddress, CallSite **pinline);
-
-    size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf);
-
-    void destroy(FreeOp *fop);
-    void destroyChunk(FreeOp *fop, unsigned chunkIndex, bool resetUses = true);
-
-    void trace(JSTracer *trc);
-    void purgeCaches();
-
-    void disableScriptEntry();
-};
-
-/*
- * Execute the given mjit code. This is a low-level call and callers must
- * provide the same guarantees as JaegerShot/CheckStackAndEnterMethodJIT.
- */
-JaegerStatus EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimit,
-                            bool partial);
-
-/* Execute a method that has been JIT compiled. */
-JaegerStatus JaegerShot(JSContext *cx, bool partial);
-
-/* Drop into the middle of a method at an arbitrary point, and execute. */
-JaegerStatus JaegerShotAtSafePoint(JSContext *cx, void *safePoint, bool partial);
-
-enum CompileStatus
-{
-    Compile_Okay,
-    Compile_Abort,        // abort compilation
-    Compile_InlineAbort,  // inlining attempt failed, continue compilation
-    Compile_Retry,        // static overflow or failed inline, try to recompile
-    Compile_Error,        // OOM
-    Compile_Skipped
-};
-
-void JS_FASTCALL
-ProfileStubCall(VMFrame &f);
-
-enum CompileRequest
-{
-    CompileRequest_Interpreter,
-    CompileRequest_JIT
-};
-
-CompileStatus
-CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
-             bool construct, CompileRequest request, StackFrame *sp);
-
-inline void
-ReleaseScriptCode(FreeOp *fop, JSScript *script)
-{
-    if (!script->hasMJITInfo())
-        return;
-
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            JSScript::JITScriptHandle *jith = script->jitHandle((bool) constructing, (bool) barriers);
-            if (jith && jith->isValid())
-                JSScript::ReleaseCode(fop, jith);
-        }
-    }
-
-    script->destroyMJITInfo(fop);
-}
-
-// Cripple any JIT code for the specified script, such that the next time
-// execution reaches the script's entry or the OSR PC the script's code will
-// be destroyed.
-void
-DisableScriptCodeForIon(JSScript *script, jsbytecode *osrPC);
-
-// Expand all stack frames inlined by the JIT within a compartment.
-void
-ExpandInlineFrames(JS::Zone *zone);
-
-// Return all VMFrames in a compartment to the interpreter. This must be
-// followed by destroying all JIT code in the compartment.
-void
-ClearAllFrames(JS::Zone *zone);
-
-// Information about a frame inlined during compilation.
-struct InlineFrame
-{
-    InlineFrame *parent;
-    jsbytecode *parentpc;
-    HeapPtrFunction fun;
-
-    // Total distance between the start of the outer JSStackFrame and the start
-    // of this frame, in multiples of sizeof(Value).
-    uint32_t depth;
-};
-
-struct CallSite
-{
-    uint32_t codeOffset;
-    uint32_t inlineIndex;
-    uint32_t pcOffset;
-    RejoinState rejoin;
-
-    void initialize(uint32_t codeOffset, uint32_t inlineIndex, uint32_t pcOffset,
-                    RejoinState rejoin) {
-        this->codeOffset = codeOffset;
-        this->inlineIndex = inlineIndex;
-        this->pcOffset = pcOffset;
-        this->rejoin = rejoin;
-    }
-
-    bool isTrap() const {
-        return rejoin == REJOIN_TRAP;
-    }
-};
-
-// Information about a check inserted into the script for triggering Ion
-// compilation at a function or loop entry point.
-struct CompileTrigger
-{
-    uint32_t pcOffset;
-
-    // Offsets into the generated code of the conditional jump in the inline
-    // path and the start of the sync code for the trigger call in the out of
-    // line path.
-    JSC::CodeLocationJump inlineJump;
-    JSC::CodeLocationLabel stubLabel;
-
-    void initialize(uint32_t pcOffset, JSC::CodeLocationJump inlineJump, JSC::CodeLocationLabel stubLabel) {
-        this->pcOffset = pcOffset;
-        this->inlineJump = inlineJump;
-        this->stubLabel = stubLabel;
-    }
-};
-
-void
-DumpAllProfiles(JSContext *cx);
-
-inline void * bsearch_nmap(NativeMapEntry *nmap, size_t nPairs, size_t bcOff)
-{
-    size_t lo = 1, hi = nPairs;
-    while (1) {
-        /* current unsearched space is from lo-1 to hi-1, inclusive. */
-        if (lo > hi)
-            return NULL; /* not found */
-        size_t mid       = (lo + hi) / 2;
-        size_t bcOff_mid = nmap[mid-1].bcOff;
-        if (bcOff < bcOff_mid) {
-            hi = mid-1;
-            continue;
-        }
-        if (bcOff > bcOff_mid) {
-            lo = mid+1;
-            continue;
-        }
-        return nmap[mid-1].ncode;
-    }
-}
-
-static inline bool
-IsLowerableFunCallOrApply(jsbytecode *pc)
-{
-#ifdef JS_MONOIC
-    return (*pc == JSOP_FUNCALL && GET_ARGC(pc) >= 1) ||
-           (*pc == JSOP_FUNAPPLY && GET_ARGC(pc) == 2);
-#else
-    return false;
-#endif
-}
-
-Shape *
-GetPICSingleShape(JSContext *cx, JSScript *script, jsbytecode *pc, bool constructing);
-
-static inline void
-PurgeCaches(JSScript *script)
-{
-    for (int constructing = 0; constructing <= 1; constructing++) {
-        for (int barriers = 0; barriers <= 1; barriers++) {
-            mjit::JITScript *jit = script->getJIT((bool) constructing, (bool) barriers);
-            if (jit)
-                jit->purgeCaches();
-        }
-    }
-}
-
-} /* namespace mjit */
-
-inline mjit::JITChunk *
-VMFrame::chunk()
-{
-    return jit()->chunk(regs.pc);
-}
-
-inline unsigned
-VMFrame::chunkIndex()
-{
-    return jit()->chunkIndex(regs.pc);
-}
-
-inline JSScript *
-VMFrame::script()
-{
-    if (regs.inlined())
-        return chunk()->inlineFrames()[regs.inlined()->inlineIndex].fun->nonLazyScript();
-    return fp()->script();
-}
-
-inline jsbytecode *
-VMFrame::pc()
-{
-    if (regs.inlined())
-        return script()->code + regs.inlined()->pcOffset;
-    return regs.pc;
-}
-
-} /* namespace js */
-
-inline void *
-JSScript::nativeCodeForPC(bool constructing, jsbytecode *pc)
-{
-    js::mjit::JITScript *jit = getJIT(constructing, zone()->compileBarriers());
-    if (!jit)
-        return NULL;
-    js::mjit::JITChunk *chunk = jit->chunk(pc);
-    if (!chunk)
-        return NULL;
-    return bsearch_nmap(chunk->nmap(), chunk->nNmapPairs, (size_t)(pc - code));
-}
-
-extern "C" void JaegerTrampolineReturn();
-extern "C" void JaegerInterpoline();
-extern "C" void JaegerInterpolineScripted();
-
-#if defined(_MSC_VER) || defined(_WIN64)
-extern "C" void *JaegerThrowpoline(js::VMFrame *vmFrame);
-#else
-extern "C" void JaegerThrowpoline();
-#endif
-
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-extern "C" void JaegerInterpolinePatched();
-#endif
-
-#endif /* jsjaeger_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/MonoIC.cpp
+++ /dev/null
@@ -1,1550 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "jscntxt.h"
-#include "jsnum.h"
-#include "jsobj.h"
-
-#include "assembler/assembler/CodeLocation.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "assembler/assembler/MacroAssembler.h"
-#include "builtin/RegExp.h"
-#ifdef JS_ION
-# include "ion/IonMacroAssembler.h"
-#endif
-#include "methodjit/CodeGenIncludes.h"
-#include "methodjit/Compiler.h"
-#include "methodjit/ICRepatcher.h"
-#include "methodjit/InlineFrameAssembler.h"
-#include "methodjit/MonoIC.h"
-#include "methodjit/PolyIC.h"
-#include "methodjit/StubCalls.h"
-#include "vm/Shape.h"
-
-#include "jsinterpinlines.h"
-#include "jsobjinlines.h"
-#include "jsscriptinlines.h"
-
-#include "methodjit/StubCalls-inl.h"
-#include "vm/Shape-inl.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::mjit::ic;
-
-typedef JSC::MacroAssembler::RegisterID RegisterID;
-typedef JSC::MacroAssembler::Address Address;
-typedef JSC::MacroAssembler::Jump Jump;
-typedef JSC::MacroAssembler::Imm32 Imm32;
-typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-typedef JSC::MacroAssembler::Call Call;
-typedef JSC::MacroAssembler::Label Label;
-typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
-typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
-
-#if defined JS_MONOIC
-
-static void
-PatchGetFallback(VMFrame &f, ic::GetGlobalNameIC *ic)
-{
-    Repatcher repatch(f.chunk());
-    JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, stubs::Name));
-    repatch.relink(ic->slowPathCall, fptr);
-}
-
-void JS_FASTCALL
-ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
-{
-    RootedObject obj(f.cx, &f.fp()->global());
-    PropertyName *name = f.script()->getName(GET_UINT32_INDEX(f.pc()));
-
-    RecompilationMonitor monitor(f.cx);
-
-    uint32_t slot;
-    {
-        RootedId id(f.cx, NameToId(name));
-        RootedShape shape(f.cx, obj->nativeLookup(f.cx, id));
-
-        if (monitor.recompiled()) {
-            stubs::Name(f);
-            return;
-        }
-
-        if (!shape ||
-            !shape->hasDefaultGetter() ||
-            !shape->hasSlot())
-        {
-            if (shape)
-                PatchGetFallback(f, ic);
-            stubs::Name(f);
-            return;
-        }
-        slot = shape->slot();
-
-        /* Patch shape guard. */
-        Repatcher repatcher(f.chunk());
-        repatcher.repatch(ic->fastPathStart.dataLabelPtrAtOffset(ic->shapeOffset), obj->lastProperty());
-
-        /* Patch loads. */
-        uint32_t index = obj->dynamicSlotIndex(slot);
-        JSC::CodeLocationLabel label = ic->fastPathStart.labelAtOffset(ic->loadStoreOffset);
-        repatcher.patchAddressOffsetForValueLoad(label, index * sizeof(Value));
-    }
-
-    /* Do load anyway... this time. */
-    stubs::Name(f);
-}
-
-static void JS_FASTCALL
-DisabledSetGlobal(VMFrame &f, ic::SetGlobalNameIC *ic)
-{
-    RootedPropertyName name(f.cx, f.script()->getName(GET_UINT32_INDEX(f.pc())));
-    stubs::SetName(f, name);
-}
-
-static void
-PatchSetFallback(VMFrame &f, ic::SetGlobalNameIC *ic)
-{
-    Repatcher repatch(f.chunk());
-    VoidStubSetGlobal stub = DisabledSetGlobal;
-    JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, stub));
-    repatch.relink(ic->slowPathCall, fptr);
-}
-
-void
-SetGlobalNameIC::patchInlineShapeGuard(Repatcher &repatcher, Shape *shape)
-{
-    JSC::CodeLocationDataLabelPtr label = fastPathStart.dataLabelPtrAtOffset(shapeOffset);
-    repatcher.repatch(label, shape);
-}
-
-static LookupStatus
-UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, Shape *shape)
-{
-    /* Give globals a chance to appear. */
-    if (!shape)
-        return Lookup_Uncacheable;
-
-    if (!shape->hasDefaultSetter() ||
-        !shape->writable() ||
-        !shape->hasSlot() ||
-        obj->watched())
-    {
-        /* Disable the IC for weird shape attributes and watchpoints. */
-        PatchSetFallback(f, ic);
-        return Lookup_Uncacheable;
-    }
-
-    /* Object is not branded, so we can use the inline path. */
-    Repatcher repatcher(f.chunk());
-    ic->patchInlineShapeGuard(repatcher, obj->lastProperty());
-
-    uint32_t index = obj->dynamicSlotIndex(shape->slot());
-    JSC::CodeLocationLabel label = ic->fastPathStart.labelAtOffset(ic->loadStoreOffset);
-    repatcher.patchAddressOffsetForValueStore(label, index * sizeof(Value),
-                                              ic->vr.isTypeKnown());
-
-    return Lookup_Cacheable;
-}
-
-void JS_FASTCALL
-ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
-{
-    RootedObject obj(f.cx, &f.fp()->global());
-    RootedPropertyName name(f.cx, f.script()->getName(GET_UINT32_INDEX(f.pc())));
-
-    RecompilationMonitor monitor(f.cx);
-
-    {
-        RootedId id(f.cx, NameToId(name));
-        Shape *shape = obj->nativeLookup(f.cx, id);
-
-        if (!monitor.recompiled()) {
-            LookupStatus status = UpdateSetGlobalName(f, ic, obj, shape);
-            if (status == Lookup_Error)
-                THROW();
-        }
-    }
-
-    stubs::SetName(f, name);
-}
-
-class EqualityICLinker : public LinkerHelper
-{
-    VMFrame &f;
-
-  public:
-    EqualityICLinker(Assembler &masm, VMFrame &f)
-        : LinkerHelper(masm, JSC::JAEGER_CODE), f(f)
-    { }
-
-    bool init(JSContext *cx) {
-        JSC::ExecutablePool *pool = LinkerHelper::init(cx);
-        if (!pool)
-            return false;
-        JS_ASSERT(!f.regs.inlined());
-        if (!f.chunk()->execPools.append(pool)) {
-            markVerified();
-            pool->release();
-            js_ReportOutOfMemory(cx);
-            return false;
-        }
-        return true;
-    }
-};
-
-/* Rough over-estimate of how much memory we need to unprotect. */
-static const uint32_t INLINE_PATH_LENGTH = 64;
-
-class EqualityCompiler : public BaseCompiler
-{
-    VMFrame &f;
-    EqualityICInfo &ic;
-
-    Vector<Jump, 4, SystemAllocPolicy> jumpList;
-    Jump trueJump;
-    Jump falseJump;
-
-  public:
-    EqualityCompiler(VMFrame &f, EqualityICInfo &ic)
-        : BaseCompiler(f.cx), f(f), ic(ic), jumpList(SystemAllocPolicy())
-    {
-    }
-
-    void linkToStub(Jump j)
-    {
-        jumpList.append(j);
-    }
-
-    void linkTrue(Jump j)
-    {
-        trueJump = j;
-    }
-
-    void linkFalse(Jump j)
-    {
-        falseJump = j;
-    }
-
-    void generateStringPath(Assembler &masm)
-    {
-        const ValueRemat &lvr = ic.lvr;
-        const ValueRemat &rvr = ic.rvr;
-
-        JS_ASSERT_IF(lvr.isConstant(), lvr.isType(JSVAL_TYPE_STRING));
-        JS_ASSERT_IF(rvr.isConstant(), rvr.isType(JSVAL_TYPE_STRING));
-
-        if (!lvr.isType(JSVAL_TYPE_STRING)) {
-            Jump lhsFail = masm.testString(Assembler::NotEqual, lvr.typeReg());
-            linkToStub(lhsFail);
-        }
-
-        if (!rvr.isType(JSVAL_TYPE_STRING)) {
-            Jump rhsFail = masm.testString(Assembler::NotEqual, rvr.typeReg());
-            linkToStub(rhsFail);
-        }
-
-        RegisterID tmp = ic.tempReg;
-
-        /* JSString::isAtom === (lengthAndFlags & ATOM_BIT) */
-        Imm32 atomBit(JSString::ATOM_BIT);
-
-        masm.load32(Address(lvr.dataReg(), JSString::offsetOfLengthAndFlags()), tmp);
-        Jump lhsNotAtomized = masm.branchTest32(Assembler::Zero, tmp, atomBit);
-        linkToStub(lhsNotAtomized);
-
-        if (!rvr.isConstant()) {
-            masm.load32(Address(rvr.dataReg(), JSString::offsetOfLengthAndFlags()), tmp);
-            Jump rhsNotAtomized = masm.branchTest32(Assembler::Zero, tmp, atomBit);
-            linkToStub(rhsNotAtomized);
-        }
-
-        if (rvr.isConstant()) {
-            JSString *str = rvr.value().toString();
-            JS_ASSERT(str->isAtom());
-            Jump test = masm.branchPtr(ic.cond, lvr.dataReg(), ImmPtr(str));
-            linkTrue(test);
-        } else {
-            Jump test = masm.branchPtr(ic.cond, lvr.dataReg(), rvr.dataReg());
-            linkTrue(test);
-        }
-
-        Jump fallthrough = masm.jump();
-        linkFalse(fallthrough);
-    }
-
-    void generateObjectPath(Assembler &masm)
-    {
-        ValueRemat &lvr = ic.lvr;
-        ValueRemat &rvr = ic.rvr;
-
-        if (!lvr.isConstant() && !lvr.isType(JSVAL_TYPE_OBJECT)) {
-            Jump lhsFail = masm.testObject(Assembler::NotEqual, lvr.typeReg());
-            linkToStub(lhsFail);
-        }
-
-        if (!rvr.isConstant() && !rvr.isType(JSVAL_TYPE_OBJECT)) {
-            Jump rhsFail = masm.testObject(Assembler::NotEqual, rvr.typeReg());
-            linkToStub(rhsFail);
-        }
-
-        if (rvr.isConstant()) {
-            JSObject *obj = &rvr.value().toObject();
-            Jump test = masm.branchPtr(ic.cond, lvr.dataReg(), ImmPtr(obj));
-            linkTrue(test);
-        } else {
-            Jump test = masm.branchPtr(ic.cond, lvr.dataReg(), rvr.dataReg());
-            linkTrue(test);
-        }
-
-        Jump fallthrough = masm.jump();
-        linkFalse(fallthrough);
-    }
-
-    bool linkForIC(Assembler &masm)
-    {
-        EqualityICLinker buffer(masm, f);
-        if (!buffer.init(cx))
-            return false;
-
-        Repatcher repatcher(f.chunk());
-
-        /* Overwrite the call to the IC with a call to the stub. */
-        JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, ic.stub));
-        repatcher.relink(ic.stubCall, fptr);
-
-        // Silently fail, the IC is disabled now.
-        if (!buffer.verifyRange(f.chunk()))
-            return true;
-
-        /* Set the targets of all type test failures to go to the stub. */
-        for (size_t i = 0; i < jumpList.length(); i++)
-            buffer.link(jumpList[i], ic.stubEntry);
-        jumpList.clear();
-
-        /* Set the targets for the the success and failure of the actual equality test. */
-        buffer.link(trueJump, ic.target);
-        buffer.link(falseJump, ic.fallThrough);
-
-        CodeLocationLabel cs = buffer.finalize(f);
-
-        /* Jump to the newly generated code instead of to the IC. */
-        repatcher.relink(ic.jumpToStub, cs);
-
-        return true;
-    }
-
-    bool update()
-    {
-        if (!ic.generated) {
-            MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-            Assembler masm(&sps, &f);
-            Value rval = f.regs.sp[-1];
-            Value lval = f.regs.sp[-2];
-
-            if (rval.isObject() && lval.isObject()) {
-                generateObjectPath(masm);
-                ic.generated = true;
-            } else if (rval.isString() && lval.isString()) {
-                generateStringPath(masm);
-                ic.generated = true;
-            } else {
-                return true;
-            }
-
-            return linkForIC(masm);
-        }
-
-        return true;
-    }
-};
-
-JSBool JS_FASTCALL
-ic::Equality(VMFrame &f, ic::EqualityICInfo *ic)
-{
-    EqualityCompiler cc(f, *ic);
-    if (!cc.update())
-        THROWV(JS_FALSE);
-
-    return ic->stub(f);
-}
-
-// Disable PGO as a precaution (see bug 791214).
-#if defined(_MSC_VER)
-# pragma optimize("g", off)
-#endif
-
-static void * JS_FASTCALL
-SlowCallFromIC(VMFrame &f, ic::CallICInfo *ic)
-{
-    stubs::SlowCall(f, ic->frameSize.getArgc(f));
-    return NULL;
-}
-
-static void * JS_FASTCALL
-SlowNewFromIC(VMFrame &f, ic::CallICInfo *ic)
-{
-    stubs::SlowNew(f, ic->frameSize.staticArgc());
-    return NULL;
-}
-
-bool
-NativeStubLinker::init(JSContext *cx)
-{
-    JSC::ExecutablePool *pool = LinkerHelper::init(cx);
-    if (!pool)
-        return false;
-
-    NativeCallStub stub;
-    stub.pc = pc;
-    stub.pool = pool;
-    stub.jump = locationOf(done);
-    if (!chunk->nativeCallStubs.append(stub)) {
-        markVerified();
-        pool->release();
-        return false;
-    }
-
-    return true;
-}
-
-/*
- * Generate epilogue code to run after a stub ABI call to a native or getter.
- * This checks for an exception, and either type checks the result against the
- * observed types for the opcode or loads the result into a register pair
- * (it will go through a type barrier afterwards).
- */
-bool
-mjit::NativeStubEpilogue(VMFrame &f, Assembler &masm, NativeStubLinker::FinalJump *result,
-                         int32_t initialFrameDepth, int32_t vpOffset,
-                         MaybeRegisterID typeReg, MaybeRegisterID dataReg)
-{
-    /* Reload fp, which may have been clobbered by restoreStackBase(). */
-    masm.loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
-
-    Jump hasException = masm.branchTest32(Assembler::Zero, Registers::ReturnReg,
-                                          Registers::ReturnReg);
-
-    Address resultAddress(JSFrameReg, vpOffset);
-
-    Vector<Jump> mismatches(f.cx);
-    if (f.cx->typeInferenceEnabled() && !typeReg.isSet()) {
-        /*
-         * Test the result of this native against the known result type set for
-         * the call. We don't assume knowledge about the types that natives can
-         * return, except when generating specialized paths in FastBuiltins.
-         */
-        types::TypeSet *types = types::TypeScript::BytecodeTypes(f.script(), f.pc());
-        if (!masm.generateTypeCheck(f.cx, resultAddress, types, &mismatches))
-            THROWV(false);
-    }
-
-    /*
-     * Can no longer trigger recompilation in this stub, clear the stub rejoin
-     * on the VMFrame.
-     */
-    masm.storePtr(ImmPtr(NULL), FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-    if (typeReg.isSet())
-        masm.loadValueAsComponents(resultAddress, typeReg.reg(), dataReg.reg());
-
-    /*
-     * The final jump is a indirect on x64, so that we'll always be able
-     * to repatch it to the interpoline later.
-     */
-    Label finished = masm.label();
-#ifdef JS_CPU_X64
-    JSC::MacroAssembler::DataLabelPtr done = masm.moveWithPatch(ImmPtr(NULL), Registers::ValueReg);
-    masm.jump(Registers::ValueReg);
-#else
-    Jump done = masm.jump();
-#endif
-
-    /* Generate a call for type check failures on the native result. */
-    if (!mismatches.empty()) {
-        for (unsigned i = 0; i < mismatches.length(); i++)
-            mismatches[i].linkTo(masm.label(), &masm);
-        masm.addPtr(Imm32(vpOffset), JSFrameReg, Registers::ArgReg1);
-        masm.fallibleVMCall(true, JS_FUNC_TO_DATA_PTR(void *, stubs::TypeBarrierReturn),
-                            f.regs.pc, NULL, initialFrameDepth);
-        masm.storePtr(ImmPtr(NULL), FrameAddress(offsetof(VMFrame, stubRejoin)));
-        masm.jump().linkTo(finished, &masm);
-    }
-
-    /* Move JaegerThrowpoline into register for very far jump on x64. */
-    hasException.linkTo(masm.label(), &masm);
-    masm.storePtr(ImmPtr(NULL), FrameAddress(offsetof(VMFrame, stubRejoin)));
-    masm.throwInJIT();
-
-    *result = done;
-    return true;
-}
-
-/*
- * Calls have an inline path and an out-of-line path. The inline path is used
- * in the fastest case: the method has JIT'd code, and |argc == nargs|.
- *
- * The inline path and OOL path are separated by a guard on the identity of
- * the callee object. This guard starts as NULL and always fails on the first
- * hit. On the OOL path, the callee is verified to be both a function and a
- * scripted function. If these conditions hold, |ic::Call| is invoked.
- *
- * |ic::Call| first ensures that the callee has JIT code. If it doesn't, the
- * call to |ic::Call| is patched to a slow path. If it does have JIT'd code,
- * the following cases can occur:
- *
- *   1) args != nargs: The call to |ic::Call| is patched with a dynamically
- *      generated stub. This stub inlines a path that looks like:
- *      ----
- *      push frame
- *      if (callee is not compiled) {
- *          Compile(callee);
- *      }
- *      call callee->arityLabel
- *
- *      The arity label is a special entry point for correcting frames for
- *      arity mismatches.
- *
- *   2) args == nargs, and the inline call site was not patched yet.
- *      The guard dividing the two paths is patched to guard on the given
- *      function object identity, and the proceeding call is patched to
- *      directly call the JIT code.
- *
- *   3) args == nargs, and the inline call site was patched already.
- *      A small stub is created which extends the original guard to also
- *      guard on the JSFunction lying underneath the function object.
- *
- * If the OOL path does not have a scripted function, but does have a
- * scripted native, then a small stub is generated which inlines the native
- * invocation.
- */
-namespace js {
-namespace mjit {
-
-class CallCompiler : public BaseCompiler
-{
-    VMFrame &f;
-    CallICInfo &ic;
-    bool callingNew;
-
-  public:
-    CallCompiler(VMFrame &f, CallICInfo &ic, bool callingNew)
-      : BaseCompiler(f.cx), f(f), ic(ic), callingNew(callingNew)
-    {
-    }
-
-    JSC::ExecutablePool *poolForSize(LinkerHelper &linker, CallICInfo::PoolIndex index)
-    {
-        JSC::ExecutablePool *ep = linker.init(f.cx);
-        if (!ep)
-            return NULL;
-        JS_ASSERT(!ic.pools[index]);
-        ic.pools[index] = ep;
-        return ep;
-    }
-
-    void disable()
-    {
-        JSC::CodeLocationCall oolCall = ic.slowPathStart.callAtOffset(ic.oolCallOffset);
-        Repatcher repatch(f.chunk());
-        JSC::FunctionPtr fptr = callingNew
-                                ? JSC::FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, SlowNewFromIC))
-                                : JSC::FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, SlowCallFromIC));
-        repatch.relink(oolCall, fptr);
-    }
-
-#ifdef JS_ION
-    bool generateIonStub()
-    {
-        RecompilationMonitor monitor(cx);
-
-        /*
-         * When IonMonkey is enabled we never inline in JM. So do not cause any
-         * recompilation by setting the UNINLINEABLE flag.
-         */
-        JS_ASSERT(!f.regs.inlined());
-
-        Assembler masm;
-        Registers regs(Registers::AvailRegs);
-
-        /* Reserve this, so we don't take something setupFallibleABICall will use. */
-        regs.takeReg(Registers::ClobberInCall);
-
-        /* If we might clobber |ic.funObjReg| later, save it now. */
-        RegisterID funObjReg = ic.funObjReg;
-        if (funObjReg == Registers::ClobberInCall) {
-            funObjReg = regs.takeAnyReg().reg();
-            masm.move(ic.funObjReg, funObjReg);
-        } else {
-            /* Make sure no temporaries collide. */
-            regs.takeReg(funObjReg);
-        }
-
-        size_t argc = ic.frameSize.staticArgc();
-
-        /* Load fun->u.i.script->ion */
-        RegisterID ionScript = regs.takeAnyReg().reg();
-        Address scriptAddr(funObjReg, JSFunction::offsetOfNativeOrScript());
-        masm.loadPtr(scriptAddr, ionScript);
-        masm.loadPtr(Address(ionScript, offsetof(JSScript, ion)), ionScript);
-
-        /* Guard that the ion pointer is valid. */
-        Jump noIonCode = masm.branchPtr(Assembler::BelowOrEqual, ionScript,
-                                        ImmPtr(ION_COMPILING_SCRIPT));
-
-        RegisterID t0 = regs.takeAnyReg().reg();
-        RegisterID t1 = Registers::ClobberInCall;
-
-        masm.move(ImmPtr(f.regs.pc), t1);
-
-        /* Set the CALLING_INTO_ION flag on the existing frame. */
-        masm.load32(Address(JSFrameReg, StackFrame::offsetOfFlags()), t0);
-        masm.or32(Imm32(StackFrame::CALLING_INTO_ION), t0);
-        masm.store32(t0, Address(JSFrameReg, StackFrame::offsetOfFlags()));
-
-        /* Store the entry fp and calling pc into the IonActivation. */
-        masm.loadPtr(&cx->mainThread().ionActivation, t0);
-        masm.storePtr(JSFrameReg, Address(t0, ion::IonActivation::offsetOfEntryFp()));
-        masm.storePtr(t1, Address(t0, ion::IonActivation::offsetOfPrevPc()));
-
-        /* Store critical fields in the VMFrame. This clobbers |t1|. */
-        int32_t storeFrameDepth = ic.frameSize.staticLocalSlots();
-        masm.storePtr(ImmPtr((void *)ic.frameSize.rejoinState(f.pc(), true)),
-                      FrameAddress(offsetof(VMFrame, stubRejoin)));
-        masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, storeFrameDepth);
-
-#ifdef JS_PUNBOX64
-        /* On X64, we must save the value mask registers, since Ion clobbers all. */
-        masm.push(Registers::TypeMaskReg);
-        masm.push(Registers::PayloadMaskReg);
-#endif
-
-        /*
-         * We manually push onto the stack:
-         *
-         *   [argv]
-         *   thisv
-         *   argc
-         *   callee
-         *   frameDescriptor
-         */
-        size_t staticPushed =
-            (sizeof(Value) * (argc + 1)) +
-            sizeof(uintptr_t) +
-            sizeof(uintptr_t) +
-            sizeof(uintptr_t);
-
-        /*
-         * Factoring in the return address, which is pushed implicitly, Ion
-         * requires that at its prologue, the stack is 8-byte aligned.
-         */
-        JS_ASSERT(ComputeByteAlignment(staticPushed + sizeof(uintptr_t), 8) == 0);
-
-        /*
-         * Alas, we may push more arguments dynamically if we need to fill in
-         * missing formal arguments with |undefined|. Reserve a register for
-         * that, which will be used to compute the frame descriptor.
-         *
-         * Note that we subtract the stack budget for the descriptor, since it
-         * is popped before decoded.
-         */
-        RegisterID stackPushed = regs.takeAnyReg().reg();
-        masm.move(Imm32(staticPushed - sizeof(uintptr_t)), stackPushed);
-
-        /*
-         * Check whether argc < nargs, because if so, we need to pad the stack.
-         *
-         * The stack is incoming with 16-byte alignment - this is guaranteed
-         * by the VMFrame. On all systems, we push four words as part of the
-         * frame, and each Value is eight bytes. This means the stack is
-         * always eight-byte aligned in the prologue of IonMonkey functions,
-         * which is the alignment it needs.
-         */
-        masm.load16(Address(funObjReg, offsetof(JSFunction, nargs)), t0);
-        Jump noPadding = masm.branch32(Assembler::BelowOrEqual, t0, Imm32(argc));
-        {
-            /* Compute the number of |undefined| values to push. */
-            masm.sub32(Imm32(argc), t0);
-
-            /* Factor this dynamic stack into our stack budget. */
-            JS_STATIC_ASSERT(sizeof(Value) == 8);
-            masm.move(t0, t1);
-            masm.lshift32(Imm32(3), t1);
-            masm.add32(t1, stackPushed);
-
-            Label loop = masm.label();
-            masm.subPtr(Imm32(sizeof(Value)), Registers::StackPointer);
-            masm.storeValue(UndefinedValue(), Address(Registers::StackPointer, 0));
-            Jump test = masm.branchSub32(Assembler::NonZero, Imm32(1), t0);
-            test.linkTo(loop, &masm);
-        }
-        noPadding.linkTo(masm.label(), &masm);
-
-        /* Find the end of the argument list. */
-        size_t spOffset = sizeof(StackFrame) +
-                          ic.frameSize.staticLocalSlots() * sizeof(Value);
-        masm.addPtr(Imm32(spOffset), JSFrameReg, t0);
-
-        /* Copy all remaining arguments. */
-        for (size_t i = 0; i < argc + 1; i++) {
-            /* Copy the argument onto the native stack. */
-#ifdef JS_NUNBOX32
-            masm.push(Address(t0, -int32_t((i + 1) * sizeof(Value)) + 4));
-            masm.push(Address(t0, -int32_t((i + 1) * sizeof(Value))));
-#elif defined JS_PUNBOX64
-            masm.push(Address(t0, -int32_t((i + 1) * sizeof(Value))));
-#endif
-        }
-
-        /* Push argc and calleeToken. */
-        masm.push(Imm32(argc));
-        masm.push(funObjReg);
-
-        /* Make and push a frame descriptor. */
-        masm.lshiftPtr(Imm32(ion::FRAMESIZE_SHIFT), stackPushed);
-        masm.orPtr(Imm32(ion::IonFrame_Entry), stackPushed);
-        masm.push(stackPushed);
-
-        /* Call into Ion. */
-        masm.loadPtr(Address(ionScript, ion::IonScript::offsetOfMethod()), t0);
-#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
-        masm.loadPtr(Address(t0, ion::IonCode::offsetOfCode()), t0);
-        masm.call(t0);
-#elif defined(JS_CPU_ARM)
-        masm.loadPtr(Address(t0, ion::IonCode::offsetOfCode()), JSC::ARMRegisters::ip);
-        masm.callAddress(JS_FUNC_TO_DATA_PTR(void *, IonVeneer));
-#endif
-
-        /* Pop arugments off the stack. */
-        masm.pop(Registers::ReturnReg);
-        masm.rshift32(Imm32(ion::FRAMESIZE_SHIFT), Registers::ReturnReg);
-        masm.addPtr(Registers::ReturnReg, Registers::StackPointer);
-
-#ifdef JS_PUNBOX64
-        /* On X64, we must save the value mask registers, since Ion clobbers all. */
-        masm.pop(Registers::PayloadMaskReg);
-        masm.pop(Registers::TypeMaskReg);
-#endif
-
-        /* Grab the original JSFrameReg. */
-        masm.loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
-
-        /* We need to grab two temporaries, so make sure the rval is safe. */
-        regs = Registers(Registers::AvailRegs);
-        regs.takeRegUnchecked(JSReturnReg_Type);
-        regs.takeRegUnchecked(JSReturnReg_Data);
-
-        /*
-         * Immediately take the Ion return value and copy it to JM's return
-         * registers. Note that we also store the value into the stack in case
-         * of recompilation, since the value cannot be recovered from registers.
-         */
-        Address rval(JSFrameReg, spOffset - ((argc + 2) * sizeof(Value)));
-#ifdef JS_NUNBOX32
-        RegisterID ionReturnType = (RegisterID)ion::JSReturnReg_Type.code();
-        RegisterID ionReturnData = (RegisterID)ion::JSReturnReg_Data.code();
-
-        /* None of these registers may overlap. */
-        JS_ASSERT(ionReturnType != JSReturnReg_Type);
-        JS_ASSERT(ionReturnType != JSReturnReg_Data);
-        JS_ASSERT(ionReturnType != JSFrameReg);
-        JS_ASSERT(ionReturnData != JSReturnReg_Type);
-        JS_ASSERT(ionReturnData != JSReturnReg_Data);
-        JS_ASSERT(ionReturnData != JSFrameReg);
-
-        masm.move(ionReturnType, JSReturnReg_Type);
-        masm.move(ionReturnData, JSReturnReg_Data);
-        masm.storeValueFromComponents(JSReturnReg_Type, JSReturnReg_Data, rval);
-#elif JS_PUNBOX64
-        RegisterID ionReturn = (RegisterID)ion::JSReturnReg.code();
-
-        /* None of these registers may overlap. */
-        JS_ASSERT(ionReturn != JSReturnReg_Type);
-        JS_ASSERT(ionReturn != JSReturnReg_Data);
-        JS_ASSERT(ionReturn != JSFrameReg);
-
-        masm.move(ionReturn, JSReturnReg_Type);
-
-        masm.storePtr(JSReturnReg_Type, rval);
-        masm.move(Registers::PayloadMaskReg, JSReturnReg_Data);
-        masm.andPtr(JSReturnReg_Type, JSReturnReg_Data);
-        masm.xorPtr(JSReturnReg_Data, JSReturnReg_Type);
-#endif
-
-        /* Unset VMFrame::stubRejoin. */
-        masm.storePtr(ImmPtr(NULL), FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-        /* Unset IonActivation::entryfp. */
-        t0 = regs.takeAnyReg().reg();
-        masm.loadPtr(&cx->mainThread().ionActivation, t0);
-        masm.storePtr(ImmPtr(NULL), Address(t0, ion::IonActivation::offsetOfEntryFp()));
-        masm.storePtr(ImmPtr(NULL), Address(t0, ion::IonActivation::offsetOfPrevPc()));
-
-        /* Unset CALLING_INTO_ION on the JS stack frame. */
-        masm.load32(Address(JSFrameReg, StackFrame::offsetOfFlags()), t0);
-        masm.and32(Imm32(~StackFrame::CALLING_INTO_ION), t0);
-        masm.store32(t0, Address(JSFrameReg, StackFrame::offsetOfFlags()));
-
-        /* Check for an exception. */
-        Jump exception = masm.testMagic(Assembler::Equal, JSReturnReg_Type);
-
-        /* If no exception, jump to the return address. */
-        NativeStubLinker::FinalJump done;
-#ifdef JS_CPU_X64
-        done = masm.moveWithPatch(ImmPtr(NULL), Registers::ValueReg);
-        masm.jump(Registers::ValueReg);
-#else
-        done = masm.jump();
-#endif
-
-        /* Otherwise, throw. */
-        exception.linkTo(masm.label(), &masm);
-        masm.throwInJIT();
-
-        NativeStubLinker linker(masm, f.chunk(), f.regs.pc, done);
-        if (!linker.init(f.cx))
-            return false;
-
-        if (!linker.verifyRange(f.chunk())) {
-            disable();
-            return true;
-        }
-
-        linker.link(noIonCode, ic.icCall());
-        linker.patchJump(ic.ionJoinPoint());
-        JSC::CodeLocationLabel cs = linker.finalize(f);
-
-        ic.updateLastOolJump(linker.locationOf(noIonCode),
-                             JITCode(cs.executableAddress(), linker.size()));
-        ic.hasIonStub_ = true;
-
-        JaegerSpew(JSpew_PICs, "generated ION stub %p (%lu bytes)\n", cs.executableAddress(),
-                   (unsigned long) masm.size());
-
-        Repatcher repatch(f.chunk());
-        repatch.relink(ic.oolJump(), cs);
-
-        return true;
-    }
-#endif
-
-    bool generateFullCallStub(JSScript *script, uint32_t flags)
-    {
-        /*
-         * Create a stub that works with arity mismatches. Like the fast-path,
-         * this allocates a frame on the caller side, but also performs extra
-         * checks for compilability. Perhaps this should be a separate, shared
-         * trampoline, but for now we generate it dynamically.
-         */
-        Assembler masm;
-        InlineFrameAssembler inlFrame(masm, ic, flags);
-        RegisterID t0 = inlFrame.tempRegs.takeAnyReg().reg();
-
-        /* Generate the inline frame creation. */
-        void *ncode = ic.funGuard.labelAtOffset(ic.joinPointOffset).executableAddress();
-        inlFrame.assemble(ncode, f.pc());
-
-        /* funObjReg is still valid. Check if a compilation is needed. */
-        Address scriptAddr(ic.funObjReg, JSFunction::offsetOfNativeOrScript());
-        masm.loadPtr(scriptAddr, t0);
-
-        // Test that:
-        // - script->mJITInfo is not NULL
-        // - script->mJITInfo->jitHandle{Ctor,Normal}->value is neither NULL nor UNJITTABLE, and
-        // - script->mJITInfo->jitHandle{Ctor,Normal}->value->arityCheckEntry is not NULL.
-        masm.loadPtr(Address(t0, JSScript::offsetOfMJITInfo()), t0);
-        Jump hasNoJitInfo = masm.branchPtr(Assembler::Equal, t0, ImmPtr(NULL));
-        size_t offset = JSScript::JITScriptSet::jitHandleOffset(callingNew,
-                                                                f.cx->zone()->compileBarriers());
-        masm.loadPtr(Address(t0, offset), t0);
-        Jump hasNoJitCode = masm.branchPtr(Assembler::BelowOrEqual, t0,
-                                           ImmPtr(JSScript::JITScriptHandle::UNJITTABLE));
-
-        masm.loadPtr(Address(t0, offsetof(JITScript, arityCheckEntry)), t0);
-
-        Jump hasCode = masm.branchPtr(Assembler::NotEqual, t0, ImmPtr(0));
-
-        hasNoJitInfo.linkTo(masm.label(), &masm);
-        hasNoJitCode.linkTo(masm.label(), &masm);
-
-        /*
-         * Write the rejoin state to indicate this is a compilation call made
-         * from an IC (the recompiler cannot detect calls made from ICs
-         * automatically).
-         */
-        masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), false)),
-                      FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-        masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
-
-        /* Try and compile. On success we get back the nmap pointer. */
-        void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
-        DataLabelPtr inlined;
-        if (ic.frameSize.isStatic()) {
-            masm.move(Imm32(ic.frameSize.staticArgc()), Registers::ArgReg1);
-            masm.fallibleVMCall(cx->typeInferenceEnabled(),
-                                compilePtr, f.regs.pc, &inlined, ic.frameSize.staticLocalSlots());
-        } else {
-            masm.load32(FrameAddress(VMFrame::offsetOfDynamicArgc()), Registers::ArgReg1);
-            masm.fallibleVMCall(cx->typeInferenceEnabled(),
-                                compilePtr, f.regs.pc, &inlined, -1);
-        }
-
-        Jump notCompiled = masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
-                                              Registers::ReturnReg);
-        masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), JSFrameReg);
-
-        /* Compute the value of ncode to use at this call site. */
-        ncode = (uint8_t *) f.chunk()->code.m_code.executableAddress() + ic.call->codeOffset;
-        masm.storePtr(ImmPtr(ncode), Address(JSFrameReg, StackFrame::offsetOfNcode()));
-
-        masm.jump(Registers::ReturnReg);
-
-        hasCode.linkTo(masm.label(), &masm);
-
-        /* Get nmap[ARITY], set argc, call. */
-        if (ic.frameSize.isStatic())
-            masm.move(Imm32(ic.frameSize.staticArgc()), JSParamReg_Argc);
-        else
-            masm.load32(FrameAddress(VMFrame::offsetOfDynamicArgc()), JSParamReg_Argc);
-        masm.jump(t0);
-
-        LinkerHelper linker(masm, JSC::JAEGER_CODE);
-        JSC::ExecutablePool *ep = poolForSize(linker, CallICInfo::Pool_ScriptStub);
-        if (!ep)
-            return false;
-
-        if (!linker.verifyRange(f.chunk())) {
-            disable();
-            return true;
-        }
-        if (ic.hasStubOolJump() && !linker.verifyRange(ic.lastOolCode())) {
-            disable();
-            return true;
-        }
-
-        linker.link(notCompiled, ic.nativeRejoin());
-        JSC::CodeLocationLabel cs = linker.finalize(f);
-
-        JaegerSpew(JSpew_PICs, "generated CALL stub %p (%lu bytes)\n", cs.executableAddress(),
-                   (unsigned long) masm.size());
-
-        if (f.regs.inlined()) {
-            JSC::LinkBuffer code((uint8_t *) cs.executableAddress(), masm.size(), JSC::JAEGER_CODE);
-            code.patch(inlined, f.regs.inlined());
-        }
-
-        Repatcher repatch(f.chunk());
-        repatch.relink(ic.lastOolJump(), cs);
-
-        return true;
-    }
-
-    bool patchInlinePath(JSScript *script, JSObject *obj)
-    {
-        JS_ASSERT(ic.frameSize.isStatic());
-        JITScript *jit = script->getJIT(callingNew, f.cx->zone()->compileBarriers());
-
-        /* Very fast path. */
-        Repatcher repatch(f.chunk());
-
-        /*
-         * Use the arguments check entry if this is a monitored call, we might
-         * not have accounted for all possible argument types.
-         */
-        void *entry = ic.typeMonitored ? jit->argsCheckEntry : jit->fastEntry;
-
-        if (!repatch.canRelink(ic.funGuard.jumpAtOffset(ic.hotJumpOffset),
-                               JSC::CodeLocationLabel(entry))) {
-            return false;
-        }
-
-        ic.fastGuardedObject = obj;
-        JS_APPEND_LINK(&ic.links, &jit->callers);
-
-        repatch.repatch(ic.funGuard, obj);
-        repatch.relink(ic.funGuard.jumpAtOffset(ic.hotJumpOffset),
-                       JSC::CodeLocationLabel(entry));
-
-        JaegerSpew(JSpew_PICs, "patched CALL path %p (obj: %p)\n",
-                   ic.funGuard.executableAddress(),
-                   static_cast<void*>(ic.fastGuardedObject));
-
-        return true;
-    }
-
-    bool generateStubForClosures(JSObject *obj)
-    {
-        JS_ASSERT(ic.frameSize.isStatic());
-
-        /* Slightly less fast path - guard on fun->script() instead. */
-        Assembler masm;
-
-        Registers tempRegs(Registers::AvailRegs);
-        tempRegs.takeReg(ic.funObjReg);
-
-        RegisterID t0 = tempRegs.takeAnyReg().reg();
-
-        /* Guard that it's actually a function object. */
-        Jump claspGuard = masm.testObjClass(Assembler::NotEqual, ic.funObjReg, t0, &FunctionClass);
-
-        /* Guard that it's the same script. */
-        Address scriptAddr(ic.funObjReg, JSFunction::offsetOfNativeOrScript());
-        Jump funGuard = masm.branchPtr(Assembler::NotEqual, scriptAddr,
-                                       ImmPtr(obj->toFunction()->nonLazyScript()));
-        Jump done = masm.jump();
-
-        LinkerHelper linker(masm, JSC::JAEGER_CODE);
-        JSC::ExecutablePool *ep = poolForSize(linker, CallICInfo::Pool_ClosureStub);
-        if (!ep)
-            return false;
-
-        ic.hasJsFunCheck = true;
-
-        if (!linker.verifyRange(f.chunk())) {
-            disable();
-            return true;
-        }
-
-        linker.link(claspGuard, ic.slowPathStart);
-        linker.link(funGuard, ic.slowPathStart);
-        linker.link(done, ic.funGuard.labelAtOffset(ic.hotPathOffset));
-        ic.funJumpTarget = linker.finalize(f);
-
-        JaegerSpew(JSpew_PICs, "generated CALL closure stub %p (%lu bytes)\n",
-                   ic.funJumpTarget.executableAddress(), (unsigned long) masm.size());
-
-        Repatcher repatch(f.chunk());
-        repatch.relink(ic.funJump, ic.funJumpTarget);
-
-        return true;
-    }
-
-    bool generateNativeStub()
-    {
-        /* Snapshot the frameDepth before SplatApplyArgs modifies it. */
-        unsigned initialFrameDepth = f.regs.sp - f.fp()->slots();
-
-        /* Protect against accessing the IC if it may have been purged. */
-        RecompilationMonitor monitor(cx);
-
-        /*
-         * SplatApplyArgs has not been called, so we call it here before
-         * potentially touching f.u.call.dynamicArgc.
-         */
-        CallArgs args;
-        if (ic.frameSize.isStatic()) {
-            JS_ASSERT(f.regs.sp - f.fp()->slots() == (int)ic.frameSize.staticLocalSlots());
-            args = CallArgsFromSp(ic.frameSize.staticArgc(), f.regs.sp);
-        } else {
-            JS_ASSERT(!f.regs.inlined());
-            JS_ASSERT(*f.regs.pc == JSOP_FUNAPPLY && GET_ARGC(f.regs.pc) == 2);
-            /* Updates regs.sp -- may cause GC. */
-            if (!ic::SplatApplyArgs(f))
-                THROWV(true);
-            args = CallArgsFromSp(f.u.call.dynamicArgc, f.regs.sp);
-        }
-
-        RootedFunction fun(cx);
-        if (!IsFunctionObject(args.calleev(), fun.address()))
-            return false;
-
-        if ((!callingNew && !fun->isNative()) || (callingNew && !fun->isNativeConstructor()))
-            return false;
-
-        if (callingNew)
-            args.setThis(MagicValue(JS_IS_CONSTRUCTING));
-
-        if (!CallJSNative(cx, fun->native(), args))
-            THROWV(true);
-
-        RootedScript fscript(cx, f.script());
-        types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
-
-        /*
-         * Native stubs are not generated for inline frames. The overhead of
-         * bailing out from the IC is far greater than the time saved by
-         * inlining the parent frame in the first place, so mark the immediate
-         * caller as uninlineable.
-         */
-        if (fscript->function()) {
-            fscript->uninlineable = true;
-            MarkTypeObjectFlags(cx, fscript->function(), types::OBJECT_FLAG_UNINLINEABLE);
-        }
-
-        /* Don't touch the IC if the call triggered a recompilation. */
-        if (monitor.recompiled())
-            return true;
-
-        JS_ASSERT(!f.regs.inlined());
-
-        /* Right now, take slow-path for IC misses or multiple stubs. */
-        if (ic.fastGuardedNative || ic.hasJsFunCheck)
-            return true;
-
-        /* Native MIC needs to warm up first. */
-        if (!ic.hit) {
-            ic.hit = true;
-            return true;
-        }
-
-        /* Generate fast-path for calling this native. */
-        Assembler masm;
-
-        /* Guard on the function object identity, for now. */
-        Jump funGuard = masm.branchPtr(Assembler::NotEqual, ic.funObjReg, ImmPtr(fun));
-
-        /*
-         * Write the rejoin state for the recompiler to use if this call
-         * triggers recompilation. Natives use a different stack address to
-         * store the return value than FASTCALLs, and without additional
-         * information we cannot tell which one is active on a VMFrame.
-         */
-        masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), true)),
-                      FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-        /* N.B. After this call, the frame will have a dynamic frame size. */
-        if (ic.frameSize.isDynamic()) {
-            masm.bumpStubCount(fscript, f.pc(), Registers::tempCallReg());
-            masm.fallibleVMCall(cx->typeInferenceEnabled(),
-                                JS_FUNC_TO_DATA_PTR(void *, ic::SplatApplyArgs),
-                                f.regs.pc, NULL, initialFrameDepth);
-        }
-
-        Registers tempRegs = Registers::tempCallRegMask();
-        RegisterID t0 = tempRegs.takeAnyReg().reg();
-        masm.bumpStubCount(fscript, f.pc(), t0);
-
-        int32_t storeFrameDepth = ic.frameSize.isStatic() ? initialFrameDepth : -1;
-        masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, storeFrameDepth);
-
-        /* Grab cx. */
-#ifdef JS_CPU_X86
-        RegisterID cxReg = tempRegs.takeAnyReg().reg();
-#else
-        RegisterID cxReg = Registers::ArgReg0;
-#endif
-        masm.loadPtr(FrameAddress(offsetof(VMFrame, cx)), cxReg);
-
-        /*
-         * Compute vp. This will always be at the same offset from fp for a
-         * given callsite, regardless of any dynamically computed argc,
-         * so get that offset from the active call.
-         */
-#ifdef JS_CPU_X86
-        RegisterID vpReg = t0;
-#else
-        RegisterID vpReg = Registers::ArgReg2;
-#endif
-        uint32_t vpOffset = (uint32_t) ((char *) args.base() - (char *) f.fp());
-        masm.addPtr(Imm32(vpOffset), JSFrameReg, vpReg);
-
-        /* Compute argc. */
-        MaybeRegisterID argcReg;
-        if (!ic.frameSize.isStatic()) {
-            argcReg = tempRegs.takeAnyReg().reg();
-            masm.load32(FrameAddress(VMFrame::offsetOfDynamicArgc()), argcReg.reg());
-        }
-
-        /* Mark vp[1] as magic for |new|. */
-        if (callingNew)
-            masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(vpReg, sizeof(Value)));
-
-        masm.restoreStackBase();
-        masm.setupABICall(Registers::NormalCall, 3);
-        masm.storeArg(2, vpReg);
-        if (ic.frameSize.isStatic())
-            masm.storeArg(1, ImmIntPtr(intptr_t(ic.frameSize.staticArgc())));
-        else
-            masm.storeArg(1, argcReg.reg());
-        masm.storeArg(0, cxReg);
-
-        js::Native native = fun->native();
-
-        /*
-         * Call RegExp.test instead of exec if the result will not be used or
-         * will only be used to test for existence. Note that this will not
-         * break inferred types for the call's result and any subsequent test,
-         * as RegExp.exec has a type handler with unknown result.
-         */
-        if (native == regexp_exec && !CallResultEscapes(f.pc()))
-            native = regexp_test;
-
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, native), false);
-
-        NativeStubLinker::FinalJump done;
-        if (!NativeStubEpilogue(f, masm, &done, initialFrameDepth, vpOffset, MaybeRegisterID(), MaybeRegisterID()))
-            return false;
-        NativeStubLinker linker(masm, f.chunk(), f.regs.pc, done);
-        if (!linker.init(f.cx))
-            THROWV(true);
-
-        if (!linker.verifyRange(f.chunk())) {
-            disable();
-            return true;
-        }
-
-        linker.patchJump(ic.nativeRejoin());
-
-        ic.fastGuardedNative = fun;
-
-        linker.link(funGuard, ic.slowPathStart);
-        ic.funJumpTarget = linker.finalize(f);
-
-        JaegerSpew(JSpew_PICs, "generated native CALL stub %p (%lu bytes)\n",
-                   ic.funJumpTarget.executableAddress(), (unsigned long) masm.size());
-
-        Repatcher repatch(f.chunk());
-        repatch.relink(ic.funJump, ic.funJumpTarget);
-
-        return true;
-    }
-
-    bool generateCallsiteCloneStub(HandleFunction original, HandleFunction fun)
-    {
-        Assembler masm;
-
-        // If we have a callsite clone, we do the folowing hack:
-        //
-        //  1) Patch funJump to a stub which guards on the identity of the
-        //     original function. If this guard fails, we jump to the original
-        //     funJump target.
-        //  2) Load the clone into the callee register.
-        //  3) Jump *back* to funGuard.
-        //
-        // For the inline path, hopefully we will succeed upon jumping back to
-        // funGuard after loading the clone.
-        //
-        // This hack is not ideal, as we can actually fail the first funGuard
-        // twice: we fail the first funGuard, pass the second funGuard, load
-        // the clone, and jump back to the first funGuard. We fail the first
-        // funGuard again, and this time we also fail the second funGuard,
-        // since a function's clone is never equal to itself. Finally, we jump
-        // to the original funJump target.
-
-        // Guard on the original function's identity.
-        Jump originalGuard = masm.branchPtr(Assembler::NotEqual, ic.funObjReg, ImmPtr(original));
-
-        // Load the clone.
-        masm.move(ImmPtr(fun), ic.funObjReg);
-
-        // Jump back to the first fun guard.
-        Jump done = masm.jump();
-
-        LinkerHelper linker(masm, JSC::JAEGER_CODE);
-        JSC::ExecutablePool *ep = linker.init(f.cx);
-        if (!ep)
-            return false;
-
-        if (!linker.verifyRange(f.chunk())) {
-            disable();
-            return true;
-        }
-
-        linker.link(originalGuard, !!ic.funJumpTarget ? ic.funJumpTarget : ic.slowPathStart);
-        linker.link(done, ic.funGuardLabel);
-        JSC::CodeLocationLabel start = linker.finalize(f);
-
-        JaegerSpew(JSpew_PICs, "generated CALL clone stub %p (%lu bytes)\n",
-                   start.executableAddress(), (unsigned long) masm.size());
-        JaegerSpew(JSpew_PICs, "guarding %p with clone %p\n",
-                   static_cast<void*>(original.get()), static_cast<void*>(fun.get()));
-
-        Repatcher repatch(f.chunk());
-        repatch.relink(ic.funJump, start);
-
-        return true;
-    }
-
-    void *update()
-    {
-        RecompilationMonitor monitor(cx);
-
-        bool lowered = ic.frameSize.lowered(f.pc());
-        JS_ASSERT_IF(lowered, !callingNew);
-
-        StackFrame *initialFp = f.fp();
-
-        stubs::UncachedCallResult ucr(f.cx);
-        if (callingNew)
-            stubs::UncachedNewHelper(f, ic.frameSize.staticArgc(), ucr);
-        else
-            stubs::UncachedCallHelper(f, ic.frameSize.getArgc(f), lowered, ucr);
-
-        // Watch out in case the IC was invalidated by a recompilation on the calling
-        // script. This can happen either if the callee is executed or if it compiles
-        // and the compilation has a static overflow. Also watch for cases where
-        // an exception is thrown and the callee frame hasn't unwound yet.
-        if (monitor.recompiled() || f.fp() != initialFp)
-            return ucr.codeAddr;
-
-        JSFunction *fun = ucr.fun;
-
-        if (!ucr.codeAddr) {
-            // No JM code is available for this script yet.
-            if (ucr.unjittable)
-                disable();
-
-#ifdef JS_ION
-
-            // If the following conditions pass, try to inline a call into
-            // an IonMonkey JIT'd function.
-            if (!callingNew &&
-                fun &&
-                !ic.hasJMStub() &&
-                !ic.hasIonStub() &&
-                ic.frameSize.isStatic() &&
-                ic.frameSize.staticArgc() <= ion::SNAPSHOT_MAX_NARGS &&
-                fun->hasScript() && fun->nonLazyScript()->hasIonScript())
-            {
-                if (!generateIonStub())
-                    THROWV(NULL);
-            }
-#endif
-            return NULL;
-        }
-
-        JS_ASSERT(fun);
-        JSScript *script = fun->nonLazyScript();
-        JS_ASSERT(script);
-
-        uint32_t flags = callingNew ? StackFrame::CONSTRUCTING : 0;
-
-        if (!ic.hit) {
-            ic.hit = true;
-            return ucr.codeAddr;
-        }
-
-        if (!ic.frameSize.isStatic() || ic.frameSize.staticArgc() != fun->nargs) {
-            if (!generateFullCallStub(script, flags))
-                THROWV(NULL);
-        } else {
-            if (!ic.fastGuardedObject && patchInlinePath(script, fun)) {
-                // Nothing, done.
-            } else if (ic.fastGuardedObject &&
-                       !ic.hasJsFunCheck &&
-                       !ic.fastGuardedNative &&
-                       ic.fastGuardedObject->toFunction()->nonLazyScript() == fun->nonLazyScript())
-            {
-                /*
-                 * Note: Multiple "function guard" stubs are not yet
-                 * supported, thus the fastGuardedNative check.
-                 */
-                if (!generateStubForClosures(fun))
-                    THROWV(NULL);
-            } else {
-                if (!generateFullCallStub(script, flags))
-                    THROWV(NULL);
-            }
-        }
-
-        if (ucr.original && !generateCallsiteCloneStub(ucr.original, ucr.fun))
-            THROWV(NULL);
-
-        return ucr.codeAddr;
-    }
-};
-
-} // namespace mjit
-} // namespace js
-
-void * JS_FASTCALL
-ic::Call(VMFrame &f, CallICInfo *ic)
-{
-    CallCompiler cc(f, *ic, false);
-    return cc.update();
-}
-
-void * JS_FASTCALL
-ic::New(VMFrame &f, CallICInfo *ic)
-{
-    CallCompiler cc(f, *ic, true);
-    return cc.update();
-}
-
-void * JS_FASTCALL
-ic::NativeCall(VMFrame &f, CallICInfo *ic)
-{
-    CallCompiler cc(f, *ic, false);
-    if (!cc.generateNativeStub())
-        stubs::SlowCall(f, ic->frameSize.getArgc(f));
-    return NULL;
-}
-
-void * JS_FASTCALL
-ic::NativeNew(VMFrame &f, CallICInfo *ic)
-{
-    CallCompiler cc(f, *ic, true);
-    if (!cc.generateNativeStub())
-        stubs::SlowNew(f, ic->frameSize.staticArgc());
-    return NULL;
-}
-
-static JS_ALWAYS_INLINE bool
-BumpStack(VMFrame &f, unsigned inc)
-{
-    if (f.regs.sp + inc < f.stackLimit)
-        return true;
-    return f.cx->stack.space().tryBumpLimit(f.cx, f.regs.sp, inc, &f.stackLimit);
-}
-
-/*
- * SplatApplyArgs is only called for expressions of the form |f.apply(x, y)|.
- * Additionally, the callee has already been checked to be the native apply.
- * All successful paths through SplatApplyArgs must set f.u.call.dynamicArgc
- * and f.regs.sp.
- */
-JSBool JS_FASTCALL
-ic::SplatApplyArgs(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    JS_ASSERT(!f.regs.inlined());
-
-    CallArgs args = CallArgsFromSp(GET_ARGC(f.regs.pc), f.regs.sp);
-    JS_ASSERT(args.length() == 2);
-    JS_ASSERT(IsNativeFunction(args.calleev(), js_fun_apply));
-
-    if (IsOptimizedArguments(f.fp(), &args[1])) {
-        /* Mirror isMagic(JS_OPTIMIZED_ARGUMENTS) case in js_fun_apply. */
-        /* Steps 4-6. */
-        unsigned length = f.regs.fp()->numActualArgs();
-        JS_ASSERT(length <= StackSpace::ARGS_LENGTH_MAX);
-
-        f.regs.sp--;
-        if (!BumpStack(f, length))
-            THROWV(false);
-
-        /* Steps 7-8. */
-        f.regs.fp()->forEachUnaliasedActual(CopyTo(f.regs.sp));
-
-        f.regs.fp()->setJitRevisedStack();
-        f.regs.sp += length;
-        f.u.call.dynamicArgc = length;
-        return true;
-    }
-
-    /*
-     * This stub should mimic the steps taken by js_fun_apply. Step 1 and part
-     * of Step 2 have already been taken care of by calling jit code.
-     */
-
-    /* Step 2 (part 2). */
-    if (args[1].isNullOrUndefined()) {
-        f.regs.sp--;
-        f.u.call.dynamicArgc = 0;
-        return true;
-    }
-
-    /* Step 3. */
-    if (!args[1].isObject()) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_APPLY_ARGS, js_apply_str);
-        THROWV(false);
-    }
-
-    /* Steps 4-5. */
-    RootedObject aobj(cx, &args[1].toObject());
-    uint32_t length;
-    if (!GetLengthProperty(cx, aobj, &length))
-        THROWV(false);
-
-    /* Step 6. */
-    if (length > StackSpace::ARGS_LENGTH_MAX) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                             JSMSG_TOO_MANY_FUN_APPLY_ARGS);
-        THROWV(false);
-    }
-
-    int delta = length - 1;
-    if (delta > 0) {
-        if (!BumpStack(f, delta))
-            THROWV(false);
-
-        MakeRangeGCSafe(f.regs.sp, delta);
-    }
-
-    f.regs.fp()->setJitRevisedStack();
-    f.regs.sp += delta;
-
-    /* Steps 7-8. */
-    if (!GetElements(cx, aobj, length, f.regs.sp - length))
-        THROWV(false);
-
-    f.u.call.dynamicArgc = length;
-    return true;
-}
-
-#if defined(_MSC_VER)
-# pragma optimize("", on)
-#endif
-
-void
-ic::GenerateArgumentCheckStub(VMFrame &f)
-{
-    JS_ASSERT(f.cx->typeInferenceEnabled());
-
-    JITScript *jit = f.jit();
-    StackFrame *fp = f.fp();
-    JSFunction *fun = fp->fun();
-    JSScript *script = fun->nonLazyScript();
-
-    if (jit->argsCheckPool)
-        jit->resetArgsCheck();
-
-    Assembler masm;
-    Vector<Jump> mismatches(f.cx);
-
-    if (!f.fp()->isConstructing()) {
-        types::TypeSet *types = types::TypeScript::ThisTypes(script);
-        Address address(JSFrameReg, StackFrame::offsetOfThis(fun));
-        if (!masm.generateTypeCheck(f.cx, address, types, &mismatches))
-            return;
-    }
-
-    for (unsigned i = 0; i < fun->nargs; i++) {
-        types::TypeSet *types = types::TypeScript::ArgTypes(script, i);
-        Address address(JSFrameReg, StackFrame::offsetOfFormalArg(fun, i));
-        if (!masm.generateTypeCheck(f.cx, address, types, &mismatches))
-            return;
-    }
-
-    Jump done = masm.jump();
-
-    LinkerHelper linker(masm, JSC::JAEGER_CODE);
-    JSC::ExecutablePool *ep = linker.init(f.cx);
-    if (!ep)
-        return;
-    jit->argsCheckPool = ep;
-
-    if (!linker.verifyRange(f.chunk())) {
-        jit->resetArgsCheck();
-        return;
-    }
-
-    for (unsigned i = 0; i < mismatches.length(); i++)
-        linker.link(mismatches[i], jit->argsCheckStub);
-    linker.link(done, jit->argsCheckFallthrough);
-
-    JSC::CodeLocationLabel cs = linker.finalize(f);
-
-    JaegerSpew(JSpew_PICs, "generated ARGS CHECK stub %p (%lu bytes)\n",
-               cs.executableAddress(), (unsigned long)masm.size());
-
-    Repatcher repatch(f.chunk());
-    repatch.relink(jit->argsCheckJump, cs);
-}
-
-void
-JITScript::resetArgsCheck()
-{
-    argsCheckPool->release();
-    argsCheckPool = NULL;
-
-    Repatcher repatch(chunk(script->code));
-    repatch.relink(argsCheckJump, argsCheckStub);
-}
-
-#endif /* JS_MONOIC */
-
deleted file mode 100644
--- a/js/src/methodjit/MonoIC.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_mono_ic_h__ && defined JS_METHODJIT && defined JS_MONOIC
-#define jsjaeger_mono_ic_h__
-
-#include "assembler/assembler/MacroAssembler.h"
-#include "assembler/assembler/CodeLocation.h"
-#include "assembler/moco/MocoStubs.h"
-#include "methodjit/MethodJIT.h"
-#include "CodeGenIncludes.h"
-#include "methodjit/ICRepatcher.h"
-
-namespace js {
-namespace mjit {
-
-class FrameSize
-{
-    uint32_t frameDepth_ : 16;
-    uint32_t argc_;
-  public:
-    void initStatic(uint32_t frameDepth, uint32_t argc) {
-        JS_ASSERT(frameDepth > 0);
-        frameDepth_ = frameDepth;
-        argc_ = argc;
-    }
-
-    void initDynamic() {
-        frameDepth_ = 0;
-        argc_ = -1;  /* quiet gcc */
-    }
-
-    bool isStatic() const {
-        return frameDepth_ > 0;
-    }
-
-    bool isDynamic() const {
-        return frameDepth_ == 0;
-    }
-
-    uint32_t staticLocalSlots() const {
-        JS_ASSERT(isStatic());
-        return frameDepth_;
-    }
-
-    uint32_t staticArgc() const {
-        JS_ASSERT(isStatic());
-        return argc_;
-    }
-
-    uint32_t getArgc(VMFrame &f) const {
-        return isStatic() ? staticArgc() : f.u.call.dynamicArgc;
-    }
-
-    bool lowered(jsbytecode *pc) const {
-        return isDynamic() || staticArgc() != GET_ARGC(pc);
-    }
-
-    RejoinState rejoinState(jsbytecode *pc, bool native) {
-        if (isStatic()) {
-            if (staticArgc() == GET_ARGC(pc))
-                return native ? REJOIN_NATIVE : REJOIN_CALL_PROLOGUE;
-            JS_ASSERT(staticArgc() == GET_ARGC(pc) - 1);
-            return native ? REJOIN_NATIVE_LOWERED : REJOIN_CALL_PROLOGUE_LOWERED_CALL;
-        }
-        return native ? REJOIN_NATIVE_LOWERED : REJOIN_CALL_PROLOGUE_LOWERED_APPLY;
-    }
-
-    bool lowered(jsbytecode *pc) {
-        return !isStatic() || staticArgc() != GET_ARGC(pc);
-    }
-};
-
-namespace ic {
-
-struct GlobalNameIC
-{
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    JSC::CodeLocationLabel  fastPathStart;
-    JSC::CodeLocationCall   slowPathCall;
-
-    /*
-     * - ARM and x64 always emit exactly one instruction which needs to be
-     *   patched. On ARM, the label points to the patched instruction, whilst
-     *   on x64 it points to the instruction after it.
-     * - For x86, the label "load" points to the start of the load/store
-     *   sequence, which may consist of one or two "mov" instructions. Because
-     *   of this, x86 is the only platform which requires non-trivial patching
-     *   code.
-     */
-    int32_t loadStoreOffset   : 15;
-    int32_t shapeOffset       : 15;
-};
-
-struct GetGlobalNameIC : public GlobalNameIC
-{
-};
-
-struct SetGlobalNameIC : public GlobalNameIC
-{
-    JSC::CodeLocationLabel  slowPathStart;
-
-    /* SET only, if we had to generate an out-of-line path. */
-    int32_t inlineShapeJump : 10;   /* Offset into inline path for shape jump. */
-    bool objConst : 1;          /* True if the object is constant. */
-    RegisterID objReg   : 5;    /* Register for object, if objConst is false. */
-    RegisterID shapeReg : 5;    /* Register for shape; volatile. */
-
-    int32_t fastRejoinOffset : 16;  /* Offset from fastPathStart to rejoin. */
-
-    /* SET only. */
-    ValueRemat vr;              /* RHS value. */
-
-    void patchInlineShapeGuard(Repatcher &repatcher, Shape *shape);
-};
-
-void JS_FASTCALL GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic);
-void JS_FASTCALL SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic);
-
-struct EqualityICInfo {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    JSC::CodeLocationLabel stubEntry;
-    JSC::CodeLocationCall stubCall;
-    BoolStub stub;
-    JSC::CodeLocationLabel target;
-    JSC::CodeLocationLabel fallThrough;
-    JSC::CodeLocationJump jumpToStub;
-
-    ValueRemat lvr, rvr;
-
-    bool generated : 1;
-    JSC::MacroAssembler::RegisterID tempReg : 5;
-    Assembler::Condition cond;
-};
-
-JSBool JS_FASTCALL Equality(VMFrame &f, ic::EqualityICInfo *ic);
-
-/* See MonoIC.cpp, CallCompiler for more information on call ICs. */
-struct CallICInfo {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-
-    /* Linked list entry for all ICs guarding on the same JIT entry point in fastGuardedObject. */
-    JSCList links;
-
-    enum PoolIndex {
-        Pool_ScriptStub,
-        Pool_ClosureStub,
-        Total_Pools
-    };
-
-    JSC::ExecutablePool *pools[Total_Pools];
-
-    /* Used for rooting and reification. */
-    JSObject *fastGuardedObject;
-    JSObject *fastGuardedNative;
-
-    /* Return site for scripted calls at this site, with PC and inlining state. */
-    CallSite *call;
-
-    FrameSize frameSize;
-
-    /* Label to the function object identity guard. */
-    JSC::CodeLocationLabel funGuardLabel;
-
-    /* Function object identity guard. */
-    JSC::CodeLocationDataLabelPtr funGuard;
-
-    /* Starting point for all slow call paths. */
-    JSC::CodeLocationLabel slowPathStart;
-
-    /* Inline to OOL jump, redirected by stubs. */
-    JSC::CodeLocationJump funJump;
-
-    /*
-     * Target of the above jump, remembered so that if we need to generate a
-     * callsite clone stub we can redirect to the original funJump target.
-     */
-    JSC::CodeLocationLabel funJumpTarget;
-
-    /*
-     * If an Ion stub has been generated, its guard may be linked to another
-     * stub. The guard location is stored in this label.
-     */
-    bool hasIonStub_;
-    JSC::JITCode lastOolCode_;
-    JSC::CodeLocationJump lastOolJump_;
-
-    /* Offset to inline scripted call, from funGuard. */
-    uint32_t hotJumpOffset   : 16;
-    uint32_t joinPointOffset : 16;
-
-    /* Out of line slow call. */
-    uint32_t oolCallOffset   : 16;
-
-    /* Jump/rejoin to patch for out-of-line scripted calls. */
-    uint32_t oolJumpOffset   : 16;
-
-    /* Label for out-of-line call to IC function. */
-    uint32_t icCallOffset    : 16;
-
-    /* Offset for deep-fun check to rejoin at. */
-    uint32_t hotPathOffset   : 16;
-
-    /* Join point for all slow call paths. */
-    uint32_t slowJoinOffset  : 16;
-
-    /* Join point for Ion calls. */
-    uint32_t ionJoinOffset : 16;
-
-    RegisterID funObjReg : 5;
-    bool hit : 1;
-    bool hasJsFunCheck : 1;
-    bool typeMonitored : 1;
-
-    inline void releasePool(PoolIndex index) {
-        if (pools[index]) {
-            pools[index]->release();
-            pools[index] = NULL;
-        }
-    }
-
-    inline void purgeGuardedObject() {
-        JS_ASSERT(fastGuardedObject);
-        releasePool(CallICInfo::Pool_ClosureStub);
-        hasJsFunCheck = false;
-        fastGuardedObject = NULL;
-        JS_REMOVE_LINK(&links);
-    }
-
-    bool hasJMStub() const {
-        return !!pools[Pool_ScriptStub];
-    }
-    bool hasIonStub() const {
-        return hasIonStub_;
-    }
-    bool hasStubOolJump() const {
-        return hasIonStub();
-    }
-    JSC::CodeLocationLabel icCall() {
-        return slowPathStart.labelAtOffset(icCallOffset);
-    }
-    JSC::CodeLocationJump oolJump() {
-        return slowPathStart.jumpAtOffset(oolJumpOffset);
-    }
-    JSC::CodeLocationJump lastOolJump() {
-        if (hasStubOolJump())
-            return lastOolJump_;
-        return oolJump();
-    }
-    JSC::JITCode lastOolCode() {
-        JS_ASSERT(hasStubOolJump());
-        return lastOolCode_;
-    }
-    void updateLastOolJump(JSC::CodeLocationJump jump, JSC::JITCode code) {
-        lastOolJump_ = jump;
-        lastOolCode_ = code;
-    }
-    JSC::CodeLocationLabel nativeRejoin() {
-        return slowPathStart.labelAtOffset(slowJoinOffset);
-    }
-    JSC::CodeLocationLabel ionJoinPoint() {
-        return funGuard.labelAtOffset(ionJoinOffset);
-    }
-
-    inline void reset(Repatcher &repatcher) {
-        if (fastGuardedObject) {
-            repatcher.repatch(funGuard, NULL);
-            repatcher.relink(funJump, slowPathStart);
-            purgeGuardedObject();
-        }
-        if (fastGuardedNative) {
-            repatcher.relink(funJump, slowPathStart);
-            fastGuardedNative = NULL;
-        }
-        if (pools[Pool_ScriptStub] || hasIonStub()) {
-            repatcher.relink(oolJump(), icCall());
-            releasePool(Pool_ScriptStub);
-        }
-        hit = false;
-        hasIonStub_ = false;
-    }
-};
-
-void * JS_FASTCALL New(VMFrame &f, ic::CallICInfo *ic);
-void * JS_FASTCALL Call(VMFrame &f, ic::CallICInfo *ic);
-void * JS_FASTCALL NativeNew(VMFrame &f, ic::CallICInfo *ic);
-void * JS_FASTCALL NativeCall(VMFrame &f, ic::CallICInfo *ic);
-JSBool JS_FASTCALL SplatApplyArgs(VMFrame &f);
-
-void GenerateArgumentCheckStub(VMFrame &f);
-
-} /* namespace ic */
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_mono_ic_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/NunboxAssembler.h
+++ /dev/null
@@ -1,513 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_assembler_h__ && defined JS_METHODJIT && defined JS_NUNBOX32
-#define jsjaeger_assembler_h__
-
-#include "assembler/assembler/MacroAssembler.h"
-#include "methodjit/CodeGenIncludes.h"
-#include "methodjit/RematInfo.h"
-
-namespace js {
-namespace mjit {
-
-/* Don't use ImmTag. Use ImmType instead. */
-struct ImmTag : JSC::MacroAssembler::Imm32
-{
-    ImmTag(JSValueTag mask)
-      : Imm32(int32_t(mask))
-    { }
-};
-
-struct ImmType : ImmTag
-{
-    ImmType(JSValueType type)
-      : ImmTag(JSVAL_TYPE_TO_TAG(type))
-    {
-        JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
-    }
-};
-
-struct ImmPayload : JSC::MacroAssembler::Imm32
-{
-    ImmPayload(uint32_t payload)
-      : Imm32(payload)
-    { }
-};
-
-class NunboxAssembler : public JSC::MacroAssembler
-{
-  public:
-#ifdef IS_BIG_ENDIAN
-    static const uint32_t PAYLOAD_OFFSET = 4;
-    static const uint32_t TAG_OFFSET     = 0;
-#else
-    static const uint32_t PAYLOAD_OFFSET = 0;
-    static const uint32_t TAG_OFFSET     = 4;
-#endif
-
-  public:
-    static const JSC::MacroAssembler::Scale JSVAL_SCALE = JSC::MacroAssembler::TimesEight;
-
-    Address payloadOf(Address address) {
-        return Address(address.base, address.offset + PAYLOAD_OFFSET);
-    }
-
-    BaseIndex payloadOf(BaseIndex address) {
-        return BaseIndex(address.base, address.index, address.scale, address.offset + PAYLOAD_OFFSET);
-    }
-
-    Address tagOf(Address address) {
-        return Address(address.base, address.offset + TAG_OFFSET);
-    }
-
-    BaseIndex tagOf(BaseIndex address) {
-        return BaseIndex(address.base, address.index, address.scale, address.offset + TAG_OFFSET);
-    }
-
-    void loadInlineSlot(RegisterID objReg, uint32_t slot,
-                        RegisterID typeReg, RegisterID dataReg) {
-        Address address(objReg, JSObject::getFixedSlotOffset(slot));
-        if (objReg == typeReg) {
-            loadPayload(address, dataReg);
-            loadTypeTag(address, typeReg);
-        } else {
-            loadTypeTag(address, typeReg);
-            loadPayload(address, dataReg);
-        }
-    }
-
-    template <typename T>
-    void loadTypeTag(T address, RegisterID reg) {
-        load32(tagOf(address), reg);
-    }
-
-    template <typename T>
-    void storeTypeTag(ImmTag imm, T address) {
-        store32(imm, tagOf(address));
-    }
-
-    template <typename T>
-    void storeTypeTag(RegisterID reg, T address) {
-        store32(reg, tagOf(address));
-    }
-
-    template <typename T>
-    void loadPayload(T address, RegisterID reg) {
-        load32(payloadOf(address), reg);
-    }
-
-    template <typename T>
-    void storePayload(RegisterID reg, T address) {
-        store32(reg, payloadOf(address));
-    }
-
-    template <typename T>
-    void storePayload(ImmPayload imm, T address) {
-        store32(imm, payloadOf(address));
-    }
-
-    bool addressUsesRegister(BaseIndex address, RegisterID reg) {
-        return (address.base == reg) || (address.index == reg);
-    }
-
-    bool addressUsesRegister(Address address, RegisterID reg) {
-        return address.base == reg;
-    }
-
-    /* Loads type first, then payload, returning label after type load. */
-    template <typename T>
-    Label loadValueAsComponents(T address, RegisterID type, RegisterID payload) {
-        JS_ASSERT(!addressUsesRegister(address, type));
-        loadTypeTag(address, type);
-        Label l = label();
-        loadPayload(address, payload);
-        return l;
-    }
-
-    void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) {
-        jsval_layout jv = JSVAL_TO_IMPL(val);
-        move(ImmTag(jv.s.tag), type);
-        move(Imm32(jv.s.payload.u32), payload);
-    }
-
-    void loadValuePayload(const Value &val, RegisterID payload) {
-        jsval_layout jv = JSVAL_TO_IMPL(val);
-        move(Imm32(jv.s.payload.u32), payload);
-    }
-
-    /*
-     * Load a (64b) js::Value from 'address' into 'type' and 'payload', and
-     * return a label which can be used by
-     * ICRepatcher::patchAddressOffsetForValueLoad to patch the address'
-     * offset.
-     *
-     * The data register is guaranteed to be clobbered last. (This makes the
-     * base register for the address reusable as 'dreg'.)
-     */
-    Label loadValueWithAddressOffsetPatch(Address address, RegisterID treg, RegisterID dreg) {
-        JS_ASSERT(address.base != treg); /* treg is clobbered first. */
-
-        Label start = label();
-#if defined JS_CPU_X86
-        /*
-         * On x86 there are two loads to patch and they both encode the offset
-         * in-line.
-         */
-        loadTypeTag(address, treg);
-        DBGLABEL_NOMASM(endType);
-        loadPayload(address, dreg);
-        DBGLABEL_NOMASM(endPayload);
-        JS_ASSERT(differenceBetween(start, endType) == 6);
-        JS_ASSERT(differenceBetween(endType, endPayload) == 6);
-        return start;
-#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
-        /*
-         * On ARM, the first instruction loads the offset from a literal pool, so the label
-         * returned points at that instruction.
-         */
-        DataLabel32 load = load64WithAddressOffsetPatch(address, treg, dreg);
-        JS_ASSERT(differenceBetween(start, load) == 0);
-        (void) load;
-        return start;
-#elif defined JS_CPU_MIPS
-        /*
-         * On MIPS there are LUI/ORI to patch.
-         */
-        load64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
-        return start;
-#endif
-    }
-
-    /*
-     * Store a (64b) js::Value from type |treg| and payload |dreg| into |address|, and
-     * return a label which can be used by
-     * ICRepatcher::patchAddressOffsetForValueStore to patch the address'
-     * offset.
-     */
-    DataLabel32 storeValueWithAddressOffsetPatch(RegisterID treg, RegisterID dreg, Address address) {
-#if defined JS_CPU_X86
-        /*
-         * On x86 there are two stores to patch and they both encode the offset
-         * in-line.
-         */
-        DataLabel32 start = dataLabel32();
-        storeTypeTag(treg, address);
-        DBGLABEL_NOMASM(endType);
-        storePayload(dreg, address);
-        DBGLABEL_NOMASM(endPayload);
-        JS_ASSERT(differenceBetween(start, endType) == 6);
-        JS_ASSERT(differenceBetween(endType, endPayload) == 6);
-        return start;
-#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
-        return store64WithAddressOffsetPatch(treg, dreg, address);
-#elif defined JS_CPU_MIPS
-        /*
-         * On MIPS there are LUI/ORI to patch.
-         */
-        DataLabel32 start = dataLabel32();
-        store64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
-        return start;
-#endif
-    }
-
-    /* Overloaded for storing a constant type. */
-    DataLabel32 storeValueWithAddressOffsetPatch(ImmType type, RegisterID dreg, Address address) {
-#if defined JS_CPU_X86
-        DataLabel32 start = dataLabel32();
-        storeTypeTag(type, address);
-        DBGLABEL_NOMASM(endType);
-        storePayload(dreg, address);
-        DBGLABEL_NOMASM(endPayload);
-        JS_ASSERT(differenceBetween(start, endType) == 10);
-        JS_ASSERT(differenceBetween(endType, endPayload) == 6);
-        return start;
-#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
-        return store64WithAddressOffsetPatch(type, dreg, address);
-#elif defined JS_CPU_MIPS
-        /*
-         * On MIPS there are LUI/ORI to patch.
-         */
-        DataLabel32 start = dataLabel32();
-        store64WithPatch(address, type, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
-        return start;
-#endif
-    }
-
-    /* Overloaded for storing constant type and data. */
-    DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) {
-        jsval_layout jv = JSVAL_TO_IMPL(v);
-        ImmTag type(jv.s.tag);
-        Imm32 payload(jv.s.payload.u32);
-#if defined JS_CPU_X86
-        DataLabel32 start = dataLabel32();
-        store32(type, tagOf(address));
-        DBGLABEL_NOMASM(endType);
-        store32(payload, payloadOf(address));
-        DBGLABEL_NOMASM(endPayload);
-        JS_ASSERT(differenceBetween(start, endType) == 10);
-        JS_ASSERT(differenceBetween(endType, endPayload) == 10);
-        return start;
-#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
-        return store64WithAddressOffsetPatch(type, payload, address);
-#elif defined JS_CPU_MIPS
-        /*
-         * On MIPS there are LUI/ORI to patch.
-         */
-        DataLabel32 start = dataLabel32();
-        store64WithPatch(address, type, payload, TAG_OFFSET, PAYLOAD_OFFSET);
-        return start;
-#endif
-    }
-
-    /* Overloaded for store with value remat info. */
-    DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
-        JS_ASSERT(!vr.isFPRegister());
-        if (vr.isConstant()) {
-            return storeValueWithAddressOffsetPatch(vr.value(), address);
-        } else if (vr.isTypeKnown()) {
-            ImmType type(vr.knownType());
-            RegisterID data(vr.dataReg());
-            return storeValueWithAddressOffsetPatch(type, data, address);
-        } else {
-            RegisterID type(vr.typeReg());
-            RegisterID data(vr.dataReg());
-            return storeValueWithAddressOffsetPatch(type, data, address);
-        }
-    }
-
-    /*
-     * Stores type first, then payload.
-     */
-    template <typename T>
-    Label storeValue(const Value &v, T address) {
-        jsval_layout jv = JSVAL_TO_IMPL(v);
-        store32(ImmTag(jv.s.tag), tagOf(address));
-        Label l = label();
-        store32(Imm32(jv.s.payload.u32), payloadOf(address));
-        return l;
-    }
-
-    template <typename T>
-    void storeValueFromComponents(RegisterID type, RegisterID payload, T address) {
-        storeTypeTag(type, address);
-        storePayload(payload, address);
-    }
-
-    template <typename T>
-    void storeValueFromComponents(ImmType type, RegisterID payload, T address) {
-        storeTypeTag(type, address);
-        storePayload(payload, address);
-    }
-
-    template <typename T>
-    Label storeValue(const ValueRemat &vr, T address) {
-        if (vr.isConstant()) {
-            return storeValue(vr.value(), address);
-        } else if (vr.isFPRegister()) {
-            Label l = label();
-            storeDouble(vr.fpReg(), address);
-            return l;
-        } else {
-            if (vr.isTypeKnown())
-                storeTypeTag(ImmType(vr.knownType()), address);
-            else
-                storeTypeTag(vr.typeReg(), address);
-            Label l = label();
-            storePayload(vr.dataReg(), address);
-            return l;
-        }
-    }
-
-    template <typename T>
-    Jump guardNotHole(T address) {
-        return branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
-    }
-
-    void loadPrivate(Address privAddr, RegisterID to) {
-        loadPtr(payloadOf(privAddr), to);
-    }
-
-    void loadObjPrivate(RegisterID base, RegisterID to, uint32_t nfixed) {
-        Address priv(base, JSObject::getPrivateDataOffset(nfixed));
-        loadPtr(priv, to);
-    }
-
-    Jump testNull(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_NULL));
-    }
-
-    Jump testNull(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_NULL));
-    }
-
-    Jump testUndefined(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_UNDEFINED));
-    }
-
-    Jump testUndefined(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_UNDEFINED));
-    }
-
-    Jump testInt32(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
-    }
-
-    Jump testInt32(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
-    }
-
-    Jump testNumber(Condition cond, RegisterID reg) {
-        cond = (cond == Equal) ? BelowOrEqual : Above;
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
-    }
-
-    Jump testNumber(Condition cond, Address address) {
-        cond = (cond == Equal) ? BelowOrEqual : Above;
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
-    }
-
-    Jump testPrimitive(Condition cond, RegisterID reg) {
-        cond = (cond == NotEqual) ? AboveOrEqual : Below;
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
-    }
-
-    Jump testPrimitive(Condition cond, Address address) {
-        cond = (cond == NotEqual) ? AboveOrEqual : Below;
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
-    }
-
-    Jump testObject(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
-    }
-
-    Jump testObject(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
-    }
-
-    Jump testGCThing(RegisterID reg) {
-        return branch32(AboveOrEqual, reg, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
-    }
-
-    Jump testGCThing(Address address) {
-        return branch32(AboveOrEqual, tagOf(address), ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
-    }
-
-    Jump testDouble(Condition cond, RegisterID reg) {
-        Condition opcond;
-        if (cond == Equal)
-            opcond = Below;
-        else
-            opcond = AboveOrEqual;
-        return branch32(opcond, reg, ImmTag(JSVAL_TAG_CLEAR));
-    }
-
-    Jump testDouble(Condition cond, Address address) {
-        Condition opcond;
-        if (cond == Equal)
-            opcond = Below;
-        else
-            opcond = AboveOrEqual;
-        return branch32(opcond, tagOf(address), ImmTag(JSVAL_TAG_CLEAR));
-    }
-
-    Jump testBoolean(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_BOOLEAN));
-    }
-
-    Jump testBoolean(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_BOOLEAN));
-    }
-
-    Jump testMagic(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_MAGIC));
-    }
-
-    Jump testString(Condition cond, RegisterID reg) {
-        return branch32(cond, reg, ImmTag(JSVAL_TAG_STRING));
-    }
-
-    Jump testString(Condition cond, Address address) {
-        return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_STRING));
-    }
-
-    Jump testPrivate(Condition cond, Address address, void *ptr) {
-        return branchPtr(cond, address, ImmPtr(ptr));
-    }
-
-    void compareValue(Address one, Address two, RegisterID T0, RegisterID T1,
-                      Vector<Jump> *mismatches) {
-        loadValueAsComponents(one, T0, T1);
-        mismatches->append(branch32(NotEqual, T0, tagOf(two)));
-        mismatches->append(branch32(NotEqual, T1, payloadOf(two)));
-    }
-
-#ifdef JS_CPU_X86
-    void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg) {
-        if (MacroAssemblerX86Common::getSSEState() >= HasSSE4_1) {
-            m_assembler.movd_rr(lo, fpReg);
-            m_assembler.pinsrd_rr(hi, fpReg);
-        } else {
-            m_assembler.movd_rr(lo, fpReg);
-            m_assembler.movd_rr(hi, Registers::FPConversionTemp);
-            m_assembler.unpcklps_rr(Registers::FPConversionTemp, fpReg);
-        }
-    }
-#endif
-
-    void breakDouble(FPRegisterID srcDest, RegisterID typeReg, RegisterID dataReg) {
-#ifdef JS_CPU_X86
-        // Move the low 32-bits of the 128-bit XMM register into dataReg.
-        // Then, right shift the 128-bit XMM register by 4 bytes.
-        // Finally, move the new low 32-bits of the 128-bit XMM register into typeReg.
-        m_assembler.movd_rr(srcDest, dataReg);
-        m_assembler.psrldq_rr(srcDest, 4);
-        m_assembler.movd_rr(srcDest, typeReg);
-#elif defined JS_CPU_SPARC
-        breakDoubleTo32(srcDest, typeReg, dataReg);
-#elif defined JS_CPU_ARM
-        // Yes, we are backwards from SPARC.
-        fastStoreDouble(srcDest, dataReg, typeReg);
-#elif defined JS_CPU_MIPS
-#if defined(IS_LITTLE_ENDIAN)
-        fastStoreDouble(srcDest, dataReg, typeReg);
-#else
-        fastStoreDouble(srcDest, typeReg, dataReg);
-#endif
-#else
-        JS_NOT_REACHED("implement this - push double, pop pop is easiest");
-#endif
-    }
-
-    void loadStaticDouble(const double *dp, FPRegisterID dest, RegisterID scratch) {
-        move(ImmPtr(dp), scratch);
-        loadDouble(Address(scratch), dest);
-    }
-
-    template <typename T>
-    Jump fastArrayLoadSlot(T address, bool holeCheck,
-                           MaybeRegisterID typeReg, RegisterID dataReg)
-    {
-        Jump notHole;
-        if (typeReg.isSet()) {
-            loadTypeTag(address, typeReg.reg());
-            if (holeCheck)
-                notHole = branch32(Equal, typeReg.reg(), ImmType(JSVAL_TYPE_MAGIC));
-        } else if (holeCheck) {
-            notHole = branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
-        }
-        loadPayload(address, dataReg);
-        return notHole;
-    }
-};
-
-typedef NunboxAssembler ValueAssembler;
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/PolyIC.cpp
+++ /dev/null
@@ -1,2832 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "PolyIC.h"
-#include "StubCalls.h"
-#include "CodeGenIncludes.h"
-#include "StubCalls-inl.h"
-#include "BaseCompiler.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "TypedArrayIC.h"
-#include "jsnum.h"
-#include "jstypedarray.h"
-#include "jsautooplen.h"
-
-#include "js/CharacterEncoding.h"
-#include "vm/Shape.h"
-
-#include "vm/ScopeObject-inl.h"
-#include "vm/StringObject-inl.h"
-
-#include "jsatominlines.h"
-#include "jsobjinlines.h"
-#include "jsinterpinlines.h"
-
-#include "vm/Shape-inl.h"
-
-#if defined JS_POLYIC
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::mjit::ic;
-
-typedef JSC::FunctionPtr FunctionPtr;
-typedef JSC::MacroAssembler::RegisterID RegisterID;
-typedef JSC::MacroAssembler::Jump Jump;
-typedef JSC::MacroAssembler::Imm32 Imm32;
-
-/* Rough over-estimate of how much memory we need to unprotect. */
-static const uint32_t INLINE_PATH_LENGTH = 64;
-
-// Helper class to simplify LinkBuffer usage in PIC stub generators.
-// This guarantees correct OOM and refcount handling for buffers while they
-// are instantiated and rooted.
-class PICLinker : public LinkerHelper
-{
-    ic::BasePolyIC &ic;
-
-  public:
-    PICLinker(Assembler &masm, ic::BasePolyIC &ic)
-      : LinkerHelper(masm, JSC::JAEGER_CODE), ic(ic)
-    { }
-
-    bool init(JSContext *cx) {
-        JSC::ExecutablePool *pool = LinkerHelper::init(cx);
-        if (!pool)
-            return false;
-        if (!ic.addPool(cx, pool)) {
-            markVerified();
-            pool->release();
-            js_ReportOutOfMemory(cx);
-            return false;
-        }
-        return true;
-    }
-};
-
-class PICStubCompiler : public BaseCompiler
-{
-  protected:
-    const char *type;
-    VMFrame &f;
-    ic::PICInfo &pic;
-    void *stub;
-    uint64_t gcNumber;
-
-  public:
-    bool canCallHook;
-
-    PICStubCompiler(const char *type, VMFrame &f, ic::PICInfo &pic, void *stub)
-      : BaseCompiler(f.cx), type(type), f(f), pic(pic), stub(stub),
-        gcNumber(f.cx->runtime->gcNumber), canCallHook(pic.canCallHook)
-    { }
-
-    LookupStatus error() {
-        /*
-         * N.B. Do not try to disable the IC, we do not want to guard on
-         * whether the IC has been recompiled when propagating errors.
-         */
-        return Lookup_Error;
-    }
-
-    LookupStatus error(JSContext *cx) {
-        return error();
-    }
-
-    LookupStatus disable(const char *reason) {
-        return disable(f.cx, reason);
-    }
-
-    LookupStatus disable(JSContext *cx, const char *reason) {
-        return pic.disable(f, reason, stub);
-    }
-
-    LookupStatus disable(VMFrame &f, const char *reason) {
-        return pic.disable(f, reason, stub);
-    }
-
-    bool hadGC() {
-        return gcNumber != f.cx->runtime->gcNumber;
-    }
-
-  protected:
-    void spew(const char *event, const char *op) {
-#ifdef JS_METHODJIT_SPEW
-        JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
-                   type, event, op, f.script()->filename(), CurrentLine(cx));
-#endif
-    }
-};
-
-static bool
-GeneratePrototypeGuards(JSContext *cx, Vector<JSC::MacroAssembler::Jump,8> &mismatches, Assembler &masm,
-                        JSObject *obj, HandleObject holder,
-                        JSC::MacroAssembler::RegisterID objReg,
-                        JSC::MacroAssembler::RegisterID scratchReg)
-{
-    typedef JSC::MacroAssembler::Address Address;
-    typedef JSC::MacroAssembler::AbsoluteAddress AbsoluteAddress;
-    typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-    typedef JSC::MacroAssembler::Jump Jump;
-
-    if (obj->hasUncacheableProto()) {
-        masm.loadPtr(Address(objReg, JSObject::offsetOfType()), scratchReg);
-        Jump j = masm.branchPtr(Assembler::NotEqual,
-                                Address(scratchReg, offsetof(types::TypeObject, proto)),
-                                ImmPtr(obj->getTaggedProto().toObjectOrNull()));
-        if (!mismatches.append(j))
-            return false;
-    }
-
-    RootedObject pobj(cx, obj->getTaggedProto().toObjectOrNull());
-    while (pobj != holder) {
-        if (pobj->hasUncacheableProto()) {
-            Jump j;
-            if (pobj->hasSingletonType()) {
-                types::TypeObject *type = pobj->getType(cx);
-                j = masm.branchPtr(Assembler::NotEqual,
-                                   AbsoluteAddress(&type->proto),
-                                   ImmPtr(pobj->getProto()),
-                                   scratchReg);
-            } else {
-                j = masm.branchPtr(Assembler::NotEqual,
-                                   AbsoluteAddress(pobj->addressOfType()),
-                                   ImmPtr(pobj->type()),
-                                   scratchReg);
-            }
-            if (!mismatches.append(j))
-                return false;
-        }
-        pobj = pobj->getProto();
-    }
-
-    return true;
-}
-
-class SetPropCompiler : public PICStubCompiler
-{
-    RootedObject obj;
-    RootedPropertyName name;
-    int lastStubSecondShapeGuard;
-
-  public:
-    SetPropCompiler(VMFrame &f, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
-                    VoidStubPIC stub)
-      : PICStubCompiler("setprop", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
-        obj(f.cx, obj), name(f.cx, name), lastStubSecondShapeGuard(pic.secondShapeGuard)
-    { }
-
-    static void reset(Repatcher &repatcher, ic::PICInfo &pic)
-    {
-        SetPropLabels &labels = pic.setPropLabels();
-        repatcher.repatchLEAToLoadPtr(labels.getDslotsLoad(pic.fastPathRejoin, pic.u.vr));
-        repatcher.repatch(labels.getInlineShapeData(pic.fastPathStart, pic.shapeGuard),
-                          NULL);
-        repatcher.relink(labels.getInlineShapeJump(pic.fastPathStart.labelAtOffset(pic.shapeGuard)),
-                         pic.slowPathStart);
-
-        FunctionPtr target(JS_FUNC_TO_DATA_PTR(void *, ic::SetPropOrName));
-        repatcher.relink(pic.slowPathCall, target);
-    }
-
-    LookupStatus patchInline(Shape *shape)
-    {
-        JS_ASSERT(!pic.inlinePathPatched);
-        JaegerSpew(JSpew_PICs, "patch setprop inline at %p\n", pic.fastPathStart.executableAddress());
-
-        Repatcher repatcher(f.chunk());
-        SetPropLabels &labels = pic.setPropLabels();
-
-        int32_t offset;
-        if (obj->isFixedSlot(shape->slot())) {
-            CodeLocationInstruction istr = labels.getDslotsLoad(pic.fastPathRejoin, pic.u.vr);
-            repatcher.repatchLoadPtrToLEA(istr);
-
-            //
-            // We've patched | mov dslots, [obj + DSLOTS_OFFSET]
-            // To:           | lea fslots, [obj + DSLOTS_OFFSET]
-            //
-            // Because the offset is wrong, it's necessary to correct it
-            // below.
-            //
-            int32_t diff = int32_t(JSObject::getFixedSlotOffset(0)) -
-                         int32_t(JSObject::offsetOfSlots());
-            JS_ASSERT(diff != 0);
-            offset = (int32_t(shape->slot()) * sizeof(Value)) + diff;
-        } else {
-            offset = obj->dynamicSlotIndex(shape->slot()) * sizeof(Value);
-        }
-
-        repatcher.repatch(labels.getInlineShapeData(pic.fastPathStart, pic.shapeGuard),
-                          obj->lastProperty());
-        repatcher.patchAddressOffsetForValueStore(labels.getInlineValueStore(pic.fastPathRejoin),
-                                                  offset, pic.u.vr.isTypeKnown());
-
-        pic.inlinePathPatched = true;
-
-        return Lookup_Cacheable;
-    }
-
-    int getLastStubSecondShapeGuard() const {
-        return lastStubSecondShapeGuard ? POST_INST_OFFSET(lastStubSecondShapeGuard) : 0;
-    }
-
-    void patchPreviousToHere(CodeLocationLabel cs)
-    {
-        Repatcher repatcher(pic.lastCodeBlock(f.chunk()));
-        CodeLocationLabel label = pic.lastPathStart();
-
-        // Patch either the inline fast path or a generated stub. The stub
-        // omits the prefix of the inline fast path that loads the shape, so
-        // the offsets are different.
-        if (pic.stubsGenerated) {
-            repatcher.relink(pic.setPropLabels().getStubShapeJump(label), cs);
-        } else {
-            CodeLocationLabel shapeGuard = label.labelAtOffset(pic.shapeGuard);
-            repatcher.relink(pic.setPropLabels().getInlineShapeJump(shapeGuard), cs);
-        }
-        if (int secondGuardOffset = getLastStubSecondShapeGuard())
-            repatcher.relink(label.jumpAtOffset(secondGuardOffset), cs);
-    }
-
-    LookupStatus generateStub(HandleShape initialShape, HandleShape shape, bool adding)
-    {
-        if (hadGC())
-            return Lookup_Uncacheable;
-
-        /* Exits to the slow path. */
-        Vector<Jump, 8> slowExits(cx);
-        Vector<Jump, 8> otherGuards(cx);
-
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-
-        // Shape guard.
-        if (pic.shapeNeedsRemat()) {
-            masm.loadShape(pic.objReg, pic.shapeReg);
-            pic.shapeRegHasBaseShape = true;
-        }
-
-        Label start = masm.label();
-        Jump shapeGuard = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                         ImmPtr(initialShape));
-
-        Label stubShapeJumpLabel = masm.label();
-
-        pic.setPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
-
-        if (pic.typeMonitored || adding) {
-            /*
-             * There are now two reasons we would want a type barrier. The
-             * first, if we are Type Monitored:
-             * Inference does not know the type of the object being updated,
-             * and we need to make sure that the updateMonitoredTypes() call
-             * covers this stub, i.e. we will be writing to an object with the
-             * same type. Add a type guard in addition to the shape guard.
-             * Note: it is possible that this test gets a spurious hit if the
-             * object has a lazy type, but in such cases no analyzed scripts
-             * depend on the object and we will reconstruct its type from the
-             * value being written here.
-             * We could also want to add a type monitor if we are simulating
-             * adding the property to the object. This is to ensure that for
-             * objects of different type, but the same shape, we ensure that the
-             * property gets marked as 'own' on the other type objects.
-             */
-            Jump typeGuard = masm.branchPtr(Assembler::NotEqual,
-                                            Address(pic.objReg, JSObject::offsetOfType()),
-                                            ImmPtr(obj->getType(cx)));
-            if (!otherGuards.append(typeGuard))
-                return error();
-        }
-
-        JS_ASSERT_IF(!shape->hasDefaultSetter(), obj->isCall());
-
-        if (adding) {
-            JS_ASSERT(shape->hasSlot());
-            pic.shapeRegHasBaseShape = false;
-
-            RootedObject holder(cx, NULL);
-            if (!GeneratePrototypeGuards(cx, otherGuards, masm, obj, holder,
-                                         pic.objReg, pic.shapeReg)) {
-                return error();
-            }
-
-            /* Emit shape guards for the object's prototype chain. */
-            JSObject *proto = obj->getProto();
-            RegisterID lastReg = pic.objReg;
-            while (proto) {
-                masm.loadPtr(Address(lastReg, JSObject::offsetOfType()), pic.shapeReg);
-                masm.loadPtr(Address(pic.shapeReg, offsetof(types::TypeObject, proto)), pic.shapeReg);
-                Jump protoGuard = masm.guardShape(pic.shapeReg, proto);
-                if (!otherGuards.append(protoGuard))
-                    return error();
-
-                proto = proto->getProto();
-                lastReg = pic.shapeReg;
-            }
-
-            if (obj->isFixedSlot(shape->slot())) {
-                Address address(pic.objReg,
-                                JSObject::getFixedSlotOffset(shape->slot()));
-                masm.storeValue(pic.u.vr, address);
-            } else {
-                /*
-                 * Note: the guard on the initial shape determines the object's
-                 * number of fixed slots and slot span, which in turn determine
-                 * the number of dynamic slots allocated for the object.
-                 * We don't need to check capacity here.
-                 */
-                masm.loadPtr(Address(pic.objReg, JSObject::offsetOfSlots()), pic.shapeReg);
-                Address address(pic.shapeReg, obj->dynamicSlotIndex(shape->slot()) * sizeof(Value));
-                masm.storeValue(pic.u.vr, address);
-            }
-
-            JS_ASSERT(shape == obj->lastProperty());
-            JS_ASSERT(shape != initialShape);
-
-            /* Write the object's new shape. */
-            masm.storePtr(ImmPtr(shape), Address(pic.objReg, JSObject::offsetOfShape()));
-        } else if (shape->hasDefaultSetter()) {
-            Address address = masm.objPropAddress(obj, pic.objReg, shape->slot());
-            masm.storeValue(pic.u.vr, address);
-        }
-
-        Jump done = masm.jump();
-
-        // Common all secondary guards into one big exit.
-        MaybeJump slowExit;
-        if (otherGuards.length()) {
-            for (Jump *pj = otherGuards.begin(); pj != otherGuards.end(); ++pj)
-                pj->linkTo(masm.label(), &masm);
-            slowExit = masm.jump();
-            pic.secondShapeGuard = masm.distanceOf(masm.label()) - masm.distanceOf(start);
-        } else {
-            pic.secondShapeGuard = 0;
-        }
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(shapeGuard, pic.slowPathStart);
-        if (slowExit.isSet())
-            buffer.link(slowExit.get(), pic.slowPathStart);
-        for (Jump *pj = slowExits.begin(); pj != slowExits.end(); ++pj)
-            buffer.link(*pj, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generate setprop stub %p %p %d at %p\n",
-                   (void*)&pic,
-                   (void*)initialShape,
-                   pic.stubsGenerated,
-                   cs.executableAddress());
-
-        // This function can patch either the inline fast path for a generated
-        // stub. The stub omits the prefix of the inline fast path that loads
-        // the shape, so the offsets are different.
-        patchPreviousToHere(cs);
-
-        pic.stubsGenerated++;
-        pic.updateLastPath(buffer, start);
-
-        if (pic.stubsGenerated == MAX_PIC_STUBS)
-            disable("max stubs reached");
-
-        return Lookup_Cacheable;
-    }
-
-    bool updateMonitoredTypes()
-    {
-        JS_ASSERT(pic.typeMonitored);
-
-        RecompilationMonitor monitor(cx);
-
-        types::TypeObject *type = obj->getType(cx);
-        if (monitor.recompiled())
-            return false;
-
-        if (!type->unknownProperties()) {
-            types::AutoEnterAnalysis enter(cx);
-            RootedId id(cx, NameToId(name));
-            types::TypeSet *types = type->getProperty(cx, types::IdToTypeId(id), true);
-            if (!types)
-                return false;
-
-            jsbytecode *pc;
-            RootedScript script(cx, cx->stack.currentScript(&pc));
-
-            if (!script->ensureRanInference(cx) || monitor.recompiled())
-                return false;
-
-            JS_ASSERT(*pc == JSOP_SETPROP || *pc == JSOP_SETNAME);
-
-            types::StackTypeSet *rhsTypes = script->analysis()->poppedTypes(pc, 0);
-            rhsTypes->addSubset(cx, types);
-        }
-
-        return !monitor.recompiled();
-    }
-
-    LookupStatus update()
-    {
-        JS_ASSERT(pic.hit);
-
-        if (!obj->isNative())
-            return disable("non-native");
-        if (obj->watched())
-            return disable("watchpoint");
-
-        Class *clasp = obj->getClass();
-
-        if (clasp->setProperty != JS_StrictPropertyStub)
-            return disable("set property hook");
-        if (clasp->ops.lookupProperty)
-            return disable("ops lookup property hook");
-        if (clasp->ops.setProperty)
-            return disable("ops set property hook");
-
-        RootedObject holder(cx);
-        RootedShape shape(cx);
-
-        /* lookupProperty can trigger recompilations. */
-        RecompilationMonitor monitor(cx);
-        if (!JSObject::lookupProperty(cx, obj, name, &holder, &shape))
-            return error();
-        if (monitor.recompiled())
-            return Lookup_Uncacheable;
-
-        /* If the property exists but is on a prototype, treat as addprop. */
-        if (shape && holder != obj) {
-            if (!holder->isNative())
-                return disable("non-native holder");
-
-            if (!shape->writable())
-                return disable("readonly");
-            if (!shape->hasDefaultSetter() || !shape->hasDefaultGetter())
-                return disable("getter/setter in prototype");
-            if (shape->hasShortID())
-                return disable("short ID in prototype");
-            if (!shape->hasSlot())
-                return disable("missing slot");
-
-            shape = NULL;
-        }
-
-        if (!shape) {
-            /* Adding a property to the object. */
-            if (obj->isDelegate())
-                return disable("delegate");
-            if (!obj->isExtensible())
-                return disable("not extensible");
-
-            if (clasp->addProperty != JS_PropertyStub)
-                return disable("add property hook");
-            if (clasp->ops.defineProperty)
-                return disable("ops define property hook");
-
-            /*
-             * Don't add properties for SETNAME, which requires checks in
-             * strict mode code.
-             */
-            if (JSOp(*f.pc()) == JSOP_SETNAME)
-                return disable("add property under SETNAME");
-
-            /*
-             * When adding a property we need to check shapes along the entire
-             * prototype chain to watch for an added setter.
-             */
-            JSObject *proto = obj;
-            while (proto) {
-                if (!proto->isNative())
-                    return disable("non-native proto");
-                proto = proto->getProto();
-            }
-
-            RootedShape initialShape(cx, obj->lastProperty());
-            uint32_t slots = obj->numDynamicSlots();
-
-            unsigned flags = 0;
-            PropertyOp getter = clasp->getProperty;
-
-            /*
-             * Define the property but do not set it yet. For setmethod,
-             * populate the slot to satisfy the method invariant (in case we
-             * hit an early return below).
-             */
-            shape = JSObject::putProperty(cx, obj, name, getter, clasp->setProperty,
-                                          SHAPE_INVALID_SLOT, JSPROP_ENUMERATE, flags, 0);
-            if (!shape)
-                return error();
-
-            if (monitor.recompiled())
-                return Lookup_Uncacheable;
-
-            /*
-             * Test after calling putProperty since it can switch obj into
-             * dictionary mode, specifically if the shape tree ancestor line
-             * exceeds PropertyTree::MAX_HEIGHT.
-             */
-            if (obj->inDictionaryMode())
-                return disable("dictionary");
-
-            if (!shape->hasDefaultSetter())
-                return disable("adding non-default setter");
-            if (!shape->hasSlot())
-                return disable("adding invalid slot");
-
-            /*
-             * Watch for cases where the object reallocated its slots when
-             * adding the property, and disable the PIC.  Otherwise we will
-             * keep generating identical PICs as side exits are taken on the
-             * capacity checks.  Alternatively, we could avoid the disable
-             * and just not generate a stub in case there are multiple shapes
-             * that can flow here which don't all require reallocation.
-             * Doing this would cause us to walk down this same update path
-             * every time a reallocation is needed, however, which will
-             * usually be a slowdown even if there *are* other shapes that
-             * don't realloc.
-             */
-            if (obj->numDynamicSlots() != slots)
-                return disable("insufficient slot capacity");
-
-#ifdef JSGC_INCREMENTAL_MJ
-            /*
-             * Since we're changing the object's shape, we need a write
-             * barrier. Taking the slow path is the easiest way to get one.
-             */
-            if (cx->zone()->compileBarriers())
-                return disable("ADDPROP write barrier required");
-#endif
-
-            if (pic.typeMonitored && !updateMonitoredTypes())
-                return Lookup_Uncacheable;
-
-            return generateStub(initialShape, shape, true);
-        }
-
-        if (!shape->writable())
-            return disable("readonly");
-        if (shape->hasDefaultSetter()) {
-            if (!shape->hasSlot())
-                return disable("invalid slot");
-            if (pic.typeMonitored && !updateMonitoredTypes())
-                return Lookup_Uncacheable;
-        } else {
-            return disable("setter");
-        }
-
-        JS_ASSERT(obj == holder);
-        if (!pic.inlinePathPatched &&
-            shape->hasDefaultSetter() &&
-            !pic.typeMonitored)
-        {
-            pic.setInlinePathShape(obj->lastProperty());
-            return patchInline(shape);
-        }
-
-        RootedShape initialShape(cx, obj->lastProperty());
-        return generateStub(initialShape, shape, false);
-    }
-};
-
-static bool
-IsCacheableProtoChain(JSObject *obj, JSObject *holder)
-{
-    while (obj != holder) {
-        /*
-         * We cannot assume that we find the holder object on the prototype
-         * chain and must check for null proto. The prototype chain can be
-         * altered during the lookupProperty call.
-         */
-        TaggedProto proto = obj->getTaggedProto();
-        if (!proto.isObject() || !proto.toObject()->isNative())
-            return false;
-        obj = proto.toObject();
-    }
-    return true;
-}
-
-static bool
-IsCacheableListBase(JSObject *obj)
-{
-    if (!obj->isProxy())
-        return false;
-
-    BaseProxyHandler *handler = GetProxyHandler(obj);
-
-    if (handler->family() != GetListBaseHandlerFamily())
-        return false;
-
-    if (obj->numFixedSlots() <= GetListBaseExpandoSlot())
-        return false;
-
-    return true;
-}
-
-template <typename IC>
-struct GetPropHelper {
-    // These fields are set in the constructor and describe a property lookup.
-    JSContext          *cx;
-    RootedObject       obj;
-    RootedPropertyName name;
-    IC                 &ic;
-    VMFrame            &f;
-
-    // These fields are set by |bind| and |lookup|. After a call to either
-    // function, these are set exactly as they are in JSOP_GETPROP or JSOP_NAME.
-    RootedObject       holder;
-    RootedShape        prop;
-
-    // This field is set by |bind| and |lookup| only if they returned
-    // Lookup_Cacheable, otherwise it is NULL.
-    RootedShape        shape;
-
-    GetPropHelper(JSContext *cx, JSObject *obj, PropertyName *name, IC &ic, VMFrame &f)
-      : cx(cx), obj(cx, obj), name(cx, name), ic(ic), f(f), holder(cx), prop(cx), shape(cx)
-    { }
-
-  public:
-    LookupStatus bind() {
-        RecompilationMonitor monitor(cx);
-        RootedObject scopeChain(cx, cx->stack.currentScriptedScopeChain());
-        if (js_CodeSpec[*f.pc()].format & JOF_GNAME)
-            scopeChain = &scopeChain->global();
-        if (!LookupName(cx, name, scopeChain, &obj, &holder, &prop))
-            return ic.error(cx);
-        if (monitor.recompiled())
-            return Lookup_Uncacheable;
-        if (!prop)
-            return ic.disable(cx, "lookup failed");
-        if (!obj->isNative())
-            return ic.disable(cx, "non-native");
-        if (!IsCacheableProtoChain(obj, holder))
-            return ic.disable(cx, "non-native holder");
-        shape = prop;
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus lookup() {
-        RootedObject aobj(cx, obj);
-        if (IsCacheableListBase(obj)) {
-            RootedId aid(cx, NameToId(name));
-            ListBaseShadowsResult shadows =
-                GetListBaseShadowsCheck()(cx, obj, aid);
-            if (shadows == ShadowCheckFailed)
-                return ic.error(cx);
-            // Either the property is shadowed or we need an additional check in
-            // the stub, which we haven't implemented.
-            if (shadows == Shadows || shadows == DoesntShadowUnique)
-                return Lookup_Uncacheable;
-            aobj = obj->getTaggedProto().toObjectOrNull();
-        }
-
-        if (!aobj->isNative())
-            return ic.disable(f, "non-native");
-
-        RecompilationMonitor monitor(cx);
-        if (!JSObject::lookupProperty(cx, aobj, name, &holder, &prop))
-            return ic.error(cx);
-        if (monitor.recompiled())
-            return Lookup_Uncacheable;
-
-        if (!prop) {
-            /*
-             * Just because we didn't find the property on the object doesn't
-             * mean it won't magically appear through various engine hacks:
-             */
-            if (obj->getClass()->getProperty && obj->getClass()->getProperty != JS_PropertyStub)
-                return Lookup_Uncacheable;
-
-            /*
-             * Don't generate missing property ICs if we skipped a non-native
-             * object, as lookups may extend beyond the prototype chain (e.g.
-             * for ListBase proxies).
-             */
-            JSObject *obj2 = obj;
-            while (obj2) {
-                if (!obj2->isNative())
-                    return Lookup_Uncacheable;
-                obj2 = obj2->getProto();
-            }
-
-#if JS_HAS_NO_SUCH_METHOD
-            /*
-             * The __noSuchMethod__ hook may substitute in a valid method.
-             * Since, if o.m is missing, o.m() will probably be an error,
-             * just mark all missing callprops as uncacheable.
-             */
-            if (*f.pc() == JSOP_CALLPROP)
-                return Lookup_Uncacheable;
-#endif
-
-            return Lookup_NoProperty;
-        }
-        if (!IsCacheableProtoChain(obj, holder))
-            return ic.disable(f, "non-native holder");
-        shape = prop;
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus testForGet() {
-        if (!shape->hasDefaultGetter()) {
-            if (shape->hasGetterValue()) {
-                JSObject *getterObj = shape->getterObject();
-                if (!getterObj->isFunction() || !getterObj->toFunction()->isNative())
-                    return ic.disable(f, "getter object not a native function");
-            }
-            if (shape->hasSlot() && holder != obj)
-                return ic.disable(f, "slotful getter hook through prototype");
-            if (!ic.canCallHook)
-                return ic.disable(f, "can't call getter hook");
-            if (f.regs.inlined()) {
-                /*
-                 * As with native stubs, getter hook stubs can't be
-                 * generated for inline frames. Mark the inner function
-                 * as uninlineable and recompile.
-                 */
-                f.script()->uninlineable = true;
-                MarkTypeObjectFlags(cx, f.script()->function(),
-                                    types::OBJECT_FLAG_UNINLINEABLE);
-                return Lookup_Uncacheable;
-            }
-        } else if (!shape->hasSlot()) {
-            return ic.disable(f, "no slot");
-        }
-
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus lookupAndTest() {
-        LookupStatus status = lookup();
-        if (status != Lookup_Cacheable)
-            return status;
-        return testForGet();
-    }
-};
-
-namespace js {
-namespace mjit {
-
-class GetPropCompiler : public PICStubCompiler
-{
-    RootedObject obj;
-    RootedPropertyName name;
-    int lastStubSecondShapeGuard;
-
-  public:
-    GetPropCompiler(VMFrame &f, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
-                    VoidStubPIC stub)
-      : PICStubCompiler("getprop", f, pic,
-                        JS_FUNC_TO_DATA_PTR(void *, stub)),
-        obj(f.cx, obj),
-        name(f.cx, name),
-        lastStubSecondShapeGuard(pic.secondShapeGuard)
-    { }
-
-    int getLastStubSecondShapeGuard() const {
-        return lastStubSecondShapeGuard ? POST_INST_OFFSET(lastStubSecondShapeGuard) : 0;
-    }
-
-    static void reset(Repatcher &repatcher, ic::PICInfo &pic)
-    {
-        GetPropLabels &labels = pic.getPropLabels();
-        repatcher.repatchLEAToLoadPtr(labels.getDslotsLoad(pic.fastPathRejoin));
-        repatcher.repatch(labels.getInlineShapeData(pic.getFastShapeGuard()), NULL);
-        repatcher.relink(labels.getInlineShapeJump(pic.getFastShapeGuard()), pic.slowPathStart);
-
-        if (pic.hasTypeCheck()) {
-            /* TODO: combine pic.u.get into ICLabels? */
-            repatcher.relink(labels.getInlineTypeJump(pic.fastPathStart), pic.getSlowTypeCheck());
-        }
-
-        JS_ASSERT(pic.kind == ic::PICInfo::GET);
-
-        FunctionPtr target(JS_FUNC_TO_DATA_PTR(void *, ic::GetProp));
-        repatcher.relink(pic.slowPathCall, target);
-    }
-
-    LookupStatus generateArrayLengthStub()
-    {
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-
-        masm.loadObjClass(pic.objReg, pic.shapeReg);
-        Jump notArray = masm.testClass(Assembler::NotEqual, pic.shapeReg, &ArrayClass);
-
-        masm.loadPtr(Address(pic.objReg, JSObject::offsetOfElements()), pic.objReg);
-        masm.load32(Address(pic.objReg, ObjectElements::offsetOfLength()), pic.objReg);
-        Jump oob = masm.branch32(Assembler::Above, pic.objReg, Imm32(JSVAL_INT_MAX));
-        masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
-        Jump done = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(notArray, pic.slowPathStart);
-        buffer.link(oob, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-
-        CodeLocationLabel start = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generate array length stub at %p\n",
-                   start.executableAddress());
-
-        patchPreviousToHere(start);
-
-        disable("array length done");
-
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus generateStringObjLengthStub()
-    {
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-
-        Jump notStringObj = masm.guardShape(pic.objReg, obj);
-
-        masm.loadPayload(Address(pic.objReg, StringObject::offsetOfLength()), pic.objReg);
-        masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
-        Jump done = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(notStringObj, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-
-        CodeLocationLabel start = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generate string object length stub at %p\n",
-                   start.executableAddress());
-
-        patchPreviousToHere(start);
-
-        disable("string object length done");
-
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus generateStringPropertyStub()
-    {
-        if (!f.fp()->script()->compileAndGo)
-            return disable("String.prototype without compile-and-go global");
-
-        RecompilationMonitor monitor(f.cx);
-
-        RootedObject obj(f.cx, f.fp()->global().getOrCreateStringPrototype(f.cx));
-        if (!obj)
-            return error();
-
-        if (monitor.recompiled())
-            return Lookup_Uncacheable;
-
-        GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
-        LookupStatus status = getprop.lookupAndTest();
-        if (status != Lookup_Cacheable)
-            return status;
-        if (getprop.obj != getprop.holder)
-            return disable("proto walk on String.prototype");
-        if (!getprop.shape->hasDefaultGetter())
-            return disable("getter hook on String.prototype");
-        if (hadGC())
-            return Lookup_Uncacheable;
-
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-
-        /* Only strings are allowed. */
-        Jump notString = masm.branchPtr(Assembler::NotEqual, pic.typeReg(),
-                                        ImmType(JSVAL_TYPE_STRING));
-
-        /*
-         * Clobber objReg with String.prototype and do some PIC stuff. Well,
-         * really this is now a MIC, except it won't ever be patched, so we
-         * just disable the PIC at the end. :FIXME:? String.prototype probably
-         * does not get random shape changes.
-         */
-        masm.move(ImmPtr(obj), pic.objReg);
-        masm.loadShape(pic.objReg, pic.shapeReg);
-        Jump shapeMismatch = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                            ImmPtr(obj->lastProperty()));
-        masm.loadObjProp(obj, pic.objReg, getprop.shape, pic.shapeReg, pic.objReg);
-
-        Jump done = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(notString, pic.getSlowTypeCheck());
-        buffer.link(shapeMismatch, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generate string call stub at %p\n",
-                   cs.executableAddress());
-
-        /* Patch the type check to jump here. */
-        if (pic.hasTypeCheck()) {
-            Repatcher repatcher(f.chunk());
-            repatcher.relink(pic.getPropLabels().getInlineTypeJump(pic.fastPathStart), cs);
-        }
-
-        /* Disable the PIC so we don't keep generating stubs on the above shape mismatch. */
-        disable("generated string call stub");
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus generateStringLengthStub()
-    {
-        JS_ASSERT(pic.hasTypeCheck());
-
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-        Jump notString = masm.branchPtr(Assembler::NotEqual, pic.typeReg(),
-                                        ImmType(JSVAL_TYPE_STRING));
-        masm.loadPtr(Address(pic.objReg, JSString::offsetOfLengthAndFlags()), pic.objReg);
-        // String length is guaranteed to be no more than 2**28, so the 32-bit operation is OK.
-        masm.urshift32(Imm32(JSString::LENGTH_SHIFT), pic.objReg);
-        masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
-        Jump done = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(notString, pic.getSlowTypeCheck());
-        buffer.link(done, pic.fastPathRejoin);
-
-        CodeLocationLabel start = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generate string length stub at %p\n",
-                   start.executableAddress());
-
-        if (pic.hasTypeCheck()) {
-            Repatcher repatcher(f.chunk());
-            repatcher.relink(pic.getPropLabels().getInlineTypeJump(pic.fastPathStart), start);
-        }
-
-        disable("generated string length stub");
-
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus patchInline(JSObject *holder, Shape *shape)
-    {
-        spew("patch", "inline");
-        Repatcher repatcher(f.chunk());
-        GetPropLabels &labels = pic.getPropLabels();
-
-        int32_t offset;
-        if (holder->isFixedSlot(shape->slot())) {
-            CodeLocationInstruction istr = labels.getDslotsLoad(pic.fastPathRejoin);
-            repatcher.repatchLoadPtrToLEA(istr);
-
-            //
-            // We've patched | mov dslots, [obj + DSLOTS_OFFSET]
-            // To:           | lea fslots, [obj + DSLOTS_OFFSET]
-            //
-            // Because the offset is wrong, it's necessary to correct it
-            // below.
-            //
-            int32_t diff = int32_t(JSObject::getFixedSlotOffset(0)) -
-                         int32_t(JSObject::offsetOfSlots());
-            JS_ASSERT(diff != 0);
-            offset  = (int32_t(shape->slot()) * sizeof(Value)) + diff;
-        } else {
-            offset = holder->dynamicSlotIndex(shape->slot()) * sizeof(Value);
-        }
-
-        repatcher.repatch(labels.getInlineShapeData(pic.getFastShapeGuard()), obj->lastProperty());
-        repatcher.patchAddressOffsetForValueLoad(labels.getValueLoad(pic.fastPathRejoin), offset);
-
-        pic.inlinePathPatched = true;
-
-        return Lookup_Cacheable;
-    }
-
-    /* For JSPropertyOp getters. */
-    void generateGetterStub(Assembler &masm, Shape *shape, jsid userid,
-                            Label start, Vector<Jump, 8> &shapeMismatches)
-    {
-        /*
-         * Getter hook needs to be called from the stub. The state is fully
-         * synced and no registers are live except the result registers.
-         */
-        JS_ASSERT(pic.canCallHook);
-        PropertyOp getter = shape->getterOp();
-
-        masm.storePtr(ImmPtr((void *) REJOIN_NATIVE_GETTER),
-                      FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-        Registers tempRegs = Registers::tempCallRegMask();
-        if (tempRegs.hasReg(Registers::ClobberInCall))
-            tempRegs.takeReg(Registers::ClobberInCall);
-
-        /* Get a register to hold obj while we set up the rest of the frame. */
-        RegisterID holdObjReg = pic.objReg;
-        if (tempRegs.hasReg(pic.objReg)) {
-            tempRegs.takeReg(pic.objReg);
-        } else {
-            holdObjReg = tempRegs.takeAnyReg().reg();
-            masm.move(pic.objReg, holdObjReg);
-        }
-
-        RegisterID t0 = tempRegs.takeAnyReg().reg();
-        masm.bumpStubCount(f.script(), f.pc(), t0);
-
-        /*
-         * Use three values above sp on the stack for use by the call to store
-         * the object and id being passed into the call as handles and to store
-         * the resulting value. Temporary slots are used by GETPROP for this,
-         * plus there is extra room on the stack reserved for a callee frame.
-         */
-        int32_t initialFrameDepth = f.regs.sp - f.fp()->slots() + 3;
-        int32_t vpOffset = (char *) f.regs.sp - (char *) f.fp();
-        int32_t idHandleOffset = (char *) (f.regs.sp + 1) - (char *) f.fp();
-        int32_t objHandleOffset = (char *) (f.regs.sp + 2) - (char *) f.fp();
-
-        /*
-         * Make sure we handle endianness correctly.
-         */
-        masm.storePtr(holdObjReg, masm.payloadOf(Address(JSFrameReg, objHandleOffset)));
-        masm.storePtr(ImmPtr((void *) JSID_BITS(userid)), masm.payloadOf(Address(JSFrameReg, idHandleOffset)));
-
-        /*
-         * On 32 bit platforms zero the upper portion of the values so that
-         * the GC does not see a corrupt value in the handle slots. The two
-         * slots will look like doubles, so won't be traced, but the objects
-         * will be held live by the object value still in place on the stack.
-         * This will need to be addressed once a moving GC can relocate the
-         * objects, as the created handles will need to be properly registered.
-         */
-#if JS_BITS_PER_WORD == 32
-        masm.storePtr(ImmPtr(NULL), masm.tagOf(Address(JSFrameReg, objHandleOffset)));
-        masm.storePtr(ImmPtr(NULL), masm.tagOf(Address(JSFrameReg, idHandleOffset)));
-#endif
-
-        if (shape->hasSlot()) {
-            masm.loadObjProp(obj, holdObjReg, shape,
-                             Registers::ClobberInCall, t0);
-            masm.storeValueFromComponents(Registers::ClobberInCall, t0, Address(JSFrameReg, vpOffset));
-        } else {
-            masm.storeValue(UndefinedValue(), Address(JSFrameReg, vpOffset));
-        }
-
-        masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, initialFrameDepth);
-
-        /* Grab cx. */
-#ifdef JS_CPU_X86
-        RegisterID cxReg = tempRegs.takeAnyReg().reg();
-#else
-        RegisterID cxReg = Registers::ArgReg0;
-#endif
-        masm.loadPtr(FrameAddress(offsetof(VMFrame, cx)), cxReg);
-
-        /* Use a temporary for parameters. */
-        masm.addPtr(Imm32(vpOffset), JSFrameReg, t0);
-
-        masm.restoreStackBase();
-        masm.setupABICall(Registers::NormalCall, 4);
-        masm.storeArg(3, t0);
-        masm.addPtr(Imm32(idHandleOffset - vpOffset + Assembler::PAYLOAD_OFFSET), t0);
-        masm.storeArg(2, t0);
-        masm.addPtr(Imm32(objHandleOffset - idHandleOffset), t0);
-        masm.storeArg(1, t0);
-        masm.storeArg(0, cxReg);
-
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, getter), false);
-
-        NativeStubLinker::FinalJump done;
-        if (!NativeStubEpilogue(f, masm, &done, 0, vpOffset, pic.shapeReg, pic.objReg))
-            return;
-        NativeStubLinker linker(masm, f.chunk(), f.regs.pc, done);
-        if (!linker.init(f.cx))
-            THROW();
-
-        if (!linker.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !linker.verifyRange(f.chunk())) {
-            disable("code memory is out of range");
-            return;
-        }
-
-        linker.patchJump(pic.fastPathRejoin);
-
-        linkerEpilogue(linker, start, shapeMismatches);
-    }
-
-    /* For getters backed by a JSNative. */
-    void generateNativeGetterStub(Assembler &masm, Shape *shape,
-                                  Label start, Vector<Jump, 8> &shapeMismatches)
-    {
-       /*
-         * Getter hook needs to be called from the stub. The state is fully
-         * synced and no registers are live except the result registers.
-         */
-        JS_ASSERT(pic.canCallHook);
-
-        JSFunction *fun = shape->getterObject()->toFunction();
-        Native native = fun->native();
-
-        masm.storePtr(ImmPtr((void *) REJOIN_NATIVE_GETTER),
-                      FrameAddress(offsetof(VMFrame, stubRejoin)));
-
-        Registers tempRegs = Registers::tempCallRegMask();
-        if (tempRegs.hasReg(Registers::ClobberInCall))
-            tempRegs.takeReg(Registers::ClobberInCall);
-
-        /* Get a register to hold obj while we set up the rest of the frame. */
-        RegisterID holdObjReg = pic.objReg;
-        if (tempRegs.hasReg(pic.objReg)) {
-            tempRegs.takeReg(pic.objReg);
-        } else {
-            holdObjReg = tempRegs.takeAnyReg().reg();
-            masm.move(pic.objReg, holdObjReg);
-        }
-
-        RegisterID t0 = tempRegs.takeAnyReg().reg();
-        masm.bumpStubCount(f.script(), f.pc(), t0);
-
-        /*
-         * A JSNative has the following signature:
-         *
-         *   JSBool native(JSContext *cx, unsigned argc, Value *vp);
-         *
-         * Since we are calling a getter, argc is always 0. vp must point to two
-         * values, the callee and the holder. We use vp == sp to avoid clobbering
-         * stack values.
-         */
-        int32_t vpOffset = (char *) f.regs.sp - (char *) f.fp();
-
-        masm.storeValue(ObjectValue(*fun), Address(JSFrameReg, vpOffset));
-        masm.storeValueFromComponents(ImmType(JSVAL_TYPE_OBJECT), holdObjReg,
-                                      Address(JSFrameReg, vpOffset + sizeof(js::Value)));
-
-        /*
-         * sp + 2 to avoid clobbering vp[0] and vp[1] if the getter calls
-         * scripted functions.
-         */
-        int32_t initialFrameDepth = f.regs.sp + 2 - f.fp()->slots();
-        masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, initialFrameDepth);
-
-        /* Grab cx. */
-#ifdef JS_CPU_X86
-        RegisterID cxReg = tempRegs.takeAnyReg().reg();
-#else
-        RegisterID cxReg = Registers::ArgReg0;
-#endif
-        masm.loadPtr(FrameAddress(offsetof(VMFrame, cx)), cxReg);
-
-        /* Grab vp. */
-        RegisterID vpReg = t0;
-        masm.addPtr(Imm32(vpOffset), JSFrameReg, vpReg);
-
-        masm.restoreStackBase();
-        masm.setupABICall(Registers::NormalCall, 3);
-        masm.storeArg(2, vpReg);
-        masm.storeArg(1, Imm32(0)); // argc
-        masm.storeArg(0, cxReg);
-
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, native), false);
-
-        NativeStubLinker::FinalJump done;
-        if (!NativeStubEpilogue(f, masm, &done, 0, vpOffset, pic.shapeReg, pic.objReg))
-            return;
-        NativeStubLinker linker(masm, f.chunk(), f.regs.pc, done);
-        if (!linker.init(f.cx))
-            THROW();
-
-        if (!linker.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !linker.verifyRange(f.chunk())) {
-            disable("code memory is out of range");
-            return;
-        }
-
-        linker.patchJump(pic.fastPathRejoin);
-
-        linkerEpilogue(linker, start, shapeMismatches);
-    }
-
-    LookupStatus generateStub(HandleObject holder, HandleShape shape)
-    {
-        Vector<Jump, 8> shapeMismatches(cx);
-
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-
-        // Ignore GC pointers baked into assembly visible on the stack.
-        SkipRoot skip(cx, &masm);
-
-        Label start;
-        Jump shapeGuardJump;
-        Jump argsLenGuard;
-
-        if (pic.shapeNeedsRemat()) {
-            masm.loadShape(pic.objReg, pic.shapeReg);
-            pic.shapeRegHasBaseShape = true;
-        }
-
-        start = masm.label();
-        shapeGuardJump = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                        ImmPtr(obj->lastProperty()));
-        Label stubShapeJumpLabel = masm.label();
-
-        if (!shapeMismatches.append(shapeGuardJump))
-            return error();
-
-        // Guard on the proxy guts for ListBase accesses, if applicable.
-        if (IsCacheableListBase(obj)) {
-            // The shape check above ensures this is a proxy with the correct
-            // number of fixed slots, but we need further checks to ensure that
-            //
-            // (a) the object is a ListBase.
-            // (b) the object does not have any expando properties, or has an
-            //     expando which does not have the desired property.
-            //
-            // If both of these hold, all accesses on non-indexed PropertyName
-            // properties will go through the object's native prototype chain.
-
-            Address handler(pic.objReg, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
-            Jump handlerGuard = masm.testPrivate(Assembler::NotEqual, handler, GetProxyHandler(obj));
-            if (!shapeMismatches.append(handlerGuard))
-                return error();
-
-            Address expandoAddress(pic.objReg, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
-
-            Value expandoValue = obj->getFixedSlot(GetListBaseExpandoSlot());
-            if (expandoValue.isObject()) {
-                JS_ASSERT(!expandoValue.toObject().nativeContains(cx, name));
-
-                // Reference object has an expando object that doesn't define the name. Check that
-                // the incoming object has an expando object with the same shape.
-                Jump expandoGuard = masm.testObject(Assembler::NotEqual, expandoAddress);
-                if (!shapeMismatches.append(expandoGuard))
-                    return error();
-
-                masm.loadPayload(expandoAddress, pic.shapeReg);
-                pic.shapeRegHasBaseShape = false;
-
-                Jump shapeGuard = masm.branchPtr(Assembler::NotEqual,
-                                                 Address(pic.shapeReg, JSObject::offsetOfShape()),
-                                                 ImmPtr(expandoValue.toObject().lastProperty()));
-                if (!shapeMismatches.append(shapeGuard))
-                    return error();
-            } else {
-                // If the incoming object does not have an expando object then
-                // we're sure we're not shadowing.
-                Jump expandoGuard = masm.testUndefined(Assembler::NotEqual, expandoAddress);
-                if (!shapeMismatches.append(expandoGuard))
-                    return error();
-            }
-        }
-
-        RegisterID holderReg = pic.objReg;
-        if (obj != holder) {
-            if (!GeneratePrototypeGuards(cx, shapeMismatches, masm, obj, holder,
-                                         pic.objReg, pic.shapeReg)) {
-                return error();
-            }
-
-            if (holder) {
-                // Bake in the holder identity. Careful not to clobber |objReg|, since we can't remat it.
-                holderReg = pic.shapeReg;
-                masm.move(ImmPtr(holder), holderReg);
-                pic.shapeRegHasBaseShape = false;
-
-                // Guard on the holder's shape.
-                Jump j = masm.guardShape(holderReg, holder);
-                if (!shapeMismatches.append(j))
-                    return error();
-            } else {
-                // Like when we add a property, we need to guard on the shape of
-                // everything on the prototype chain.
-                JSObject *proto = obj->getTaggedProto().toObjectOrNull();
-                RegisterID lastReg = pic.objReg;
-                while (proto) {
-                    masm.loadPtr(Address(lastReg, JSObject::offsetOfType()), pic.shapeReg);
-                    masm.loadPtr(Address(pic.shapeReg, offsetof(types::TypeObject, proto)), pic.shapeReg);
-                    Jump protoGuard = masm.guardShape(pic.shapeReg, proto);
-                    if (!shapeMismatches.append(protoGuard))
-                        return error();
-
-                    proto = proto->getProto();
-                    lastReg = pic.shapeReg;
-                }
-            }
-
-            pic.secondShapeGuard = masm.distanceOf(masm.label()) - masm.distanceOf(start);
-        } else {
-            pic.secondShapeGuard = 0;
-        }
-
-        if (shape && !shape->hasDefaultGetter()) {
-            if (shape->hasGetterValue()) {
-                generateNativeGetterStub(masm, shape, start, shapeMismatches);
-            } else {
-                RootedId userid(cx);
-                if (!shape->getUserId(cx, &userid))
-                    return error();
-                generateGetterStub(masm, shape, userid, start, shapeMismatches);
-            }
-            pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
-            return Lookup_Cacheable;
-        }
-
-        /*
-         * A non-null 'shape' tells us where to find the property value in the
-         * holder object. A null shape means that the above checks guard the
-         * absence of the property, so the get-prop returns 'undefined'. A
-         * missing property guarantees a type barrier below so we don't have to
-         * check type information.
-         */
-        if (shape)
-            masm.loadObjProp(holder, holderReg, shape, pic.shapeReg, pic.objReg);
-        else
-            masm.loadValueAsComponents(UndefinedValue(), pic.shapeReg, pic.objReg);
-
-        Jump done = masm.jump();
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        // The final exit jumps to the store-back in the inline stub.
-        buffer.link(done, pic.fastPathRejoin);
-
-        linkerEpilogue(buffer, start, shapeMismatches);
-
-        pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
-        return Lookup_Cacheable;
-    }
-
-    void linkerEpilogue(LinkerHelper &buffer, Label start, Vector<Jump, 8> &shapeMismatches)
-    {
-        // The guard exit jumps to the original slow case.
-        for (Jump *pj = shapeMismatches.begin(); pj != shapeMismatches.end(); ++pj)
-            buffer.link(*pj, pic.slowPathStart);
-
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generated %s stub at %p\n", type, cs.executableAddress());
-
-        patchPreviousToHere(cs);
-
-        pic.stubsGenerated++;
-        pic.updateLastPath(buffer, start);
-
-        if (pic.stubsGenerated == MAX_PIC_STUBS)
-            disable("max stubs reached");
-    }
-
-    void patchPreviousToHere(CodeLocationLabel cs)
-    {
-        Repatcher repatcher(pic.lastCodeBlock(f.chunk()));
-        CodeLocationLabel label = pic.lastPathStart();
-
-        // Patch either the inline fast path or a generated stub. The stub
-        // omits the prefix of the inline fast path that loads the shape, so
-        // the offsets are different.
-        int shapeGuardJumpOffset;
-        if (pic.stubsGenerated)
-            shapeGuardJumpOffset = pic.getPropLabels().getStubShapeJumpOffset();
-        else
-            shapeGuardJumpOffset = pic.shapeGuard + pic.getPropLabels().getInlineShapeJumpOffset();
-        int secondGuardOffset = getLastStubSecondShapeGuard();
-
-        JaegerSpew(JSpew_PICs, "Patching previous (%d stubs) (start %p) (offset %d) (second %d)\n",
-                   (int) pic.stubsGenerated, label.executableAddress(),
-                   shapeGuardJumpOffset, secondGuardOffset);
-
-        repatcher.relink(label.jumpAtOffset(shapeGuardJumpOffset), cs);
-        if (secondGuardOffset)
-            repatcher.relink(label.jumpAtOffset(secondGuardOffset), cs);
-    }
-
-    LookupStatus update()
-    {
-        JS_ASSERT(pic.hit);
-
-        GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
-        RecompilationMonitor monitor(cx);
-        LookupStatus status = getprop.lookupAndTest();
-
-        if (status != Lookup_Cacheable && status != Lookup_NoProperty) {
-            /* Don't touch the IC if it may have been destroyed. */
-            if (!monitor.recompiled())
-                pic.hadUncacheable = true;
-            return status;
-        }
-
-        if (hadGC())
-            return Lookup_Uncacheable;
-
-        if (obj == getprop.holder &&
-            getprop.shape->hasDefaultGetter() &&
-            !pic.inlinePathPatched)
-        {
-            pic.setInlinePathShape(obj->lastProperty());
-            return patchInline(getprop.holder, getprop.shape);
-        }
-
-        return generateStub(getprop.holder, getprop.shape);
-    }
-};
-
-}  // namespace mjit
-}  // namespace js
-
-class ScopeNameCompiler : public PICStubCompiler
-{
-  private:
-    typedef Vector<Jump, 8> JumpList;
-
-    RootedObject scopeChain;
-    RootedPropertyName name;
-    GetPropHelper<ScopeNameCompiler> getprop;
-    ScopeNameCompiler *thisFromCtor() { return this; }
-
-    void patchPreviousToHere(CodeLocationLabel cs)
-    {
-        ScopeNameLabels &       labels = pic.scopeNameLabels();
-        Repatcher               repatcher(pic.lastCodeBlock(f.chunk()));
-        CodeLocationLabel       start = pic.lastPathStart();
-        JSC::CodeLocationJump   jump;
-
-        // Patch either the inline fast path or a generated stub.
-        if (pic.stubsGenerated)
-            jump = labels.getStubJump(start);
-        else
-            jump = labels.getInlineJump(start);
-        repatcher.relink(jump, cs);
-    }
-
-    LookupStatus walkScopeChain(Assembler &masm, JumpList &fails)
-    {
-        /* Walk the scope chain. */
-        JSObject *tobj = scopeChain;
-
-        /* For GETXPROP, we'll never enter this loop. */
-        JS_ASSERT_IF(pic.kind == ic::PICInfo::XNAME, tobj && tobj == getprop.holder);
-        JS_ASSERT_IF(pic.kind == ic::PICInfo::XNAME, getprop.obj == tobj);
-
-        while (tobj && tobj != getprop.holder) {
-            if (!IsCacheableNonGlobalScope(tobj))
-                return disable("non-cacheable scope chain object");
-            JS_ASSERT(tobj->isNative());
-
-            /* Guard on intervening shapes. */
-            masm.loadShape(pic.objReg, pic.shapeReg);
-            Jump j = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                    ImmPtr(tobj->lastProperty()));
-            if (!fails.append(j))
-                return error();
-
-            /* Load the next link in the scope chain. */
-            Address parent(pic.objReg, ScopeObject::offsetOfEnclosingScope());
-            masm.loadPayload(parent, pic.objReg);
-
-            tobj = &tobj->asScope().enclosingScope();
-        }
-
-        if (tobj != getprop.holder)
-            return disable("scope chain walk terminated early");
-
-        return Lookup_Cacheable;
-    }
-
-  public:
-    ScopeNameCompiler(VMFrame &f, JSObject *scopeChain, ic::PICInfo &pic,
-                      PropertyName *name, VoidStubPIC stub)
-      : PICStubCompiler("name", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
-        scopeChain(f.cx, scopeChain), name(f.cx, name),
-        getprop(f.cx, NULL, name, *thisFromCtor(), f)
-    { }
-
-    static void reset(Repatcher &repatcher, ic::PICInfo &pic)
-    {
-        ScopeNameLabels &labels = pic.scopeNameLabels();
-
-        /* Link the inline path back to the slow path. */
-        JSC::CodeLocationJump inlineJump = labels.getInlineJump(pic.fastPathStart);
-        repatcher.relink(inlineJump, pic.slowPathStart);
-
-        VoidStubPIC stub;
-        switch (pic.kind) {
-          case ic::PICInfo::NAME:
-            stub = ic::Name;
-            break;
-          case ic::PICInfo::XNAME:
-            stub = ic::XName;
-            break;
-          default:
-            JS_NOT_REACHED("Invalid pic kind in ScopeNameCompiler::reset");
-            return;
-        }
-        FunctionPtr target(JS_FUNC_TO_DATA_PTR(void *, stub));
-        repatcher.relink(pic.slowPathCall, target);
-    }
-
-    LookupStatus generateGlobalStub(JSObject *obj)
-    {
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-        JumpList fails(cx);
-        ScopeNameLabels &labels = pic.scopeNameLabels();
-
-        /* For GETXPROP, the object is already in objReg. */
-        if (pic.kind == ic::PICInfo::NAME)
-            masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), pic.objReg);
-
-        JS_ASSERT(obj == getprop.holder);
-        JS_ASSERT(getprop.holder == &scopeChain->global());
-
-        LookupStatus status = walkScopeChain(masm, fails);
-        if (status != Lookup_Cacheable)
-            return status;
-
-        /* If a scope chain walk was required, the final object needs a NULL test. */
-        MaybeJump finalNull;
-        if (pic.kind == ic::PICInfo::NAME)
-            finalNull = masm.branchTestPtr(Assembler::Zero, pic.objReg, pic.objReg);
-        masm.loadShape(pic.objReg, pic.shapeReg);
-        Jump finalShape = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                         ImmPtr(getprop.holder->lastProperty()));
-
-        masm.loadObjProp(obj, pic.objReg, getprop.shape, pic.shapeReg, pic.objReg);
-
-        Jump done = masm.jump();
-
-        /* All failures flow to here, so there is a common point to patch. */
-        for (Jump *pj = fails.begin(); pj != fails.end(); ++pj)
-            pj->linkTo(masm.label(), &masm);
-        if (finalNull.isSet())
-            finalNull.get().linkTo(masm.label(), &masm);
-        finalShape.linkTo(masm.label(), &masm);
-        Label failLabel = masm.label();
-        Jump failJump = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(failJump, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generated %s global stub at %p\n", type, cs.executableAddress());
-        spew("NAME stub", "global");
-
-        patchPreviousToHere(cs);
-
-        pic.stubsGenerated++;
-        pic.updateLastPath(buffer, failLabel);
-        labels.setStubJump(masm, failLabel, failJump);
-
-        if (pic.stubsGenerated == MAX_PIC_STUBS)
-            disable("max stubs reached");
-
-        return Lookup_Cacheable;
-    }
-
-    enum CallObjPropKind {
-        ARG,
-        VAR
-    };
-
-    LookupStatus generateCallStub(JSObject *obj)
-    {
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-        Vector<Jump, 8> fails(cx);
-        ScopeNameLabels &labels = pic.scopeNameLabels();
-
-        /* For GETXPROP, the object is already in objReg. */
-        if (pic.kind == ic::PICInfo::NAME)
-            masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), pic.objReg);
-
-        JS_ASSERT(obj == getprop.holder);
-        JS_ASSERT(getprop.holder != &scopeChain->global());
-
-        Shape *shape = getprop.shape;
-        if (!shape->hasDefaultGetter())
-            return disable("unhandled callobj sprop getter");
-
-        LookupStatus status = walkScopeChain(masm, fails);
-        if (status != Lookup_Cacheable)
-            return status;
-
-        /* If a scope chain walk was required, the final object needs a NULL test. */
-        MaybeJump finalNull;
-        if (pic.kind == ic::PICInfo::NAME)
-            finalNull = masm.branchTestPtr(Assembler::Zero, pic.objReg, pic.objReg);
-        masm.loadShape(pic.objReg, pic.shapeReg);
-        Jump finalShape = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                         ImmPtr(getprop.holder->lastProperty()));
-        Address address = masm.objPropAddress(obj, pic.objReg, shape->slot());
-
-        /* Safe because type is loaded first. */
-        masm.loadValueAsComponents(address, pic.shapeReg, pic.objReg);
-
-        Jump done = masm.jump();
-
-        // All failures flow to here, so there is a common point to patch.
-        for (Jump *pj = fails.begin(); pj != fails.end(); ++pj)
-            pj->linkTo(masm.label(), &masm);
-        if (finalNull.isSet())
-            finalNull.get().linkTo(masm.label(), &masm);
-        finalShape.linkTo(masm.label(), &masm);
-        Label failLabel = masm.label();
-        Jump failJump = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(failJump, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generated %s call stub at %p\n", type, cs.executableAddress());
-
-        patchPreviousToHere(cs);
-
-        pic.stubsGenerated++;
-        pic.updateLastPath(buffer, failLabel);
-        labels.setStubJump(masm, failLabel, failJump);
-
-        if (pic.stubsGenerated == MAX_PIC_STUBS)
-            disable("max stubs reached");
-
-        return Lookup_Cacheable;
-    }
-
-    LookupStatus updateForName()
-    {
-        // |getprop.obj| is filled by bind()
-        LookupStatus status = getprop.bind();
-        if (status != Lookup_Cacheable)
-            return status;
-
-        return update(getprop.obj);
-    }
-
-    LookupStatus updateForXName()
-    {
-        // |obj| and |getprop.obj| are NULL, but should be the given scopeChain.
-        getprop.obj = scopeChain;
-        LookupStatus status = getprop.lookup();
-        if (status != Lookup_Cacheable)
-            return status;
-
-        return update(getprop.obj);
-    }
-
-    LookupStatus update(JSObject *obj)
-    {
-        if (obj != getprop.holder)
-            return disable("property is on proto of a scope object");
-
-        if (obj->isCall())
-            return generateCallStub(obj);
-
-        LookupStatus status = getprop.testForGet();
-        if (status != Lookup_Cacheable)
-            return status;
-
-        if (obj->isGlobal())
-            return generateGlobalStub(obj);
-
-        return disable("scope object not handled yet");
-    }
-
-    bool retrieve(MutableHandleValue vp, PICInfo::Kind kind)
-    {
-        RootedObject obj(cx, getprop.obj);
-        RootedObject holder(cx, getprop.holder);
-        RootedShape prop(cx, getprop.prop);
-
-        if (!prop) {
-            /* Kludge to allow (typeof foo == "undefined") tests. */
-            if (kind == ic::PICInfo::NAME) {
-                JSOp op2 = JSOp(f.pc()[JSOP_NAME_LENGTH]);
-                if (op2 == JSOP_TYPEOF) {
-                    vp.setUndefined();
-                    return true;
-                }
-            }
-            ReportAtomNotDefined(cx, name);
-            return false;
-        }
-
-        // If the property was found, but we decided not to cache it, then
-        // take a slow path and do a full property fetch.
-        if (!getprop.shape) {
-            if (!JSObject::getProperty(cx, obj, obj, name, vp))
-                return false;
-            return true;
-        }
-
-        RootedShape shape(cx, getprop.shape);
-        Rooted<JSObject*> normalized(cx, obj);
-        if (obj->isWith() && !shape->hasDefaultGetter())
-            normalized = &obj->asWith().object();
-        if (shape->isDataDescriptor() && shape->hasDefaultGetter()) {
-            /* Fast path for Object instance properties. */
-            JS_ASSERT(shape->slot() != SHAPE_INVALID_SLOT || !shape->hasDefaultSetter());
-            if (shape->slot() != SHAPE_INVALID_SLOT)
-                vp.set(holder->nativeGetSlot(shape->slot()));
-            else
-                vp.setUndefined();
-        } else {
-            if (!js_NativeGet(cx, normalized, holder, shape, 0, vp))
-                return false;
-        }
-        return true;
-    }
-};
-
-class BindNameCompiler : public PICStubCompiler
-{
-    RootedObject scopeChain;
-    RootedPropertyName name;
-
-  public:
-    BindNameCompiler(VMFrame &f, JSObject *scopeChain, ic::PICInfo &pic,
-                     PropertyName *name, VoidStubPIC stub)
-      : PICStubCompiler("bind", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
-        scopeChain(f.cx, scopeChain), name(f.cx, name)
-    { }
-
-    static void reset(Repatcher &repatcher, ic::PICInfo &pic)
-    {
-        BindNameLabels &labels = pic.bindNameLabels();
-
-        /* Link the inline jump back to the slow path. */
-        JSC::CodeLocationJump inlineJump = labels.getInlineJump(pic.getFastShapeGuard());
-        repatcher.relink(inlineJump, pic.slowPathStart);
-
-        /* Link the slow path to call the IC entry point. */
-        FunctionPtr target(JS_FUNC_TO_DATA_PTR(void *, ic::BindName));
-        repatcher.relink(pic.slowPathCall, target);
-    }
-
-    void patchPreviousToHere(CodeLocationLabel cs)
-    {
-        BindNameLabels &labels = pic.bindNameLabels();
-        Repatcher repatcher(pic.lastCodeBlock(f.chunk()));
-        JSC::CodeLocationJump jump;
-
-        /* Patch either the inline fast path or a generated stub. */
-        if (pic.stubsGenerated)
-            jump = labels.getStubJump(pic.lastPathStart());
-        else
-            jump = labels.getInlineJump(pic.getFastShapeGuard());
-        repatcher.relink(jump, cs);
-    }
-
-    LookupStatus generateStub(JSObject *obj)
-    {
-        MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-        Assembler masm(&sps, &f);
-        Vector<Jump, 8> fails(cx);
-
-        BindNameLabels &labels = pic.bindNameLabels();
-
-        if (!IsCacheableNonGlobalScope(scopeChain))
-            return disable("non-cacheable obj at start of scope chain");
-
-        /* Guard on the shape of the scope chain. */
-        masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), pic.objReg);
-        masm.loadShape(pic.objReg, pic.shapeReg);
-        Jump firstShape = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                         ImmPtr(scopeChain->lastProperty()));
-
-        if (scopeChain != obj) {
-            /* Walk up the scope chain. */
-            JSObject *tobj = &scopeChain->asScope().enclosingScope();
-            Address parent(pic.objReg, ScopeObject::offsetOfEnclosingScope());
-            while (tobj) {
-                if (!IsCacheableNonGlobalScope(tobj))
-                    return disable("non-cacheable obj in scope chain");
-                masm.loadPayload(parent, pic.objReg);
-                masm.loadShape(pic.objReg, pic.shapeReg);
-                Jump shapeTest = masm.branchPtr(Assembler::NotEqual, pic.shapeReg,
-                                                ImmPtr(tobj->lastProperty()));
-                if (!fails.append(shapeTest))
-                    return error();
-                if (tobj == obj)
-                    break;
-                tobj = &tobj->asScope().enclosingScope();
-            }
-            if (tobj != obj)
-                return disable("indirect hit");
-        }
-
-        Jump done = masm.jump();
-
-        // All failures flow to here, so there is a common point to patch.
-        for (Jump *pj = fails.begin(); pj != fails.end(); ++pj)
-            pj->linkTo(masm.label(), &masm);
-        firstShape.linkTo(masm.label(), &masm);
-        Label failLabel = masm.label();
-        Jump failJump = masm.jump();
-
-        pic.updatePCCounters(f, masm);
-
-        PICLinker buffer(masm, pic);
-        if (!buffer.init(cx))
-            return error();
-
-        if (!buffer.verifyRange(pic.lastCodeBlock(f.chunk())) ||
-            !buffer.verifyRange(f.chunk())) {
-            return disable("code memory is out of range");
-        }
-
-        buffer.link(failJump, pic.slowPathStart);
-        buffer.link(done, pic.fastPathRejoin);
-        CodeLocationLabel cs = buffer.finalize(f);
-        JaegerSpew(JSpew_PICs, "generated %s stub at %p\n", type, cs.executableAddress());
-
-        patchPreviousToHere(cs);
-
-        pic.stubsGenerated++;
-        pic.updateLastPath(buffer, failLabel);
-        labels.setStubJump(masm, failLabel, failJump);
-
-        if (pic.stubsGenerated == MAX_PIC_STUBS)
-            disable("max stubs reached");
-
-        return Lookup_Cacheable;
-    }
-
-    JSObject *update()
-    {
-        RecompilationMonitor monitor(cx);
-
-        RootedObject scope(cx);
-        if (!LookupNameWithGlobalDefault(cx, name, scopeChain, &scope))
-            return NULL;
-
-        if (monitor.recompiled())
-            return scope;
-
-        if (!pic.hit) {
-            spew("first hit", "nop");
-            pic.hit = true;
-            return scope;
-        }
-
-        LookupStatus status = generateStub(scope);
-        if (status == Lookup_Error)
-            return NULL;
-
-        return scope;
-    }
-};
-
-static void JS_FASTCALL
-DisabledGetPropIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::GetProp(f, pic->name);
-}
-
-static void JS_FASTCALL
-DisabledGetPropNoCacheIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::GetPropNoCache(f, pic->name);
-}
-
-void JS_FASTCALL
-ic::GetProp(VMFrame &f, ic::PICInfo *pic)
-{
-    bool cached = pic->cached;
-    VoidStubPIC stub = cached ? DisabledGetPropIC : DisabledGetPropNoCacheIC;
-
-    RootedPropertyName name(f.cx, pic->name);
-    if (name == f.cx->names().length) {
-        if (IsOptimizedArguments(f.fp(), &f.regs.sp[-1])) {
-            f.regs.sp[-1].setInt32(f.regs.fp()->numActualArgs());
-            return;
-        }
-        if (!f.regs.sp[-1].isPrimitive()) {
-            JSObject *obj = &f.regs.sp[-1].toObject();
-            if (obj->isArray() || obj->isString()) {
-                GetPropCompiler cc(f, obj, *pic, NULL, stub);
-                if (obj->isArray()) {
-                    LookupStatus status = cc.generateArrayLengthStub();
-                    if (status == Lookup_Error)
-                        THROW();
-                    f.regs.sp[-1].setNumber(obj->getArrayLength());
-                } else {
-                    LookupStatus status = cc.generateStringObjLengthStub();
-                    if (status == Lookup_Error)
-                        THROW();
-                    JSString *str = obj->asString().unbox();
-                    f.regs.sp[-1].setInt32(str->length());
-                }
-                return;
-            }
-        }
-    }
-
-    RootedValue objval(f.cx, f.regs.sp[-1]);
-
-    if (f.regs.sp[-1].isString()) {
-        GetPropCompiler cc(f, NULL, *pic, name, stub);
-        if (name == f.cx->names().length) {
-            LookupStatus status = cc.generateStringLengthStub();
-            if (status == Lookup_Error)
-                THROW();
-            JSString *str = f.regs.sp[-1].toString();
-            f.regs.sp[-1].setInt32(str->length());
-        } else {
-            LookupStatus status = cc.generateStringPropertyStub();
-            if (status == Lookup_Error)
-                THROW();
-            RootedObject obj(f.cx, ToObjectFromStack(f.cx, objval));
-            if (!obj)
-                THROW();
-            MutableHandleValue vp = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-            if (!JSObject::getProperty(f.cx, obj, obj, name, vp))
-                THROW();
-        }
-        return;
-    }
-
-    RecompilationMonitor monitor(f.cx);
-
-    RootedObject obj(f.cx, ToObjectFromStack(f.cx, objval));
-    if (!obj)
-        THROW();
-
-    if (!monitor.recompiled() && pic->shouldUpdate(f)) {
-        GetPropCompiler cc(f, obj, *pic, name, stub);
-        if (!cc.update())
-            THROW();
-    }
-
-    RootedValue v(f.cx);
-    if (cached) {
-        RootedScript script(f.cx, f.script());
-        if (!GetPropertyOperation(f.cx, script, f.pc(), &objval, &v))
-            THROW();
-    } else {
-        if (!JSObject::getProperty(f.cx, obj, obj, name, &v))
-            THROW();
-    }
-
-    f.regs.sp[-1] = v;
-}
-
-static void JS_FASTCALL
-DisabledSetPropIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::SetProp(f, pic->name);
-}
-
-static void JS_FASTCALL
-DisabledSetNameIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::SetName(f, pic->name);
-}
-
-void JS_FASTCALL
-ic::SetPropOrName(VMFrame &f, ic::PICInfo *pic)
-{
-    JS_ASSERT(pic->isSet());
-    JS_ASSERT(*f.pc() == JSOP_SETPROP || *f.pc() == JSOP_SETNAME);
-
-    // Save this in case the compiler triggers a recompilation of this script.
-    RootedPropertyName name(f.cx, pic->name);
-
-    RecompilationMonitor monitor(f.cx);
-
-    RootedValue objval(f.cx, f.regs.sp[-2]);
-    JSObject *obj = ToObjectFromStack(f.cx, objval);
-    if (!obj)
-        THROW();
-
-    // Note, we can't use SetProp/Name for PROPINC PICs because the property
-    // cache can't handle a GET and SET from the same scripted PC.
-    if (!monitor.recompiled() && pic->shouldUpdate(f)) {
-        VoidStubPIC disabled = *f.pc() == JSOP_SETPROP ? DisabledSetPropIC : DisabledSetNameIC;
-        SetPropCompiler cc(f, obj, *pic, name, disabled);
-        LookupStatus status = cc.update();
-        if (status == Lookup_Error)
-            THROW();
-        if (status != Lookup_Cacheable && !monitor.recompiled())
-            pic->hadUncacheable = true;
-    }
-
-    if (*f.pc() == JSOP_SETPROP)
-        stubs::SetProp(f, name);
-    else
-        stubs::SetName(f, name);
-}
-
-static void JS_FASTCALL
-DisabledNameIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::Name(f);
-}
-
-static void JS_FASTCALL
-DisabledXNameIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::GetProp(f, pic->name);
-}
-
-void JS_FASTCALL
-ic::XName(VMFrame &f, ic::PICInfo *pic)
-{
-    /* GETXPROP is guaranteed to have an object. */
-    JSObject *obj = &f.regs.sp[-1].toObject();
-
-    ScopeNameCompiler cc(f, obj, *pic, pic->name, DisabledXNameIC);
-
-    LookupStatus status = cc.updateForXName();
-    if (status == Lookup_Error)
-        THROW();
-
-    RootedValue rval(f.cx);
-    if (!cc.retrieve(&rval, PICInfo::XNAME))
-        THROW();
-    f.regs.sp[-1] = rval;
-}
-
-void JS_FASTCALL
-ic::Name(VMFrame &f, ic::PICInfo *pic)
-{
-    ScopeNameCompiler cc(f, f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
-
-    LookupStatus status = cc.updateForName();
-    if (status == Lookup_Error)
-        THROW();
-
-    RootedValue rval(f.cx);
-    if (!cc.retrieve(&rval, PICInfo::NAME))
-        THROW();
-    f.regs.sp[0] = rval;
-}
-
-static void JS_FASTCALL
-DisabledBindNameIC(VMFrame &f, ic::PICInfo *pic)
-{
-    stubs::BindName(f, pic->name);
-}
-
-void JS_FASTCALL
-ic::BindName(VMFrame &f, ic::PICInfo *pic)
-{
-    VoidStubPIC stub = DisabledBindNameIC;
-    BindNameCompiler cc(f, f.fp()->scopeChain(), *pic, pic->name, stub);
-
-    JSObject *obj = cc.update();
-    if (!obj)
-        THROW();
-
-    f.regs.sp[0].setObject(*obj);
-}
-
-void
-BaseIC::spew(VMFrame &f, const char *event, const char *message)
-{
-#ifdef JS_METHODJIT_SPEW
-    JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
-               js_CodeName[JSOp(*f.pc())], event, message,
-               f.cx->fp()->script()->filename(), CurrentLine(f.cx));
-#endif
-}
-
-/* Total length of scripts preceding a frame. */
-inline uint32_t
-frameCountersOffset(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-
-    uint32_t offset = 0;
-    if (cx->regs().inlined()) {
-        offset += cx->fp()->script()->length;
-        uint32_t index = cx->regs().inlined()->inlineIndex;
-        InlineFrame *frames = f.chunk()->inlineFrames();
-        for (unsigned i = 0; i < index; i++)
-            offset += frames[i].fun->nonLazyScript()->length;
-    }
-
-    jsbytecode *pc;
-    JSScript *script = cx->stack.currentScript(&pc);
-    offset += pc - script->code;
-
-    return offset;
-}
-
-LookupStatus
-BaseIC::disable(VMFrame &f, const char *reason, void *stub)
-{
-    if (f.chunk()->pcLengths) {
-        uint32_t offset = frameCountersOffset(f);
-        f.chunk()->pcLengths[offset].picsLength = 0;
-    }
-
-    disabled = true;
-
-    spew(f, "disabled", reason);
-    Repatcher repatcher(f.chunk());
-    repatcher.relink(slowPathCall, FunctionPtr(stub));
-    return Lookup_Uncacheable;
-}
-
-void
-BaseIC::updatePCCounters(VMFrame &f, Assembler &masm)
-{
-    if (f.chunk()->pcLengths) {
-        uint32_t offset = frameCountersOffset(f);
-        f.chunk()->pcLengths[offset].picsLength += masm.size();
-    }
-}
-
-bool
-BaseIC::shouldUpdate(VMFrame &f)
-{
-    if (!hit) {
-        hit = true;
-        spew(f, "ignored", "first hit");
-        return false;
-    }
-    JS_ASSERT(stubsGenerated < MAX_PIC_STUBS);
-    return true;
-}
-
-void
-PICInfo::purge(Repatcher &repatcher)
-{
-    switch (kind) {
-      case SET:
-        SetPropCompiler::reset(repatcher, *this);
-        break;
-      case NAME:
-      case XNAME:
-        ScopeNameCompiler::reset(repatcher, *this);
-        break;
-      case BIND:
-        BindNameCompiler::reset(repatcher, *this);
-        break;
-      case GET:
-        GetPropCompiler::reset(repatcher, *this);
-        break;
-      default:
-        JS_NOT_REACHED("Unhandled PIC kind");
-        break;
-    }
-    reset();
-}
-
-static void JS_FASTCALL
-DisabledGetElem(VMFrame &f, ic::GetElementIC *ic)
-{
-    stubs::GetElem(f);
-}
-
-bool
-GetElementIC::shouldUpdate(VMFrame &f)
-{
-    if (!hit) {
-        hit = true;
-        spew(f, "ignored", "first hit");
-        return false;
-    }
-    JS_ASSERT(stubsGenerated < MAX_GETELEM_IC_STUBS);
-    return true;
-}
-
-LookupStatus
-GetElementIC::disable(VMFrame &f, const char *reason)
-{
-    slowCallPatched = true;
-    void *stub = JS_FUNC_TO_DATA_PTR(void *, DisabledGetElem);
-    BaseIC::disable(f, reason, stub);
-    return Lookup_Uncacheable;
-}
-
-LookupStatus
-GetElementIC::error(JSContext *cx)
-{
-    return Lookup_Error;
-}
-
-void
-GetElementIC::purge(Repatcher &repatcher)
-{
-    // Repatch the inline jumps.
-    if (inlineTypeGuardPatched)
-        repatcher.relink(fastPathStart.jumpAtOffset(inlineTypeGuard), slowPathStart);
-    if (inlineShapeGuardPatched)
-        repatcher.relink(fastPathStart.jumpAtOffset(inlineShapeGuard), slowPathStart);
-
-    if (slowCallPatched) {
-        repatcher.relink(slowPathCall,
-                         FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, ic::GetElement)));
-    }
-
-    reset();
-}
-
-LookupStatus
-GetElementIC::attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandlePropertyName name,
-                            MutableHandleValue vp)
-{
-    JS_ASSERT(v.isString());
-    JSContext *cx = f.cx;
-
-    // don't handle special logic required for property access on proxies.
-    if (!obj->isNative())
-        return Lookup_Uncacheable;
-
-    GetPropHelper<GetElementIC> getprop(cx, obj, name, *this, f);
-    LookupStatus status = getprop.lookupAndTest();
-    if (status != Lookup_Cacheable)
-        return status;
-
-    // With TI enabled, string property stubs can only be added to an opcode if
-    // the value read will go through a type barrier afterwards. TI only
-    // accounts for integer-valued properties accessed by GETELEM/CALLELEM.
-    if (cx->typeInferenceEnabled() && !forcedTypeBarrier)
-        return disable(f, "string element access may not have type barrier");
-
-    MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-    Assembler masm(&sps, &f);
-
-    // Guard on the string's type and identity.
-    MaybeJump atomTypeGuard;
-    if (hasInlineTypeGuard() && !inlineTypeGuardPatched) {
-        // We link all string-key dependent stubs together, and store the
-        // first set of guards in the IC, separately, from int-key dependent
-        // stubs. As long as we guarantee that the first string-key dependent
-        // stub guards on the key type, then all other string-key stubs can
-        // omit the guard.
-        JS_ASSERT(!idRemat.isTypeKnown());
-        atomTypeGuard = masm.testString(Assembler::NotEqual, typeReg);
-    } else {
-        // If there was no inline type guard, then a string type is guaranteed.
-        // Otherwise, we are guaranteed the type has already been checked, via
-        // the comment above.
-        JS_ASSERT_IF(!hasInlineTypeGuard(), idRemat.knownType() == JSVAL_TYPE_STRING);
-    }
-
-    // Reify the shape before guards that could flow into shape guarding stubs.
-    if (!typeRegHasBaseShape) {
-        masm.loadShape(objReg, typeReg);
-        typeRegHasBaseShape = true;
-    }
-
-    MaybeJump atomIdGuard;
-    if (!idRemat.isConstant())
-        atomIdGuard = masm.branchPtr(Assembler::NotEqual, idRemat.dataReg(), ImmPtr(v.toString()));
-
-    // Guard on the base shape.
-    Jump shapeGuard = masm.branchPtr(Assembler::NotEqual, typeReg, ImmPtr(obj->lastProperty()));
-
-    Vector<Jump, 8> otherGuards(cx);
-
-    // Guard on the prototype, if applicable.
-    MaybeJump protoGuard;
-    RootedObject holder(cx, getprop.holder);
-    RegisterID holderReg = objReg;
-    if (obj != holder) {
-        if (!GeneratePrototypeGuards(cx, otherGuards, masm, obj, holder, objReg, typeReg))
-            return error(cx);
-
-        // Bake in the holder identity. Careful not to clobber |objReg|, since we can't remat it.
-        holderReg = typeReg;
-        masm.move(ImmPtr(holder), holderReg);
-        typeRegHasBaseShape = false;
-
-        // Guard on the holder's shape.
-        protoGuard = masm.guardShape(holderReg, holder);
-    }
-
-    // Load the value.
-    RootedShape shape(cx, getprop.shape);
-    masm.loadObjProp(holder, holderReg, shape, typeReg, objReg);
-
-    Jump done = masm.jump();
-
-    updatePCCounters(f, masm);
-
-    PICLinker buffer(masm, *this);
-    if (!buffer.init(cx))
-        return error(cx);
-
-    if (hasLastStringStub && !buffer.verifyRange(lastStringStub))
-        return disable(f, "code memory is out of range");
-    if (!buffer.verifyRange(f.chunk()))
-        return disable(f, "code memory is out of range");
-
-    // Patch all guards.
-    buffer.maybeLink(atomIdGuard, slowPathStart);
-    buffer.maybeLink(atomTypeGuard, slowPathStart);
-    buffer.link(shapeGuard, slowPathStart);
-    buffer.maybeLink(protoGuard, slowPathStart);
-    for (Jump *pj = otherGuards.begin(); pj != otherGuards.end(); ++pj)
-        buffer.link(*pj, slowPathStart);
-    buffer.link(done, fastPathRejoin);
-
-    CodeLocationLabel cs = buffer.finalize(f);
-#if DEBUG
-    Latin1CharsZ latin1 = LossyTwoByteCharsToNewLatin1CharsZ(cx, v.toString()->ensureLinear(cx)->range());
-    JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom %p (\"%s\") shape %p (%s: %d)\n",
-               js_CodeName[JSOp(*f.pc())], cs.executableAddress(), (void*)name, latin1.get(),
-               (void*)holder->lastProperty(), cx->fp()->script()->filename(),
-               CurrentLine(cx));
-    JS_free(latin1);
-#endif
-
-    // Update the inline guards, if needed.
-    if (shouldPatchInlineTypeGuard() || shouldPatchUnconditionalShapeGuard()) {
-        Repatcher repatcher(f.chunk());
-
-        if (shouldPatchInlineTypeGuard()) {
-            // A type guard is present in the inline path, and this is the
-            // first string stub, so patch it now.
-            JS_ASSERT(!inlineTypeGuardPatched);
-            JS_ASSERT(atomTypeGuard.isSet());
-
-            repatcher.relink(fastPathStart.jumpAtOffset(inlineTypeGuard), cs);
-            inlineTypeGuardPatched = true;
-        }
-
-        if (shouldPatchUnconditionalShapeGuard()) {
-            // The shape guard is unconditional, meaning there is no type
-            // check. This is the first stub, so it has to be patched. Note
-            // that it is wrong to patch the inline shape guard otherwise,
-            // because it follows an integer-id guard.
-            JS_ASSERT(!hasInlineTypeGuard());
-
-            repatcher.relink(fastPathStart.jumpAtOffset(inlineShapeGuard), cs);
-            inlineShapeGuardPatched = true;
-        }
-    }
-
-    // If there were previous stub guards, patch them now.
-    if (hasLastStringStub) {
-        Repatcher repatcher(lastStringStub);
-        CodeLocationLabel stub(lastStringStub.start());
-        if (atomGuard)
-            repatcher.relink(stub.jumpAtOffset(atomGuard), cs);
-        repatcher.relink(stub.jumpAtOffset(firstShapeGuard), cs);
-        if (secondShapeGuard)
-            repatcher.relink(stub.jumpAtOffset(secondShapeGuard), cs);
-    }
-
-    // Update state.
-    hasLastStringStub = true;
-    lastStringStub = JITCode(cs.executableAddress(), buffer.size());
-    if (atomIdGuard.isSet()) {
-        atomGuard = buffer.locationOf(atomIdGuard.get()) - cs;
-        JS_ASSERT(atomGuard == buffer.locationOf(atomIdGuard.get()) - cs);
-        JS_ASSERT(atomGuard);
-    } else {
-        atomGuard = 0;
-    }
-    if (protoGuard.isSet()) {
-        secondShapeGuard = buffer.locationOf(protoGuard.get()) - cs;
-        JS_ASSERT(secondShapeGuard == buffer.locationOf(protoGuard.get()) - cs);
-        JS_ASSERT(secondShapeGuard);
-    } else {
-        secondShapeGuard = 0;
-    }
-    firstShapeGuard = buffer.locationOf(shapeGuard) - cs;
-    JS_ASSERT(firstShapeGuard == buffer.locationOf(shapeGuard) - cs);
-    JS_ASSERT(firstShapeGuard);
-
-    stubsGenerated++;
-
-    if (stubsGenerated == MAX_GETELEM_IC_STUBS)
-        disable(f, "max stubs reached");
-
-    // Finally, fetch the value to avoid redoing the property lookup.
-    vp.set(holder->getSlot(shape->slot()));
-
-    return Lookup_Cacheable;
-}
-
-#if defined JS_METHODJIT_TYPED_ARRAY
-LookupStatus
-GetElementIC::attachTypedArray(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, MutableHandleValue vp)
-{
-    JSContext *cx = f.cx;
-
-    if (!v.isInt32())
-        return disable(f, "typed array with string key");
-
-    if (JSOp(*f.pc()) == JSOP_CALLELEM)
-        return disable(f, "typed array with call");
-
-    // The fast-path guarantees that after the dense shape guard, the type is
-    // known to be int32, either via type inference or the inline type check.
-    JS_ASSERT(hasInlineTypeGuard() || idRemat.knownType() == JSVAL_TYPE_INT32);
-
-    MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-    Assembler masm(&sps, &f);
-
-    // Guard on this typed array's shape/class.
-    Jump shapeGuard = masm.guardShape(objReg, obj);
-
-    // Bounds check.
-    Jump outOfBounds;
-    Address typedArrayLength = masm.payloadOf(Address(objReg, TypedArray::lengthOffset()));
-    if (idRemat.isConstant()) {
-        JS_ASSERT(idRemat.value().toInt32() == v.toInt32());
-        outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, Imm32(v.toInt32()));
-    } else {
-        outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, idRemat.dataReg());
-    }
-
-    // Load the array's packed data vector.
-    masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
-
-    Int32Key key = idRemat.isConstant()
-                 ? Int32Key::FromConstant(v.toInt32())
-                 : Int32Key::FromRegister(idRemat.dataReg());
-
-    if (!masm.supportsFloatingPoint() &&
-        (TypedArray::type(obj) == TypedArray::TYPE_FLOAT32 ||
-         TypedArray::type(obj) == TypedArray::TYPE_FLOAT64 ||
-         TypedArray::type(obj) == TypedArray::TYPE_UINT32))
-    {
-        return disable(f, "fpu not supported");
-    }
-
-    MaybeRegisterID tempReg;
-    masm.loadFromTypedArray(TypedArray::type(obj), objReg, key, typeReg, objReg, tempReg);
-
-    Jump done = masm.jump();
-
-    updatePCCounters(f, masm);
-
-    PICLinker buffer(masm, *this);
-    if (!buffer.init(cx))
-        return error(cx);
-
-    if (!buffer.verifyRange(f.chunk()))
-        return disable(f, "code memory is out of range");
-
-    buffer.link(shapeGuard, slowPathStart);
-    buffer.link(outOfBounds, slowPathStart);
-    buffer.link(done, fastPathRejoin);
-
-    CodeLocationLabel cs = buffer.finalizeCodeAddendum();
-    JaegerSpew(JSpew_PICs, "generated getelem typed array stub at %p\n", cs.executableAddress());
-
-    // If we can generate a typed array stub, the shape guard is conditional.
-    // Also, we only support one typed array.
-    JS_ASSERT(!shouldPatchUnconditionalShapeGuard());
-    JS_ASSERT(!inlineShapeGuardPatched);
-
-    Repatcher repatcher(f.chunk());
-    repatcher.relink(fastPathStart.jumpAtOffset(inlineShapeGuard), cs);
-    inlineShapeGuardPatched = true;
-
-    stubsGenerated++;
-
-    // In the future, it might make sense to attach multiple typed array stubs.
-    // For simplicitly, they are currently monomorphic.
-    if (stubsGenerated == MAX_GETELEM_IC_STUBS)
-        disable(f, "max stubs reached");
-
-    disable(f, "generated typed array stub");
-
-    // Fetch the value as expected of Lookup_Cacheable for GetElement.
-    Rooted<jsid> idRoot(cx, id);
-    if (!JSObject::getGeneric(cx, obj, obj, idRoot, vp))
-        return Lookup_Error;
-
-    return Lookup_Cacheable;
-}
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-LookupStatus
-GetElementIC::update(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, MutableHandleValue vp)
-{
-    /*JSObject *obj, const Value &v, jsid id, Value *vp)
-     * Only treat this as a GETPROP for non-numeric string identifiers. The
-     * GETPROP IC assumes the id has already gone through filtering for string
-     * indexes in the emitter.
-     */
-    uint32_t dummy;
-    if (v.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) {
-        RootedPropertyName name(f.cx, JSID_TO_ATOM(id)->asPropertyName());
-        return attachGetProp(f, obj, v, name, vp);
-    }
-
-#if defined JS_METHODJIT_TYPED_ARRAY
-    /*
-     * Typed array ICs can make stub calls, and need to know which registers
-     * are in use and need to be restored after the call. If type inference is
-     * enabled then we don't necessarily know the full set of such registers
-     * when generating the IC (loop-carried registers may be allocated later),
-     * and additionally the push/pop instructions used to save/restore in the
-     * IC are not compatible with carrying entries in floating point registers.
-     * Since we can use type information to generate inline paths for typed
-     * arrays, just don't generate these ICs with inference enabled.
-     */
-    if (!f.cx->typeInferenceEnabled() && obj->isTypedArray())
-        return attachTypedArray(f, obj, v, id, vp);
-#endif
-
-    return disable(f, "unhandled object and key type");
-}
-
-void JS_FASTCALL
-ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
-{
-    JSContext *cx = f.cx;
-
-    // Right now, we don't optimize for strings or lazy arguments.
-    if (!f.regs.sp[-2].isObject()) {
-        ic->disable(f, "non-object");
-        stubs::GetElem(f);
-        return;
-    }
-
-    RootedValue idval(cx, f.regs.sp[-1]);
-
-    RecompilationMonitor monitor(cx);
-
-    RootedValue objval(f.cx, f.regs.sp[-2]);
-    RootedObject obj(cx, ToObjectFromStack(cx, objval));
-    if (!obj)
-        THROW();
-
-    RootedId id(cx);
-    if (!ValueToId<CanGC>(cx, idval, &id))
-            THROW();
-
-    MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-
-    if (!monitor.recompiled() && ic->shouldUpdate(f)) {
-#ifdef DEBUG
-        f.regs.sp[-2] = MagicValue(JS_GENERIC_MAGIC);
-#endif
-        LookupStatus status = ic->update(f, obj, idval, id, res);
-        if (status != Lookup_Uncacheable && status != Lookup_NoProperty) {
-            if (status == Lookup_Error)
-                THROW();
-
-            // If the result can be cached, the value was already retrieved.
-            JS_ASSERT(!f.regs.sp[-2].isMagic());
-            return;
-        }
-    }
-
-    if (!JSObject::getGeneric(cx, obj, obj, id, res))
-        THROW();
-
-#if JS_HAS_NO_SUCH_METHOD
-    if (*f.pc() == JSOP_CALLELEM && JS_UNLIKELY(f.regs.sp[-2].isPrimitive())) {
-        if (!OnUnknownMethod(cx, obj, idval, res))
-            THROW();
-    }
-#endif
-}
-
-#define APPLY_STRICTNESS(f, s)                          \
-    (FunctionTemplateConditional(s, f<true>, f<false>))
-
-LookupStatus
-SetElementIC::disable(VMFrame &f, const char *reason)
-{
-    slowCallPatched = true;
-    VoidStub stub = APPLY_STRICTNESS(stubs::SetElem, strictMode);
-    BaseIC::disable(f, reason, JS_FUNC_TO_DATA_PTR(void *, stub));
-    return Lookup_Uncacheable;
-}
-
-LookupStatus
-SetElementIC::error(JSContext *cx)
-{
-    return Lookup_Error;
-}
-
-void
-SetElementIC::purge(Repatcher &repatcher)
-{
-    // Repatch the inline jumps.
-    if (inlineShapeGuardPatched)
-        repatcher.relink(fastPathStart.jumpAtOffset(inlineShapeGuard), slowPathStart);
-    if (inlineHoleGuardPatched)
-        repatcher.relink(fastPathStart.jumpAtOffset(inlineHoleGuard), slowPathStart);
-
-    if (slowCallPatched) {
-        void *stub = JS_FUNC_TO_DATA_PTR(void *, APPLY_STRICTNESS(ic::SetElement, strictMode));
-        repatcher.relink(slowPathCall, FunctionPtr(stub));
-    }
-
-    reset();
-}
-
-#if defined JS_METHODJIT_TYPED_ARRAY
-LookupStatus
-SetElementIC::attachTypedArray(VMFrame &f, JSObject *obj, int32_t key)
-{
-    // Right now, only one shape guard extension is supported.
-    JS_ASSERT(!inlineShapeGuardPatched);
-
-    JSContext *cx = f.cx;
-    MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
-    Assembler masm(&sps, &f);
-
-    // Restore |obj|.
-    masm.rematPayload(StateRemat::FromInt32(objRemat), objReg);
-
-    // Guard on this typed array's shape.
-    Jump shapeGuard = masm.guardShape(objReg, obj);
-
-    // Bounds check.
-    Jump outOfBounds;
-    Address typedArrayLength = masm.payloadOf(Address(objReg, TypedArray::lengthOffset()));
-    if (hasConstantKey)
-        outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, Imm32(keyValue));
-    else
-        outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, keyReg);
-
-    // Load the array's packed data vector.
-    masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
-
-    if (!masm.supportsFloatingPoint() &&
-        (TypedArray::type(obj) == TypedArray::TYPE_FLOAT32 ||
-         TypedArray::type(obj) == TypedArray::TYPE_FLOAT64))
-    {
-        return disable(f, "fpu not supported");
-    }
-
-    int shift = TypedArray::slotWidth(obj);
-    if (hasConstantKey) {
-        Address addr(objReg, keyValue * shift);
-        if (!StoreToTypedArray(cx, masm, obj, addr, vr, volatileMask))
-            return error(cx);
-    } else {
-        Assembler::Scale scale = Assembler::TimesOne;
-        switch (shift) {
-          case 2:
-            scale = Assembler::TimesTwo;
-            break;
-          case 4:
-            scale = Assembler::TimesFour;
-            break;
-          case 8:
-            scale = Assembler::TimesEight;
-            break;
-        }
-        BaseIndex addr(objReg, keyReg, scale);
-        if (!StoreToTypedArray(cx, masm, obj, addr, vr, volatileMask))
-            return error(cx);
-    }
-
-    Jump done = masm.jump();
-
-    // The stub does not rely on any pointers or numbers that could be ruined
-    // by a GC or shape regenerated GC. We let this stub live for the lifetime
-    // of the script.
-    JS_ASSERT(!execPool);
-    LinkerHelper buffer(masm, JSC::JAEGER_CODE);
-    execPool = buffer.init(cx);
-    if (!execPool)
-        return error(cx);
-
-    if (!buffer.verifyRange(f.chunk()))
-        return disable(f, "code memory is out of range");
-
-    // Note that the out-of-bounds path simply does nothing.
-    buffer.link(shapeGuard, slowPathStart);
-    buffer.link(outOfBounds, fastPathRejoin);
-    buffer.link(done, fastPathRejoin);
-    masm.finalize(buffer);
-
-    CodeLocationLabel cs = buffer.finalizeCodeAddendum();
-    JaegerSpew(JSpew_PICs, "generated setelem typed array stub at %p\n", cs.executableAddress());
-
-    Repatcher repatcher(f.chunk());
-    repatcher.relink(fastPathStart.jumpAtOffset(inlineShapeGuard), cs);
-    inlineShapeGuardPatched = true;
-
-    stubsGenerated++;
-
-    // In the future, it might make sense to attach multiple typed array stubs.
-    // For simplicitly, they are currently monomorphic.
-    if (stubsGenerated == MAX_GETELEM_IC_STUBS)
-        disable(f, "max stubs reached");
-
-    disable(f, "generated typed array stub");
-
-    return Lookup_Cacheable;
-}
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-LookupStatus
-SetElementIC::update(VMFrame &f, const Value &objval, const Value &idval)
-{
-    if (!objval.isObject())
-        return disable(f, "primitive lval");
-    if (!idval.isInt32())
-        return disable(f, "non-int32 key");
-
-    JSObject *obj = &objval.toObject();
-    int32_t key = idval.toInt32();
-
-#if defined JS_METHODJIT_TYPED_ARRAY
-    /* Not attaching typed array stubs with linear scan allocator, see GetElementIC. */
-    if (!f.cx->typeInferenceEnabled() && obj->isTypedArray())
-        return attachTypedArray(f, obj, key);
-#endif
-
-    return disable(f, "unsupported object type");
-}
-
-bool
-SetElementIC::shouldUpdate(VMFrame &f)
-{
-    if (!hit) {
-        hit = true;
-        spew(f, "ignored", "first hit");
-        return false;
-    }
-#ifdef JSGC_INCREMENTAL_MJ
-    JS_ASSERT(!f.cx->zone()->compileBarriers());
-#endif
-    JS_ASSERT(stubsGenerated < MAX_PIC_STUBS);
-    return true;
-}
-
-template<JSBool strict>
-void JS_FASTCALL
-ic::SetElement(VMFrame &f, ic::SetElementIC *ic)
-{
-    if (ic->shouldUpdate(f)) {
-        LookupStatus status = ic->update(f, f.regs.sp[-3], f.regs.sp[-2]);
-        if (status == Lookup_Error)
-            THROW();
-    }
-
-    stubs::SetElem<strict>(f);
-}
-
-template void JS_FASTCALL ic::SetElement<true>(VMFrame &f, SetElementIC *ic);
-template void JS_FASTCALL ic::SetElement<false>(VMFrame &f, SetElementIC *ic);
-
-#endif /* JS_POLYIC */
-
deleted file mode 100644
--- a/js/src/methodjit/PolyIC.h
+++ /dev/null
@@ -1,528 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_poly_ic_h__ && defined JS_METHODJIT
-#define jsjaeger_poly_ic_h__
-
-#include "jscntxt.h"
-#include "assembler/assembler/MacroAssembler.h"
-#include "assembler/assembler/CodeLocation.h"
-#include "js/Vector.h"
-#include "methodjit/MethodJIT.h"
-#include "methodjit/ICRepatcher.h"
-#include "BaseAssembler.h"
-#include "RematInfo.h"
-#include "BaseCompiler.h"
-#include "methodjit/ICLabels.h"
-#include "assembler/moco/MocoStubs.h"
-
-namespace js {
-namespace mjit {
-namespace ic {
-
-/* Maximum number of stubs for a given callsite. */
-static const uint32_t MAX_PIC_STUBS = 16;
-static const uint32_t MAX_GETELEM_IC_STUBS = 17;
-
-enum LookupStatus {
-    Lookup_Error = 0,
-    Lookup_Uncacheable,
-    Lookup_Cacheable,
-    Lookup_NoProperty
-};
-
-struct BaseIC : public MacroAssemblerTypedefs {
-
-    // Address of inline fast-path.
-    CodeLocationLabel fastPathStart;
-
-    // Address to rejoin to the fast-path.
-    CodeLocationLabel fastPathRejoin;
-
-    // Start of the slow path.
-    CodeLocationLabel slowPathStart;
-
-    // Slow path stub call.
-    CodeLocationCall slowPathCall;
-
-    // Offset from start of stub to jump target of second shape guard as Nitro
-    // asm data location. This is 0 if there is only one shape guard in the
-    // last stub.
-    int32_t secondShapeGuard;
-
-    // Whether or not the callsite has been hit at least once.
-    bool hit : 1;
-    bool slowCallPatched : 1;
-
-    // Whether getter/setter hooks can be called from IC stubs.
-    bool canCallHook : 1;
-
-    // Whether a type barrier is in place for the result of the op.
-    bool forcedTypeBarrier : 1;
-
-    // Whether this IC has been disabled.
-    bool disabled : 1;
-
-    // Number of stubs generated.
-    uint32_t stubsGenerated : 5;
-
-    bool shouldUpdate(VMFrame &f);
-    void spew(VMFrame &f, const char *event, const char *reason);
-    LookupStatus disable(VMFrame &f, const char *reason, void *stub);
-    void updatePCCounters(VMFrame &f, Assembler &masm);
-
-  protected:
-    void reset() {
-        hit = false;
-        slowCallPatched = false;
-        forcedTypeBarrier = false;
-        disabled = false;
-        stubsGenerated = 0;
-        secondShapeGuard = 0;
-    }
-};
-
-class BasePolyIC : public BaseIC {
-    typedef Vector<JSC::ExecutablePool *, 2, SystemAllocPolicy> ExecPoolVector;
-
-    // ExecutablePools that IC stubs were generated into.  Very commonly (eg.
-    // 99.5% of BasePolyICs) there are 0 or 1, and there are lots of
-    // BasePolyICs, so we space-optimize for that case.  If the bottom bit of
-    // the pointer is 0, execPool should be used, and it will be NULL (for 0
-    // pools) or non-NULL (for 1 pool).  If the bottom bit of the
-    // pointer is 1, taggedExecPools should be used, but only after de-tagging
-    // (for 2 or more pools).
-    union {
-        JSC::ExecutablePool *execPool;      // valid when bottom bit is a 0
-        ExecPoolVector *taggedExecPools;    // valid when bottom bit is a 1
-    } u;
-
-    static bool isTagged(void *p) {
-        return !!(intptr_t(p) & 1);
-    }
-
-    static ExecPoolVector *tag(ExecPoolVector *p) {
-        JS_ASSERT(!isTagged(p));
-        return (ExecPoolVector *)(intptr_t(p) | 1);
-    }
-
-    static ExecPoolVector *detag(ExecPoolVector *p) {
-        JS_ASSERT(isTagged(p));
-        return (ExecPoolVector *)(intptr_t(p) & ~1);
-    }
-
-    bool areZeroPools()     { return !u.execPool; }
-    bool isOnePool()        { return u.execPool && !isTagged(u.execPool); }
-    bool areMultiplePools() { return isTagged(u.taggedExecPools); }
-
-    ExecPoolVector *multiplePools() {
-        JS_ASSERT(areMultiplePools());
-        return detag(u.taggedExecPools);
-    }
-
-  public:
-    bool addPool(JSContext *cx, JSC::ExecutablePool *pool) {
-        if (areZeroPools()) {
-            u.execPool = pool;
-            return true;
-        }
-        if (isOnePool()) {
-            JSC::ExecutablePool *oldPool = u.execPool;
-            JS_ASSERT(!isTagged(oldPool));
-            ExecPoolVector *execPools = js_new<ExecPoolVector>(SystemAllocPolicy());
-            if (!execPools)
-                return false;
-            if (!execPools->append(oldPool) || !execPools->append(pool)) {
-                js_delete(execPools);
-                return false;
-            }
-            u.taggedExecPools = tag(execPools);
-            return true;
-        }
-        return multiplePools()->append(pool);
-    }
-
-  protected:
-    void reset() {
-        BaseIC::reset();
-        if (areZeroPools()) {
-            // Common case:  do nothing.
-        } else if (isOnePool()) {
-            u.execPool->release();
-            u.execPool = NULL;
-        } else {
-            ExecPoolVector *execPools = multiplePools();
-            for (size_t i = 0; i < execPools->length(); i++)
-                (*execPools)[i]->release();
-            js_delete(execPools);
-            u.execPool = NULL;
-        }
-        JS_ASSERT(areZeroPools());
-    }
-};
-
-struct GetElementIC : public BasePolyIC {
-
-    // On stub entry:
-    //   If hasInlineTypeCheck() is true, and inlineTypeCheckPatched is false,
-    //     - typeReg contains the type of the |id| parameter.
-    //   If hasInlineTypeCheck() is true, and inlineTypeCheckPatched is true,
-    //     - typeReg contains the shape of |objReg| iff typeRegHasBaseShape
-    //       is true.
-    //   Otherwise, typeReg is garbage.
-    //
-    // On stub exit, typeReg must contain the type of the result value.
-    RegisterID typeReg   : 5;
-
-    // On stub entry, objReg contains the object pointer for the |obj| parameter.
-    // On stub exit, objReg must contain the payload of the result value.
-    RegisterID objReg    : 5;
-
-    // Offset from the fast path to the inline type check.
-    // This is only set if hasInlineTypeCheck() is true.
-    unsigned inlineTypeGuard  : 8;
-
-    // Offset from the fast path to the inline shape guard. This is always
-    // set; if |id| is known to not be int32, then it's an unconditional
-    // jump to the slow path.
-    unsigned inlineShapeGuard : 8;
-
-    // This is usable if hasInlineTypeGuard() returns true, which implies
-    // that a dense array fast path exists. The inline type guard serves as
-    // the head of the chain of all string-based element stubs.
-    bool inlineTypeGuardPatched : 1;
-
-    // This is always usable, and specifies whether the inline shape guard
-    // has been patched. If hasInlineTypeGuard() is true, it guards against
-    // a dense array, and guarantees the inline type guard has passed.
-    // Otherwise, there is no inline type guard, and the shape guard is just
-    // an unconditional jump.
-    bool inlineShapeGuardPatched : 1;
-
-    ////////////////////////////////////////////
-    // State for string-based property stubs. //
-    ////////////////////////////////////////////
-
-    // True if typeReg is guaranteed to have the shape of objReg.
-    bool typeRegHasBaseShape : 1;
-
-    // These offsets are used for string-key dependent stubs, such as named
-    // property accesses. They are separated from the int-key dependent stubs,
-    // in order to guarantee that the id type needs only one guard per type.
-    int32_t atomGuard : 8;          // optional, non-zero if present
-    int32_t firstShapeGuard : 11;    // always set
-    int32_t secondShapeGuard : 11;   // optional, non-zero if present
-
-    bool hasLastStringStub : 1;
-    JITCode lastStringStub;
-
-    // A limited ValueRemat instance. It may contains either:
-    //  1) A constant, or
-    //  2) A known type and data reg, or
-    //  3) A data reg.
-    // The sync bits are not set, and the type reg is never set and should not
-    // be used, as it is encapsulated more accurately in |typeReg|. Also, note
-    // carefully that the data reg is immutable.
-    ValueRemat idRemat;
-
-    bool hasInlineTypeGuard() const {
-        return !idRemat.isTypeKnown();
-    }
-    bool shouldPatchInlineTypeGuard() {
-        return hasInlineTypeGuard() && !inlineTypeGuardPatched;
-    }
-    bool shouldPatchUnconditionalShapeGuard() {
-        // The shape guard is only unconditional if the type is known to not
-        // be an int32.
-        if (idRemat.isTypeKnown() && idRemat.knownType() != JSVAL_TYPE_INT32)
-            return !inlineShapeGuardPatched;
-        return false;
-    }
-
-    void purge(Repatcher &repatcher);
-    LookupStatus update(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, MutableHandleValue vp);
-    LookupStatus attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandlePropertyName name,
-                               MutableHandleValue vp);
-    LookupStatus attachTypedArray(VMFrame &f, HandleObject obj, HandleValue v, HandleId id,
-                                  MutableHandleValue vp);
-    LookupStatus disable(VMFrame &f, const char *reason);
-    LookupStatus error(JSContext *cx);
-    bool shouldUpdate(VMFrame &f);
-
-  protected:
-    void reset() {
-        BasePolyIC::reset();
-        inlineTypeGuardPatched = false;
-        inlineShapeGuardPatched = false;
-        typeRegHasBaseShape = false;
-        hasLastStringStub = false;
-    }
-};
-
-struct SetElementIC : public BaseIC {
-
-    // On stub entry:
-    //   objReg contains the payload of the |obj| parameter.
-    // On stub exit:
-    //   objReg may be clobbered.
-    RegisterID objReg    : 5;
-
-    // Information on how to rematerialize |objReg|.
-    int32_t objRemat       : MIN_STATE_REMAT_BITS;
-
-    // Offset from the start of the fast path to the inline shape guard.
-    unsigned inlineShapeGuard : 6;
-
-    // True if the shape guard has been patched; false otherwise.
-    bool inlineShapeGuardPatched : 1;
-
-    // Offset from the start of the fast path to the inline hole guard.
-    unsigned inlineHoleGuard : 8;
-
-    // True if the capacity guard has been patched; false otherwise.
-    bool inlineHoleGuardPatched : 1;
-
-    // True if this is from a strict-mode script.
-    bool strictMode : 1;
-
-    // A bitmask of registers that are volatile and must be preserved across
-    // stub calls inside the IC.
-    uint32_t volatileMask;
-
-    // If true, then keyValue contains a constant index value >= 0. Otherwise,
-    // keyReg contains a dynamic integer index in any range.
-    bool hasConstantKey : 1;
-    union {
-        RegisterID keyReg;
-        int32_t    keyValue;
-    };
-
-    // Rematerialize information about the value being stored.
-    ValueRemat vr;
-
-    // Optional executable pool for the out-of-line hole stub.
-    JSC::ExecutablePool *execPool;
-
-    void purge(Repatcher &repatcher);
-    LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, int32_t key);
-    LookupStatus update(VMFrame &f, const Value &objval, const Value &idval);
-    LookupStatus disable(VMFrame &f, const char *reason);
-    LookupStatus error(JSContext *cx);
-    bool shouldUpdate(VMFrame &f);
-
-  protected:
-    void reset() {
-        BaseIC::reset();
-        if (execPool) {
-            execPool->release();
-            execPool = NULL;
-        }
-        inlineShapeGuardPatched = false;
-        inlineHoleGuardPatched = false;
-    }
-};
-
-struct PICInfo : public BasePolyIC {
-    PICInfo() { reset(); }
-
-    // Operation this is a PIC for.
-    enum Kind
-#ifdef _MSC_VER
-    : uint8_t
-#endif
-    {
-        GET,        // JSOP_GETPROP
-        SET,        // JSOP_SETPROP, JSOP_SETNAME
-        NAME,       // JSOP_NAME
-        BIND,       // JSOP_BINDNAME
-        XNAME       // JSOP_GETXPROP
-    };
-
-    union {
-        struct {
-            RegisterID typeReg  : 5;  // reg used for checking type
-            bool hasTypeCheck   : 1;  // type check and reg are present
-
-            // Reverse offset from slowPathStart to the type check slow path.
-            int32_t typeCheckOffset;
-        } get;
-        ValueRemat vr;
-    } u;
-
-    // Address of the start of the last generated stub, if any. Note that this
-    // does not correctly overlay with the allocated memory; it does however
-    // overlay the portion that may need to be patched, which is good enough.
-    JITCode lastStubStart;
-
-    // Return the start address of the last path in this PIC, which is the
-    // inline path if no stubs have been generated yet.
-    CodeLocationLabel lastPathStart() {
-        if (!stubsGenerated)
-            return fastPathStart;
-        return CodeLocationLabel(lastStubStart.start());
-    }
-
-    CodeLocationLabel getFastShapeGuard() {
-        return fastPathStart.labelAtOffset(shapeGuard);
-    }
-
-    CodeLocationLabel getSlowTypeCheck() {
-        JS_ASSERT(isGet());
-        return slowPathStart.labelAtOffset(u.get.typeCheckOffset);
-    }
-
-    // Return a JITCode block corresponding to the code memory to attach a
-    // new stub to.
-    JITCode lastCodeBlock(JITChunk *chunk) {
-        if (!stubsGenerated)
-            return JITCode(chunk->code.m_code.executableAddress(), chunk->code.m_size);
-        return lastStubStart;
-    }
-
-    void updateLastPath(LinkerHelper &linker, Label label) {
-        CodeLocationLabel loc = linker.locationOf(label);
-        lastStubStart = JITCode(loc.executableAddress(), linker.size());
-    }
-
-    Kind kind : 3;
-
-    // True if register R holds the base object shape along exits from the
-    // last stub.
-    bool shapeRegHasBaseShape : 1;
-
-    // If set, at least one lookup was uncacheable (no stub was generated).
-    bool hadUncacheable : 1;
-
-    // State flags.
-    bool inlinePathPatched : 1;     // inline path has been patched
-
-    RegisterID shapeReg : 5;        // also the out type reg
-    RegisterID objReg   : 5;        // also the out data reg
-
-    // Whether type properties need to be updated to reflect generated stubs.
-    bool typeMonitored : 1;
-
-    // For GET caches, whether the access may use the property cache.
-    bool cached : 1;
-
-    // Offset from start of fast path to initial shape guard.
-    uint32_t shapeGuard;
-
-    inline bool isSet() const {
-        return kind == SET;
-    }
-    inline bool isGet() const {
-        return kind == GET;
-    }
-    inline bool isBind() const {
-        return kind == BIND;
-    }
-    inline bool isScopeName() const {
-        return kind == NAME || kind == XNAME;
-    }
-    inline RegisterID typeReg() {
-        JS_ASSERT(isGet());
-        return u.get.typeReg;
-    }
-    inline bool hasTypeCheck() {
-        JS_ASSERT(isGet());
-        return u.get.hasTypeCheck;
-    }
-    inline bool shapeNeedsRemat() {
-        return !shapeRegHasBaseShape;
-    }
-
-    union {
-        GetPropLabels getPropLabels_;
-        SetPropLabels setPropLabels_;
-        BindNameLabels bindNameLabels_;
-        ScopeNameLabels scopeNameLabels_;
-    };
-    void setLabels(const ic::GetPropLabels &labels) {
-        JS_ASSERT(isGet());
-        getPropLabels_ = labels;
-    }
-    void setLabels(const ic::SetPropLabels &labels) {
-        JS_ASSERT(isSet());
-        setPropLabels_ = labels;
-    }
-    void setLabels(const ic::BindNameLabels &labels) {
-        JS_ASSERT(kind == BIND);
-        bindNameLabels_ = labels;
-    }
-    void setLabels(const ic::ScopeNameLabels &labels) {
-        JS_ASSERT(kind == NAME || kind == XNAME);
-        scopeNameLabels_ = labels;
-    }
-
-    GetPropLabels &getPropLabels() {
-        JS_ASSERT(isGet());
-        return getPropLabels_;
-    }
-    SetPropLabels &setPropLabels() {
-        JS_ASSERT(isSet());
-        return setPropLabels_;
-    }
-    BindNameLabels &bindNameLabels() {
-        JS_ASSERT(kind == BIND);
-        return bindNameLabels_;
-    }
-    ScopeNameLabels &scopeNameLabels() {
-        JS_ASSERT(kind == NAME || kind == XNAME);
-        return scopeNameLabels_;
-    }
-
-    // Where in the script did we generate this PIC?
-    jsbytecode *pc;
-
-    // Index into the script's atom table.
-    PropertyName *name;
-
-  private:
-    Shape *inlinePathShape_;
-
-  public:
-    void purge(Repatcher &repatcher);
-
-    void setInlinePathShape(Shape *shape) {
-        JS_ASSERT(!inlinePathShape_);
-        inlinePathShape_ = shape;
-    }
-
-    Shape *getSingleShape() {
-        if (disabled || hadUncacheable || stubsGenerated > 0)
-            return NULL;
-        return inlinePathShape_;
-    }
-
-  protected:
-    // Reset the data members to the state of a fresh PIC before any patching
-    // or stub generation was done.
-    void reset() {
-        BasePolyIC::reset();
-        inlinePathPatched = false;
-        shapeRegHasBaseShape = true;
-        hadUncacheable = false;
-        inlinePathShape_ = NULL;
-    }
-};
-
-#ifdef JS_POLYIC
-void JS_FASTCALL GetProp(VMFrame &f, ic::PICInfo *);
-void JS_FASTCALL SetPropOrName(VMFrame &f, ic::PICInfo *);
-void JS_FASTCALL Name(VMFrame &f, ic::PICInfo *);
-void JS_FASTCALL XName(VMFrame &f, ic::PICInfo *);
-void JS_FASTCALL BindName(VMFrame &f, ic::PICInfo *);
-void JS_FASTCALL GetElement(VMFrame &f, ic::GetElementIC *);
-template <JSBool strict> void JS_FASTCALL SetElement(VMFrame &f, ic::SetElementIC *);
-#endif
-
-} /* namespace ic */
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jsjaeger_poly_ic_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/PunboxAssembler.h
+++ /dev/null
@@ -1,411 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_assembler64_h__ && defined JS_METHODJIT && defined JS_PUNBOX64
-#define jsjaeger_assembler64_h__
-
-#include "assembler/assembler/MacroAssembler.h"
-#include "js/Value.h"
-#include "methodjit/MachineRegs.h"
-#include "methodjit/RematInfo.h"
-
-namespace js {
-namespace mjit {
-
-struct Imm64 : JSC::MacroAssembler::ImmPtr
-{
-    Imm64(uint64_t u)
-      : ImmPtr((const void *)u)
-    { }
-};
-
-/* Tag stored in shifted format. */
-struct ImmTag : JSC::MacroAssembler::ImmPtr
-{
-    ImmTag(JSValueShiftedTag shtag)
-      : ImmPtr((const void *)shtag)
-    { }
-};
-
-struct ImmType : ImmTag
-{
-    ImmType(JSValueType type)
-      : ImmTag(JSValueShiftedTag(JSVAL_TYPE_TO_SHIFTED_TAG(type)))
-    {
-        JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
-    }
-};
-
-struct ImmPayload : Imm64
-{
-    ImmPayload(uint64_t payload)
-      : Imm64(payload)
-    { }
-};
-
-class PunboxAssembler : public JSC::MacroAssembler
-{
-  public:
-    static const uint32_t PAYLOAD_OFFSET = 0;
-
-    static const JSC::MacroAssembler::Scale JSVAL_SCALE = JSC::MacroAssembler::TimesEight;
-
-    template <typename T>
-    T payloadOf(T address) {
-        return address;
-    }
-
-    template <typename T>
-    T valueOf(T address) {
-        return address;
-    }
-
-    void loadInlineSlot(RegisterID objReg, uint32_t slot,
-                        RegisterID typeReg, RegisterID dataReg) {
-        Address address(objReg, JSObject::getFixedSlotOffset(slot));
-        loadValueAsComponents(address, typeReg, dataReg);
-    }
-
-    template <typename T>
-    void loadValue(T address, RegisterID dst) {
-        loadPtr(address, dst);
-    }
-
-    void convertValueToType(RegisterID val) {
-        andPtr(Registers::TypeMaskReg, val);
-    }
-
-    void convertValueToPayload(RegisterID val) {
-        andPtr(Registers::PayloadMaskReg, val);
-    }
-
-    // Returns a label after the one Value load.
-    template <typename T>
-    Label loadValueAsComponents(T address, RegisterID type, RegisterID payload) {
-        loadValue(address, type);
-        Label l = label();
-
-        move(Registers::PayloadMaskReg, payload);
-        andPtr(type, payload);
-        xorPtr(payload, type);
-
-        return l;
-    }
-
-    void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) {
-        uint64_t bits = JSVAL_TO_IMPL(val).asBits;
-        move(Imm64(bits & JSVAL_TAG_MASK), type);
-        move(Imm64(bits & JSVAL_PAYLOAD_MASK), payload);
-    }
-
-    void loadValuePayload(const Value &val, RegisterID payload) {
-        move(Imm64(JSVAL_TO_IMPL(val).asBits & JSVAL_PAYLOAD_MASK), payload);
-    }
-
-    /*
-     * Load a (64b) js::Value from 'address' into 'type' and 'payload', and
-     * return a label which can be used by
-     * Repatcher::patchAddressOffsetForValue to patch the address offset.
-     */
-    Label loadValueWithAddressOffsetPatch(Address address, RegisterID type, RegisterID payload) {
-        return loadValueAsComponents(address, type, payload);
-    }
-
-    template <typename T>
-    void storeValueFromComponents(RegisterID type, RegisterID payload, T address) {
-        move(type, Registers::ValueReg);
-        orPtr(payload, Registers::ValueReg);
-        storeValue(Registers::ValueReg, address);
-    }
-
-    template <typename T>
-    void storeValueFromComponents(ImmTag type, RegisterID payload, T address) {
-        move(type, Registers::ValueReg);
-        orPtr(payload, Registers::ValueReg);
-        storeValue(Registers::ValueReg, address);
-    }
-
-    /*
-     * Store a (64b) js::Value from 'type' and 'payload' into 'address', and
-     * return a label which can be used by
-     * Repatcher::patchAddressOffsetForValueStore to patch the address offset.
-     */
-    DataLabel32 storeValueWithAddressOffsetPatch(RegisterID type, RegisterID payload, Address address) {
-        move(type, Registers::ValueReg);
-        orPtr(payload, Registers::ValueReg);
-        return storePtrWithAddressOffsetPatch(Registers::ValueReg, address);
-    }
-
-    /* Overload for constant type. */
-    DataLabel32 storeValueWithAddressOffsetPatch(ImmTag type, RegisterID payload, Address address) {
-        move(type, Registers::ValueReg);
-        orPtr(payload, Registers::ValueReg);
-        return storePtrWithAddressOffsetPatch(Registers::ValueReg, address);
-    }
-
-    /* Overload for constant type and constant data. */
-    DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) {
-        move(ImmPtr(JSVAL_TO_IMPL(v).asPtr), Registers::ValueReg);
-        return storePtrWithAddressOffsetPatch(Registers::ValueReg, valueOf(address));
-    }
-
-    /* Overloaded for store with value remat info. */
-    DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
-        JS_ASSERT(!vr.isFPRegister());
-        if (vr.isConstant()) {
-            return storeValueWithAddressOffsetPatch(vr.value(), address);
-        } else if (vr.isTypeKnown()) {
-            ImmType type(vr.knownType());
-            RegisterID data(vr.dataReg());
-            return storeValueWithAddressOffsetPatch(type, data, address);
-        } else {
-            RegisterID type(vr.typeReg());
-            RegisterID data(vr.dataReg());
-            return storeValueWithAddressOffsetPatch(type, data, address);
-        }
-    }
-
-    template <typename T>
-    void loadTypeTag(T address, RegisterID reg) {
-        loadValue(address, reg);
-        convertValueToType(reg);
-    }
-
-    template <typename T>
-    void storeTypeTag(ImmTag imm, T address) {
-        loadPayload(address, Registers::ValueReg);
-        orPtr(imm, Registers::ValueReg);
-        storePtr(Registers::ValueReg, valueOf(address));
-    }
-
-    template <typename T>
-    void storeTypeTag(RegisterID reg, T address) {
-        /* The type tag must be stored in shifted format. */
-        loadPayload(address, Registers::ValueReg);
-        orPtr(reg, Registers::ValueReg);
-        storePtr(Registers::ValueReg, valueOf(address));
-    }
-
-    template <typename T>
-    void loadPayload(T address, RegisterID reg) {
-        loadValue(address, reg);
-        convertValueToPayload(reg);
-    }
-
-    template <typename T>
-    void storePayload(RegisterID reg, T address) {
-        /* Not for doubles. */
-        loadTypeTag(address, Registers::ValueReg);
-        orPtr(reg, Registers::ValueReg);
-        storePtr(Registers::ValueReg, valueOf(address));
-    }
-
-    template <typename T>
-    void storePayload(ImmPayload imm, T address) {
-        /* Not for doubles. */
-        storePtr(imm, valueOf(address));
-    }
-
-    template <typename T>
-    void storeValue(RegisterID reg, T address) {
-        storePtr(reg, valueOf(address));
-    }
-
-    template <typename T>
-    void storeValue(const Value &v, T address) {
-        storePtr(Imm64(JSVAL_TO_IMPL(v).asBits), valueOf(address));
-    }
-
-    template <typename T>
-    void storeValue(const ValueRemat &vr, T address) {
-        if (vr.isConstant())
-            storeValue(vr.value(), address);
-        else if (vr.isFPRegister())
-            storeDouble(vr.fpReg(), address);
-        else if (vr.isTypeKnown())
-            storeValueFromComponents(ImmType(vr.knownType()), vr.dataReg(), address);
-        else
-            storeValueFromComponents(vr.typeReg(), vr.dataReg(), address);
-    }
-
-    template <typename T>
-    Jump guardNotHole(T address) {
-        loadTypeTag(address, Registers::ValueReg);
-        return branchPtr(Equal, Registers::ValueReg, ImmType(JSVAL_TYPE_MAGIC));
-    }
-
-    void loadPrivate(Address privAddr, RegisterID to) {
-        loadPtr(privAddr, to);
-        lshiftPtr(Imm32(1), to);
-    }
-
-    void loadObjPrivate(RegisterID base, RegisterID to, uint32_t nfixed) {
-        Address priv(base, JSObject::getPrivateDataOffset(nfixed));
-        loadPtr(priv, to);
-    }
-
-    Jump testNull(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_NULL));
-    }
-
-    Jump testNull(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testNull(cond, Registers::ValueReg);
-    }
-
-    Jump testUndefined(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_UNDEFINED));
-    }
-
-    Jump testUndefined(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testUndefined(cond, Registers::ValueReg);
-    }
-
-    Jump testInt32(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_INT32));
-    }
-
-    Jump testInt32(Condition cond, Address address) {
-        loadTypeTag(address, Registers::ValueReg);
-        return testInt32(cond, Registers::ValueReg);
-    }
-
-    Jump testNumber(Condition cond, RegisterID reg) {
-        cond = (cond == Equal) ? Below : AboveOrEqual;
-        return branchPtr(cond, reg,
-                         ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET));
-    }
-
-    Jump testNumber(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testNumber(cond, Registers::ValueReg);
-    }
-
-    Jump testPrimitive(Condition cond, RegisterID reg) {
-        cond = (cond == Equal) ? Below : AboveOrEqual;
-        return branchPtr(cond, reg,
-                         ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET));
-    }
-
-    Jump testPrimitive(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testPrimitive(cond, Registers::ValueReg);
-    }
-
-    Jump testObject(Condition cond, RegisterID reg) {
-        cond = (cond == Equal) ? AboveOrEqual : Below;
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_OBJECT));
-    }
-
-    Jump testObject(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testObject(cond, Registers::ValueReg);
-    }
-
-    Jump testGCThing(RegisterID reg) {
-        return branchPtr(AboveOrEqual, reg, ImmTag(JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET));
-    }
-
-    Jump testGCThing(Address address) {
-        loadValue(address, Registers::ValueReg);
-        return branchPtr(AboveOrEqual, Registers::ValueReg,
-                         ImmTag(JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET));
-    }
-
-    Jump testDouble(Condition cond, RegisterID reg) {
-        cond = (cond == Equal) ? BelowOrEqual : Above;
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_MAX_DOUBLE));
-    }
-
-    Jump testDouble(Condition cond, Address address) {
-        loadValue(address, Registers::ValueReg);
-        return testDouble(cond, Registers::ValueReg);
-    }
-
-    Jump testBoolean(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_BOOLEAN));
-    }
-
-    Jump testBoolean(Condition cond, Address address) {
-        loadTypeTag(address, Registers::ValueReg);
-        return testBoolean(cond, Registers::ValueReg);
-    }
-
-    Jump testMagic(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_MAGIC));
-    }
-
-    Jump testString(Condition cond, RegisterID reg) {
-        return branchPtr(cond, reg, ImmTag(JSVAL_SHIFTED_TAG_STRING));
-    }
-
-    Jump testString(Condition cond, Address address) {
-        loadTypeTag(address, Registers::ValueReg);
-        return testString(cond, Registers::ValueReg);
-    }
-
-    Jump testPrivate(Condition cond, Address address, void *ptr) {
-        uint64_t valueBits = PrivateValue(ptr).asRawBits();
-        return branchPtr(cond, address, ImmPtr((void *) valueBits));
-    }
-
-    void compareValue(Address one, Address two, RegisterID T0, RegisterID T1,
-                      Vector<Jump> *mismatches) {
-        loadValue(one, T0);
-        mismatches->append(branchPtr(NotEqual, T0, two));
-    }
-
-    void breakDouble(FPRegisterID srcDest, RegisterID typeReg, RegisterID dataReg) {
-        m_assembler.movq_rr(srcDest, typeReg);
-        move(Registers::PayloadMaskReg, dataReg);
-        andPtr(typeReg, dataReg);
-        xorPtr(dataReg, typeReg);
-    }
-
-    void fastLoadDouble(RegisterID dataReg, RegisterID typeReg, FPRegisterID fpReg) {
-        move(typeReg, Registers::ValueReg);
-        orPtr(dataReg, Registers::ValueReg);
-        m_assembler.movq_rr(Registers::ValueReg, fpReg);
-    }
-
-    void loadStaticDouble(const double *dp, FPRegisterID dest, RegisterID scratch) {
-        union DoublePun {
-            double d;
-            uint64_t u;
-        } pun;
-        pun.d = *dp;
-        move(ImmPtr(reinterpret_cast<void*>(pun.u)), scratch);
-        m_assembler.movq_rr(scratch, dest);
-    }
-
-    template <typename T>
-    Jump fastArrayLoadSlot(T address, bool holeCheck,
-                           MaybeRegisterID typeReg, RegisterID dataReg)
-    {
-        Jump notHole;
-        if (typeReg.isSet()) {
-            loadValueAsComponents(address, typeReg.reg(), dataReg);
-            if (holeCheck)
-                notHole = branchPtr(Equal, typeReg.reg(), ImmType(JSVAL_TYPE_MAGIC));
-        } else {
-            if (holeCheck) {
-                loadTypeTag(address, Registers::ValueReg);
-                notHole = branchPtr(Equal, Registers::ValueReg, ImmType(JSVAL_TYPE_MAGIC));
-            }
-            loadPayload(address, dataReg);
-        }
-        return notHole;
-    }
-};
-
-typedef PunboxAssembler ValueAssembler;
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/RematInfo.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jsjaeger_remat_h__ && defined JS_METHODJIT
-#define jsjaeger_remat_h__
-
-#include "jscntxt.h"
-#include "MachineRegs.h"
-#include "assembler/assembler/MacroAssembler.h"
-#include "vm/Stack.h"
-
-namespace js {
-namespace mjit {
-
-// Lightweight, union-able components of FrameEntry.
-struct StateRemat {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::Address Address;
-
-    static const int32_t CONSTANT = -int(UINT16_LIMIT * sizeof(Value));
-
-    // This union encodes the fastest rematerialization of a non-constant
-    // value. The |offset| field can be used to recover information
-    // without this struct's helpers:
-    //  1) A value in (CONSTANT, 0) is an argument slot.
-    //  2) A value in [0, fp) is a register ID.
-    //  3) A value in [fp, inf) is a local slot.
-    union {
-        RegisterID  reg_;
-        int32_t     offset_;
-    };
-
-    static StateRemat FromInt32(int32_t i32) {
-        StateRemat sr;
-        sr.offset_ = i32;
-        return sr;
-    }
-    static StateRemat FromRegister(RegisterID reg) {
-        StateRemat sr;
-        sr.reg_ = reg;
-        JS_ASSERT(sr.inRegister());
-        return sr;
-    }
-    static StateRemat FromAddress(Address address) {
-        JS_ASSERT(address.base == JSFrameReg);
-        StateRemat sr;
-        sr.offset_ = address.offset;
-        JS_ASSERT(sr.inMemory());
-        return sr;
-    }
-
-    // Minimum number of bits needed to compactly store the int32_t
-    // representation in a struct or union. This prevents bloating the IC
-    // structs by an extra 8 bytes in some cases. 16 bits are needed to encode
-    // the largest local:
-    //   ((UINT16_LIMIT - 1) * sizeof(Value) + sizeof(StackFrame),
-    // And an extra bit for the sign on arguments.
-#define MIN_STATE_REMAT_BITS        21
-
-    bool isConstant() const { return offset_ == CONSTANT; }
-    bool inRegister() const { return offset_ >= 0 &&
-                                     offset_ <= int32_t(JSC::MacroAssembler::TotalRegisters); }
-    bool inMemory() const {
-        return offset_ >= int32_t(sizeof(StackFrame)) ||
-               offset_ < 0;
-    }
-
-    int32_t toInt32() const { return offset_; }
-    Address address() const {
-        JS_ASSERT(inMemory());
-        return Address(JSFrameReg, offset_);
-    }
-    RegisterID reg() const {
-        JS_ASSERT(inRegister());
-        return reg_;
-    }
-};
-
-/* Lightweight version of FrameEntry. */
-struct ValueRemat {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-    union {
-        struct {
-            union {
-                int32_t     typeRemat_;
-                JSValueType knownType_;
-            } type;
-            int32_t dataRemat_   : MIN_STATE_REMAT_BITS;
-            bool    isTypeKnown_ : 1;
-        } s;
-        jsval v_;
-        FPRegisterID fpreg_;
-    } u;
-    bool isConstant_    : 1;
-    bool isFPRegister_  : 1;
-    bool isDataSynced   : 1;
-    bool isTypeSynced   : 1;
-
-    static ValueRemat FromConstant(const Value &v) {
-        ValueRemat vr;
-        vr.isConstant_ = true;
-        vr.isFPRegister_ = false;
-        vr.u.v_ = v;
-        return vr;
-    }
-    static ValueRemat FromFPRegister(FPRegisterID fpreg) {
-        ValueRemat vr;
-        vr.isConstant_ = false;
-        vr.isFPRegister_ = true;
-        vr.u.fpreg_ = fpreg;
-        return vr;
-    }
-    static ValueRemat FromKnownType(JSValueType type, RegisterID dataReg) {
-        ValueRemat vr;
-        vr.isConstant_ = false;
-        vr.isFPRegister_ = false;
-        vr.u.s.type.knownType_ = type;
-        vr.u.s.isTypeKnown_ = true;
-        vr.u.s.dataRemat_ = StateRemat::FromRegister(dataReg).toInt32();
-
-        // Assert bitfields are okay.
-        JS_ASSERT(vr.dataReg() == dataReg);
-        return vr;
-    }
-    static ValueRemat FromRegisters(RegisterID typeReg, RegisterID dataReg) {
-        ValueRemat vr;
-        vr.isConstant_ = false;
-        vr.isFPRegister_ = false;
-        vr.u.s.isTypeKnown_ = false;
-        vr.u.s.type.typeRemat_ = StateRemat::FromRegister(typeReg).toInt32();
-        vr.u.s.dataRemat_ = StateRemat::FromRegister(dataReg).toInt32();
-
-        // Assert bitfields are okay.
-        JS_ASSERT(vr.dataReg() == dataReg);
-        JS_ASSERT(vr.typeReg() == typeReg);
-        return vr;
-    }
-
-    FPRegisterID fpReg() const {
-        JS_ASSERT(isFPRegister());
-        return u.fpreg_;
-    }
-    RegisterID dataReg() const {
-        JS_ASSERT(!isConstant() && !isFPRegister());
-        return dataRemat().reg();
-    }
-    RegisterID typeReg() const {
-        JS_ASSERT(!isTypeKnown());
-        return typeRemat().reg();
-    }
-
-    bool isConstant() const { return isConstant_; }
-    bool isFPRegister() const { return isFPRegister_; }
-    bool isTypeKnown() const { return isConstant() || isFPRegister() || u.s.isTypeKnown_; }
-
-    StateRemat dataRemat() const {
-        JS_ASSERT(!isConstant());
-        return StateRemat::FromInt32(u.s.dataRemat_);
-    }
-    StateRemat typeRemat() const {
-        JS_ASSERT(!isTypeKnown());
-        return StateRemat::FromInt32(u.s.type.typeRemat_);
-    }
-    Value value() const {
-        JS_ASSERT(isConstant());
-        return u.v_;
-    }
-    JSValueType knownType() const {
-        JS_ASSERT(isTypeKnown());
-        if (isConstant()) {
-            const Value v = value();
-            if (v.isDouble())
-                return JSVAL_TYPE_DOUBLE;
-            return v.extractNonDoubleType();
-        }
-        if (isFPRegister())
-            return JSVAL_TYPE_DOUBLE;
-        return u.s.type.knownType_;
-    }
-    bool isType(JSValueType type_) const {
-        return isTypeKnown() && knownType() == type_;
-    }
-};
-
-/*
- * Describes how to rematerialize a value during compilation.
- */
-struct RematInfo {
-    typedef JSC::MacroAssembler::RegisterID RegisterID;
-    typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-
-    enum SyncState {
-        SYNCED,
-        UNSYNCED
-    };
-
-    enum RematType {
-        TYPE,
-        DATA
-    };
-
-    /* Physical location. */
-    enum PhysLoc {
-        /*
-         * Backing bits are in memory. No fast remat.
-         */
-        PhysLoc_Memory = 0,
-
-        /* Backing bits are known at compile time. */
-        PhysLoc_Constant,
-
-        /* Backing bits are in a general purpose register. */
-        PhysLoc_Register,
-
-        /* Backing bits are part of a floating point register. */
-        PhysLoc_FPRegister,
-
-        /* Backing bits are invalid/unknown. */
-        PhysLoc_Invalid
-    };
-
-    void setRegister(RegisterID reg) {
-        reg_ = reg;
-        location_ = PhysLoc_Register;
-    }
-
-    RegisterID reg() const {
-        JS_ASSERT(inRegister());
-        return reg_;
-    }
-
-    void setFPRegister(FPRegisterID reg) {
-        fpreg_ = reg;
-        location_ = PhysLoc_FPRegister;
-    }
-
-    FPRegisterID fpreg() const {
-        JS_ASSERT(inFPRegister());
-        return fpreg_;
-    }
-
-    void setMemory() {
-        location_ = PhysLoc_Memory;
-        sync_ = SYNCED;
-    }
-
-#ifdef DEBUG
-    void invalidate() {
-        location_ = PhysLoc_Invalid;
-    }
-#else
-    void invalidate() {}
-#endif
-
-    void setConstant() { location_ = PhysLoc_Constant; }
-
-    bool isConstant() const {
-        JS_ASSERT(location_ != PhysLoc_Invalid);
-        return location_ == PhysLoc_Constant;
-    }
-
-    bool inRegister() const {
-        JS_ASSERT(location_ != PhysLoc_Invalid);
-        return location_ == PhysLoc_Register;
-    }
-
-    bool inFPRegister() const {
-        JS_ASSERT(location_ != PhysLoc_Invalid);
-        return location_ == PhysLoc_FPRegister;
-    }
-
-    bool inMemory() const {
-        JS_ASSERT(location_ != PhysLoc_Invalid);
-        return location_ == PhysLoc_Memory;
-    }
-
-    bool synced() const { return sync_ == SYNCED; }
-    void sync() {
-        JS_ASSERT(!synced());
-        sync_ = SYNCED;
-    }
-    void unsync() {
-        sync_ = UNSYNCED;
-    }
-
-    void inherit(const RematInfo &other) {
-        JS_STATIC_ASSERT(sizeof(RegisterID) == sizeof(FPRegisterID));
-        reg_ = other.reg_;
-        location_ = other.location_;
-    }
-
-  private:
-    union {
-        /* Set if location is PhysLoc_Register. */
-        RegisterID reg_;
-
-        /*
-         * Set if location is PhysLoc_FPRegister.  This must be the data for a FE,
-         * and the known type is JSVAL_TYPE_DOUBLE.
-         */
-        FPRegisterID fpreg_;
-    };
-
-    /* Remat source. */
-    PhysLoc location_;
-
-    /* Sync state. */
-    SyncState sync_;
-};
-
-template <class T>
-class MaybeRegister {
-  public:
-    MaybeRegister()
-      : reg_((T)0), set(false)
-    { }
-
-    MaybeRegister(T reg)
-      : reg_(reg), set(true)
-    { }
-
-    inline T reg() const { JS_ASSERT(set); return reg_; }
-    inline void setReg(T r) { reg_ = r; set = true; }
-    inline bool isSet() const { return set; }
-
-    MaybeRegister<T> & operator =(const MaybeRegister<T> &other) {
-        set = other.set;
-        reg_ = other.reg_;
-        return *this;
-    }
-
-    MaybeRegister<T> & operator =(T r) {
-        setReg(r);
-        return *this;
-    }
-
-  private:
-    T reg_;
-    bool set;
-};
-
-typedef MaybeRegister<JSC::MacroAssembler::RegisterID> MaybeRegisterID;
-typedef MaybeRegister<JSC::MacroAssembler::FPRegisterID> MaybeFPRegisterID;
-
-class MaybeJump {
-    typedef JSC::MacroAssembler::Jump Jump;
-  public:
-    MaybeJump()
-      : set(false)
-    { }
-
-    inline Jump getJump() const { JS_ASSERT(set); return jump; }
-    inline Jump get() const { JS_ASSERT(set); return jump; }
-    inline void setJump(const Jump &j) { jump = j; set = true; }
-    inline bool isSet() const { return set; }
-
-    inline MaybeJump &operator=(Jump j) { setJump(j); return *this; }
-
-  private:
-    Jump jump;
-    bool set;
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/Retcon.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#ifdef JS_METHODJIT
-
-#include "mozilla/DebugOnly.h"
-
-#include "Retcon.h"
-#include "MethodJIT.h"
-#include "Compiler.h"
-#include "StubCalls.h"
-#include "jsdbgapi.h"
-#include "jsnum.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "assembler/assembler/RepatchBuffer.h"
-
-#include "jscntxtinlines.h"
-#include "jsinterpinlines.h"
-
-using namespace js;
-using namespace js::mjit;
-
-using mozilla::DebugOnly;
-
-namespace js {
-namespace mjit {
-
-static inline void
-SetRejoinState(StackFrame *fp, const CallSite &site, void **location)
-{
-    if (site.rejoin == REJOIN_SCRIPTED) {
-        fp->setRejoin(ScriptedRejoin(site.pcOffset));
-        *location = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolineScripted);
-    } else {
-        fp->setRejoin(StubRejoin(site.rejoin));
-        *location = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
-    }
-}
-
-static inline bool
-CallsiteMatches(uint8_t *codeStart, const CallSite &site, void *location)
-{
-    if (codeStart + site.codeOffset == location)
-        return true;
-
-#ifdef JS_CPU_ARM
-    if (codeStart + site.codeOffset + 4 == location)
-        return true;
-#endif
-
-    return false;
-}
-
-void
-Recompiler::patchCall(JITChunk *chunk, StackFrame *fp, void **location)
-{
-    uint8_t* codeStart = (uint8_t *)chunk->code.m_code.executableAddress();
-
-    CallSite *callSites_ = chunk->callSites();
-    for (uint32_t i = 0; i < chunk->nCallSites; i++) {
-        if (CallsiteMatches(codeStart, callSites_[i], *location)) {
-            JS_ASSERT(callSites_[i].inlineIndex == analyze::CrossScriptSSA::OUTER_FRAME);
-            SetRejoinState(fp, callSites_[i], location);
-            return;
-        }
-    }
-
-    JS_NOT_REACHED("failed to find call site");
-}
-
-void
-Recompiler::patchNative(JSRuntime *rt, JITChunk *chunk, StackFrame *fp,
-                        jsbytecode *pc, RejoinState rejoin)
-{
-    /*
-     * There is a native call or getter IC at pc which triggered recompilation.
-     * The recompilation could have been triggered either by the native call
-     * itself, or by a SplatApplyArgs preparing for the native call. Either
-     * way, we don't want to patch up the call, but will instead steal the pool
-     * for the IC so it doesn't get freed with the JITChunk, and patch up the
-     * jump at the end to go to the interpoline.
-     *
-     * When doing this, we do not reset the the IC itself; there may be other
-     * native calls from this chunk on the stack and we need to find and patch
-     * all live stubs before purging the chunk's caches.
-     */
-    fp->setRejoin(StubRejoin(rejoin));
-
-    /* :XXX: We might crash later if this fails. */
-    rt->jaegerRuntime().orphanedNativeFrames.append(fp);
-
-    DebugOnly<bool> found = false;
-
-    /*
-     * Find and patch all native call stubs attached to the given PC. There may
-     * be multiple ones for getter stubs attached to e.g. a GETELEM.
-     */
-    for (unsigned i = 0; i < chunk->nativeCallStubs.length(); i++) {
-        NativeCallStub &stub = chunk->nativeCallStubs[i];
-        if (stub.pc != pc)
-            continue;
-
-        found = true;
-
-        /* Check for pools that were already patched. */
-        if (!stub.pool)
-            continue;
-
-        /* Patch the native fallthrough to go to the interpoline. */
-        {
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-            /* Win64 needs stack adjustment */
-            void *interpoline = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolinePatched);
-#else
-            void *interpoline = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
-#endif
-            uint8_t *start = (uint8_t *)stub.jump.executableAddress();
-            JSC::RepatchBuffer repatch(JSC::JITCode(start - 32, 64));
-#ifdef JS_CPU_X64
-            repatch.repatch(stub.jump, interpoline);
-#else
-            repatch.relink(stub.jump, JSC::CodeLocationLabel(interpoline));
-#endif
-        }
-
-        /* :XXX: We leak the pool if this fails. Oh well. */
-        rt->jaegerRuntime().orphanedNativePools.append(stub.pool);
-
-        /* Mark as stolen in case there are multiple calls on the stack. */
-        stub.pool = NULL;
-    }
-
-    JS_ASSERT(found);
-}
-
-void
-Recompiler::patchFrame(JSRuntime *rt, VMFrame *f, JSScript *script)
-{
-    /*
-     * Check if the VMFrame returns directly into the script's jitcode. This
-     * depends on the invariant that f->fp() reflects the frame at the point
-     * where the call occurred, irregardless of any frames which were pushed
-     * inside the call.
-     */
-    StackFrame *fp = f->fp();
-    void **addr = f->returnAddressLocation();
-    RejoinState rejoin = (RejoinState) f->stubRejoin;
-    if (rejoin == REJOIN_NATIVE ||
-        rejoin == REJOIN_NATIVE_LOWERED ||
-        rejoin == REJOIN_NATIVE_GETTER) {
-        /* Native call. */
-        if (fp->script() == script) {
-            patchNative(rt, fp->jit()->chunk(f->regs.pc), fp, f->regs.pc, rejoin);
-            f->stubRejoin = REJOIN_NATIVE_PATCHED;
-        }
-    } else if (rejoin == REJOIN_NATIVE_PATCHED) {
-        /* Already patched, don't do anything. */
-    } else if (rejoin) {
-        /* Recompilation triggered by CompileFunction. */
-        if (fp->script() == script) {
-            fp->setRejoin(StubRejoin(rejoin));
-            *addr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
-            f->stubRejoin = 0;
-        }
-    } else {
-        for (int constructing = 0; constructing <= 1; constructing++) {
-            for (int barriers = 0; barriers <= 1; barriers++) {
-                JITScript *jit = script->getJIT((bool) constructing, (bool) barriers);
-                if (jit) {
-                    JITChunk *chunk = jit->findCodeChunk(*addr);
-                    if (chunk)
-                        patchCall(chunk, fp, addr);
-                }
-            }
-        }
-    }
-}
-
-StackFrame *
-Recompiler::expandInlineFrameChain(StackFrame *outer, InlineFrame *inner)
-{
-    StackFrame *parent;
-    if (inner->parent)
-        parent = expandInlineFrameChain(outer, inner->parent);
-    else
-        parent = outer;
-
-    JaegerSpew(JSpew_Recompile, "Expanding inline frame\n");
-
-    StackFrame *fp = (StackFrame *) ((uint8_t *)outer + sizeof(Value) * inner->depth);
-    fp->initInlineFrame(inner->fun, parent, inner->parentpc);
-    uint32_t pcOffset = inner->parentpc - parent->script()->code;
-
-    void **location = fp->addressOfNativeReturnAddress();
-    *location = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolineScripted);
-    parent->setRejoin(ScriptedRejoin(pcOffset));
-
-    return fp;
-}
-
-/*
- * Whether a given return address for a frame indicates it returns directly
- * into JIT code.
- */
-static inline bool
-JITCodeReturnAddress(void *data)
-{
-    return data != NULL  /* frame is interpreted */
-        && data != JS_FUNC_TO_DATA_PTR(void *, JaegerTrampolineReturn)
-        && data != JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline)
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-        && data != JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolinePatched)
-#endif
-        && data != JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolineScripted);
-}
-
-/*
- * Expand all inlined frames within fp per 'inlined' and update next and regs
- * to refer to the new innermost frame.
- */
-void
-Recompiler::expandInlineFrames(Zone *zone,
-                               StackFrame *fp, mjit::CallSite *inlined,
-                               StackFrame *next, VMFrame *f)
-{
-    JS_ASSERT_IF(next, next->prev() == fp && next->prevInline() == inlined);
-
-    /*
-     * Treat any frame expansion as a recompilation event, so that f.jit() is
-     * stable if no recompilations have occurred.
-     */
-    for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
-        comp->types.frameExpansions++;
-
-    jsbytecode *pc = next ? next->prevpc() : f->regs.pc;
-    JITChunk *chunk = fp->jit()->chunk(pc);
-
-    /*
-     * Patch the VMFrame's return address if it is returning at the given inline site.
-     * Note there is no worry about handling a native or CompileFunction call here,
-     * as such IC stubs are not generated within inline frames.
-     */
-    void **frameAddr = f->returnAddressLocation();
-    uint8_t* codeStart = (uint8_t *)chunk->code.m_code.executableAddress();
-
-    InlineFrame *inner = &chunk->inlineFrames()[inlined->inlineIndex];
-    jsbytecode *innerpc = inner->fun->nonLazyScript()->code + inlined->pcOffset;
-
-    StackFrame *innerfp = expandInlineFrameChain(fp, inner);
-
-    /* Check if the VMFrame returns into the inlined frame. */
-    if (f->stubRejoin && f->fp() == fp) {
-        /* The VMFrame is calling CompileFunction. */
-        JS_ASSERT(f->stubRejoin != REJOIN_NATIVE &&
-                  f->stubRejoin != REJOIN_NATIVE_LOWERED &&
-                  f->stubRejoin != REJOIN_NATIVE_GETTER &&
-                  f->stubRejoin != REJOIN_NATIVE_PATCHED);
-        innerfp->setRejoin(StubRejoin((RejoinState) f->stubRejoin));
-        *frameAddr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
-        f->stubRejoin = 0;
-    }
-    if (CallsiteMatches(codeStart, *inlined, *frameAddr)) {
-        /* The VMFrame returns directly into the expanded frame. */
-        SetRejoinState(innerfp, *inlined, frameAddr);
-    }
-
-    if (f->fp() == fp) {
-        JS_ASSERT(f->regs.inlined() == inlined);
-        f->regs.expandInline(innerfp, innerpc);
-    }
-
-    /*
-     * Note: unlike the case for recompilation, during frame expansion we don't
-     * need to worry about the next VMFrame holding a reference to the inlined
-     * frame in its entryncode. entryncode is non-NULL only if the next frame's
-     * code was discarded and has executed via the Interpoline, which can only
-     * happen after all inline frames have been expanded.
-     */
-
-    if (next) {
-        next->resetInlinePrev(innerfp, innerpc);
-        void **addr = next->addressOfNativeReturnAddress();
-        if (JITCodeReturnAddress(*addr)) {
-            innerfp->setRejoin(ScriptedRejoin(inlined->pcOffset));
-            *addr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpolineScripted);
-        }
-    }
-}
-
-void
-ExpandInlineFrames(Zone *zone)
-{
-    JSRuntime *rt = zone->rt;
-
-    if (!rt->hasJaegerRuntime())
-        return;
-
-    for (VMFrame *f = rt->jaegerRuntime().activeFrame(); f != NULL; f = f->previous) {
-        if (f->entryfp->compartment()->zone() != zone)
-            continue;
-
-        if (f->regs.inlined())
-            mjit::Recompiler::expandInlineFrames(zone, f->fp(), f->regs.inlined(), NULL, f);
-
-        StackFrame *end = f->entryfp->prev();
-        StackFrame *next = NULL;
-        for (StackFrame *fp = f->fp(); fp != end; fp = fp->prev()) {
-            if (!next) {
-                next = fp;
-                continue;
-            }
-            mjit::CallSite *inlined;
-            next->prevpc(&inlined);
-            if (inlined) {
-                mjit::Recompiler::expandInlineFrames(zone, fp, inlined, next, f);
-                fp = next;
-                next = NULL;
-            } else {
-                if (fp->downFramesExpanded())
-                    break;
-                next = fp;
-            }
-            fp->setDownFramesExpanded();
-        }
-    }
-}
-
-void
-ClearAllFrames(Zone *zone)
-{
-    JSRuntime *rt = zone->rt;
-
-    if (!rt->hasJaegerRuntime())
-        return;
-
-    ExpandInlineFrames(zone);
-
-    for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
-        comp->types.recompilations++;
-
-    for (VMFrame *f = rt->jaegerRuntime().activeFrame();
-         f != NULL;
-         f = f->previous)
-    {
-        if (f->entryfp->compartment()->zone() != zone)
-            continue;
-
-        Recompiler::patchFrame(rt, f, f->fp()->script());
-
-        // Clear ncode values from all frames associated with the VMFrame.
-        // Patching the VMFrame's return address will cause all its frames to
-        // finish in the interpreter, unless the interpreter enters one of the
-        // intermediate frames at a loop boundary (where EnterMethodJIT will
-        // overwrite ncode). However, leaving stale values for ncode in stack
-        // frames can confuse the recompiler, which may see the VMFrame before
-        // it has resumed execution.
-
-        for (StackFrame *fp = f->fp(); fp != f->entryfp; fp = fp->prev())
-            fp->setNativeReturnAddress(NULL);
-    }
-
-    // Purge all ICs in chunks for which we patched any native frames, see patchNative.
-    for (VMFrame *f = rt->jaegerRuntime().activeFrame();
-         f != NULL;
-         f = f->previous)
-    {
-        if (f->entryfp->compartment()->zone() != zone)
-            continue;
-
-        JS_ASSERT(f->stubRejoin != REJOIN_NATIVE &&
-                  f->stubRejoin != REJOIN_NATIVE_LOWERED &&
-                  f->stubRejoin != REJOIN_NATIVE_GETTER);
-        if (f->stubRejoin == REJOIN_NATIVE_PATCHED && f->jit() && f->chunk())
-            f->chunk()->purgeCaches();
-    }
-}
-
-/*
- * Recompilation can be triggered either by the debugger (turning debug mode on for
- * a script or setting/clearing a trap), or by dynamic changes in type information
- * from type inference. When recompiling we don't immediately recompile the JIT
- * code, but destroy the old code and remove all references to the code, including
- * those from active stack frames. Things to do:
- *
- * - Purge scripted call inline caches calling into the script.
- *
- * - For frames with an ncode return address in the original script, redirect
- *   to the interpoline.
- *
- * - For VMFrames with a stub call return address in the original script,
- *   redirect to the interpoline.
- *
- * - For VMFrames whose entryncode address (the value of entryfp->ncode before
- *   being clobbered with JaegerTrampolineReturn) is in the original script,
- *   redirect that entryncode to the interpoline.
- */
-void
-Recompiler::clearStackReferences(FreeOp *fop, JSScript *script)
-{
-    JS_ASSERT(script->hasMJITInfo());
-
-    JaegerSpew(JSpew_Recompile, "recompiling script (file \"%s\") (line \"%d\") (length \"%d\") (usecount=\"%d\")\n",
-               script->filename(), script->lineno, script->length, (int) script->getUseCount());
-
-    JSCompartment *comp = script->compartment();
-    types::AutoEnterAnalysis enter(fop, comp);
-
-    /*
-     * The strategy for this goes as follows:
-     *
-     * 1) Scan the stack, looking at all return addresses that could go into JIT
-     *    code.
-     * 2) If an address corresponds to a call site registered by |callSite| during
-     *    the last compilation, patch it to go to the interpoline.
-     * 3) Purge the old compiled state.
-     */
-
-    // Find all JIT'd stack frames to account for return addresses that will
-    // need to be patched after recompilation.
-    for (VMFrame *f = fop->runtime()->jaegerRuntime().activeFrame();
-         f != NULL;
-         f = f->previous)
-    {
-        if (f->entryfp->compartment() != comp)
-            continue;
-
-        // Scan all frames owned by this VMFrame.
-        StackFrame *end = f->entryfp->prev();
-        StackFrame *next = NULL;
-        for (StackFrame *fp = f->fp(); fp != end; fp = fp->prev()) {
-            if (fp->script() != script) {
-                next = fp;
-                continue;
-            }
-
-            if (next) {
-                // check for a scripted call returning into the recompiled script.
-                // this misses scanning the entry fp, which cannot return directly
-                // into JIT code.
-                void **addr = next->addressOfNativeReturnAddress();
-
-                if (JITCodeReturnAddress(*addr)) {
-                    JITChunk *chunk = fp->jit()->findCodeChunk(*addr);
-                    patchCall(chunk, fp, addr);
-                }
-            }
-
-            next = fp;
-        }
-
-        patchFrame(comp->rt, f, script);
-    }
-
-    comp->types.recompilations++;
-
-    // Purge all ICs in chunks for which we patched any native frames, see patchNative.
-    for (VMFrame *f = fop->runtime()->jaegerRuntime().activeFrame();
-         f != NULL;
-         f = f->previous)
-    {
-        if (f->fp()->script() == script) {
-            JS_ASSERT(f->stubRejoin != REJOIN_NATIVE &&
-                      f->stubRejoin != REJOIN_NATIVE_LOWERED &&
-                      f->stubRejoin != REJOIN_NATIVE_GETTER);
-            if (f->stubRejoin == REJOIN_NATIVE_PATCHED && f->jit() && f->chunk())
-                f->chunk()->purgeCaches();
-        }
-    }
-}
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* JS_METHODJIT */
-
deleted file mode 100644
--- a/js/src/methodjit/Retcon.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-/*
- * Retroactive continuity ("retcon") refers to the retroactive modification
- * or reinterpretation of established facts.
- */
-
-#if !defined jsjaeger_retcon_h__ && defined JS_METHODJIT
-#define jsjaeger_retcon_h__
-
-#include "jscntxt.h"
-#include "jsscript.h"
-#include "MethodJIT.h"
-#include "Compiler.h"
-
-namespace js {
-namespace mjit {
-
-/*
- * This class is responsible for sanely destroying a JITed script while frames
- * for it are still on the stack, removing all references in the world to it
- * and patching up those existing frames to go into the interpreter. If you
- * ever change the code associated with a JSScript, or otherwise would cause
- * existing JITed code to be incorrect, you /must/ use this to invalidate the
- * JITed code, fixing up the stack in the process.
- */
-class Recompiler {
-public:
-
-    // Clear all uses of compiled code for script on the stack. This must be
-    // followed by destroying all JIT code for the script.
-    static void
-    clearStackReferences(FreeOp *fop, JSScript *script);
-
-    static void
-    expandInlineFrames(JS::Zone *zone, StackFrame *fp, mjit::CallSite *inlined,
-                       StackFrame *next, VMFrame *f);
-
-    static void patchFrame(JSRuntime *rt, VMFrame *f, JSScript *script);
-
-private:
-
-    static void patchCall(JITChunk *chunk, StackFrame *fp, void **location);
-    static void patchNative(JSRuntime *rt, JITChunk *chunk, StackFrame *fp,
-                            jsbytecode *pc, RejoinState rejoin);
-
-    static StackFrame *
-    expandInlineFrameChain(StackFrame *outer, InlineFrame *inner);
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/StubCalls-inl.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jslogic_h_inl__ && defined JS_METHODJIT
-#define jslogic_h_inl__
-
-#include "methodjit/StubCalls.h"
-
-namespace js {
-namespace mjit {
-
-static inline void
-ThrowException(VMFrame &f)
-{
-    void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline);
-    *f.returnAddressLocation() = ptr;
-}
-
-#define THROW()   do { mjit::ThrowException(f); return; } while (0)
-#define THROWV(v) do { mjit::ThrowException(f); return v; } while (0)
-
-static inline void
-ReportAtomNotDefined(JSContext *cx, JSAtom *atom)
-{
-    JSAutoByteString printable;
-    if (js_AtomToPrintableString(cx, atom, &printable))
-        js_ReportIsNotDefined(cx, printable.ptr());
-}
-
-inline bool
-stubs::UncachedCallResult::setFunction(JSContext *cx, CallArgs &args,
-                                       HandleScript callScript, jsbytecode *callPc)
-{
-    if (!IsFunctionObject(args.calleev(), fun.address()))
-        return true;
-
-    if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
-        return false;
-
-    if (cx->typeInferenceEnabled() && fun->isInterpreted() &&
-        fun->nonLazyScript()->shouldCloneAtCallsite)
-    {
-        original = fun;
-        fun = CloneFunctionAtCallsite(cx, original, callScript, callPc);
-        if (!fun)
-            return false;
-        args.setCallee(ObjectValue(*fun));
-    }
-
-    return true;
-}
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* jslogic_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/StubCalls.cpp
+++ /dev/null
@@ -1,1756 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "mozilla/DebugOnly.h"
-#include "mozilla/FloatingPoint.h"
-
-#include "jscntxt.h"
-#include "jsobj.h"
-#include "jslibmath.h"
-#include "jsiter.h"
-#include "jsnum.h"
-#include "jsbool.h"
-#include "assembler/assembler/MacroAssemblerCodeRef.h"
-#include "jstypes.h"
-#include "jsworkers.h"
-
-#include "gc/Marking.h"
-#include "ion/AsmJS.h"
-#include "vm/Debugger.h"
-#include "vm/NumericConversions.h"
-#include "vm/Shape.h"
-#include "vm/String.h"
-#include "methodjit/Compiler.h"
-#include "methodjit/StubCalls.h"
-#include "methodjit/Retcon.h"
-
-#include "jsatominlines.h"
-#include "jsboolinlines.h"
-#include "jscntxtinlines.h"
-#include "jsfuninlines.h"
-#include "jsinterpinlines.h"
-#include "jsnuminlines.h"
-#include "jsobjinlines.h"
-#include "jsscriptinlines.h"
-#include "jstypedarray.h"
-
-#include "StubCalls-inl.h"
-#include "vm/RegExpObject-inl.h"
-#include "vm/Shape-inl.h"
-#include "vm/String-inl.h"
-
-#ifdef JS_ION
-#include "ion/Ion.h"
-#endif
-
-#ifdef XP_WIN
-# include "jswin.h"
-#endif
-
-#include "jsautooplen.h"
-
-using namespace js;
-using namespace js::mjit;
-using namespace js::types;
-using namespace JSC;
-
-using mozilla::DebugOnly;
-using mozilla::DoubleIsInt32;
-using mozilla::IsNaN;
-using mozilla::IsNegative;
-
-void JS_FASTCALL
-stubs::BindName(VMFrame &f, PropertyName *name_)
-{
-    RootedPropertyName name(f.cx, name_);
-    RootedObject scope(f.cx);
-    if (!LookupNameWithGlobalDefault(f.cx, name, f.fp()->scopeChain(), &scope))
-        THROW();
-    f.regs.sp[0].setObject(*scope);
-}
-
-JSObject * JS_FASTCALL
-stubs::BindGlobalName(VMFrame &f)
-{
-    return &f.fp()->global();
-}
-
-void JS_FASTCALL
-stubs::SetName(VMFrame &f, PropertyName *name)
-{
-    JSContext *cx = f.cx;
-    RootedObject scope(cx, &f.regs.sp[-2].toObject());
-    HandleValue value = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-    RootedScript fscript(cx, f.script());
-
-    if (!SetNameOperation(cx, fscript, f.pc(), scope, value))
-        THROW();
-
-    f.regs.sp[-2] = f.regs.sp[-1];
-}
-
-void JS_FASTCALL
-stubs::Name(VMFrame &f)
-{
-    RootedValue rval(f.cx);
-    if (!NameOperation(f.cx, f.pc(), &rval))
-        THROW();
-    f.regs.sp[0] = rval;
-}
-
-void JS_FASTCALL
-stubs::IntrinsicName(VMFrame &f, PropertyName *nameArg)
-{
-    RootedValue rval(f.cx);
-
-    // PropertyNames are atoms and will never be allocated from the nursery,
-    // and the ones passed to this stub are referenced by the script so it will
-    // root them. The compacting GC will discard methodjit code.
-    SkipRoot skip(f.cx, &nameArg);
-    HandlePropertyName name = HandlePropertyName::fromMarkedLocation(&nameArg);
-    if (!f.cx->global().get()->getIntrinsicValue(f.cx, name, &rval))
-        THROW();
-    f.regs.sp[0] = rval;
-}
-
-void JS_FASTCALL
-stubs::GetElem(VMFrame &f)
-{
-    MutableHandleValue lval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-    HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-    MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-
-    if (!GetElementOperation(f.cx, JSOp(*f.pc()), lval, rval, res))
-        THROW();
-}
-
-template<JSBool strict>
-void JS_FASTCALL
-stubs::SetElem(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    HandleValue objval = HandleValue::fromMarkedLocation(&regs.sp[-3]);
-    Value &idval  = regs.sp[-2];
-    RootedValue rval(cx, regs.sp[-1]);
-
-    RootedObject obj(cx, ToObjectFromStack(cx, objval));
-    if (!obj)
-        THROW();
-
-    RootedId id(f.cx);
-    if (!ValueToId<CanGC>(f.cx, idval, &id))
-        THROW();
-
-    TypeScript::MonitorAssign(cx, obj, id);
-
-    if (obj->isArray() && JSID_IS_INT(id)) {
-        uint32_t length = obj->getDenseInitializedLength();
-        int32_t i = JSID_TO_INT(id);
-        if ((uint32_t)i >= length) {
-            if (f.script()->hasAnalysis())
-                f.script()->analysis()->getCode(f.pc()).arrayWriteHole = true;
-        }
-    }
-
-    if (!JSObject::setGeneric(cx, obj, obj, id, &rval, strict))
-        THROW();
-
-    /* :FIXME: Moving the assigned object into the lowest stack slot
-     * is a temporary hack. What we actually want is an implementation
-     * of popAfterSet() that allows popping more than one value;
-     * this logic can then be handled in Compiler.cpp. */
-    regs.sp[-3] = regs.sp[-1];
-}
-
-template void JS_FASTCALL stubs::SetElem<true>(VMFrame &f);
-template void JS_FASTCALL stubs::SetElem<false>(VMFrame &f);
-
-void JS_FASTCALL
-stubs::ToId(VMFrame &f)
-{
-    HandleValue objval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-    MutableHandleValue idval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-
-    JSObject *obj = ToObjectFromStack(f.cx, objval);
-    if (!obj)
-        THROW();
-
-    RootedId id(f.cx);
-    if (!ValueToId<CanGC>(f.cx, idval, &id))
-        THROW();
-
-    idval.set(IdToValue(id));
-    if (!idval.isInt32()) {
-        RootedScript fscript(f.cx, f.script());
-        TypeScript::MonitorUnknown(f.cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::ImplicitThis(VMFrame &f, PropertyName *name_)
-{
-    RootedObject scopeObj(f.cx, f.cx->stack.currentScriptedScopeChain());
-    RootedPropertyName name(f.cx, name_);
-
-    RootedObject obj(f.cx);
-    if (!LookupNameWithGlobalDefault(f.cx, name, scopeObj, &obj))
-        THROW();
-
-    if (!ComputeImplicitThis(f.cx, obj, MutableHandleValue::fromMarkedLocation(&f.regs.sp[0])))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::BitOr(VMFrame &f)
-{
-    int32_t i, j;
-
-    if (!ToInt32(f.cx, f.regs.sp[-2], &i) || !ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-
-    i = i | j;
-    f.regs.sp[-2].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::BitXor(VMFrame &f)
-{
-    int32_t i, j;
-
-    if (!ToInt32(f.cx, f.regs.sp[-2], &i) || !ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-
-    i = i ^ j;
-    f.regs.sp[-2].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::BitAnd(VMFrame &f)
-{
-    int32_t i, j;
-
-    if (!ToInt32(f.cx, f.regs.sp[-2], &i) || !ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-
-    i = i & j;
-    f.regs.sp[-2].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::BitNot(VMFrame &f)
-{
-    int32_t i;
-
-    if (!ToInt32(f.cx, f.regs.sp[-1], &i))
-        THROW();
-    i = ~i;
-    f.regs.sp[-1].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::Lsh(VMFrame &f)
-{
-    int32_t i, j;
-    if (!ToInt32(f.cx, f.regs.sp[-2], &i))
-        THROW();
-    if (!ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-    i = i << (j & 31);
-    f.regs.sp[-2].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::Rsh(VMFrame &f)
-{
-    int32_t i, j;
-    if (!ToInt32(f.cx, f.regs.sp[-2], &i))
-        THROW();
-    if (!ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-    i = i >> (j & 31);
-    f.regs.sp[-2].setInt32(i);
-}
-
-void JS_FASTCALL
-stubs::Ursh(VMFrame &f)
-{
-    uint32_t u;
-    if (!ToUint32(f.cx, f.regs.sp[-2], &u))
-        THROW();
-    int32_t j;
-    if (!ToInt32(f.cx, f.regs.sp[-1], &j))
-        THROW();
-
-    u >>= (j & 31);
-
-    if (!f.regs.sp[-2].setNumber(uint32_t(u))) {
-        RootedScript fscript(f.cx, f.script());
-        TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
-    }
-}
-
-template<JSBool strict>
-void JS_FASTCALL
-stubs::DefFun(VMFrame &f, JSFunction *funArg)
-{
-    /*
-     * A top-level function defined in Global or Eval code (see ECMA-262
-     * Ed. 3), or else a SpiderMonkey extension: a named function statement in
-     * a compound statement (not at the top statement level of global code, or
-     * at the top level of a function body).
-     */
-    JSContext *cx = f.cx;
-    StackFrame *fp = f.fp();
-    RootedFunction fun(f.cx, funArg);
-
-    /*
-     * If static link is not current scope, clone fun's object to link to the
-     * current scope via parent. We do this to enable sharing of compiled
-     * functions among multiple equivalent scopes, amortizing the cost of
-     * compilation over a number of executions.  Examples include XUL scripts
-     * and event handlers shared among Firefox or other Mozilla app chrome
-     * windows, and user-defined JS functions precompiled and then shared among
-     * requests in server-side JS.
-     */
-    HandleObject scopeChain = f.fp()->scopeChain();
-    if (fun->isNative() || fun->environment() != scopeChain) {
-        fun = CloneFunctionObjectIfNotSingleton(cx, fun, scopeChain);
-        if (!fun)
-            THROW();
-    } else {
-        JS_ASSERT(f.script()->compileAndGo);
-        JS_ASSERT(f.fp()->isGlobalFrame() || f.fp()->isEvalInFunction());
-    }
-
-    /*
-     * ECMA requires functions defined when entering Eval code to be
-     * impermanent.
-     */
-    unsigned attrs = fp->isEvalFrame()
-                  ? JSPROP_ENUMERATE
-                  : JSPROP_ENUMERATE | JSPROP_PERMANENT;
-
-    /*
-     * We define the function as a property of the variable object and not the
-     * current scope chain even for the case of function expression statements
-     * and functions defined by eval inside let or with blocks.
-     */
-    Rooted<JSObject*> parent(cx, &fp->varObj());
-
-    /* ES5 10.5 (NB: with subsequent errata). */
-    RootedPropertyName name(cx, fun->atom()->asPropertyName());
-    RootedShape shape(cx);
-    RootedObject pobj(cx);
-    if (!JSObject::lookupProperty(cx, parent, name, &pobj, &shape))
-        THROW();
-
-    RootedValue rval(cx, ObjectValue(*fun));
-
-    do {
-        /* Steps 5d, 5f. */
-        if (!shape || pobj != parent) {
-            if (!JSObject::defineProperty(cx, parent, name, rval,
-                                          JS_PropertyStub, JS_StrictPropertyStub, attrs))
-            {
-                THROW();
-            }
-            break;
-        }
-
-        /* Step 5e. */
-        JS_ASSERT(parent->isNative());
-        if (parent->isGlobal()) {
-            if (shape->configurable()) {
-                if (!JSObject::defineProperty(cx, parent, name, rval,
-                                              JS_PropertyStub, JS_StrictPropertyStub, attrs))
-                {
-                    THROW();
-                }
-                break;
-            }
-
-            if (shape->isAccessorDescriptor() || !shape->writable() || !shape->enumerable()) {
-                JSAutoByteString bytes;
-                if (js_AtomToPrintableString(cx, name, &bytes)) {
-                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                                         JSMSG_CANT_REDEFINE_PROP, bytes.ptr());
-                }
-                THROW();
-            }
-        }
-
-        /*
-         * Non-global properties, and global properties which we aren't simply
-         * redefining, must be set.  First, this preserves their attributes.
-         * Second, this will produce warnings and/or errors as necessary if the
-         * specified Call object property is not writable (const).
-         */
-
-        /* Step 5f. */
-        if (!JSObject::setProperty(cx, parent, parent, name, &rval, strict))
-            THROW();
-    } while (false);
-}
-
-template void JS_FASTCALL stubs::DefFun<true>(VMFrame &f, JSFunction *fun);
-template void JS_FASTCALL stubs::DefFun<false>(VMFrame &f, JSFunction *fun);
-
-#define RELATIONAL(OP)                                                        \
-    JS_BEGIN_MACRO                                                            \
-        JSContext *cx = f.cx;                                                 \
-        FrameRegs &regs = f.regs;                                             \
-        Value &rval = regs.sp[-1];                                            \
-        Value &lval = regs.sp[-2];                                            \
-        bool cond;                                                            \
-        if (!ToPrimitive(cx, JSTYPE_NUMBER, MutableHandleValue::fromMarkedLocation(&lval))) \
-            THROWV(JS_FALSE);                                                 \
-        if (!ToPrimitive(cx, JSTYPE_NUMBER, MutableHandleValue::fromMarkedLocation(&rval))) \
-            THROWV(JS_FALSE);                                                 \
-        if (lval.isString() && rval.isString()) {                             \
-            JSString *l = lval.toString(), *r = rval.toString();              \
-            int32_t cmp;                                                      \
-            if (!CompareStrings(cx, l, r, &cmp))                              \
-                THROWV(JS_FALSE);                                             \
-            cond = cmp OP 0;                                                  \
-        } else {                                                              \
-            double l, r;                                                      \
-            if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r))           \
-                THROWV(JS_FALSE);                                             \
-            cond = (l OP r);                                                  \
-        }                                                                     \
-        regs.sp[-2].setBoolean(cond);                                         \
-        return cond;                                                          \
-    JS_END_MACRO
-
-JSBool JS_FASTCALL
-stubs::LessThan(VMFrame &f)
-{
-    RELATIONAL(<);
-}
-
-JSBool JS_FASTCALL
-stubs::LessEqual(VMFrame &f)
-{
-    RELATIONAL(<=);
-}
-
-JSBool JS_FASTCALL
-stubs::GreaterThan(VMFrame &f)
-{
-    RELATIONAL(>);
-}
-
-JSBool JS_FASTCALL
-stubs::GreaterEqual(VMFrame &f)
-{
-    RELATIONAL(>=);
-}
-
-JSBool JS_FASTCALL
-stubs::ValueToBoolean(VMFrame &f)
-{
-    return ToBoolean(f.regs.sp[-1]);
-}
-
-void JS_FASTCALL
-stubs::Not(VMFrame &f)
-{
-    JSBool b = !ToBoolean(f.regs.sp[-1]);
-    f.regs.sp[-1].setBoolean(b);
-}
-
-template <bool EQ>
-static inline bool
-StubEqualityOp(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    Value &rval = regs.sp[-1];
-    Value &lval = regs.sp[-2];
-
-    bool cond;
-
-    /* The string==string case is easily the hottest;  try it first. */
-    if (lval.isString() && rval.isString()) {
-        JSString *l = lval.toString();
-        JSString *r = rval.toString();
-        bool equal;
-        if (!EqualStrings(cx, l, r, &equal))
-            return false;
-        cond = equal == EQ;
-    } else if (SameType(lval, rval)) {
-        JS_ASSERT(!lval.isString());    /* this case is handled above */
-        if (lval.isDouble()) {
-            double l = lval.toDouble();
-            double r = rval.toDouble();
-            if (EQ)
-                cond = (l == r);
-            else
-                cond = (l != r);
-        } else if (lval.isObject()) {
-            JSObject *l = &lval.toObject(), *r = &rval.toObject();
-            cond = (l == r) == EQ;
-        } else if (lval.isNullOrUndefined()) {
-            cond = EQ;
-        } else {
-            cond = (lval.payloadAsRawUint32() == rval.payloadAsRawUint32()) == EQ;
-        }
-    } else {
-        if (lval.isNullOrUndefined()) {
-            cond = (rval.isNullOrUndefined() ||
-                    (rval.isObject() && EmulatesUndefined(&rval.toObject()))) ==
-                    EQ;
-        } else if (rval.isNullOrUndefined()) {
-            cond = (lval.isObject() && EmulatesUndefined(&lval.toObject())) == EQ;
-        } else {
-            if (!ToPrimitive(cx, MutableHandleValue::fromMarkedLocation(&lval)))
-                return false;
-            if (!ToPrimitive(cx, MutableHandleValue::fromMarkedLocation(&rval)))
-                return false;
-
-            /*
-             * The string==string case is repeated because ToPrimitive can
-             * convert lval/rval to strings.
-             */
-            if (lval.isString() && rval.isString()) {
-                JSString *l = lval.toString();
-                JSString *r = rval.toString();
-                bool equal;
-                if (!EqualStrings(cx, l, r, &equal))
-                    return false;
-                cond = equal == EQ;
-            } else {
-                double l, r;
-                if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r))
-                    return false;
-
-                if (EQ)
-                    cond = (l == r);
-                else
-                    cond = (l != r);
-            }
-        }
-    }
-
-    regs.sp[-2].setBoolean(cond);
-    return true;
-}
-
-JSBool JS_FASTCALL
-stubs::Equal(VMFrame &f)
-{
-    if (!StubEqualityOp<true>(f))
-        THROWV(JS_FALSE);
-    return f.regs.sp[-2].toBoolean();
-}
-
-JSBool JS_FASTCALL
-stubs::NotEqual(VMFrame &f)
-{
-    if (!StubEqualityOp<false>(f))
-        THROWV(JS_FALSE);
-    return f.regs.sp[-2].toBoolean();
-}
-
-void JS_FASTCALL
-stubs::Add(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-    Value &rval = regs.sp[-1];
-    Value &lval = regs.sp[-2];
-
-    /* The string + string case is easily the hottest;  try it first. */
-    bool lIsString = lval.isString();
-    bool rIsString = rval.isString();
-    JSString *lstr, *rstr;
-    if (lIsString && rIsString) {
-        lstr = lval.toString();
-        rstr = rval.toString();
-        goto string_concat;
-
-    } else {
-        bool lIsObject = lval.isObject(), rIsObject = rval.isObject();
-        if (!ToPrimitive(f.cx, MutableHandleValue::fromMarkedLocation(&lval)))
-            THROW();
-        if (!ToPrimitive(f.cx, MutableHandleValue::fromMarkedLocation(&rval)))
-            THROW();
-        if ((lIsString = lval.isString()) || (rIsString = rval.isString())) {
-            if (lIsString) {
-                lstr = lval.toString();
-            } else {
-                lstr = ToString<CanGC>(cx, lval);
-                if (!lstr)
-                    THROW();
-            }
-            if (rIsString) {
-                rstr = rval.toString();
-            } else {
-                // Save/restore lstr in case of GC activity under ToString.
-                regs.sp[-2].setString(lstr);
-                rstr = ToString<CanGC>(cx, rval);
-                if (!rstr)
-                    THROW();
-                lstr = regs.sp[-2].toString();
-            }
-            if (lIsObject || rIsObject)
-                TypeScript::MonitorString(cx, f.script(), f.pc());
-            goto string_concat;
-
-        } else {
-            double l, r;
-            if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r))
-                THROW();
-            l += r;
-            Value nres = NumberValue(l);
-            if (nres.isDouble() &&
-                (lIsObject || rIsObject || (!lval.isDouble() && !rval.isDouble())))
-            {
-                TypeScript::MonitorOverflow(cx, f.script(), f.pc());
-            }
-            regs.sp[-2] = nres;
-        }
-    }
-    return;
-
-  string_concat:
-    JSString *str = ConcatStrings<NoGC>(cx, lstr, rstr);
-    if (!str) {
-        RootedString nlstr(cx, lstr), nrstr(cx, rstr);
-        str = ConcatStrings<CanGC>(cx, nlstr, nrstr);
-        if (!str)
-            THROW();
-    }
-    regs.sp[-2].setString(str);
-    regs.sp--;
-}
-
-
-void JS_FASTCALL
-stubs::Sub(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-    double d1, d2;
-    if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
-        THROW();
-    double d = d1 - d2;
-    if (!regs.sp[-2].setNumber(d)) {
-        RootedScript fscript(cx, f.script());
-        TypeScript::MonitorOverflow(cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::Mul(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-    double d1, d2;
-    if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
-        THROW();
-    double d = d1 * d2;
-    if (!regs.sp[-2].setNumber(d)) {
-        RootedScript fscript(cx, f.script());
-        TypeScript::MonitorOverflow(cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::Div(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    JSRuntime *rt = cx->runtime;
-    FrameRegs &regs = f.regs;
-
-    double d1, d2;
-    if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
-        THROW();
-    if (d2 == 0) {
-        const Value *vp;
-#ifdef XP_WIN
-        /* XXX MSVC miscompiles such that (NaN == 0) */
-        if (IsNaN(d2))
-            vp = &rt->NaNValue;
-        else
-#endif
-        if (d1 == 0 || IsNaN(d1))
-            vp = &rt->NaNValue;
-        else if (IsNegative(d1) != IsNegative(d2))
-            vp = &rt->negativeInfinityValue;
-        else
-            vp = &rt->positiveInfinityValue;
-        regs.sp[-2] = *vp;
-        RootedScript fscript(cx, f.script());
-        TypeScript::MonitorOverflow(cx, fscript, f.pc());
-    } else {
-        d1 /= d2;
-        if (!regs.sp[-2].setNumber(d1)) {
-            RootedScript fscript(cx, f.script());
-            TypeScript::MonitorOverflow(cx, fscript, f.pc());
-        }
-    }
-}
-
-void JS_FASTCALL
-stubs::Mod(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    Value &lref = regs.sp[-2];
-    Value &rref = regs.sp[-1];
-    int32_t l, r;
-    if (lref.isInt32() && rref.isInt32() &&
-        (l = lref.toInt32()) >= 0 && (r = rref.toInt32()) > 0) {
-        int32_t mod = l % r;
-        regs.sp[-2].setInt32(mod);
-    } else {
-        double d1, d2;
-        if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
-            THROW();
-        if (d2 == 0) {
-            regs.sp[-2].setDouble(js_NaN);
-        } else {
-            d1 = js_fmod(d1, d2);
-            regs.sp[-2].setDouble(d1);
-        }
-        RootedScript fscript(cx, f.script());
-        TypeScript::MonitorOverflow(cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::DebuggerStatement(VMFrame &f, jsbytecode *pc)
-{
-    JSDebuggerHandler handler = f.cx->runtime->debugHooks.debuggerHandler;
-    if (handler || !f.cx->compartment->getDebuggees().empty()) {
-        JSTrapStatus st = JSTRAP_CONTINUE;
-        RootedValue rval(f.cx);
-        if (handler) {
-            RootedScript fscript(f.cx, f.script());
-            st = handler(f.cx, fscript, pc, rval.address(), f.cx->runtime->debugHooks.debuggerHandlerData);
-        }
-        if (st == JSTRAP_CONTINUE)
-            st = Debugger::onDebuggerStatement(f.cx, &rval);
-
-        switch (st) {
-          case JSTRAP_THROW:
-            f.cx->setPendingException(rval);
-            THROW();
-
-          case JSTRAP_RETURN:
-            f.cx->clearPendingException();
-            f.cx->fp()->setReturnValue(rval);
-            *f.returnAddressLocation() = f.cx->jaegerRuntime().forceReturnFromFastCall();
-            break;
-
-          case JSTRAP_ERROR:
-            f.cx->clearPendingException();
-            THROW();
-
-          default:
-            break;
-        }
-    }
-}
-
-void JS_FASTCALL
-stubs::Interrupt(VMFrame &f, jsbytecode *pc)
-{
-    gc::MaybeVerifyBarriers(f.cx);
-
-    if (!js_HandleExecutionInterrupt(f.cx))
-        THROW();
-}
-
-#ifdef JS_ION
-void JS_FASTCALL
-stubs::TriggerIonCompile(VMFrame &f)
-{
-    RootedScript script(f.cx, f.script());
-
-    if (OffThreadCompilationEnabled(f.cx) && !f.cx->runtime->profilingScripts) {
-        if (script->hasIonScript()) {
-            /*
-             * Normally TriggerIonCompile is not called if !script->ion, but the
-             * latter jump can be bypassed if DisableScriptCodeForIon wants this
-             * code to be destroyed so that the Ion code can start running.
-             */
-            ExpandInlineFrames(f.cx->zone());
-            Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), script);
-            f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(),
-                                  /* resetUses = */ false);
-            return;
-        }
-
-        /*
-         * Also check for other possible values of script->ion, which could show up
-         * if Ion code was invalidated after calling DisableScriptCodeForIon.
-         */
-        if (!script->canIonCompile() || script->isIonCompilingOffThread())
-            return;
-
-        jsbytecode *osrPC = f.regs.pc;
-        if (*osrPC != JSOP_LOOPENTRY)
-            osrPC = NULL;
-
-        ion::MethodStatus compileStatus;
-        if (osrPC) {
-            compileStatus = ion::CanEnterAtBranch(f.cx, script, f.cx->fp(), osrPC,
-                                                  f.fp()->isConstructing());
-        } else {
-            compileStatus = ion::CanEnter(f.cx, script, f.cx->fp(), f.fp()->isConstructing());
-        }
-
-        if (compileStatus != ion::Method_Compiled) {
-            if (f.cx->isExceptionPending())
-                THROW();
-        }
-
-        return;
-    }
-
-    ExpandInlineFrames(f.cx->zone());
-    Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), script);
-
-    if (ion::IsEnabled(f.cx) && f.jit()->nchunks == 1 &&
-        script->canIonCompile() && !script->hasIonScript())
-    {
-        // After returning to the interpreter, IonMonkey will try to compile
-        // this script. Don't destroy the JITChunk immediately so that Ion
-        // still has access to its ICs.
-        JS_ASSERT(!f.jit()->mustDestroyEntryChunk);
-        f.jit()->mustDestroyEntryChunk = true;
-        f.jit()->disableScriptEntry();
-        return;
-    }
-
-    f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
-}
-#endif
-
-void JS_FASTCALL
-stubs::RecompileForInline(VMFrame &f)
-{
-    ExpandInlineFrames(f.cx->zone());
-    Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script());
-    f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
-}
-
-void JS_FASTCALL
-stubs::Trap(VMFrame &f, uint32_t trapTypes)
-{
-    RootedValue rval(f.cx);
-
-    /*
-     * Trap may be called for a single-step interrupt trap and/or a
-     * regular trap. Try the single-step first, and if it lets control
-     * flow through or does not exist, do the regular trap.
-     */
-    JSTrapStatus result = JSTRAP_CONTINUE;
-    if (trapTypes & JSTRAP_SINGLESTEP) {
-        /*
-         * single step mode may be paused without recompiling by
-         * setting the interruptHook to NULL.
-         */
-        JSInterruptHook hook = f.cx->runtime->debugHooks.interruptHook;
-        if (hook) {
-            RootedScript fscript(f.cx, f.script());
-            result = hook(f.cx, fscript, f.pc(), rval.address(),
-                          f.cx->runtime->debugHooks.interruptHookData);
-        }
-
-        if (result == JSTRAP_CONTINUE)
-            result = Debugger::onSingleStep(f.cx, &rval);
-    }
-
-    if (result == JSTRAP_CONTINUE && (trapTypes & JSTRAP_TRAP))
-        result = Debugger::onTrap(f.cx, &rval);
-
-    switch (result) {
-      case JSTRAP_THROW:
-        f.cx->setPendingException(rval);
-        THROW();
-
-      case JSTRAP_RETURN:
-        f.cx->clearPendingException();
-        f.cx->fp()->setReturnValue(rval);
-        *f.returnAddressLocation() = f.cx->jaegerRuntime().forceReturnFromFastCall();
-        break;
-
-      case JSTRAP_ERROR:
-        f.cx->clearPendingException();
-        THROW();
-
-      default:
-        break;
-    }
-}
-
-void JS_FASTCALL
-stubs::This(VMFrame &f)
-{
-    /*
-     * We can't yet inline scripts which need to compute their 'this' object
-     * from a primitive; the frame we are computing 'this' for does not exist yet.
-     */
-    if (f.regs.inlined()) {
-        f.script()->uninlineable = true;
-        MarkTypeObjectFlags(f.cx, &f.fp()->callee(), OBJECT_FLAG_UNINLINEABLE);
-    }
-
-    if (!ComputeThis(f.cx, f.fp()))
-        THROW();
-    f.regs.sp[-1] = f.fp()->thisValue();
-}
-
-void JS_FASTCALL
-stubs::Neg(VMFrame &f)
-{
-    double d;
-    if (!ToNumber(f.cx, f.regs.sp[-1], &d))
-        THROW();
-    d = -d;
-    if (!f.regs.sp[-1].setNumber(d)) {
-        RootedScript fscript(f.cx, f.script());
-        TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::NewInitArray(VMFrame &f, uint32_t count)
-{
-    Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
-    RootedScript fscript(f.cx, f.script());
-
-    NewObjectKind newKind = UseNewTypeForInitializer(f.cx, fscript, f.pc(), &ArrayClass);
-    RootedObject obj(f.cx, NewDenseAllocatedArray(f.cx, count, NULL, newKind));
-    if (!obj)
-        THROW();
-
-    if (type) {
-        obj->setType(type);
-    } else {
-        if (!SetInitializerObjectType(f.cx, fscript, f.pc(), obj, newKind))
-            THROW();
-    }
-
-    f.regs.sp[0].setObject(*obj);
-}
-
-void JS_FASTCALL
-stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
-{
-    JSContext *cx = f.cx;
-    Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
-    RootedScript fscript(f.cx, f.script());
-
-    NewObjectKind newKind = UseNewTypeForInitializer(f.cx, fscript, f.pc(), &ObjectClass);
-    RootedObject obj(cx);
-    if (baseobj) {
-        Rooted<JSObject*> base(cx, baseobj);
-        obj = CopyInitializerObject(cx, base, newKind);
-    } else {
-        gc::AllocKind allocKind = GuessObjectGCKind(0);
-        obj = NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind);
-    }
-
-    if (!obj)
-        THROW();
-
-    if (type) {
-        obj->setType(type);
-    } else {
-        if (!SetInitializerObjectType(cx, fscript, f.pc(), obj, newKind))
-            THROW();
-    }
-
-    f.regs.sp[0].setObject(*obj);
-}
-
-void JS_FASTCALL
-stubs::InitElem(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    /* Pop the element's value into rval. */
-    JS_ASSERT(regs.stackDepth() >= 3);
-    HandleValue rref = HandleValue::fromMarkedLocation(&regs.sp[-1]);
-    MutableHandleValue idval = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
-
-    /* Find the object being initialized at top of stack. */
-    const Value &lref = regs.sp[-3];
-    JS_ASSERT(lref.isObject());
-    RootedObject obj(cx, &lref.toObject());
-
-    if (!InitElemOperation(cx, obj, idval, rref))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::RegExp(VMFrame &f, JSObject *regexArg)
-{
-    /*
-     * Push a regexp object cloned from the regexp literal object mapped by the
-     * bytecode at pc.
-     */
-    RootedObject regex(f.cx, regexArg);
-    RootedObject proto(f.cx, f.fp()->global().getOrCreateRegExpPrototype(f.cx));
-    if (!proto)
-        THROW();
-    JS_ASSERT(proto);
-    JSObject *obj = CloneRegExpObject(f.cx, regex, proto);
-    if (!obj)
-        THROW();
-    f.regs.sp[0].setObject(*obj);
-}
-
-JSObject * JS_FASTCALL
-stubs::Lambda(VMFrame &f, JSFunction *fun_)
-{
-    RootedFunction fun(f.cx, fun_);
-    JSObject *clone = Lambda(f.cx, fun, f.fp()->scopeChain());
-    if (!clone)
-        THROWV(NULL);
-
-    return clone;
-}
-
-void JS_FASTCALL
-stubs::GetProp(VMFrame &f, PropertyName *name)
-{
-    MutableHandleValue objval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-    if (!GetPropertyOperation(f.cx, f.script(), f.pc(), objval, objval))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::GetPropNoCache(VMFrame &f, PropertyName *name)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    const Value &lval = f.regs.sp[-1];
-
-    // Uncached lookups are only used for .prototype accesses at the start of constructors.
-    JS_ASSERT(lval.isObject());
-    JS_ASSERT(name == cx->names().classPrototype);
-
-    RootedObject obj(cx, &lval.toObject());
-    RootedValue rval(cx);
-    if (!JSObject::getProperty(cx, obj, obj, name, &rval))
-        THROW();
-
-    regs.sp[-1] = rval;
-}
-
-void JS_FASTCALL
-stubs::SetProp(VMFrame &f, PropertyName *name)
-{
-    JSContext *cx = f.cx;
-    HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-    HandleValue lval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-
-    if (!SetPropertyOperation(cx, f.pc(), lval, rval))
-        THROW();
-
-    f.regs.sp[-2] = f.regs.sp[-1];
-}
-
-void JS_FASTCALL
-stubs::Iter(VMFrame &f, uint32_t flags)
-{
-    if (!ValueToIterator(f.cx, flags, MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1])))
-        THROW();
-    JS_ASSERT(!f.regs.sp[-1].isPrimitive());
-}
-
-static void
-InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    /* Load the property's initial value into rval. */
-    JS_ASSERT(regs.stackDepth() >= 2);
-    RootedValue rval(f.cx, regs.sp[-1]);
-
-    /* Load the object being initialized into lval/obj. */
-    RootedObject obj(cx, &regs.sp[-2].toObject());
-    JS_ASSERT(obj->isNative());
-
-    /* Get the immediate property name into id. */
-    RootedId id(cx, NameToId(name));
-
-    if (JS_UNLIKELY(name == cx->names().proto)
-        ? !baseops::SetPropertyHelper(cx, obj, obj, id, 0, &rval, false)
-        : !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
-                                JSPROP_ENUMERATE, 0, 0, 0)) {
-        THROW();
-    }
-}
-
-void JS_FASTCALL
-stubs::InitProp(VMFrame &f, PropertyName *name)
-{
-    InitPropOrMethod(f, name, JSOP_INITPROP);
-}
-
-void JS_FASTCALL
-stubs::IterNext(VMFrame &f)
-{
-    JS_ASSERT(f.regs.stackDepth() >= 1);
-    JS_ASSERT(f.regs.sp[-1].isObject());
-
-    RootedObject iterobj(f.cx, &f.regs.sp[-1].toObject());
-    f.regs.sp[0].setNull();
-    f.regs.sp++;
-    if (!js_IteratorNext(f.cx, iterobj, MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1])))
-        THROW();
-}
-
-JSBool JS_FASTCALL
-stubs::IterMore(VMFrame &f)
-{
-    JS_ASSERT(f.regs.stackDepth() >= 1);
-    JS_ASSERT(f.regs.sp[-1].isObject());
-
-    RootedValue v(f.cx);
-    Rooted<JSObject*> iterobj(f.cx, &f.regs.sp[-1].toObject());
-    if (!js_IteratorMore(f.cx, iterobj, &v))
-        THROWV(JS_FALSE);
-
-    return v.toBoolean();
-}
-
-void JS_FASTCALL
-stubs::EndIter(VMFrame &f)
-{
-    JS_ASSERT(f.regs.stackDepth() >= 1);
-    RootedObject obj(f.cx, &f.regs.sp[-1].toObject());
-    if (!CloseIterator(f.cx, obj))
-        THROW();
-}
-
-JSString * JS_FASTCALL
-stubs::TypeOf(VMFrame &f)
-{
-    const Value &ref = f.regs.sp[-1];
-    JSType type = JS_TypeOfValue(f.cx, ref);
-    return TypeName(type, f.cx);
-}
-
-void JS_FASTCALL
-stubs::StrictEq(VMFrame &f)
-{
-    const Value &rhs = f.regs.sp[-1];
-    const Value &lhs = f.regs.sp[-2];
-    bool equal;
-    if (!StrictlyEqual(f.cx, lhs, rhs, &equal))
-        THROW();
-    f.regs.sp--;
-    f.regs.sp[-1].setBoolean(equal == JS_TRUE);
-}
-
-void JS_FASTCALL
-stubs::StrictNe(VMFrame &f)
-{
-    const Value &rhs = f.regs.sp[-1];
-    const Value &lhs = f.regs.sp[-2];
-    bool equal;
-    if (!StrictlyEqual(f.cx, lhs, rhs, &equal))
-        THROW();
-    f.regs.sp--;
-    f.regs.sp[-1].setBoolean(equal != JS_TRUE);
-}
-
-void JS_FASTCALL
-stubs::Throw(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-
-    JS_ASSERT(!cx->isExceptionPending());
-    cx->setPendingException(f.regs.sp[-1]);
-    THROW();
-}
-
-void JS_FASTCALL
-stubs::Arguments(VMFrame &f)
-{
-    ArgumentsObject *obj = ArgumentsObject::createExpected(f.cx, f.fp());
-    if (!obj)
-        THROW();
-    f.regs.sp[0] = ObjectValue(*obj);
-}
-
-JSBool JS_FASTCALL
-stubs::InstanceOf(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-    FrameRegs &regs = f.regs;
-
-    RootedValue rref(cx, regs.sp[-1]);
-    if (rref.isPrimitive()) {
-        js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
-                            -1, rref, NullPtr());
-        THROWV(JS_FALSE);
-    }
-    RootedObject obj(cx, &rref.toObject());
-    MutableHandleValue lref = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
-    JSBool cond = JS_FALSE;
-    if (!HasInstance(cx, obj, lref, &cond))
-        THROWV(JS_FALSE);
-    f.regs.sp[-2].setBoolean(cond);
-    return cond;
-}
-
-void JS_FASTCALL
-stubs::FastInstanceOf(VMFrame &f)
-{
-    const Value &lref = f.regs.sp[-1];
-
-    if (lref.isPrimitive()) {
-        /*
-         * Throw a runtime error if instanceof is called on a function that
-         * has a non-object as its .prototype value.
-         */
-        RootedValue val(f.cx, f.regs.sp[-2]);
-        js_ReportValueError(f.cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
-        THROW();
-    }
-
-    bool isDelegate;
-    RootedObject obj(f.cx, &lref.toObject());
-    if (!IsDelegate(f.cx, obj, f.regs.sp[-3], &isDelegate))
-        THROW();
-    f.regs.sp[-3].setBoolean(isDelegate);
-}
-
-void JS_FASTCALL
-stubs::EnterBlock(VMFrame &f, JSObject *obj)
-{
-    FrameRegs &regs = f.regs;
-    JS_ASSERT(!f.regs.inlined());
-
-    StaticBlockObject &blockObj = obj->asStaticBlock();
-
-    if (*regs.pc == JSOP_ENTERBLOCK) {
-        JS_ASSERT(regs.stackDepth() == blockObj.stackDepth());
-        JS_ASSERT(regs.stackDepth() + blockObj.slotCount() <= f.fp()->script()->nslots);
-        Value *vp = regs.sp + blockObj.slotCount();
-        SetValueRangeToUndefined(regs.sp, vp);
-        regs.sp = vp;
-    }
-
-    /* Clone block iff there are any closed-over variables. */
-    if (!regs.fp()->pushBlock(f.cx, blockObj))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::LeaveBlock(VMFrame &f)
-{
-    f.fp()->popBlock(f.cx);
-}
-
-inline void *
-FindNativeCode(VMFrame &f, jsbytecode *target)
-{
-    void* native = f.fp()->script()->nativeCodeForPC(f.fp()->isConstructing(), target);
-    if (native)
-        return native;
-
-    uint32_t sourceOffset = f.pc() - f.script()->code;
-    uint32_t targetOffset = target - f.script()->code;
-
-    CrossChunkEdge *edges = f.jit()->edges();
-    for (size_t i = 0; i < f.jit()->nedges; i++) {
-        const CrossChunkEdge &edge = edges[i];
-        if (edge.source == sourceOffset && edge.target == targetOffset)
-            return edge.shimLabel;
-    }
-
-    JS_NOT_REACHED("Missing edge");
-    return NULL;
-}
-
-void * JS_FASTCALL
-stubs::TableSwitch(VMFrame &f, jsbytecode *origPc)
-{
-    jsbytecode * const originalPC = origPc;
-
-    DebugOnly<JSOp> op = JSOp(*originalPC);
-    JS_ASSERT(op == JSOP_TABLESWITCH);
-
-    uint32_t jumpOffset = GET_JUMP_OFFSET(originalPC);
-    jsbytecode *pc = originalPC + JUMP_OFFSET_LEN;
-
-    /* Note: compiler adjusts the stack beforehand. */
-    Value rval = f.regs.sp[-1];
-
-    int32_t tableIdx;
-    if (rval.isInt32()) {
-        tableIdx = rval.toInt32();
-    } else if (rval.isDouble()) {
-        double d = rval.toDouble();
-        if (d == 0) {
-            /* Treat -0 (double) as 0. */
-            tableIdx = 0;
-        } else if (!DoubleIsInt32(d, &tableIdx)) {
-            goto finally;
-        }
-    } else {
-        goto finally;
-    }
-
-    {
-        int32_t low = GET_JUMP_OFFSET(pc);
-        pc += JUMP_OFFSET_LEN;
-        int32_t high = GET_JUMP_OFFSET(pc);
-        pc += JUMP_OFFSET_LEN;
-
-        tableIdx -= low;
-        if ((uint32_t) tableIdx < (uint32_t)(high - low + 1)) {
-            pc += JUMP_OFFSET_LEN * tableIdx;
-            if (uint32_t candidateOffset = GET_JUMP_OFFSET(pc))
-                jumpOffset = candidateOffset;
-        }
-    }
-
-finally:
-    /* Provide the native address. */
-    return FindNativeCode(f, originalPC + jumpOffset);
-}
-
-void JS_FASTCALL
-stubs::Pos(VMFrame &f)
-{
-    if (!ToNumber(f.cx, &f.regs.sp[-1]))
-        THROW();
-    if (!f.regs.sp[-1].isInt32()) {
-        RootedScript fscript(f.cx, f.script());
-        TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
-    }
-}
-
-void JS_FASTCALL
-stubs::DelName(VMFrame &f, PropertyName *name_)
-{
-    RootedObject scopeObj(f.cx, f.cx->stack.currentScriptedScopeChain());
-    RootedPropertyName name(f.cx, name_);
-
-    RootedObject obj(f.cx), obj2(f.cx);
-    RootedShape prop(f.cx);
-    if (!LookupName(f.cx, name, scopeObj, &obj, &obj2, &prop))
-        THROW();
-
-    /* Strict mode code should never contain JSOP_DELNAME opcodes. */
-    JS_ASSERT(!f.script()->strict);
-
-    /* ECMA says to return true if name is undefined or inherited. */
-    f.regs.sp++;
-    f.regs.sp[-1] = BooleanValue(true);
-    if (prop) {
-        JSBool succeeded;
-        if (!JSObject::deleteProperty(f.cx, obj, name, &succeeded))
-            THROW();
-        MutableHandleValue rval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-        rval.setBoolean(succeeded);
-    }
-}
-
-template<JSBool strict>
-void JS_FASTCALL
-stubs::DelProp(VMFrame &f, PropertyName *name_)
-{
-    JSContext *cx = f.cx;
-    RootedPropertyName name(cx, name_);
-
-    RootedValue objval(cx, f.regs.sp[-1]);
-    RootedObject obj(cx, ToObjectFromStack(cx, objval));
-    if (!obj)
-        THROW();
-
-    JSBool succeeded;
-    if (!JSObject::deleteProperty(cx, obj, name, &succeeded))
-        THROW();
-    if (strict && !succeeded) {
-        obj->reportNotConfigurable(cx, NameToId(name));
-        THROW();
-    }
-
-    f.regs.sp[-1] = BooleanValue(succeeded);
-}
-
-template void JS_FASTCALL stubs::DelProp<true>(VMFrame &f, PropertyName *name);
-template void JS_FASTCALL stubs::DelProp<false>(VMFrame &f, PropertyName *name);
-
-template<JSBool strict>
-void JS_FASTCALL
-stubs::DelElem(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-
-    RootedValue objval(cx, f.regs.sp[-2]);
-    RootedObject obj(cx, ToObjectFromStack(cx, objval));
-    if (!obj)
-        THROW();
-
-    const Value &propval = f.regs.sp[-1];
-    JSBool succeeded;
-    if (!JSObject::deleteByValue(cx, obj, propval, &succeeded))
-        THROW();
-    if (strict && !succeeded) {
-        // XXX This observably calls ToString(propval).  We should convert to
-        //     PropertyKey and use that to delete, and to report an error if
-        //     necessary -- but this code's all dying soon, so who cares?
-        RootedId id(cx);
-        if (!ValueToId<CanGC>(cx, propval, &id))
-            THROW();
-        obj->reportNotConfigurable(cx, id);
-        THROW();
-    }
-
-    MutableHandleValue rval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
-    rval.setBoolean(succeeded);
-}
-
-void JS_FASTCALL
-stubs::DefVarOrConst(VMFrame &f, PropertyName *dn)
-{
-    unsigned attrs = JSPROP_ENUMERATE;
-    if (!f.fp()->isEvalFrame())
-        attrs |= JSPROP_PERMANENT;
-    if (JSOp(*f.regs.pc) == JSOP_DEFCONST)
-        attrs |= JSPROP_READONLY;
-
-    Rooted<JSObject*> varobj(f.cx, &f.fp()->varObj());
-    RootedPropertyName name(f.cx, dn);
-
-    if (!DefVarOrConstOperation(f.cx, varobj, name, attrs))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::SetConst(VMFrame &f, PropertyName *name)
-{
-    JSContext *cx = f.cx;
-
-    RootedObject obj(cx, &f.fp()->varObj());
-    HandleValue ref = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
-
-    if (!JSObject::defineProperty(cx, obj, name, ref, JS_PropertyStub, JS_StrictPropertyStub,
-                                  JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY))
-    {
-        THROW();
-    }
-}
-
-JSBool JS_FASTCALL
-stubs::In(VMFrame &f)
-{
-    JSContext *cx = f.cx;
-
-    const Value &rref = f.regs.sp[-1];
-    if (!rref.isObject()) {
-        RootedValue val(cx, rref);
-        js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, val, NullPtr());
-        THROWV(JS_FALSE);
-    }
-
-    RootedObject obj(cx, &rref.toObject());
-    RootedId id(cx);
-    if (!ValueToId<CanGC>(f.cx, f.regs.sp[-2], &id))
-        THROWV(JS_FALSE);
-
-    RootedObject obj2(cx);
-    RootedShape prop(cx);
-    if (!JSObject::lookupGeneric(cx, obj, id, &obj2, &prop))
-        THROWV(JS_FALSE);
-
-    return !!prop;
-}
-
-template void JS_FASTCALL stubs::DelElem<true>(VMFrame &f);
-template void JS_FASTCALL stubs::DelElem<false>(VMFrame &f);
-
-void JS_FASTCALL
-stubs::TypeBarrierHelper(VMFrame &f, uint32_t which)
-{
-    JS_ASSERT(which == 0 || which == 1);
-
-    /* The actual pushed value is at sp[0], fix up the stack. See finishBarrier. */
-    Value &result = f.regs.sp[-1 - (int)which];
-    result = f.regs.sp[0];
-
-    /*
-     * Break type barriers at this bytecode if we have added many objects to
-     * the target already. This isn't needed if inference results for the
-     * script have been destroyed, as we will reanalyze and prune type barriers
-     * as they are regenerated.
-     */
-    RootedScript fscript(f.cx, f.script());
-    if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
-        AutoEnterAnalysis enter(f.cx);
-        fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
-    }
-
-    TypeScript::Monitor(f.cx, fscript, f.pc(), result);
-}
-
-void JS_FASTCALL
-stubs::StubTypeHelper(VMFrame &f, int32_t which)
-{
-    const Value &result = f.regs.sp[which];
-
-    RootedScript fscript(f.cx, f.script());
-    if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
-        AutoEnterAnalysis enter(f.cx);
-        fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
-    }
-
-    TypeScript::Monitor(f.cx, fscript, f.pc(), result);
-}
-
-/*
- * Variant of TypeBarrierHelper for checking types after making a native call.
- * The stack is already correct, and no fixup should be performed.
- */
-void JS_FASTCALL
-stubs::TypeBarrierReturn(VMFrame &f, Value *vp)
-{
-    RootedScript fscript(f.cx, f.script());
-    TypeScript::Monitor(f.cx, fscript, f.pc(), vp[0]);
-}
-
-void JS_FASTCALL
-stubs::NegZeroHelper(VMFrame &f)
-{
-    f.regs.sp[-1].setDouble(-0.0);
-    RootedScript fscript(f.cx, f.script());
-    TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
-}
-
-void JS_FASTCALL
-stubs::CheckArgumentTypes(VMFrame &f)
-{
-    StackFrame *fp = f.fp();
-    JSFunction *fun = fp->fun();
-    RootedScript fscript(f.cx, fun->nonLazyScript());
-    RecompilationMonitor monitor(f.cx);
-
-    {
-        /* Postpone recompilations until all args have been updated. */
-        types::AutoEnterAnalysis enter(f.cx);
-
-        if (!f.fp()->isConstructing())
-            TypeScript::SetThis(f.cx, fscript, fp->thisValue());
-        for (unsigned i = 0; i < fun->nargs; i++)
-            TypeScript::SetArgument(f.cx, fscript, i, fp->unaliasedFormal(i, DONT_CHECK_ALIASING));
-    }
-
-    if (monitor.recompiled())
-        return;
-
-#ifdef JS_MONOIC
-    ic::GenerateArgumentCheckStub(f);
-#endif
-}
-
-#ifdef DEBUG
-void JS_FASTCALL
-stubs::AssertArgumentTypes(VMFrame &f)
-{
-    StackFrame *fp = f.fp();
-    JSFunction *fun = fp->fun();
-    JSScript *script = fun->nonLazyScript();
-
-    /*
-     * Don't check the type of 'this' for constructor frames, the 'this' value
-     * has not been constructed yet.
-     */
-    if (!fp->isConstructing()) {
-        Type type = GetValueType(f.cx, fp->thisValue());
-        if (!TypeScript::ThisTypes(script)->hasType(type))
-            TypeFailure(f.cx, "Missing type for this: %s", TypeString(type));
-    }
-
-    for (unsigned i = 0; i < fun->nargs; i++) {
-        Type type = GetValueType(f.cx, fp->unaliasedFormal(i, DONT_CHECK_ALIASING));
-        if (!TypeScript::ArgTypes(script, i)->hasType(type))
-            TypeFailure(f.cx, "Missing type for arg %d: %s", i, TypeString(type));
-    }
-}
-#endif
-
-/*
- * These two are never actually called, they just give us a place to rejoin if
- * there is an invariant failure when initially entering a loop.
- */
-void JS_FASTCALL stubs::MissedBoundsCheckEntry(VMFrame &f) {}
-void JS_FASTCALL stubs::MissedBoundsCheckHead(VMFrame &f) {}
-
-void * JS_FASTCALL
-stubs::InvariantFailure(VMFrame &f, void *rval)
-{
-    /*
-     * Patch this call to the return site of the call triggering the invariant
-     * failure (or a MissedBoundsCheck* function if the failure occurred on
-     * initial loop entry), and trigger a recompilation which will then
-     * redirect to the rejoin point for that call. We want to make things look
-     * to the recompiler like we are still inside that call, and that after
-     * recompilation we will return to the call's rejoin point.
-     */
-    void *repatchCode = f.scratch;
-    JS_ASSERT(repatchCode);
-    void **frameAddr = f.returnAddressLocation();
-    *frameAddr = repatchCode;
-
-    /* Recompile the outermost script, and don't hoist any bounds checks. */
-    JSScript *script = f.fp()->script();
-    JS_ASSERT(!script->failedBoundsCheck);
-    script->failedBoundsCheck = true;
-
-    ExpandInlineFrames(f.cx->zone());
-
-    mjit::Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), script);
-    mjit::ReleaseScriptCode(f.cx->runtime->defaultFreeOp(), script);
-
-    /* Return the same value (if any) as the call triggering the invariant failure. */
-    return rval;
-}
-
-void JS_FASTCALL
-stubs::Exception(VMFrame &f)
-{
-    // Check the interrupt flag to allow interrupting deeply nested exception
-    // handling.
-    if (f.cx->runtime->interrupt && !js_HandleExecutionInterrupt(f.cx))
-        THROW();
-
-    f.regs.sp[0] = f.cx->getPendingException();
-    f.cx->clearPendingException();
-}
-
-void JS_FASTCALL
-stubs::StrictEvalPrologue(VMFrame &f)
-{
-    if (!f.fp()->jitStrictEvalPrologue(f.cx))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::HeavyweightFunctionPrologue(VMFrame &f)
-{
-    if (!f.fp()->jitHeavyweightFunctionPrologue(f.cx))
-        THROW();
-}
-
-void JS_FASTCALL
-stubs::Epilogue(VMFrame &f)
-{
-    f.fp()->epilogue(f.cx);
-}
-
-void JS_FASTCALL
-stubs::AnyFrameEpilogue(VMFrame &f)
-{
-    /*
-     * On the normal execution path, emitReturn calls ScriptDebugEpilogue
-     * and inlines epilogue. This function implements forced early
-     * returns, so it must have the same effect.
-     */
-    bool ok = true;
-    if (f.cx->compartment->debugMode())
-        ok = js::ScriptDebugEpilogue(f.cx, f.fp(), ok);
-    f.fp()->epilogue(f.cx);
-    if (!ok)
-        THROW();
-}
-
-template <bool Clamped>
-int32_t JS_FASTCALL
-stubs::ConvertToTypedInt(JSContext *cx, Value *vp)
-{
-    JS_ASSERT(!vp->isInt32());
-
-    if (vp->isDouble()) {
-        if (Clamped)
-            return ClampDoubleToUint8(vp->toDouble());
-        return ToInt32(vp->toDouble());
-    }
-
-    if (vp->isNull() || vp->isObject() || vp->isUndefined())
-        return 0;
-
-    if (vp->isBoolean())
-        return vp->toBoolean() ? 1 : 0;
-
-    JS_ASSERT(vp->isString());
-
-    int32_t i32 = 0;
-#ifdef DEBUG
-    bool success =
-#endif
-        StringToNumberType<int32_t>(cx, vp->toString(), &i32);
-    JS_ASSERT(success);
-
-    return i32;
-}
-
-template int32_t JS_FASTCALL stubs::ConvertToTypedInt<true>(JSContext *, Value *);
-template int32_t JS_FASTCALL stubs::ConvertToTypedInt<false>(JSContext *, Value *);
-
-void JS_FASTCALL
-stubs::ConvertToTypedFloat(JSContext *cx, Value *vp)
-{
-    JS_ASSERT(!vp->isDouble() && !vp->isInt32());
-
-    if (vp->isNull()) {
-        vp->setDouble(0);
-    } else if (vp->isObject() || vp->isUndefined()) {
-        vp->setDouble(js_NaN);
-    } else if (vp->isBoolean()) {
-        vp->setDouble(vp->toBoolean() ? 1 : 0);
-    } else {
-        JS_ASSERT(vp->isString());
-        double d = 0;
-#ifdef DEBUG
-        bool success =
-#endif
-            StringToNumberType<double>(cx, vp->toString(), &d);
-        JS_ASSERT(success);
-        vp->setDouble(d);
-    }
-}
-
-void JS_FASTCALL
-stubs::WriteBarrier(VMFrame &f, Value *addr)
-{
-#ifdef JS_GC_ZEAL
-    if (!f.cx->zone()->needsBarrier())
-        return;
-#endif
-    gc::MarkValueUnbarriered(f.cx->zone()->barrierTracer(), addr, "write barrier");
-}
-
-void JS_FASTCALL
-stubs::GCThingWriteBarrier(VMFrame &f, Value *addr)
-{
-#ifdef JS_GC_ZEAL
-    if (!f.cx->zone()->needsBarrier())
-        return;
-#endif
-
-    gc::Cell *cell = (gc::Cell *)addr->toGCThing();
-    if (cell && !cell->isMarked())
-        gc::MarkValueUnbarriered(f.cx->zone()->barrierTracer(), addr, "write barrier");
-}
deleted file mode 100644
--- a/js/src/methodjit/StubCalls.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined jslogic_h__ && defined JS_METHODJIT
-#define jslogic_h__
-
-#include "jsfuninlines.h"
-#include "MethodJIT.h"
-
-namespace js {
-namespace mjit {
-namespace stubs {
-
-typedef enum JSTrapType {
-    JSTRAP_NONE = 0,
-    JSTRAP_TRAP = 1,
-    JSTRAP_SINGLESTEP = 2
-} JSTrapType;
-
-void JS_FASTCALL This(VMFrame &f);
-void JS_FASTCALL NewInitArray(VMFrame &f, uint32_t count);
-void JS_FASTCALL NewInitObject(VMFrame &f, JSObject *base);
-void JS_FASTCALL Trap(VMFrame &f, uint32_t trapTypes);
-void JS_FASTCALL DebuggerStatement(VMFrame &f, jsbytecode *pc);
-void JS_FASTCALL Interrupt(VMFrame &f, jsbytecode *pc);
-void JS_FASTCALL TriggerIonCompile(VMFrame &f);
-void JS_FASTCALL RecompileForInline(VMFrame &f);
-void JS_FASTCALL InitElem(VMFrame &f);
-void JS_FASTCALL InitProp(VMFrame &f, PropertyName *name);
-
-void JS_FASTCALL HitStackQuota(VMFrame &f);
-void * JS_FASTCALL FixupArity(VMFrame &f, uint32_t argc);
-void * JS_FASTCALL CompileFunction(VMFrame &f, uint32_t argc);
-void JS_FASTCALL SlowNew(VMFrame &f, uint32_t argc);
-void JS_FASTCALL SlowCall(VMFrame &f, uint32_t argc);
-void * JS_FASTCALL UncachedNew(VMFrame &f, uint32_t argc);
-void * JS_FASTCALL UncachedCall(VMFrame &f, uint32_t argc);
-void * JS_FASTCALL UncachedLoweredCall(VMFrame &f, uint32_t argc);
-void JS_FASTCALL Eval(VMFrame &f, uint32_t argc);
-void JS_FASTCALL ScriptDebugPrologue(VMFrame &f);
-void JS_FASTCALL ScriptDebugEpilogue(VMFrame &f);
-void JS_FASTCALL ScriptProbeOnlyPrologue(VMFrame &f);
-void JS_FASTCALL ScriptProbeOnlyEpilogue(VMFrame &f);
-
-/*
- * Result struct for UncachedXHelper.
- *
- * These functions can have one of two results:
- *
- *   (1) The function was executed in the interpreter. Then all fields
- *       are NULL except unjittable.
- *
- *   (2) The function was not executed, and the function has been compiled
- *       to JM native code. Then all fields are non-NULL.
- */
-struct UncachedCallResult {
-    RootedFunction fun;        // callee function
-    RootedFunction original;   // NULL if fun is not a callsite clone, else
-                               // points to the original function.
-    void           *codeAddr;  // code address of compiled callee function
-    bool           unjittable; // did we try to JIT and fail?
-
-    UncachedCallResult(JSContext *cx) : fun(cx), original(cx) {}
-
-    void init() {
-        fun = NULL;
-        original = NULL;
-        codeAddr = NULL;
-        unjittable = false;
-    }
-    inline bool setFunction(JSContext *cx, CallArgs &args,
-                            HandleScript callScript, jsbytecode *callPc);
-};
-
-/*
- * Helper functions for stubs and IC functions for calling functions.
- * These functions either execute the function, return a native code
- * pointer that can be used to call the function, or throw.
- */
-void UncachedCallHelper(VMFrame &f, uint32_t argc, bool lowered, UncachedCallResult &ucr);
-void UncachedNewHelper(VMFrame &f, uint32_t argc, UncachedCallResult &ucr);
-
-void JS_FASTCALL CreateThis(VMFrame &f, JSObject *proto);
-void JS_FASTCALL Throw(VMFrame &f);
-
-void * JS_FASTCALL TableSwitch(VMFrame &f, jsbytecode *origPc);
-
-void JS_FASTCALL BindName(VMFrame &f, PropertyName *name);
-JSObject * JS_FASTCALL BindGlobalName(VMFrame &f);
-void JS_FASTCALL SetName(VMFrame &f, PropertyName *name);
-void JS_FASTCALL IntrinsicName(VMFrame &f, PropertyName *name);
-void JS_FASTCALL Name(VMFrame &f);
-void JS_FASTCALL GetProp(VMFrame &f, PropertyName *name);
-void JS_FASTCALL GetPropNoCache(VMFrame &f, PropertyName *name);
-void JS_FASTCALL SetProp(VMFrame &f, PropertyName *name);
-void JS_FASTCALL GetElem(VMFrame &f);
-template<JSBool strict> void JS_FASTCALL SetElem(VMFrame &f);
-void JS_FASTCALL ToId(VMFrame &f);
-void JS_FASTCALL ImplicitThis(VMFrame &f, PropertyName *name);
-
-template <JSBool strict> void JS_FASTCALL DelProp(VMFrame &f, PropertyName *name);
-template <JSBool strict> void JS_FASTCALL DelElem(VMFrame &f);
-void JS_FASTCALL DelName(VMFrame &f, PropertyName *name);
-JSBool JS_FASTCALL In(VMFrame &f);
-
-void JS_FASTCALL DefVarOrConst(VMFrame &f, PropertyName *name);
-void JS_FASTCALL SetConst(VMFrame &f, PropertyName *name);
-template<JSBool strict> void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
-void JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
-JSObject * JS_FASTCALL Lambda(VMFrame &f, JSFunction *fun);
-JSObject * JS_FASTCALL FlatLambda(VMFrame &f, JSFunction *fun);
-void JS_FASTCALL Arguments(VMFrame &f);
-void JS_FASTCALL EnterBlock(VMFrame &f, JSObject *obj);
-void JS_FASTCALL LeaveBlock(VMFrame &f);
-
-JSBool JS_FASTCALL LessThan(VMFrame &f);
-JSBool JS_FASTCALL LessEqual(VMFrame &f);
-JSBool JS_FASTCALL GreaterThan(VMFrame &f);
-JSBool JS_FASTCALL GreaterEqual(VMFrame &f);
-JSBool JS_FASTCALL Equal(VMFrame &f);
-JSBool JS_FASTCALL NotEqual(VMFrame &f);
-
-void JS_FASTCALL BitOr(VMFrame &f);
-void JS_FASTCALL BitXor(VMFrame &f);
-void JS_FASTCALL BitAnd(VMFrame &f);
-void JS_FASTCALL BitNot(VMFrame &f);
-void JS_FASTCALL Lsh(VMFrame &f);
-void JS_FASTCALL Rsh(VMFrame &f);
-void JS_FASTCALL Ursh(VMFrame &f);
-void JS_FASTCALL Add(VMFrame &f);
-void JS_FASTCALL Sub(VMFrame &f);
-void JS_FASTCALL Mul(VMFrame &f);
-void JS_FASTCALL Div(VMFrame &f);
-void JS_FASTCALL Mod(VMFrame &f);
-void JS_FASTCALL Neg(VMFrame &f);
-void JS_FASTCALL Pos(VMFrame &f);
-void JS_FASTCALL Not(VMFrame &f);
-void JS_FASTCALL StrictEq(VMFrame &f);
-void JS_FASTCALL StrictNe(VMFrame &f);
-
-void JS_FASTCALL Iter(VMFrame &f, uint32_t flags);
-void JS_FASTCALL IterNext(VMFrame &f);
-JSBool JS_FASTCALL IterMore(VMFrame &f);
-void JS_FASTCALL EndIter(VMFrame &f);
-
-JSBool JS_FASTCALL ValueToBoolean(VMFrame &f);
-JSString * JS_FASTCALL TypeOf(VMFrame &f);
-JSBool JS_FASTCALL InstanceOf(VMFrame &f);
-void JS_FASTCALL FastInstanceOf(VMFrame &f);
-
-/*
- * Helper for triggering recompilation should a name read miss a type barrier,
- * produce undefined or -0.
- */
-void JS_FASTCALL TypeBarrierHelper(VMFrame &f, uint32_t which);
-void JS_FASTCALL TypeBarrierReturn(VMFrame &f, Value *vp);
-void JS_FASTCALL NegZeroHelper(VMFrame &f);
-
-void JS_FASTCALL StubTypeHelper(VMFrame &f, int32_t which);
-
-void JS_FASTCALL CheckArgumentTypes(VMFrame &f);
-
-#ifdef DEBUG
-void JS_FASTCALL AssertArgumentTypes(VMFrame &f);
-#endif
-
-void JS_FASTCALL MissedBoundsCheckEntry(VMFrame &f);
-void JS_FASTCALL MissedBoundsCheckHead(VMFrame &f);
-void * JS_FASTCALL InvariantFailure(VMFrame &f, void *repatchCode);
-
-template <bool strict> int32_t JS_FASTCALL ConvertToTypedInt(JSContext *cx, Value *vp);
-void JS_FASTCALL ConvertToTypedFloat(JSContext *cx, Value *vp);
-
-void JS_FASTCALL Exception(VMFrame &f);
-
-void JS_FASTCALL StrictEvalPrologue(VMFrame &f);
-void JS_FASTCALL HeavyweightFunctionPrologue(VMFrame &f);
-
-void JS_FASTCALL AnyFrameEpilogue(VMFrame &f);
-void JS_FASTCALL Epilogue(VMFrame &f);
-
-JSObject * JS_FASTCALL
-NewDenseUnallocatedArray(VMFrame &f, uint32_t length);
-
-void JS_FASTCALL ArrayConcatTwoArrays(VMFrame &f);
-void JS_FASTCALL ArrayShift(VMFrame &f);
-
-void JS_FASTCALL WriteBarrier(VMFrame &f, Value *addr);
-void JS_FASTCALL GCThingWriteBarrier(VMFrame &f, Value *addr);
-
-void JS_FASTCALL CrossChunkShim(VMFrame &f, void *edge);
-
-} /* namespace stubs */
-
-/*
- * If COND is true, return A; otherwise, return B. This allows us to choose between
- * function template instantiations without running afoul of C++'s overload resolution
- * rules. (Try simplifying, and you'll either see the problem --- or have found a
- * better solution!)
- */
-template<typename FuncPtr>
-inline FuncPtr FunctionTemplateConditional(bool cond, FuncPtr a, FuncPtr b) {
-    return cond ? a : b;
-}
-
-}} /* namespace stubs,mjit,js */
-
-extern "C" void *
-js_InternalThrow(js::VMFrame &f);
-
-extern "C" void *
-js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VMFrame &f);
-
-#endif /* jslogic_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/StubCompiler.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "StubCalls.h"
-#include "StubCompiler.h"
-#include "Compiler.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "FrameState-inl.h"
-
-using namespace js;
-using namespace mjit;
-
-StubCompiler::StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame)
-: cx(cx),
-  cc(cc),
-  frame(frame),
-  masm(&cc.sps, &cc.PC),
-  generation(1),
-  lastGeneration(0),
-  exits(CompilerAllocPolicy(cx, cc)),
-  joins(CompilerAllocPolicy(cx, cc)),
-  scriptJoins(CompilerAllocPolicy(cx, cc)),
-  jumpList(SystemAllocPolicy())
-{
-#ifdef DEBUG
-    masm.setSpewPath(true);
-#endif
-}
-
-void
-StubCompiler::linkExitDirect(Jump j, Label L)
-{
-    exits.append(CrossPatch(j, L));
-}
-
-JSC::MacroAssembler::Label
-StubCompiler::syncExit(Uses uses)
-{
-    JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW MERGE CODE ---- \n");
-
-    if (lastGeneration == generation) {
-        Jump j2 = masm.jump();
-        jumpList.append(j2);
-    }
-
-    Label l = masm.label();
-    frame.sync(masm, uses);
-    lastGeneration = generation;
-
-    JaegerSpew(JSpew_Insns, " ---- END SLOW MERGE CODE ---- \n");
-
-    return l;
-}
-
-JSC::MacroAssembler::Label
-StubCompiler::syncExitAndJump(Uses uses)
-{
-    Label l = syncExit(uses);
-    Jump j2 = masm.jump();
-    jumpList.append(j2);
-    /* Suppress jumping on next sync/link. */
-    generation++;
-    return l;
-}
-
-// Link an exit from the fast path to a slow path. This does two main things:
-// (a) links the given jump to the slow path, and (b) generates a prolog for
-// the slow path that syncs frame state for a slow call that uses |uses|
-// values from the top of the stack.
-//
-// The return value is the label for the start of the merge code. This is
-// the correct place to jump to in order to execute the slow path being
-// generated here.
-//
-// Note 1: Slow path generation is interleaved with fast path generation, but
-// the slow path goes into a separate buffer. The slow path code is appended
-// to the fast path code to keep it nearby in code memory.
-//
-// Note 2: A jump from the fast path to the slow path is called an "exit".
-//         A jump from the slow path to the fast path is called a "rejoin".
-JSC::MacroAssembler::Label
-StubCompiler::linkExit(Jump j, Uses uses)
-{
-    Label l = syncExit(uses);
-    linkExitDirect(j, l);
-    return l;
-}
-
-// Special version of linkExit that is used when there is a JavaScript
-// control-flow branch after the slow path. Our compilation strategy
-// requires the JS frame to be fully materialized in memory across branches.
-// This function does a linkExit and also fully materializes the frame.
-void
-StubCompiler::linkExitForBranch(Jump j)
-{
-    Label l = syncExit(Uses(frame.frameSlots()));
-    linkExitDirect(j, l);
-}
-
-void
-StubCompiler::leave()
-{
-    JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW LEAVE CODE ---- \n");
-    for (size_t i = 0; i < jumpList.length(); i++)
-        jumpList[i].linkTo(masm.label(), &masm);
-    jumpList.clear();
-    generation++;
-    JaegerSpew(JSpew_Insns, " ---- END SLOW LEAVE CODE ---- \n");
-}
-
-void
-StubCompiler::rejoin(Changes changes)
-{
-    JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW RESTORE CODE ---- \n");
-
-    frame.merge(masm, changes);
-
-    unsigned index = crossJump(masm.jump(), cc.getLabel());
-    if (cc.loop)
-        cc.loop->addJoin(index, false);
-
-    JaegerSpew(JSpew_Insns, " ---- END SLOW RESTORE CODE ---- \n");
-}
-
-void
-StubCompiler::linkRejoin(Jump j)
-{
-    crossJump(j, cc.getLabel());
-}
-
-typedef JSC::MacroAssembler::RegisterID RegisterID;
-typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-typedef JSC::MacroAssembler::Imm32 Imm32;
-typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
-
-JSC::MacroAssembler::Call
-StubCompiler::emitStubCall(void *ptr, RejoinState rejoin, Uses uses)
-{
-    return emitStubCall(ptr, rejoin, uses, frame.totalDepth());
-}
-
-JSC::MacroAssembler::Call
-StubCompiler::emitStubCall(void *ptr, RejoinState rejoin, Uses uses, int32_t slots)
-{
-    JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
-    masm.bumpStubCount(cc.script_, cc.PC, Registers::tempCallReg());
-    DataLabelPtr inlinePatch;
-    Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
-                                  ptr, cc.outerPC(), &inlinePatch, slots);
-    JaegerSpew(JSpew_Insns, " ---- END SLOW CALL CODE ---- \n");
-
-    /* Add the call site for debugging and recompilation. */
-    Compiler::InternalCallSite site(masm.callReturnOffset(cl),
-                                    cc.inlineIndex(), cc.inlinePC(),
-                                    rejoin, true);
-    site.inlinePatch = inlinePatch;
-
-    /* Add a hook for restoring loop invariants if necessary. */
-    if (cc.loop && cc.loop->generatingInvariants()) {
-        site.loopJumpLabel = masm.label();
-        Jump j = masm.jump();
-        Label l = masm.label();
-        /* MissedBoundsCheck* are not actually called, so f.regs need to be written before InvariantFailure. */
-        bool entry = (ptr == JS_FUNC_TO_DATA_PTR(void *, stubs::MissedBoundsCheckEntry))
-                  || (ptr == JS_FUNC_TO_DATA_PTR(void *, stubs::MissedBoundsCheckHead));
-        cc.loop->addInvariantCall(j, l, true, entry, cc.callSites.length(), uses);
-    }
-
-    cc.addCallSite(site);
-    return cl;
-}
-
-void
-StubCompiler::fixCrossJumps(uint8_t *ncode, size_t offset, size_t total)
-{
-    JSC::LinkBuffer fast(ncode, total, JSC::JAEGER_CODE);
-    JSC::LinkBuffer slow(ncode + offset, total - offset, JSC::JAEGER_CODE);
-
-    for (size_t i = 0; i < exits.length(); i++)
-        fast.link(exits[i].from, slow.locationOf(exits[i].to));
-
-    for (size_t i = 0; i < scriptJoins.length(); i++) {
-        const CrossJumpInScript &cj = scriptJoins[i];
-        slow.link(cj.from, fast.locationOf(cc.labelOf(cj.pc, cj.inlineIndex)));
-    }
-
-    for (size_t i = 0; i < joins.length(); i++)
-        slow.link(joins[i].from, fast.locationOf(joins[i].to));
-}
-
-unsigned
-StubCompiler::crossJump(Jump j, Label L)
-{
-    joins.append(CrossPatch(j, L));
-
-    /* This won't underflow, as joins has space preallocated for some entries. */
-    return joins.length() - 1;
-}
-
-bool
-StubCompiler::jumpInScript(Jump j, jsbytecode *target)
-{
-    if (cc.knownJump(target)) {
-        unsigned index = crossJump(j, cc.labelOf(target, cc.inlineIndex()));
-        if (cc.loop)
-            cc.loop->addJoin(index, false);
-    } else {
-        if (!scriptJoins.append(CrossJumpInScript(j, target, cc.inlineIndex())))
-            return false;
-        if (cc.loop)
-            cc.loop->addJoin(scriptJoins.length() - 1, true);
-    }
-    return true;
-}
-
-void
-StubCompiler::patchJoin(unsigned i, bool script, Assembler::Address address, AnyRegisterID reg)
-{
-    Jump &j = script ? scriptJoins[i].from : joins[i].from;
-    j.linkTo(masm.label(), &masm);
-
-    if (reg.isReg())
-        masm.loadPayload(address, reg.reg());
-    else
-        masm.loadDouble(address, reg.fpreg());
-
-    j = masm.jump();
-}
deleted file mode 100644
--- a/js/src/methodjit/StubCompiler.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined(jsstub_compiler_h__) && defined(JS_METHODJIT)
-#define jsstub_compiler_h__
-
-#include "jscntxt.h"
-#include "MethodJIT.h"
-#include "methodjit/FrameState.h"
-#include "CodeGenIncludes.h"
-
-namespace js {
-namespace mjit {
-
-class Compiler;
-
-class StubCompiler
-{
-    typedef JSC::MacroAssembler::Call Call;
-    typedef JSC::MacroAssembler::Jump Jump;
-    typedef JSC::MacroAssembler::Label Label;
-
-    struct CrossPatch {
-        CrossPatch(Jump from, Label to)
-          : from(from), to(to)
-        { }
-
-        Jump from;
-        Label to;
-    };
-
-    struct CrossJumpInScript {
-        CrossJumpInScript(Jump from, jsbytecode *pc, uint32_t inlineIndex)
-          : from(from), pc(pc), inlineIndex(inlineIndex)
-        { }
-
-        Jump from;
-        jsbytecode *pc;
-        uint32_t inlineIndex;
-    };
-
-    JSContext *cx;
-    Compiler &cc;
-    FrameState &frame;
-
-  public:
-    Assembler masm;
-
-  private:
-    uint32_t generation;
-    uint32_t lastGeneration;
-
-    Vector<CrossPatch, 64, mjit::CompilerAllocPolicy> exits;
-    Vector<CrossPatch, 64, mjit::CompilerAllocPolicy> joins;
-    Vector<CrossJumpInScript, 64, mjit::CompilerAllocPolicy> scriptJoins;
-    Vector<Jump, 8, SystemAllocPolicy> jumpList;
-
-  public:
-    StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame);
-
-    size_t size() {
-        return masm.size();
-    }
-
-    uint8_t *buffer() {
-        return masm.buffer();
-    }
-
-    /*
-     * Force a frame sync and return a label before the syncing code.
-     * A Jump may bind to the label with leaveExitDirect().
-     */
-    JSC::MacroAssembler::Label syncExit(Uses uses);
-
-    /*
-     * Sync the exit, and state that code will be immediately outputted
-     * to the out-of-line buffer.
-     */
-    JSC::MacroAssembler::Label syncExitAndJump(Uses uses);
-
-    /* Exits from the fast path into the slow path. */
-    JSC::MacroAssembler::Label linkExit(Jump j, Uses uses);
-    void linkExitForBranch(Jump j);
-    void linkExitDirect(Jump j, Label L);
-
-    void leave();
-    void leaveWithDepth(uint32_t depth);
-
-    /*
-     * Rejoins slow-path code back to the fast-path. The invalidation param
-     * specifies how many stack slots below sp must not be reloaded from
-     * registers.
-     */
-    void rejoin(Changes changes);
-    void linkRejoin(Jump j);
-
-    /* Finish all native code patching. */
-    void fixCrossJumps(uint8_t *ncode, size_t offset, size_t total);
-    bool jumpInScript(Jump j, jsbytecode *target);
-    unsigned crossJump(Jump j, Label l);
-
-    Call emitStubCall(void *ptr, RejoinState rejoin, Uses uses);
-    Call emitStubCall(void *ptr, RejoinState rejoin, Uses uses, int32_t slots);
-
-    void patchJoin(unsigned i, bool script, Assembler::Address address, AnyRegisterID reg);
-};
-
-} /* namepsace mjit */
-} /* namespace js */
-
-#endif /* jsstub_compiler_h__ */
-
deleted file mode 100644
--- a/js/src/methodjit/TrampolineCompiler.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "TrampolineCompiler.h"
-#include "StubCalls.h"
-#include "assembler/assembler/LinkBuffer.h"
-#include "assembler/jit/ExecutableAllocator.h"
-
-namespace js {
-namespace mjit {
-
-#define CHECK_RESULT(x) if (!(x)) return false
-#define COMPILE(which, pool, how) CHECK_RESULT(compileTrampoline(&(which), &pool, how))
-#define RELEASE(which, pool) JS_BEGIN_MACRO \
-    which = NULL;                           \
-    if (pool)                               \
-        pool->release();                    \
-    pool = NULL;                            \
-JS_END_MACRO
-
-typedef JSC::MacroAssembler::Address Address;
-typedef JSC::MacroAssembler::Label Label;
-typedef JSC::MacroAssembler::Jump Jump;
-typedef JSC::MacroAssembler::ImmPtr ImmPtr;
-typedef JSC::MacroAssembler::Imm32 Imm32;
-typedef JSC::MacroAssembler::Address Address;
-
-bool
-TrampolineCompiler::compile()
-{
-#ifdef JS_METHODJIT_SPEW
-    JMCheckLogging();
-#endif
-
-    COMPILE(trampolines->forceReturn, trampolines->forceReturnPool, generateForceReturn);
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-    COMPILE(trampolines->forceReturnFast, trampolines->forceReturnFastPool, generateForceReturnFast);
-#endif
-
-    return true;
-}
-
-void
-TrampolineCompiler::release(Trampolines *tramps)
-{
-    RELEASE(tramps->forceReturn, tramps->forceReturnPool);
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-    RELEASE(tramps->forceReturnFast, tramps->forceReturnFastPool);
-#endif
-}
-
-bool
-TrampolineCompiler::compileTrampoline(Trampolines::TrampolinePtr *where,
-                                      JSC::ExecutablePool **poolp, TrampolineGenerator generator)
-{
-    Assembler masm;
-
-    Label entry = masm.label();
-    CHECK_RESULT(generator(masm));
-    JS_ASSERT(entry.isSet());
-
-    bool ok;
-    JSC::LinkBuffer buffer(&masm, execAlloc, poolp, &ok, JSC::JAEGER_CODE);
-    if (!ok)
-        return false;
-    masm.finalize(buffer);
-    uint8_t *result = (uint8_t*)buffer.finalizeCodeAddendum().dataLocation();
-    *where = JS_DATA_TO_FUNC_PTR(Trampolines::TrampolinePtr, result + masm.distanceOf(entry));
-
-    return true;
-}
-
-/*
- * This is shamelessly copied from emitReturn, but with several changes:
- * - There was always at least one inline call.
- * - We don't know if there are activation objects or a script with nesting
- *   state whose active frames need adjustment, so we always stub the epilogue.
- * - We don't know where we came from, so we don't know frame depth or PC.
- * - There is no stub buffer.
- */
-bool
-TrampolineCompiler::generateForceReturn(Assembler &masm)
-{
-    /* The JSStackFrame register may have been clobbered while returning, reload it. */
-    masm.loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
-
-    /* Perform the frame epilogue. */
-    masm.fallibleVMCall(true, JS_FUNC_TO_DATA_PTR(void *, stubs::AnyFrameEpilogue), NULL, NULL, 0);
-
-    /* Store any known return value */
-    masm.loadValueAsComponents(UndefinedValue(), JSReturnReg_Type, JSReturnReg_Data);
-    Jump rvalClear = masm.branchTest32(Assembler::Zero,
-                                       FrameFlagsAddress(), Imm32(StackFrame::HAS_RVAL));
-    Address rvalAddress(JSFrameReg, StackFrame::offsetOfReturnValue());
-    masm.loadValueAsComponents(rvalAddress, JSReturnReg_Type, JSReturnReg_Data);
-    rvalClear.linkTo(masm.label(), &masm);
-
-    /* Return to the caller */
-    masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfNcode()), Registers::ReturnReg);
-    masm.jump(Registers::ReturnReg);
-    return true;
-}
-
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-bool
-TrampolineCompiler::generateForceReturnFast(Assembler &masm)
-{
-#ifdef _WIN64
-    masm.addPtr(Imm32(32), Registers::StackPointer);
-#else
-    // In case of no fast call, when we change the return address,
-    // we need to make sure add esp by 8.
-    masm.addPtr(Imm32(16), Registers::StackPointer);
-#endif
-    return generateForceReturn(masm);
-}
-#endif
-
-} /* namespace mjit */
-} /* namespace js */
-
deleted file mode 100644
--- a/js/src/methodjit/TrampolineCompiler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#if !defined trampolines_h__ && defined JS_METHODJIT
-#define trampolines_h__
-
-#include "assembler/jit/ExecutableAllocator.h"
-#include "methodjit/CodeGenIncludes.h"
-
-namespace js {
-namespace mjit {
-
-class TrampolineCompiler
-{
-    typedef bool (*TrampolineGenerator)(Assembler &masm);
-
-public:
-    TrampolineCompiler(JSC::ExecutableAllocator *alloc, Trampolines *tramps)
-      : execAlloc(alloc), trampolines(tramps)
-    { }
-
-    bool compile();
-    static void release(Trampolines *tramps);
-
-private:
-    bool compileTrampoline(Trampolines::TrampolinePtr *where, JSC::ExecutablePool **pool,
-                           TrampolineGenerator generator);
-
-    /* Generators for trampolines. */
-    static bool generateForceReturn(Assembler &masm);
-
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-    static bool generateForceReturnFast(Assembler &masm);
-#endif
-
-    JSC::ExecutableAllocator *execAlloc;
-    Trampolines *trampolines;
-};
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif
-
deleted file mode 100644
--- a/js/src/methodjit/TrampolineMIPS.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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 "jstypes.h"
-
-/*
- * The MIPS VMFrame is 112 bytes as follows.
- *
- * 108  [ unused4      ] For alignment.
- * 104  [ ra           ]
- * 100  [ gp           ] If PIC code is generated, we will save gp.
- *  96  [ s7           ]
- *  92  [ s6           ]
- *  88  [ s5           ]
- *  84  [ s4           ]
- *  80  [ s3           ]
- *  76  [ s2           ]
- *  72  [ s1           ]
- *  68  [ s0           ]
- *  64  [ stubRejoin   ]
- *  60  [ entrycode    ]
- *  56  [ entryfp      ]
- *  52  [ stkLimit     ]
- *  48  [ cx           ]
- *  44  [ regs.fp_     ]
- *  40  [ regs.inlined_]
- *  36  [ regs.pc      ]
- *  32  [ regs.sp      ]
- *  28  [ scratch      ]
- *  24  [ previous     ]
- *  20  [ args.ptr2    ]  [ dynamicArgc ]  (union)
- *  16  [ args.ptr     ]  [ lazyArgsObj ]  (union)
- *  12  [ unused3      ] O32 ABI, space for a3 (used in callee)
- *   8  [ unused2      ] O32 ABI, space for a2 (used in callee)
- *   4  [ unused1      ] O32 ABI, space for a1 (used in callee)
- *   0  [ unused0      ] O32 ABI, space for a0 (used in callee)
- */
-
-asm (
-    ".text"     "\n"
-    ".align 2"  "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerThrowpoline"  "\n"
-    ".ent   JaegerThrowpoline"  "\n"
-    ".type  JaegerThrowpoline,@function"    "\n"
-"JaegerThrowpoline:"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-    "la     $25,js_InternalThrow"   "\n"
-    ".reloc 1f,R_MIPS_JALR,js_InternalThrow"    "\n"
-"1: jalr    $25"    "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#else
-    "jal    js_InternalThrow"       "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#endif
-    "beq    $2,$0,1f"   "\n"
-    "nop"   "\n"
-    "jr     $2  # jump to a scripted handler"   "\n"
-    "nop"   "\n"
-"1:"        "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-    "la     $25,PopActiveVMFrame"   "\n"
-    ".reloc 1f,R_MIPS_JALR,PopActiveVMFrame"    "\n"
-"1:  jalr   $25"    "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#else
-    "jal    PopActiveVMFrame"       "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#endif
-    "lw     $31,104($29)"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-#endif
-    "lw     $23,96($29)"    "\n"
-    "lw     $22,92($29)"    "\n"
-    "lw     $21,88($29)"    "\n"
-    "lw     $20,84($29)"    "\n"
-    "lw     $19,80($29)"    "\n"
-    "lw     $18,76($29)"    "\n"
-    "lw     $17,72($29)"    "\n"
-    "lw     $16,68($29)"    "\n"
-    "li     $2,0    # return 0 to represent an unhandled exception."    "\n"
-    "jr     $31"            "\n"
-    "addiu  $29,$29,112"    "\n"
-    ".set   reorder"        "\n"
-    ".set   macro"          "\n"
-    ".end   JaegerThrowpoline" "\n"
-    ".size  JaegerThrowpoline,.-JaegerThrowpoline"  "\n"
-);
-
-asm (
-    ".text"     "\n"
-    ".align 2"  "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerTrampoline"   "\n"
-    ".ent   JaegerTrampoline"   "\n"
-    ".type  JaegerTrampoline,@function" "\n"
-"JaegerTrampoline:"     "\n"
-#if defined(__PIC__)
-    "lui    $28,%hi(_gp_disp)"  "\n"
-    "addiu  $28,$28,%lo(_gp_disp)"      "\n"
-    "addu   $28,$28,$25"    "\n"
-#endif
-    "addiu  $29,$29,-112"   "\n"
-    "sw     $31,104($29)"   "\n"
-#if defined(__PIC__)
-    "sw     $28,100($29)"   "\n"
-#endif
-    "sw     $23,96($29)"    "\n"
-    "sw     $22,92($29)"    "\n"
-    "sw     $21,88($29)"    "\n"
-    "sw     $20,84($29)"    "\n"
-    "sw     $19,80($29)"    "\n"
-    "sw     $18,76($29)"    "\n"
-    "sw     $17,72($29)"    "\n"
-    "sw     $16,68($29)"    "\n"
-    "sw     $0,64($29)  # stubRejoin"	"\n"
-    "sw     $5,60($29)  # entrycode"	"\n"
-    "sw     $5,56($29)  # entryfp"	"\n"
-    "sw     $7,52($29)  # stackLimit"	"\n"
-    "sw     $4,48($29)  # cx"	"\n"
-    "sw     $5,44($29)  # regs.fp"	"\n"
-    "move   $16,$5      # preserve fp to s0"    "\n"
-    "move   $17,$6      # preserve code to s1"  "\n"
-#if defined(__PIC__)
-    "la     $25,PushActiveVMFrame"  "\n"
-    ".reloc 1f,R_MIPS_JALR,PushActiveVMFrame"   "\n"
-"1:  jalr    $25"    "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#else
-    "jal    PushActiveVMFrame"      "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#endif
-
-    "move   $25,$17 # move code to $25"	"\n"
-    "jr     $25     # jump to the compiled JavaScript Function"	"\n"
-    "nop"       "\n"
-    ".set   reorder"    "\n"
-    ".set   macro"      "\n"
-    ".end   JaegerTrampoline"   "\n"
-    ".size  JaegerTrampoline,.-JaegerTrampoline"    "\n"
-);
-
-asm (
-    ".text"     "\n"
-    ".align 2"  "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerTrampolineReturn" "\n"
-    ".ent   JaegerTrampolineReturn" "\n"
-    ".type  JaegerTrampolineReturn,@function"   "\n"
-"JaegerTrampolineReturn:"   "\n"
-#if defined(IS_LITTLE_ENDIAN)
-    "sw     $4,28($16)  # a0: fp->rval type for LITTLE-ENDIAN"  "\n"
-    "sw     $6,24($16)  # a2: fp->rval data for LITTLE-ENDIAN"  "\n"
-#else
-    "sw     $4,24($16)  # a0: fp->rval type for BIG-ENDIAN"     "\n"
-    "sw     $6,28($16)  # a2: fp->rval data for BIG-ENDIAN"     "\n"
-#endif
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-    "la     $25,PopActiveVMFrame"   "\n"
-    ".reloc 1f,R_MIPS_JALR,PopActiveVMFrame"    "\n"
-"1:  jalr    $25"    "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#else
-    "jal    PopActiveVMFrame"       "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#endif
-    "lw     $31,104($29)"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-#endif
-    "lw     $23,96($29)"    "\n"
-    "lw     $22,92($29)"    "\n"
-    "lw     $21,88($29)"    "\n"
-    "lw     $20,84($29)"    "\n"
-    "lw     $19,80($29)"    "\n"
-    "lw     $18,76($29)"    "\n"
-    "lw     $17,72($29)"    "\n"
-    "lw     $16,68($29)"    "\n"
-    "li     $2,1    # return ture to indicate successful completion"    "\n"
-    "jr     $31"    "\n"
-    "addiu  $29,$29,112"    "\n"
-    ".set   reorder"        "\n"
-    ".set   macro"          "\n"
-    ".end   JaegerTrampolineReturn" "\n"
-    ".size  JaegerTrampolineReturn,.-JaegerTrampolineReturn"    "\n"
-);
-
-asm (
-    ".text"     "\n"
-    ".align 2" "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerStubVeneer"   "\n"
-    ".ent   JaegerStubVeneer"   "\n"
-    ".type  JaegerStubVeneer,@function" "\n"
-"JaegerStubVeneer:"     "\n"
-    "addiu  $29,$29,-24 # Need 16 (a0-a3) + 4 (align) + 4 ($31) bytes"  "\n"
-    "sw     $31,20($29) # Store $31 to 20($29)" "\n"
-    "move   $25,$2      # the target address is passed from $2"  "\n"
-    "jalr   $25"    "\n"
-    "nop"           "\n"
-    "lw     $31,20($29)"        "\n"
-    "jr     $31"    "\n"
-    "addiu  $29,$29,24"         "\n"
-    ".set   reorder"    "\n"
-    ".set   macro"      "\n"
-    ".end   JaegerStubVeneer"   "\n"
-    ".size  JaegerStubVeneer,.-JaegerStubVeneer"    "\n"
-);
-
-asm (
-    ".text"     "\n"
-    ".align 2" "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerInterpolineScripted"	"\n"
-    ".ent   JaegerInterpolineScripted"	"\n"
-    ".type  JaegerInterpolineScripted,@function"    "\n"
-"JaegerInterpolineScripted:"	"\n"
-    "lw     $16,16($16) # Load f->prev_"  "\n"
-    "b      JaegerInterpoline"  "\n"
-    "sw     $16,44($29) # Update f->regs->fp_"  "\n"
-    ".set   reorder"    "\n"
-    ".set   macro"      "\n"
-    ".end   JaegerInterpolineScripted"   "\n"
-    ".size  JaegerInterpolineScripted,.-JaegerInterpolineScripted"  "\n"
-);
-
-asm (
-    ".text"     "\n"
-    ".align 2" "\n"
-    ".set   noreorder"  "\n"
-    ".set   nomacro"    "\n"
-    ".set   nomips16"   "\n"
-    ".globl JaegerInterpoline"	"\n"
-    ".ent   JaegerInterpoline"	"\n"
-    ".type  JaegerInterpoline,@function"    "\n"
-"JaegerInterpoline:"	"\n"
-    "move   $5,$4   # returntype"   "\n"
-    "move   $4,$6   # returnData"   "\n"
-    "move   $6,$2   # returnReg"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-    "la     $25,js_InternalInterpret"   "\n"
-    ".reloc 1f,R_MIPS_JALR,js_InternalInterpret"    "\n"
-"1:  jalr    $25"    "\n"
-    "move   $7,$29  # f"    "\n"
-#else
-    "jal    js_InternalInterpret"   "\n"
-    "move   $7,$29  # f"    "\n"
-#endif
-    "lw     $16,44($29) # Load f->regs->fp_ to s0"  "\n"
-#if defined(IS_LITTLE_ENDIAN)
-    "lw     $4,28($16)  # a0: fp->rval type for LITTLE-ENDIAN"  "\n"
-    "lw     $6,24($16)  # a2: fp->rval data for LITTLE-ENDIAN"  "\n"
-#else
-    "lw     $4,24($16)  # a0: fp->rval type for BIG-ENDIAN"     "\n"
-    "lw     $6,28($16)  # a2: fp->rval data for BIG-ENDIAN"     "\n"
-#endif
-    "lw     $5,28($29)  # Load sctrach -> argc"     "\n"
-    "beq    $2,$0,1f"   "\n"
-    "nop"               "\n"
-    "jr     $2"         "\n"
-    "nop"               "\n"
-"1:"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-    "la     $25,PopActiveVMFrame"   "\n"
-    ".reloc 1f,R_MIPS_JALR,PopActiveVMFrame"    "\n"
-"1:  jalr   $25"    "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#else
-    "jal    PopActiveVMFrame"       "\n"
-    "move   $4,$29  # set up a0"    "\n"
-#endif
-    "lw     $31,104($29)"    "\n"
-#if defined(__PIC__)
-    "lw     $28,100($29)"    "\n"
-#endif
-    "lw     $23,96($29)"    "\n"
-    "lw     $22,92($29)"    "\n"
-    "lw     $21,88($29)"    "\n"
-    "lw     $20,84($29)"    "\n"
-    "lw     $19,80($29)"    "\n"
-    "lw     $18,76($29)"    "\n"
-    "lw     $17,72($29)"    "\n"
-    "lw     $16,68($29)"    "\n"
-    "li     $2,0    # return 0"     "\n"
-    "jr     $31"    "\n"
-    "addiu  $29,$29,112"    "\n"
-    ".set   reorder"    "\n"
-    ".set   macro"      "\n"
-    ".end   JaegerInterpoline"	"\n"
-    ".size  JaegerInterpoline,.-JaegerInterpoline"  "\n"
-);
deleted file mode 100644
--- a/js/src/methodjit/TrampolineMasmX64.asm
+++ /dev/null
@@ -1,229 +0,0 @@
-; -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-; 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/.
-
-
-extern js_InternalThrow:PROC
-extern PushActiveVMFrame:PROC
-extern PopActiveVMFrame:PROC
-extern js_InternalInterpret:PROC
-
-.CODE
-
-; JSBool JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code,
-;                         Value *stackLimit, void *safePoint);
-JaegerTrampoline PROC FRAME
-    push    rbp
-    .PUSHREG rbp
-    mov     rbp, rsp
-    .SETFRAME rbp, 0
-    push    r12
-    .PUSHREG r12
-    push    r13
-    .PUSHREG r13
-    push    r14
-    .PUSHREG r14
-    push    r15
-    .PUSHREG r15
-    push    rdi
-    .PUSHREG rdi
-    push    rsi
-    .PUSHREG rsi
-    push    rbx
-    .PUSHREG rbx
-    sub     rsp, 16*10+8
-    .ALLOCSTACK 168
-    ; .SAVEXMM128 only supports 16 byte alignment offset
-    movdqa  xmmword ptr [rsp], xmm6
-    .SAVEXMM128 xmm6, 0
-    movdqa  xmmword ptr [rsp+16], xmm7
-    .SAVEXMM128 xmm7, 16
-    movdqa  xmmword ptr [rsp+16*2], xmm8
-    .SAVEXMM128 xmm8, 32
-    movdqa  xmmword ptr [rsp+16*3], xmm9
-    .SAVEXMM128 xmm9, 48
-    movdqa  xmmword ptr [rsp+16*4], xmm10
-    .SAVEXMM128 xmm10, 64
-    movdqa  xmmword ptr [rsp+16*5], xmm11
-    .SAVEXMM128 xmm11, 80
-    movdqa  xmmword ptr [rsp+16*6], xmm12
-    .SAVEXMM128 xmm12, 96
-    movdqa  xmmword ptr [rsp+16*7], xmm13
-    .SAVEXMM128 xmm13, 112
-    movdqa  xmmword ptr [rsp+16*8], xmm14
-    .SAVEXMM128 xmm14, 128
-    movdqa  xmmword ptr [rsp+16*9], xmm15
-    .SAVEXMM128 xmm15, 144
-    ; stack aligment  for Win64 ABI
-    sub     rsp, 8
-    .ALLOCSTACK 8
-    .ENDPROLOG
-
-    ; Load mask registers
-    mov     r13, 0ffff800000000000h
-    mov     r14, 7fffffffffffh
-
-    ; Build the JIT frame.
-    ; rcx = cx
-    ; rdx = fp
-    ; r9 = inlineCallCount
-    ; fp must go into rbx
-    push    0       ; stubRejoin
-    push    rdx     ; entryncode
-    push    rdx     ; entryFp
-    push    r9      ; inlineCallCount
-    push    rcx     ; cx
-    push    rdx     ; fp
-    mov     rbx, rdx
-
-    ; Space for the rest of the VMFrame.
-    sub     rsp, 28h
-
-    ; This is actually part of the VMFrame.
-    mov     r10, [rbp+8*5+8]
-    push    r10
-
-    ; Set cx->regs and set the active frame. Save r8 and align frame in one
-    push    r8
-    mov     rcx, rsp
-    sub     rsp, 20h
-    call    PushActiveVMFrame
-    add     rsp, 20h
-
-    ; Jump into the JIT code.
-    jmp     qword ptr [rsp]
-JaegerTrampoline ENDP
-
-; void JaegerTrampolineReturn();
-JaegerTrampolineReturn PROC FRAME
-    .ENDPROLOG
-    or      rsi, rdi
-    mov     qword ptr [rbx+30h], rsi
-    sub     rsp, 20h
-    lea     rcx, [rsp+20h]
-    call    PopActiveVMFrame
-
-    add     rsp, 68h+20h+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    mov     rax, 1
-    ret
-JaegerTrampolineReturn ENDP
-
-
-; void JaegerThrowpoline()
-JaegerThrowpoline PROC FRAME
-    .ENDPROLOG
-    ; For Windows x64 stub calls, we pad the stack by 32 before
-    ; calling, so we must account for that here. See doStubCall.
-    lea     rcx, [rsp+20h]
-    call    js_InternalThrow
-    test    rax, rax
-    je      throwpoline_exit
-    add     rsp, 20h
-    jmp     rax
-
-throwpoline_exit:
-    lea     rcx, [rsp+20h]
-    call    PopActiveVMFrame
-    add     rsp, 68h+20h+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    xor     rax, rax
-    ret
-JaegerThrowpoline ENDP
-
-JaegerInterpoline PROC FRAME
-    .ENDPROLOG
-    mov     rcx, rdi
-    mov     rdx, rsi
-    lea     r9, [rsp+20h]
-    mov     r8, rax
-    call    js_InternalInterpret
-    mov     rbx, qword ptr [rsp+38h+20h] ; Load Frame
-    mov     rsi, qword ptr [rbx+30h]     ; Load rval payload
-    and     rsi, r14                     ; Mask rval payload
-    mov     rdi, qword ptr [rbx+30h]     ; Load rval type
-    and     rdi, r13                     ; Mask rval type
-    mov     rcx, qword ptr [rsp+18h+20h] ; Load scratch -> argc
-    test    rax, rax
-    je      interpoline_exit
-    add     rsp, 20h
-    jmp     rax
-
-interpoline_exit:
-    lea     rcx, [rsp+20h]
-    call    PopActiveVMFrame
-    add     rsp, 68h+20h+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    xor     rax, rax
-    ret
-JaegerInterpoline ENDP
-
-JaegerInterpolineScripted PROC FRAME
-    .ENDPROLOG
-    mov     rbx, qword ptr [rbx+20h] ; Load prev
-    mov     qword ptr [rsp+38h], rbx ; fp -> regs.fp
-    sub     rsp, 20h
-    jmp     JaegerInterpoline
-JaegerInterpolineScripted ENDP
-
-JaegerInterpolinePatched PROC FRAME
-    sub     rsp, 20h
-    .ALLOCSTACK 32
-    .ENDPROLOG
-    jmp     JaegerInterpoline
-JaegerInterpolinePatched ENDP
-
-
-END
deleted file mode 100644
--- a/js/src/methodjit/TrampolineMingwX64.s
+++ /dev/null
@@ -1,252 +0,0 @@
-# -*- Mode: C++# tab-width: 4# indent-tabs-mode: nil# c-basic-offset: 4 -*-
-# 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/.
-
-
-.extern js_InternalThrow
-.extern PushActiveVMFrame
-.extern PopActiveVMFrame
-.extern js_InternalInterpret
-
-.text
-.intel_syntax noprefix
-
-# JSBool JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code,
-#                         Value *stackLimit, void *safePoint)#
-.globl JaegerTrampoline
-.def JaegerTrampoline
-   .scl 3
-   .type 46
-.endef
-JaegerTrampoline:
-    push    rbp
-    # .PUSHREG rbp
-    mov     rbp, rsp
-    # .SETFRAME rbp, 0
-    push    r12
-    # .PUSHREG r12
-    push    r13
-    # .PUSHREG r13
-    push    r14
-    # .PUSHREG r14
-    push    r15
-    # .PUSHREG r15
-    push    rdi
-    # .PUSHREG rdi
-    push    rsi
-    # .PUSHREG rsi
-    push    rbx
-    # .PUSHREG rbx
-    sub     rsp, 16*10+8
-    # .ALLOCSTACK 168
-    # .SAVEXMM128 only supports 16 byte alignment offset
-    movdqa  xmmword ptr [rsp], xmm6
-    # .SAVEXMM128 xmm6, 0
-    movdqa  xmmword ptr [rsp+16], xmm7
-    # .SAVEXMM128 xmm7, 16
-    movdqa  xmmword ptr [rsp+16*2], xmm8
-    # .SAVEXMM128 xmm8, 32
-    movdqa  xmmword ptr [rsp+16*3], xmm9
-    # .SAVEXMM128 xmm9, 48
-    movdqa  xmmword ptr [rsp+16*4], xmm10
-    # .SAVEXMM128 xmm10, 64
-    movdqa  xmmword ptr [rsp+16*5], xmm11
-    # .SAVEXMM128 xmm11, 80
-    movdqa  xmmword ptr [rsp+16*6], xmm12
-    # .SAVEXMM128 xmm12, 96
-    movdqa  xmmword ptr [rsp+16*7], xmm13
-    # .SAVEXMM128 xmm13, 112
-    movdqa  xmmword ptr [rsp+16*8], xmm14
-    # .SAVEXMM128 xmm14, 128
-    movdqa  xmmword ptr [rsp+16*9], xmm15
-    # .SAVEXMM128 xmm15, 144
-    # stack aligment  for Win64 ABI
-    sub     rsp, 8
-    # .ALLOCSTACK 8
-    # .ENDPROLOG
-
-    # Load mask registers
-    mov     r13, 0xffff800000000000
-    mov     r14, 0x7fffffffffff
-
-    # Build the JIT frame.
-    # rcx = cx
-    # rdx = fp
-    # r9 = inlineCallCount
-    # fp must go into rbx
-    push    0       # stubRejoin
-    push    rdx     # entryncode
-    push    rdx     # entryFp
-    push    r9      # inlineCallCount
-    push    rcx     # cx
-    push    rdx     # fp
-    mov     rbx, rdx
-
-    # Space for the rest of the VMFrame.
-    sub     rsp, 0x28
-
-    # This is actually part of the VMFrame.
-    mov     r10, [rbp+8*5+8]
-    push    r10
-
-    # Set cx->regs and set the active frame. Save r8 and align frame in one
-    push    r8
-    mov     rcx, rsp
-    sub     rsp, 0x20
-    call    PushActiveVMFrame
-    add     rsp, 0x20
-
-    # Jump into the JIT code.
-    jmp     qword ptr [rsp]
-
-# void JaegerTrampolineReturn()#
-.globl JaegerTrampolineReturn
-.def JaegerTrampolineReturn
-   .scl 3
-   .type 46
-.endef
-JaegerTrampolineReturn:
-    # .ENDPROLOG
-    or      rsi, rdi
-    mov     qword ptr [rbx + 0x30], rsi
-    sub     rsp, 0x20
-    lea     rcx, [rsp+0x20]
-    call    PopActiveVMFrame
-
-    add     rsp, 0x68+0x20+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    mov     rax, 1
-    ret
-
-
-# void JaegerThrowpoline()
-.globl JaegerThrowpoline
-.def JaegerTrampoline
-   .scl 3
-   .type 46
-.endef
-JaegerThrowpoline:
-    # .ENDPROLOG
-    # For Windows x64 stub calls, we pad the stack by 32 before
-    # calling, so we must account for that here. See doStubCall.
-    lea     rcx, [rsp+0x20]
-    call    js_InternalThrow
-    test    rax, rax
-    je      throwpoline_exit
-    add     rsp, 0x20
-    jmp     rax
-
-throwpoline_exit:
-    lea     rcx, [rsp+0x20]
-    call    PopActiveVMFrame
-    add     rsp, 0x68+0x20+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    xor     rax, rax
-    ret
-
-
-.globl JaegerInterpoline
-.def JaegerInterpoline
-   .scl 3
-   .type 46
-.endef
-JaegerInterpoline:
-    #.ENDPROLOG
-    mov     rcx, rdi
-    mov     rdx, rsi
-    lea     r9, [rsp+0x20]
-    mov     r8, rax
-    call    js_InternalInterpret
-    mov     rbx, qword ptr [rsp+0x38+0x20] # Load Frame
-    mov     rsi, qword ptr [rbx+0x30]      # Load rval payload
-    and     rsi, r14                       # Mask rval payload
-    mov     rdi, qword ptr [rbx+0x30]      # Load rval type
-    and     rdi, r13                       # Mask rval type
-    mov     rcx, qword ptr [rsp+0x18+0x20] # Load scratch -> argc
-    test    rax, rax
-    je      interpoline_exit
-    add     rsp, 0x20
-    jmp     rax
-
-interpoline_exit:
-    lea     rcx, [rsp+0x20]
-    call    PopActiveVMFrame
-    add     rsp, 0x68+0x20+8+16*10+8
-    movdqa  xmm6, xmmword ptr [rsp-16*10-8]
-    movdqa  xmm7, xmmword ptr [rsp-16*9-8]
-    movdqa  xmm8, xmmword ptr [rsp-16*8-8]
-    movdqa  xmm9, xmmword ptr [rsp-16*7-8]
-    movdqa  xmm10, xmmword ptr [rsp-16*6-8]
-    movdqa  xmm11, xmmword ptr [rsp-16*5-8]
-    movdqa  xmm12, xmmword ptr [rsp-16*4-8]
-    movdqa  xmm13, xmmword ptr [rsp-16*3-8]
-    movdqa  xmm14, xmmword ptr [rsp-16*2-8]
-    movdqa  xmm15, xmmword ptr [rsp-16*1-8]
-    pop     rbx
-    pop     rsi
-    pop     rdi
-    pop     r15
-    pop     r14
-    pop     r13
-    pop     r12
-    pop     rbp
-    xor     rax, rax
-    ret
-
-.globl JaegerInterpolineScripted
-.def JaegerInterpolineScripted
-   .scl 3
-   .type 46
-.endef
-JaegerInterpolineScripted:
-    #.ENDPROLOG
-    mov     rbx, qword ptr [rbx+0x20] # Load prev
-    mov     qword ptr [rsp+0x38], rbx # fp -> regs.fp
-    sub     rsp, 0x20
-    jmp     JaegerInterpoline
-
-.globl JaegerInterpolinePatched
-.def JaegerInterpolinePatched
-   .scl 3
-   .type 46
-.endef
-JaegerInterpolinePatched:
-    sub     rsp, 0x20
-    #.ALLOCSTACK 32
-    #.ENDPROLOG
-    jmp     JaegerInterpoline
deleted file mode 100644
--- a/js/src/methodjit/TrampolineSUNWX64.s
+++ /dev/null
@@ -1,137 +0,0 @@
-/ -*- Mode: C++/ tab-width: 4/ indent-tabs-mode: nil/ c-basic-offset: 4 -*-
-/ 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/.
-
-.text
-
-/ JSBool JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code,
-/                         Value *stackLimit)
-.global JaegerTrampoline
-.type   JaegerTrampoline, @function
-JaegerTrampoline:
-    /* Prologue. */
-    pushq %rbp
-    movq %rsp, %rbp
-    /* Save non-volatile registers. */
-    pushq %r12
-    pushq %r13
-    pushq %r14
-    pushq %r15
-    pushq %rbx
-
-    /* Load mask registers. */
-    movq $0xFFFF800000000000, %r13
-    movq $0x00007FFFFFFFFFFF, %r14
-
-    /* Build the JIT frame.
-     * rdi = cx
-     * rsi = fp
-     * rcx = inlineCallCount
-     * fp must go into rbx
-     */
-    pushq $0x0        /* stubRejoin */
-    pushq %rsi        /* entryncode */
-    pushq %rsi        /* entryfp */
-    pushq %rcx        /* inlineCallCount */
-    pushq %rdi        /* cx */
-    pushq %rsi        /* fp */
-    movq  %rsi, %rbx
-
-    /* Space for the rest of the VMFrame. */
-    subq  $0x28, %rsp
-
-    /* This is actually part of the VMFrame. */
-    pushq %r8
-
-    /* Set cx->regs and set the active frame. Save rdx and align frame in one. */
-    pushq %rdx
-    movq  %rsp, %rdi
-    call PushActiveVMFrame
-
-    /* Jump into into the JIT'd code. */
-    jmp *0(%rsp)
-.size   JaegerTrampoline, . - JaegerTrampoline
-
-/ void JaegerTrampolineReturn()
-.global JaegerTrampolineReturn
-.type   JaegerTrampolineReturn, @function
-JaegerTrampolineReturn:
-    or   %rdi, %rsi
-    movq %rsx, 0x30(%rbx)
-    movq %rsp, %rdi
-    call PopActiveVMFrame
-
-    addq $0x68, %rsp
-    popq %rbx
-    popq %r15
-    popq %r14
-    popq %r13
-    popq %r12
-    popq %rbp
-    movq $1, %rax
-    ret
-.size   JaegerTrampolineReturn, . - JaegerTrampolineReturn
-
-
-/ void *JaegerThrowpoline(js::VMFrame *vmFrame)
-.global JaegerThrowpoline
-.type   JaegerThrowpoline, @function
-JaegerThrowpoline:
-    movq %rsp, %rdi
-    call js_InternalThrow
-    testq %rax, %rax
-    je   throwpoline_exit
-    jmp  *%rax
-  throwpoline_exit:
-    movq %rsp, %rdi
-    call PopActiveVMFrame
-    addq $0x68, %rsp
-    popq %rbx
-    popq %r15
-    popq %r14
-    popq %r13
-    popq %r12
-    popq %rbp
-    xorq %rax,%rax
-    ret
-.size   JaegerThrowpoline, . - JaegerThrowpoline
-
-/ void JaegerInterpoline()
-.global JaegerInterpoline
-.type   JaegerInterpoline, @function
-JaegerInterpoline:
-    movq %rsp, %rcx
-    movq %rax, %rdx
-    call js_InternalInterpret
-    movq 0x38(%rsp), %rbx             /* Load frame */
-    movq 0x30(%rbx), %rsi             /* Load rval payload */
-    and %r14, %rsi                    /* Mask rval payload */
-    movq 0x30(%rbx), %rdi             /* Load rval type */
-    and %r13, %rdi                    /* Mask rval type */
-    movq 0x18(%rsp), %rcx             /* Load scratch -> argc */
-    testq %rax, %rax
-    je   interpoline_exit
-    jmp  *%rax
-  interpoline_exit:
-    movq %rsp, %rdi
-    call PopActiveVMFrame
-    addq $0x68, %rsp
-    popq %rbx
-    popq %r15
-    popq %r14
-    popq %r13
-    popq %r12
-    popq %rbp
-    xorq %rax,%rax
-    ret
-.size   JaegerInterpoline, . - JaegerInterpoline
-
-/ void JaegerInterpolineScripted()
-.global JaegerInterpolineScripted
-.type   JaegerInterpolineScripted, @function
-JaegerInterpolineScripted:
-    movq 0x20(%rbx), %rbx             /* load prev */
-    movq %rbx, 0x38(%rsp)
-    jmp JaegerInterpoline
-.size   JaegerInterpolineScripted, . - JaegerInterpolineScripted
deleted file mode 100644
--- a/js/src/methodjit/TrampolineSUNWX86.s
+++ /dev/null
@@ -1,146 +0,0 @@
-/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-/ 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/.
-
-.text
-
-/ JSBool JaegerTrampoline(JSContext *cx, StackFrame *fp, void *code,
-/                         Value *stackLimit)
-.global JaegerTrampoline
-.type   JaegerTrampoline, @function
-JaegerTrampoline:
-    /* Prologue. */
-    pushl %ebp
-    movl %esp, %ebp
-    /* Save non-volatile registers. */
-    pushl %esi
-    pushl %edi
-    pushl %ebx
-
-    /* Build the JIT frame. Push fields in order, */
-    /* then align the stack to form esp == VMFrame. */
-    movl  12(%ebp), %ebx                       /* load fp */
-    pushl %ebx                                 /* unused1 */
-    pushl %ebx                                 /* unused0 */
-    pushl $0x0                                 /* stubRejoin */
-    pushl %ebx                                 /* entryncode */
-    pushl %ebx                                 /* entryfp */
-    pushl 20(%ebp)                             /* stackLimit */
-    pushl 8(%ebp)                              /* cx */
-    pushl %ebx                                 /* fp */
-    subl $0x1C, %esp
-
-    /* Jump into the JIT'd code. */
-    /* No fastcall for sunstudio. */
-    pushl %esp
-    call PushActiveVMFrame
-    popl  %edx
-
-    movl 28(%esp), %ebp                       /* load fp for JIT code */
-    jmp  *88(%esp)
-.size   JaegerTrampoline, . - JaegerTrampoline
-
-/ void JaegerTrampolineReturn()
-.global JaegerTrampolineReturn
-.type   JaegerTrampolineReturn, @function
-JaegerTrampolineReturn:
-    movl  %esi, 0x18(%ebp)
-    movl  %edi, 0x1C(%ebp)
-    movl  %esp, %ebp
-    addl  $0x48, %ebp
-    pushl %esp
-    call PopActiveVMFrame
-
-    addl $0x40, %esp
-    popl %ebx
-    popl %edi
-    popl %esi
-    popl %ebp
-    movl $1, %eax
-    ret
-.size   JaegerTrampolineReturn, . - JaegerTrampolineReturn
-
-
-/ void *JaegerThrowpoline(js::VMFrame *vmFrame)
-.global JaegerThrowpoline
-.type   JaegerThrowpoline, @function
-JaegerThrowpoline:
-    /* For Sun Studio there is no fast call. */
-    /* We add the stack by 16 before. */
-    addl $0x10, %esp
-    /* Align the stack to 16 bytes. */
-    pushl %esp
-    pushl (%esp)
-    pushl (%esp)
-    pushl (%esp)
-    call js_InternalThrow
-    /* Bump the stack by 0x2c, as in the basic trampoline, but */
-    /* also one more word to clean up the stack for jsl_InternalThrow,*/
-    /* and another to balance the alignment above. */
-    addl $0x10, %esp
-    testl %eax, %eax
-    je   throwpoline_exit
-    jmp  *%eax
-throwpoline_exit:
-    pushl %esp
-    call PopActiveVMFrame
-    addl $0x40, %esp
-    popl %ebx
-    popl %edi
-    popl %esi
-    popl %ebp
-    xorl %eax, %eax
-    ret
-.size   JaegerThrowpoline, . - JaegerThrowpoline
-
-/ void JaegerInterpoline()
-.global JaegerInterpoline
-.type   JaegerInterpoline, @function
-JaegerInterpoline:
-    /* For Sun Studio there is no fast call. */
-    /* We add the stack by 16 before. */
-    addl $0x10, %esp
-    /* Align the stack to 16 bytes. */
-    pushl %esp
-    pushl %eax
-    pushl %edi
-    pushl %esi
-    call js_InternalInterpret
-    addl $0x10, %esp
-    movl 0x1C(%esp), %ebp    /* Load frame */
-    movl 0x18(%ebp), %esi    /* Load rval payload */
-    movl 0x1C(%ebp), %edi    /* Load rval type */
-    movl 0xC(%esp), %ecx     /* Load scratch -> argc, for any scripted call */
-    testl %eax, %eax
-    je   interpoline_exit
-    jmp  *%eax
-interpoline_exit:
-    pushl %esp
-    call PopActiveVMFrame
-    addl $0x40, %esp
-    popl %ebx
-    popl %edi
-    popl %esi
-    popl %ebp
-    xorl %eax, %eax
-    ret
-.size   JaegerInterpoline, . - JaegerInterpoline
-
-/ void JaegerInterpolineScripted()
-.global JaegerInterpolineScripted
-.type   JaegerInterpolineScripted, @function
-JaegerInterpolineScripted:
-    movl 0x10(%ebp), %ebp
-    movl %ebp, 0x1C(%esp)
-    subl $0x10, %esp
-    jmp JaegerInterpoline
-.size   JaegerInterpolineScripted, . - JaegerInterpolineScripted
-
-/ void JaegerInterpolinePatched()
-.global JaegerInterpolinePatched
-.type   JaegerInterpolinePatched, @function
-JaegerInterpolinePatched:
-    subl $0x10, %esp
-    jmp JaegerInterpoline
-.size   JaegerInterpolinePatched, . - JaegerInterpolinePatched
deleted file mode 100644
--- a/js/src/methodjit/TrampolineSparc.s
+++ /dev/null
@@ -1,132 +0,0 @@
-! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-! 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/.
-
-.text
-
-! JSBool JaegerTrampoline(JSContext *cx, JSStackFrame *fp, void *code,
-!                        , uintptr_t inlineCallCount)
-.global JaegerTrampoline
-.type   JaegerTrampoline, #function
-JaegerTrampoline:
-    save    %sp,-168,%sp
-    st      %i1, [%fp - 36]        ! fp
-    st      %i0, [%fp - 32]        ! cx
-    st      %i3, [%fp - 28]        ! stackLimit
-    st      %i1, [%fp - 24]        ! entryFp
-    st      %i1, [%fp - 20]        ! entryncode
-    st      %g0, [%fp - 16]        ! stubRejoin
-    call    PushActiveVMFrame
-    mov     %sp, %o0
-    ld      [%fp - 36], %l0         ! fp
-    jmp     %i2
-    st      %i7, [%fp - 12]         ! return address
-.size   JaegerTrampoline, . - JaegerTrampoline
-
-! void JaegerTrampolineReturn()
-.global JaegerTrampolineReturn
-.type   JaegerTrampolineReturn, #function
-JaegerTrampolineReturn:
-    st      %l2, [%l0 + 0x18]                        /* fp->rval type */
-    st      %l3, [%l0 + 0x1c]                        /* fp->rval data */
-    call    PopActiveVMFrame
-    mov     %sp, %o0
-    ld      [%fp - 12], %i7         ! return address
-    mov     1, %i0
-    ret
-    restore		
-.size   JaegerTrampolineReturn, . - JaegerTrampolineReturn
-
-! void *JaegerThrowpoline(js::VMFrame *vmFrame)
-.global JaegerThrowpoline
-.type   JaegerThrowpoline, #function
-JaegerThrowpoline:
-    call    js_InternalThrow
-    mov     %sp,%o0
-    tst     %o0
-    be      throwpoline_exit
-    nop
-    jmp     %o0
-    nop
-throwpoline_exit:
-    ta      3
-    mov     %sp, %o2
-    mov     %fp, %o3
-    ldd     [%o2 + (0*8)], %l0
-    ldd     [%o2 + (1*8)], %l2
-    ldd     [%o2 + (2*8)], %l4
-    ldd     [%o2 + (3*8)], %l6
-    ldd     [%o2 + (4*8)], %i0
-    ldd     [%o2 + (5*8)], %i2
-    ldd     [%o2 + (6*8)], %i4
-    ldd     [%o2 + (7*8)], %i6
-    ld      [%o3 - 12], %i7         ! return address
-    mov     %o2, %sp
-    call    PopActiveVMFrame
-    mov     %sp, %o0
-    clr     %i0
-    ret
-    restore
-.size   JaegerThrowpoline, . - JaegerThrowpoline
-
-! void JaegerInterpolineScripted()
-.global JaegerInterpolineScripted
-.type   JaegerInterpolineScripted, #function
-JaegerInterpolineScripted:
-    ld      [%l0 + 0x10], %l0                        /* Load f->prev_ */
-    st      %l0, [%fp - 36]                          /* Update f->regs->fp_ */
-    ba     interpoline_enter
-    nop
-.size    JaegerInterpolineScripted, . - JaegerInterpolineScripted
-
-! void JaegerInterpoline()
-.global JaegerInterpoline
-.type   JaegerInterpoline, #function
-JaegerInterpoline:
-interpoline_enter:
-    mov     %o0,%o2
-    mov     %l3,%o0
-    mov     %l2,%o1
-    call    js_InternalInterpret
-    mov     %sp,%o3
-    ld      [%fp - 36], %l0
-    ld      [%l0 + 0x18], %l2                        /* fp->rval type */
-    ld      [%l0 + 0x1c], %l3                        /* fp->rval data */
-    ld      [%fp - 48], %l4
-    tst     %o0
-    be      interpoline_exit
-    nop
-    jmp     %o0
-    nop
-interpoline_exit:
-    ta      3
-    mov     %sp, %o2
-    mov     %fp, %o3
-    ldd     [%o2 + (0*8)], %l0
-    ldd     [%o2 + (1*8)], %l2
-    ldd     [%o2 + (2*8)], %l4
-    ldd     [%o2 + (3*8)], %l6
-    ldd     [%o2 + (4*8)], %i0
-    ldd     [%o2 + (5*8)], %i2
-    ldd     [%o2 + (6*8)], %i4
-    ldd     [%o2 + (7*8)], %i6
-    ld      [%o3 - 12], %i7         ! return address
-    mov     %o2, %sp
-    call    PopActiveVMFrame
-    mov     %sp, %o0
-    clr     %i0
-    ret
-    restore
-.size    JaegerInterpoline, . - JaegerInterpoline
-
-! void JaegerStubVeneer()
-.global JaegerStubVeneer
-.type   JaegerStubVeneer, #function
-JaegerStubVeneer:
-    call    %i0
-    nop
-    ld      [%fp - 8], %g2
-    jmp     %g2
-    nop
-.size    JaegerStubVeneer, . - JaegerStubVeneer
deleted file mode 100644
--- a/js/src/methodjit/TypedArrayIC.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#ifndef js_typedarray_ic_h___
-#define js_typedarray_ic_h___
-
-#include "jscntxt.h"
-#include "jstypedarray.h"
-
-#include "vm/NumericConversions.h"
-
-#include "jsnuminlines.h"
-#include "jstypedarrayinlines.h"
-
-namespace js {
-namespace mjit {
-
-#ifdef JS_METHODJIT_TYPED_ARRAY
-
-typedef JSC::MacroAssembler::RegisterID RegisterID;
-typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
-typedef JSC::MacroAssembler::Jump Jump;
-typedef JSC::MacroAssembler::Imm32 Imm32;
-typedef JSC::MacroAssembler::ImmDouble ImmDouble;
-
-static inline bool
-ConstantFoldForFloatArray(JSContext *cx, ValueRemat *vr)
-{
-    if (!vr->isTypeKnown())
-        return true;
-
-    // Objects and undefined coerce to NaN, which coerces to 0.
-    // Null converts to 0.
-    if (vr->knownType() == JSVAL_TYPE_OBJECT ||
-        vr->knownType() == JSVAL_TYPE_UNDEFINED) {
-        *vr = ValueRemat::FromConstant(DoubleValue(js_NaN));
-        return true;
-    }
-    if (vr->knownType() == JSVAL_TYPE_NULL) {
-        *vr = ValueRemat::FromConstant(DoubleValue(0));
-        return true;
-    }
-
-    if (!vr->isConstant())
-        return true;
-
-    if (vr->knownType() == JSVAL_TYPE_DOUBLE)
-        return true;
-
-    double d = 0;
-    Value v = vr->value();
-    if (v.isString()) {
-        if (!StringToNumberType<double>(cx, v.toString(), &d))
-            return false;
-    } else if (v.isBoolean()) {
-        d = v.toBoolean() ? 1 : 0;
-    } else if (v.isInt32()) {
-        d = v.toInt32();
-    } else {
-        JS_NOT_REACHED("unknown constant type");
-    }
-    *vr = ValueRemat::FromConstant(DoubleValue(d));
-    return true;
-}
-
-static inline bool
-ConstantFoldForIntArray(JSContext *cx, JSObject *tarray, ValueRemat *vr)
-{
-    if (!vr->isTypeKnown())
-        return true;
-
-    // Objects and undefined coerce to NaN, which coerces to 0.
-    // Null converts to 0.
-    if (vr->knownType() == JSVAL_TYPE_OBJECT ||
-        vr->knownType() == JSVAL_TYPE_UNDEFINED ||
-        vr->knownType() == JSVAL_TYPE_NULL) {
-        *vr = ValueRemat::FromConstant(Int32Value(0));
-        return true;
-    }
-
-    if (!vr->isConstant())
-        return true;
-
-    // Convert from string to double first (see bug 624483).
-    Value v = vr->value();
-    if (v.isString()) {
-        double d;
-        if (!StringToNumberType<double>(cx, v.toString(), &d))
-            return false;
-        v.setNumber(d);
-    }
-
-    int32_t i32 = 0;
-    if (v.isDouble()) {
-        i32 = (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
-              ? ClampDoubleToUint8(v.toDouble())
-              : ToInt32(v.toDouble());
-    } else if (v.isInt32()) {
-        i32 = v.toInt32();
-        if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
-            i32 = ClampIntForUint8Array(i32);
-    } else if (v.isBoolean()) {
-        i32 = v.toBoolean() ? 1 : 0;
-    } else {
-        JS_NOT_REACHED("unknown constant type");
-    }
-
-    *vr = ValueRemat::FromConstant(Int32Value(i32));
-
-    return true;
-}
-
-// Generate code that will ensure a dynamically typed value, pinned in |vr|,
-// can be stored in an integer typed array. If any sort of conversion is
-// required, |dataReg| will be clobbered by a new value. |saveMask| is
-// used to ensure that |dataReg| (and volatile registers) are preserved
-// across any conversion process.
-static void
-GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr,
-                         uint32_t saveMask)
-{
-    if (vr.isConstant()) {
-        // Constants are always folded to ints up-front.
-        JS_ASSERT(vr.knownType() == JSVAL_TYPE_INT32);
-        return;
-    }
-
-    if (!vr.isTypeKnown() || vr.knownType() != JSVAL_TYPE_INT32) {
-        // If a conversion is necessary, save registers now.
-        MaybeJump checkInt32;
-        if (!vr.isTypeKnown())
-            checkInt32 = masm.testInt32(Assembler::Equal, vr.typeReg());
-
-        // Store the value to convert.
-        StackMarker vp = masm.allocStack(sizeof(Value), sizeof(double));
-        masm.storeValue(vr, masm.addressOfExtra(vp));
-
-        // Preserve volatile registers.
-        PreserveRegisters saveForCall(masm);
-        saveForCall.preserve(saveMask & Registers::TempRegs);
-
-        masm.setupABICall(Registers::FastCall, 2);
-        masm.storeArg(0, masm.vmFrameOffset(offsetof(VMFrame, cx)));
-        masm.storeArgAddr(1, masm.addressOfExtra(vp));
-
-        typedef int32_t (JS_FASTCALL *Int32CxVp)(JSContext *, Value *);
-        Int32CxVp stub;
-        if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
-            stub = stubs::ConvertToTypedInt<true>;
-        else
-            stub = stubs::ConvertToTypedInt<false>;
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, stub), false);
-        if (vr.dataReg() != Registers::ReturnReg)
-            masm.move(Registers::ReturnReg, vr.dataReg());
-
-        saveForCall.restore();
-        masm.freeStack(vp);
-
-        if (checkInt32.isSet())
-            checkInt32.get().linkTo(masm.label(), &masm);
-    }
-
-    // Performing clamping, if needed.
-    if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
-        masm.clampInt32ToUint8(vr.dataReg());
-}
-
-// Generate code that will ensure a dynamically typed value, pinned in |vr|,
-// can be stored in an integer typed array.  saveMask| is used to ensure that
-// |dataReg| (and volatile registers) are preserved across any conversion
-// process.
-//
-// Constants are left untouched. Any other value is placed into destReg.
-static void
-GenConversionForFloatArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr,
-                           FPRegisterID destReg, uint32_t saveMask)
-{
-    if (vr.isConstant()) {
-        // Constants are always folded to doubles up-front.
-        JS_ASSERT(vr.knownType() == JSVAL_TYPE_DOUBLE);
-        return;
-    }
-
-    // Fast-path, if the value is a double, skip converting.
-    MaybeJump isDouble;
-    if (!vr.isTypeKnown())
-        isDouble = masm.testDouble(Assembler::Equal, vr.typeReg());
-
-    // If the value is an integer, inline the conversion.
-    MaybeJump skip1, skip2;
-    if (!vr.isTypeKnown() || vr.knownType() == JSVAL_TYPE_INT32) {
-        MaybeJump isNotInt32;
-        if (!vr.isTypeKnown())
-            isNotInt32 = masm.testInt32(Assembler::NotEqual, vr.typeReg());
-        masm.convertInt32ToDouble(vr.dataReg(), destReg);
-        if (isNotInt32.isSet()) {
-            skip1 = masm.jump();
-            isNotInt32.get().linkTo(masm.label(), &masm);
-        }
-    }
-
-    // Generate a generic conversion call, if not known to be int32_t or double.
-    if (!vr.isTypeKnown() ||
-        (vr.knownType() != JSVAL_TYPE_INT32 &&
-         vr.knownType() != JSVAL_TYPE_DOUBLE)) {
-        // Store this value, which is also an outparam.
-        StackMarker vp = masm.allocStack(sizeof(Value), sizeof(double));
-        masm.storeValue(vr, masm.addressOfExtra(vp));
-
-        // Preserve volatile registers, and make the call.
-        PreserveRegisters saveForCall(masm);
-        saveForCall.preserve(saveMask & Registers::TempRegs);
-        masm.setupABICall(Registers::FastCall, 2);
-        masm.storeArg(0, masm.vmFrameOffset(offsetof(VMFrame, cx)));
-        masm.storeArgAddr(1, masm.addressOfExtra(vp));
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, stubs::ConvertToTypedFloat), false);
-        saveForCall.restore();
-
-        // Load the value from the outparam, then pop the stack.
-        masm.loadDouble(masm.addressOfExtra(vp), destReg);
-        masm.freeStack(vp);
-        skip2 = masm.jump();
-    }
-
-    if (isDouble.isSet())
-        isDouble.get().linkTo(masm.label(), &masm);
-
-    // If it's possible the value was already a double, load it directly
-    // from registers (the known type is distinct from typeReg, which has
-    // 32-bits of the 64-bit double).
-    if (!vr.isTypeKnown() || vr.knownType() == JSVAL_TYPE_DOUBLE)
-        masm.fastLoadDouble(vr.dataReg(), vr.typeReg(), destReg);
-
-    // At this point, all loads into xmm1 are complete.
-    if (skip1.isSet())
-        skip1.get().linkTo(masm.label(), &masm);
-    if (skip2.isSet())
-        skip2.get().linkTo(masm.label(), &masm);
-
-    if (TypedArray::type(tarray) == js::TypedArray::TYPE_FLOAT32)
-        masm.convertDoubleToFloat(destReg, destReg);
-}
-
-template <typename T>
-static bool
-StoreToTypedArray(JSContext *cx, Assembler &masm, JSObject *tarray, T address,
-                  const ValueRemat &vrIn, uint32_t saveMask)
-{
-    ValueRemat vr = vrIn;
-
-    uint32_t type = TypedArray::type(tarray);
-    switch (type) {
-      case js::TypedArray::TYPE_INT8:
-      case js::TypedArray::TYPE_UINT8:
-      case js::TypedArray::TYPE_UINT8_CLAMPED:
-      case js::TypedArray::TYPE_INT16:
-      case js::TypedArray::TYPE_UINT16:
-      case js::TypedArray::TYPE_INT32:
-      case js::TypedArray::TYPE_UINT32:
-      {
-        if (!ConstantFoldForIntArray(cx, tarray, &vr))
-            return false;
-
-        PreserveRegisters saveRHS(masm);
-        PreserveRegisters saveLHS(masm);
-
-        // There are three tricky situations to handle:
-        //   (1) The RHS needs conversion. saveMask will be stomped, and
-        //       the RHS may need to be stomped.
-        //   (2) The RHS may need to be clamped, which clobbers it.
-        //   (3) The RHS may need to be in a single-byte register.
-        //
-        // In all of these cases, we try to find a free register that can be
-        // used to mutate the RHS. Failing that, we evict an existing volatile
-        // register.
-        //
-        // Note that we are careful to preserve the RHS before saving registers
-        // for the conversion call. This is because the object and key may be
-        // in temporary registers, and we want to restore those without killing
-        // the mutated RHS.
-        bool singleByte = (type == js::TypedArray::TYPE_INT8 ||
-                           type == js::TypedArray::TYPE_UINT8 ||
-                           type == js::TypedArray::TYPE_UINT8_CLAMPED);
-        bool mayNeedConversion = (!vr.isTypeKnown() || vr.knownType() != JSVAL_TYPE_INT32);
-        bool mayNeedClamping = !vr.isConstant() && (type == js::TypedArray::TYPE_UINT8_CLAMPED);
-        bool needsSingleByteReg = singleByte &&
-                                  !vr.isConstant() &&
-                                  !(Registers::SingleByteRegs & Registers::maskReg(vr.dataReg()));
-        bool rhsIsMutable = !vr.isConstant() && !(saveMask & Registers::maskReg(vr.dataReg()));
-
-        if (((mayNeedConversion || mayNeedClamping) && !rhsIsMutable) || needsSingleByteReg) {
-            // First attempt to find a free temporary register that:
-            //   - is compatible with the RHS constraints
-            //   - won't clobber the key, object, or RHS type regs
-            //   - is temporary, but
-            //   - is not in saveMask, which contains live volatile registers.
-            uint32_t allowMask = Registers::AvailRegs;
-            if (singleByte)
-                allowMask &= Registers::SingleByteRegs;
-
-            // Create a mask of registers we absolutely cannot clobber.
-            uint32_t pinned = Assembler::maskAddress(address);
-            if (!vr.isTypeKnown())
-                pinned |= Registers::maskReg(vr.typeReg());
-
-            Registers avail = allowMask & ~(pinned | saveMask);
-
-            RegisterID newReg;
-            if (!avail.empty()) {
-                newReg = avail.takeAnyReg().reg();
-            } else {
-                // If no registers meet the ideal set, relax a constraint and spill.
-                avail = allowMask & ~pinned;
-
-                if (!avail.empty()) {
-                    newReg = avail.takeAnyReg().reg();
-                    saveRHS.preserve(Registers::maskReg(newReg));
-                } else {
-                    // Oh no! *All* single byte registers are pinned. This
-                    // sucks. We'll swap the type and data registers in |vr|
-                    // and unswap them later.
-
-                    // If |vr|'s registers are part of the address, swapping is
-                    // going to cause problems during the store.
-                    uint32_t vrRegs = Registers::mask2Regs(vr.dataReg(), vr.typeReg());
-                    uint32_t lhsMask = vrRegs & Assembler::maskAddress(address);
-
-                    // We'll also need to save any of the registers which won't
-                    // be restored via |lhsMask| above.
-                    uint32_t rhsMask = vrRegs & ~lhsMask;
-
-                    // Push them, but get the order right. We'll pop LHS first.
-                    saveRHS.preserve(rhsMask);
-                    saveLHS.preserve(lhsMask);
-
-                    // Don't store/restore registers if we dont have to.
-                    saveMask &= ~lhsMask;
-
-                    // Actually perform the swap.
-                    masm.swap(vr.typeReg(), vr.dataReg());
-                    vr = ValueRemat::FromRegisters(vr.dataReg(), vr.typeReg());
-                    newReg = vr.dataReg();
-                }
-
-                // Now, make sure the new register is not in the saveMask,
-                // so it won't get restored right after the call.
-                saveMask &= ~Registers::maskReg(newReg);
-            }
-
-            if (vr.dataReg() != newReg)
-                masm.move(vr.dataReg(), newReg);
-
-            // Update |vr|.
-            if (vr.isTypeKnown())
-                vr = ValueRemat::FromKnownType(vr.knownType(), newReg);
-            else
-                vr = ValueRemat::FromRegisters(vr.typeReg(), newReg);
-        }
-
-        GenConversionForIntArray(masm, tarray, vr, saveMask);
-
-        // Restore the registers in |address|. |GenConversionForIntArray| won't
-        // restore them because we told it not to by fiddling with |saveMask|.
-        saveLHS.restore();
-
-        if (vr.isConstant())
-            masm.storeToTypedIntArray(type, Imm32(vr.value().toInt32()), address);
-        else
-            masm.storeToTypedIntArray(type, vr.dataReg(), address);
-
-        // Note that this will finish restoring the damage from the
-        // earlier register swap.
-        saveRHS.restore();
-        break;
-      }
-
-      case js::TypedArray::TYPE_FLOAT32:
-      case js::TypedArray::TYPE_FLOAT64: {
-        /*
-         * Use a temporary for conversion. Inference is disabled, so no FP
-         * registers are live.
-         */
-        Registers regs(Registers::TempFPRegs);
-        FPRegisterID temp = regs.takeAnyReg().fpreg();
-
-        if (!ConstantFoldForFloatArray(cx, &vr))
-            return false;
-        GenConversionForFloatArray(masm, tarray, vr, temp, saveMask);
-        if (vr.isConstant())
-            masm.storeToTypedFloatArray(type, ImmDouble(vr.value().toDouble()), address);
-        else
-            masm.storeToTypedFloatArray(type, temp, address);
-        break;
-      }
-    }
-
-    return true;
-}
-
-#endif /* JS_METHODJIT_TYPED_ARRAY */
-
-} /* namespace mjit */
-} /* namespace js */
-
-#endif /* js_typedarray_ic_h___ */
-
new file mode 100644
--- /dev/null
+++ b/js/src/parjs-benchmarks/nbody-seeded.js
@@ -0,0 +1,554 @@
+//
+// NBody adapted from Intel's nbody benchmark.
+//
+
+load(libdir + "util.js");
+load(libdir + "seedrandom.js");
+
+var NBody = {
+  Constant: {
+    "deltaTime": 1,     // 0.005 in their code.
+    "epsSqr": 50,       // softening factor, when they compute, set to 50.
+    "initialVelocity": 8 // set to 0 to turn off
+  },
+
+  init: function init(mode, numBodies) {
+    var initPos = new Array(numBodies);
+    var initVel = new Array(numBodies);
+
+    // initialization of inputs
+    for (var i = 0; i < numBodies; i++) {
+      // [x,y,z]
+      initPos[i] = [Math.floor((Math.random()) * 40000),
+                    Math.floor((Math.random()) * 20000),
+                    Math.floor((Math.random() - .25) * 50000)];
+
+      // [x,y,z,x,y,z]
+      initVel[i] = [(Math.random() - 0.5) * NBody.Constant.initialVelocity,
+                    (Math.random() - 0.5) * NBody.Constant.initialVelocity,
+                    (Math.random()) * NBody.Constant.initialVelocity + 10,
+
+                    (Math.random() - 0.5) * NBody.Constant.initialVelocity,
+                    (Math.random() - 0.5) * NBody.Constant.initialVelocity,
+                    (Math.random()) * NBody.Constant.initialVelocity];
+    }
+
+    NBody.private = {};
+
+    if (mode === "par") {
+      NBody.private.pos = new ParallelArray(initPos);
+      NBody.private.vel = new ParallelArray(initVel);
+    } else {
+      NBody.private.pos = initPos;
+      NBody.private.vel = initVel;
+    }
+
+    NBody.numBodies = numBodies;
+    NBody.time = 0;
+  },
+
+  // Parallel
+
+  tickPar: function tickPar() {
+    NBody.private.vel = new ParallelArray([NBody.numBodies], NBody.velocityPar);
+    NBody.private.pos = new ParallelArray([NBody.numBodies], NBody.positionPar);
+    NBody.time++;
+  },
+
+  velocityPar: function velocityPar(index) {
+    var pos = NBody.private.pos;
+    var vel = NBody.private.vel;
+
+    var deltaTime = NBody.Constant.deltaTime;
+    var epsSqr = NBody.Constant.epsSqr;
+    var time = NBody.time;
+
+    var shape = vel.shape[0];
+
+    var newVel;
+    var newX, newY, newZ;
+    var newX2, newY2, newZ2;
+
+    var cX = Math.cos(time / 22) * -4200;
+    var cY = Math.sin(time / 14) * 9200;
+    var cZ = Math.sin(time / 27) * 6000;
+
+    // pull to center
+    var maxDistance = 3400;
+    var pullStrength = .042;
+
+    var speedLimit = 8;
+
+    // zones
+    var zone = 400;
+    var repel = 100;
+    var align = 300;
+    var attract = 100;
+
+    if (time < 500) {
+      speedLimit = 2000;
+      var attractPower = 100.9;
+    } else {
+      speedLimit = .2;
+      attractPower = 20.9;
+    }
+
+    var zoneSqrd = zone * zone + zone * zone + zone * zone;
+
+    var accX = 0, accY = 0, accZ = 0;
+    var accX2 = 0, accY2 = 0, accZ2 = 0;
+    var i;
+
+    // define particle 1 center distance
+    var dirToCenterX = cX - pos.get(index)[0];
+    var dirToCenterY = cY - pos.get(index)[1];
+    var dirToCenterZ = cZ - pos.get(index)[2];
+
+    var distanceSquaredTo = dirToCenterX * dirToCenterX + dirToCenterY * dirToCenterY + dirToCenterZ * dirToCenterZ;
+    var distToCenter = Math.sqrt(distanceSquaredTo);
+
+    // orient to center
+    if (distToCenter > maxDistance) {
+      var velc = (distToCenter - maxDistance) * pullStrength;
+      if (time < 200)
+        velc = .2;
+      else velc = (distToCenter - maxDistance) * pullStrength;
+
+      accX += (dirToCenterX / distToCenter) * velc;
+      accY += (dirToCenterY / distToCenter) * velc;
+      accZ += (dirToCenterZ / distToCenter) * velc;
+    }
+
+    for (i = 0; i < shape; i = i + 1) {
+      var rx = pos.get(i)[0] - pos.get(index)[0];
+      var ry = pos.get(i)[1] - pos.get(index)[1];
+      var rz = pos.get(i)[2] - pos.get(index)[2];
+
+      // make sure we are not testing the particle against its own position
+      var areSame = 0;
+      if (pos.get(i)[0] == pos.get(index)[0] && pos.get(i)[1] == pos.get(index)[1] && pos.get(i)[2] == pos.get(index)[2])
+        areSame += 1;
+
+      var distSqrd = rx * rx + ry * ry + rz * rz;
+
+      // cant use eqals to test, only <= or >= WTF
+      if (distSqrd < zoneSqrd && areSame <= 0) {
+        var length = Math.sqrt(distSqrd);
+        var percent = distSqrd / zoneSqrd;
+
+        if (distSqrd < repel) {
+          var F = (repel / percent - 1) * .025;
+
+          var normalRx = (rx / length) * F;
+          var normalRy = (ry / length) * F;
+          var normalRz = (rz / length) * F;
+
+          accX = accX + normalRx;
+          accY = accY + normalRy;
+          accZ = accZ + normalRz;
+
+          accX2 = accX2 - normalRx;
+          accY2 = accY2 - normalRy;
+          accZ2 = accZ2 - normalRz;
+        } else if (distSqrd < align) { //align
+          var threshDelta = align - repel;
+          var adjustedPercent = (percent - repel) / threshDelta;
+          var Q = (.5 - Math.cos(adjustedPercent * 3.14159265 * 2) * .5 + .5) * 100.9;
+
+          // get velocity 2
+          var velX2 = vel.get(i)[4];
+          var velY2 = vel.get(i)[5];
+          var velZ2 = vel.get(i)[6];
+
+          var velLength2 = Math.sqrt(velX2 * velX2 + velY2 * velY2 + velZ2 * velZ2);
+
+          // normalize vel2 and multiply by factor
+          velX2 = (velX2 / velLength2) * Q;
+          velY2 = (velY2 / velLength2) * Q;
+          velZ2 = (velZ2 / velLength2) * Q;
+
+          // get own velocity
+          var velX = vel.get(i)[0];
+          var velY = vel.get(i)[1];
+          var velZ = vel.get(i)[2];
+
+          var velLength = Math.sqrt(velX * velX + velY * velY + velZ * velZ);
+
+          // normalize own velocity
+          velX = (velX / velLength) * Q;
+          velY = (velY / velLength) * Q;
+          velZ = (velZ / velLength) * Q;
+
+          accX += velX2;
+          accY += velY2;
+          accZ += velZ2;
+
+          accX2 += velX;
+          accY2 += velY;
+          accZ2 += velZ;
+        }
+
+        if (distSqrd > attract) { // attract
+          var threshDelta2 = 1 - attract;
+          var adjustedPercent2 = (percent - attract) / threshDelta2;
+          var C = (1 - (Math.cos(adjustedPercent2 * 3.14159265 * 2) * 0.5 + 0.5)) * attractPower;
+
+          // normalize the distance vector
+          var dx = (rx / (length)) * C;
+          var dy = (ry / (length)) * C;
+          var dz = (rz / (length)) * C;
+
+          accX += dx;
+          accY += dy;
+          accZ += dz;
+
+          accX2 -= dx;
+          accY2 -= dy;
+          accZ2 -= dz;
+        }
+      }
+    }
+
+    // Speed limits
+    if (time > 500) {
+      var accSquared = accX * accX + accY * accY + accZ * accZ;
+      if (accSquared > speedLimit) {
+        accX = accX * .015;
+        accY = accY * .015;
+        accZ = accZ * .015;
+      }
+
+      var accSquared2 = accX2 * accX2 + accY2 * accY2 + accZ2 * accZ2;
+      if (accSquared2 > speedLimit) {
+        accX2 = accX2 * .015;
+        accY2 = accY2 * .015;
+        accZ2 = accZ2 * .015;
+      }
+    }
+
+    // Caclulate new velocity
+    newX = (vel.get(index)[0]) + accX;
+    newY = (vel.get(index)[1]) + accY;
+    newZ = (vel.get(index)[2]) + accZ;
+
+    newX2 = (vel.get(index)[3]) + accX2;
+    newY2 = (vel.get(index)[4]) + accY2;
+    newZ2 = (vel.get(index)[5]) + accZ2;
+
+    if (time < 500) {
+      var acs = newX2 * newX2 + newY2 * newY2 + newZ2 * newZ2;
+      if (acs > speedLimit) {
+        newX2 = newX2 * .15;
+        newY2 = newY2 * .15;
+        newZ2 = newZ2 * .15;
+      }
+
+      var acs2 = newX * newX + newY * newY + newZ * newZ;
+      if (acs2 > speedLimit) {
+        newX = newX * .15;
+        newY = newY * .15;
+        newZ = newZ * .15;
+      }
+    }
+
+    return [newX, newY, newZ, newX2, newY2, newZ2];
+  },
+
+  positionPar: function positionPar(index) {
+    var vel = NBody.private.vel;
+    var pos = NBody.private.pos;
+
+    var x = 0;
+    var y = 0;
+    var z = 0;
+
+    var velX = vel.get(index)[0];
+    var velY = vel.get(index)[1];
+    var velZ = vel.get(index)[2];
+
+    var velX2 = vel.get(index)[3];
+    var velY2 = vel.get(index)[4];
+    var velZ2 = vel.get(index)[5];
+
+    var netVelX = (velX - velX2);
+    var netVelY = (velY - velY2);
+    var netVelZ = (velZ - velZ2);
+
+    x = pos.get(index)[0] + (netVelX);
+    y = pos.get(index)[1] + (netVelY);
+    z = pos.get(index)[2] + (netVelZ);
+
+    return [x, y, z];
+  },
+
+  // Sequential
+
+  tickSeq: function tickSeq() {
+    var numBodies = NBody.numBodies;
+    var newVel = new Array(numBodies);
+    var newPos = new Array(numBodies);
+
+    for (var i = 0; i < numBodies; i++)
+      newVel[i] = NBody.velocitySeq(i);
+
+    for (var i = 0; i < numBodies; i++)
+      newPos[i] = NBody.positionSeq(i);
+
+    NBody.private.vel = newVel;
+    NBody.private.pos = newPos;
+
+    NBody.time++;
+  },
+
+  velocitySeq: function velocitySeq(index) {
+    var vel = NBody.private.vel;
+    var pos = NBody.private.pos;
+
+    var deltaTime = NBody.Constant.deltaTime;
+    var epsSqr = NBody.Constant.epsSqr;
+    var time = NBody.time;
+
+    var shape = pos.length;
+
+    var newVel;
+    var newX, newY, newZ;
+    var newX2, newY2, newZ2;
+
+    var cX = Math.cos(time / 22) * -4200;
+    var cY = Math.sin(time / 14) * 9200;
+    var cZ = Math.sin(time / 27) * 6000;
+
+    // pull to center
+    var maxDistance = 3400;
+    var pullStrength = .042;
+
+    var speedLimit = 8;
+
+    // zones
+    var zone = 400;
+    var repel = 100;
+    var align = 300;
+    var attract = 100;
+
+
+    if (time < 500) {
+      speedLimit = 2000;
+      var attractPower = 100.9;
+    } else {
+      speedLimit = .2;
+      attractPower = 20.9;
+    }
+
+    var zoneSqrd = zone * zone + zone * zone + zone * zone;
+
+    var accX = 0, accY = 0, accZ = 0;
+    var accX2 = 0, accY2 = 0, accZ2 = 0;
+    var i;
+
+    // define particle 1 center distance
+    var dirToCenterX = cX - pos[index][0];
+    var dirToCenterY = cY - pos[index][1];
+    var dirToCenterZ = cZ - pos[index][2];
+
+    var distanceSquaredTo = dirToCenterX * dirToCenterX + dirToCenterY * dirToCenterY + dirToCenterZ * dirToCenterZ;
+    var distToCenter = Math.sqrt(distanceSquaredTo);
+
+    // orient to center
+    if (distToCenter > maxDistance) {
+      var velc = (distToCenter - maxDistance) * pullStrength;
+      if (time < 200)
+        velc = .2;
+      else velc = (distToCenter - maxDistance) * pullStrength;
+
+      accX += (dirToCenterX / distToCenter) * velc;
+      accY += (dirToCenterY / distToCenter) * velc;
+      accZ += (dirToCenterZ / distToCenter) * velc;
+    }
+
+    for (i = 0; i < shape; i = i + 1) {
+      var rx = pos[i][0] - pos[index][0];
+      var ry = pos[i][1] - pos[index][1];
+      var rz = pos[i][2] - pos[index][2];
+
+      var areSame = 0;
+      if (pos[i][0] == pos[index][0] && pos[i][1] == pos[index][1] && pos[i][2] == pos[index][2])
+        areSame += 1;
+
+      var distSqrd = rx * rx + ry * ry + rz * rz;
+
+      // cant use eqals to test, only <= or >= WTF
+      if (distSqrd < zoneSqrd && areSame <= 0) {
+        var length = Math.sqrt(distSqrd);
+        var percent = distSqrd / zoneSqrd;
+
+
+        if (distSqrd < repel) {
+          var F = (repel / percent - 1) * .025;
+
+          var normalRx = (rx / length) * F;
+          var normalRy = (ry / length) * F;
+          var normalRz = (rz / length) * F;
+
+          accX = accX + normalRx;
+          accY = accY + normalRy;
+          accZ = accZ + normalRz;
+
+          accX2 = accX2 - normalRx;
+          accY2 = accY2 - normalRy;
+          accZ2 = accZ2 - normalRz;
+        } else if (distSqrd < align) { //align
+          var threshDelta = align - repel;
+          var adjustedPercent = (percent - repel) / threshDelta;
+          var Q = (.5 - Math.cos(adjustedPercent * 3.14159265 * 2) * .5 + .5) * 100;
+
+          // get velocity 2
+          var velX2 = vel[i][3];
+          var velY2 = vel[i][4];
+          var velZ2 = vel[i][5];
+
+          var velLength2 = Math.sqrt(velX2 * velX2 + velY2 * velY2 + velZ2 * velZ2);
+
+          // normalize vel2 and multiply by factor
+          velX2 = (velX2 / velLength2) * Q;
+          velY2 = (velY2 / velLength2) * Q;
+          velZ2 = (velZ2 / velLength2) * Q;
+
+          // get own velocity
+          var velX = vel[i][0];
+          var velY = vel[i][1];
+          var velZ = vel[i][2];
+
+          var velLength = Math.sqrt(velX * velX + velY * velY + velZ * velZ);
+
+          // normalize own velocity
+          velX = (velX / velLength) * Q;
+          velY = (velY / velLength) * Q;
+          velZ = (velZ / velLength) * Q;
+
+          accX += velX2;
+          accY += velY2;
+          accZ += velZ2;
+
+          accX2 += velX;
+          accY2 += velY;
+          accZ2 += velZ;
+        }
+
+        if (distSqrd > attract) {        //attract
+          var threshDelta2 = 1 - align;
+          var adjustedPercent2 = (percent - align) / threshDelta2;
+          var C = (1 - (Math.cos(adjustedPercent2 * 3.14159265 * 2) * 0.5 + 0.5)) * attractPower;
+
+          // normalize the distance vector
+          var dx = (rx / (length)) * C;
+          var dy = (ry / (length)) * C;
+          var dz = (rz / (length)) * C;
+
+          debug = 1.1;
+
+          accX += dx;
+          accY += dy;
+          accZ += dz;
+
+          accX2 -= dx;
+          accY2 -= dy;
+          accZ2 -= dz;
+        }
+      }
+    }
+
+    // enforce speed limits
+    if (time > 500) {
+      var accSquared = accX * accX + accY * accY + accZ * accZ;
+      if (accSquared > speedLimit) {
+        accX = accX * .015;
+        accY = accY * .015;
+        accZ = accZ * .015;
+      }
+
+      var accSquared2 = accX2 * accX2 + accY2 * accY2 + accZ2 * accZ2;
+      if (accSquared2 > speedLimit) {
+        accX2 = accX2 * .015;
+        accY2 = accY2 * .015;
+        accZ2 = accZ2 * .015;
+      }
+    }
+
+    // Caclulate new velocity
+    newX = vel[index][0] + accX;
+    newY = vel[index][1] + accY;
+    newZ = vel[index][2] + accZ;
+
+    newX2 = vel[index][3] + accX2;
+    newY2 = vel[index][4] + accY2;
+    newZ2 = vel[index][5] + accZ2;
+
+    if (time < 500) {
+      var acs = newX2 * newX2 + newY2 * newY2 + newZ2 * newZ2;
+      if (acs > speedLimit) {
+        newX2 = newX2 * .15;
+        newY2 = newY2 * .15;
+        newZ2 = newZ2 * .15;
+      }
+
+      var acs2 = newX * newX + newY * newY + newZ * newZ;
+      if (acs2 > speedLimit) {
+        newX = newX * .15;
+        newY = newY * .15;
+        newZ = newZ * .15;
+      }
+    }
+
+    return [newX, newY, newZ, newX2, newY2, newZ2];
+  },
+
+  positionSeq: function positionSeq(index) {
+    var vel = NBody.private.vel;
+    var pos = NBody.private.pos;
+
+    var x = 0;
+    var y = 0;
+    var z = 0;
+
+    var velX = vel[index][0];
+    var velY = vel[index][1];
+    var velZ = vel[index][2];
+
+    var velX2 = vel[index][3];
+    var velY2 = vel[index][4];
+    var velZ2 = vel[index][5];
+
+    var netX = (velX - velX2);
+    var netY = (velY - velY2);
+    var netZ = (velZ - velZ2);
+
+    x = pos[index][0] + netX;
+    y = pos[index][1] + netY;
+    z = pos[index][2] + netZ;
+
+    return [x, y, z];
+  }
+};
+
+function emulateNBody(mode, numBodies, ticks) {
+  NBody.init(mode, numBodies);
+  for (var i = 0; i < ticks; i++) {
+    var start = Date.now();
+    if (mode === "par")
+      NBody.tickPar();
+    else
+      NBody.tickSeq();
+    //print(NBody.private.pos);
+    print(mode + " bodies=" + numBodies + " tick=" + (i+1) + "/" + ticks + ": " + (Date.now() - start) + " ms");
+  }
+}
+
+// Using 4000 bodies going off Rick's comment as 4000 being a typical workload.
+const NUMBODIES = 4000;
+const TICKS = 10;
+
+Math.seedrandom("seed");
+
+benchmark("NBODY", 1, DEFAULT_MEASURE,
+          function () { emulateNBody("seq", NUMBODIES, TICKS); },
+          function () { emulateNBody("par", NUMBODIES, TICKS); });
new file mode 100644
--- /dev/null
+++ b/js/src/parjs-benchmarks/seedrandom.js
@@ -0,0 +1,299 @@
+// seedrandom.js version 2.1.
+// Author: David Bau
+// Date: 2013 Mar 16
+//
+// Defines a method Math.seedrandom() that, when called, substitutes
+// an explicitly seeded RC4-based algorithm for Math.random().  Also
+// supports automatic seeding from local or network sources of entropy.
+//
+// http://davidbau.com/encode/seedrandom.js
+// http://davidbau.com/encode/seedrandom-min.js
+//
+// Usage:
+//
+//   <script src=http://davidbau.com/encode/seedrandom-min.js></script>
+//
+//   Math.seedrandom('yay.');  Sets Math.random to a function that is
+//                             initialized using the given explicit seed.
+//
+//   Math.seedrandom();        Sets Math.random to a function that is
+//                             seeded using the current time, dom state,
+//                             and other accumulated local entropy.
+//                             The generated seed string is returned.
+//
+//   Math.seedrandom('yowza.', true);
+//                             Seeds using the given explicit seed mixed
+//                             together with accumulated entropy.
+//
+//   <script src="https://jsonlib.appspot.com/urandom?callback=Math.seedrandom">
+//   </script>                 Seeds using urandom bits from a server.
+//
+// More advanced examples:
+//
+//   Math.seedrandom("hello.");           // Use "hello." as the seed.
+//   document.write(Math.random());       // Always 0.9282578795792454
+//   document.write(Math.random());       // Always 0.3752569768646784
+//   var rng1 = Math.random;              // Remember the current prng.
+//
+//   var autoseed = Math.seedrandom();    // New prng with an automatic seed.
+//   document.write(Math.random());       // Pretty much unpredictable x.
+//
+//   Math.random = rng1;                  // Continue "hello." prng sequence.
+//   document.write(Math.random());       // Always 0.7316977468919549
+//
+//   Math.seedrandom(autoseed);           // Restart at the previous seed.
+//   document.write(Math.random());       // Repeat the 'unpredictable' x.
+//
+//   function reseed(event, count) {      // Define a custom entropy collector.
+//     var t = [];
+//     function w(e) {
+//       t.push([e.pageX, e.pageY, +new Date]);
+//       if (t.length < count) { return; }
+//       document.removeEventListener(event, w);
+//       Math.seedrandom(t, true);        // Mix in any previous entropy.
+//     }
+//     document.addEventListener(event, w);
+//   }
+//   reseed('mousemove', 100);            // Reseed after 100 mouse moves.
+//
+// Version notes:
+//
+// The random number sequence is the same as version 1.0 for string seeds.
+// Version 2.0 changed the sequence for non-string seeds.
+// Version 2.1 speeds seeding and uses window.crypto to autoseed if present.
+//
+// The standard ARC4 key scheduler cycles short keys, which means that
+// seedrandom('ab') is equivalent to seedrandom('abab') and 'ababab'.
+// Therefore it is a good idea to add a terminator to avoid trivial
+// equivalences on short string seeds, e.g., Math.seedrandom(str + '\0').
+// Starting with version 2.0, a terminator is added automatically for
+// non-string seeds, so seeding with the number 111 is the same as seeding
+// with '111\0'.
+//
+// When seedrandom() is called with zero args, it uses a seed
+// drawn from the browser crypto object if present.  If there is no
+// crypto support, seedrandom() uses the current time, the native rng,
+// and a walk of several DOM objects to collect a few bits of entropy.
+//
+// Each time the one- or two-argument forms of seedrandom are called,
+// entropy from the passed seed is accumulated in a pool to help generate
+// future seeds for the zero- and two-argument forms of seedrandom.
+//
+// On speed - This javascript implementation of Math.random() is about
+// 3-10x slower than the built-in Math.random() because it is not native
+// code, but that is typically fast enough.  Some details (timings on
+// Chrome 25 on a 2010 vintage macbook):
+//
+// seeded Math.random()          - avg less than 0.0002 milliseconds per call
+// seedrandom('explicit.')       - avg less than 0.2 milliseconds per call
+// seedrandom('explicit.', true) - avg less than 0.2 milliseconds per call
+// seedrandom() with crypto      - avg less than 0.2 milliseconds per call
+// seedrandom() without crypto   - avg about 12 milliseconds per call
+//
+// On a 2012 windows 7 1.5ghz i5 laptop, Chrome, Firefox 19, IE 10, and
+// Opera have similarly fast timings.  Slowest numbers are on Opera, with
+// about 0.0005 milliseconds per seeded Math.random() and 15 milliseconds
+// for autoseeding.
+//
+// LICENSE (BSD):
+//
+// Copyright 2013 David Bau, all rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright
+//      notice, this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. Neither the name of this module nor the names of its contributors may
+//      be used to endorse or promote products derived from this software
+//      without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+/**
+ * All code is in an anonymous closure to keep the global namespace clean.
+ */
+(function (
+    global, pool, math, width, chunks, digits) {
+
+//
+// The following constants are related to IEEE 754 limits.
+//
+var startdenom = math.pow(width, chunks),
+    significance = math.pow(2, digits),
+    overflow = significance * 2,
+    mask = width - 1;
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+math['seedrandom'] = function(seed, use_entropy) {
+  var key = [];
+
+  // Flatten the seed string or build one from local entropy if needed.
+  var shortseed = mixkey(flatten(
+    use_entropy ? [seed, tostring(pool)] :
+    0 in arguments ? seed : autoseed(), 3), key);
+
+  // Use the seed to initialize an ARC4 generator.
+  var arc4 = new ARC4(key);
+
+  // Mix the randomness into accumulated entropy.
+  mixkey(tostring(arc4.S), pool);
+
+  // Override Math.random
+
+  // This function returns a random double in [0, 1) that contains
+  // randomness in every bit of the mantissa of the IEEE 754 value.
+
+  math['random'] = function() {         // Closure to return a random double:
+    var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+        d = startdenom,                 //   and denominator d = 2 ^ 48.
+        x = 0;                          //   and no 'extra last byte'.
+    while (n < significance) {          // Fill up all significant digits by
+      n = (n + x) * width;              //   shifting numerator and
+      d *= width;                       //   denominator and generating a
+      x = arc4.g(1);                    //   new least-significant-byte.
+    }
+    while (n >= overflow) {             // To avoid rounding up, before adding
+      n /= 2;                           //   last byte, shift everything
+      d /= 2;                           //   right using integer math until
+      x >>>= 1;                         //   we have exactly the desired bits.
+    }
+    return (n + x) / d;                 // Form the number within [0, 1).
+  };
+
+  // Return the seed that was used
+  return shortseed;
+};
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+/** @constructor */
+function ARC4(key) {
+  var t, keylen = key.length,
+      me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+  // The empty key [] is treated as [0].
+  if (!keylen) { key = [keylen++]; }
+
+  // Set up S using the standard key scheduling algorithm.
+  while (i < width) {
+    s[i] = i++;
+  }
+  for (i = 0; i < width; i++) {
+    s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+    s[j] = t;
+  }
+
+  // The "g" method returns the next (count) outputs as one number.
+  (me.g = function(count) {
+    // Using instance members instead of closure state nearly doubles speed.
+    var t, r = 0,
+        i = me.i, j = me.j, s = me.S;
+    while (count--) {
+      t = s[i = mask & (i + 1)];
+      r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+    }
+    me.i = i; me.j = j;
+    return r;
+    // For robust unpredictability discard an initial batch of values.
+    // See http://www.rsa.com/rsalabs/node.asp?id=2009
+  })(width);
+}
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+function flatten(obj, depth) {
+  var result = [], typ = (typeof obj)[0], prop;
+  if (depth && typ == 'o') {
+    for (prop in obj) {
+      if (obj.hasOwnProperty(prop)) {
+        try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+      }
+    }
+  }
+  return (result.length ? result : typ == 's' ? obj : obj + '\0');
+}
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+function mixkey(seed, key) {
+  var stringseed = seed + '', smear, j = 0;
+  while (j < stringseed.length) {
+    key[mask & j] =
+      mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+  }
+  return tostring(key);
+}
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto if available.
+//
+/** @param {Uint8Array=} seed */
+function autoseed(seed) {
+  try {
+    global.crypto.getRandomValues(seed = new Uint8Array(width));
+    return tostring(seed);
+  } catch (e) {
+    return [+new Date, global.document, global.history,
+            global.navigator, global.screen, tostring(pool)];
+  }
+}
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+function tostring(a) {
+  return String.fromCharCode.apply(0, a);
+}
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to intefere with determinstic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+mixkey(math.random(), pool);
+
+// End anonymous scope, and pass initial values.
+})(
+  this,   // global window object
+  [],     // pool: entropy pool starts empty
+  Math,   // math: package containing random, pow, and seedrandom
+  256,    // width: each RC4 output is 0 <= x < 256
+  6,      // chunks: at least six RC4 outputs for each double
+  52      // digits: there are 52 significant digits in a double
+);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -40,17 +40,16 @@
 #include "jstypedarrayinlines.h"
 #include "jsworkers.h"
 #include "jswrapper.h"
 #include "jsperf.h"
 
 #include "builtin/TestingFunctions.h"
 #include "frontend/BytecodeEmitter.h"
 #include "frontend/Parser.h"
-#include "methodjit/MethodJIT.h"
 #include "vm/Shape.h"
 
 #include "prmjtime.h"
 
 #include "jsoptparse.h"
 #include "jsheaptools.h"
 
 #include "jsinferinlines.h"
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -16,17 +16,16 @@
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsopcodeinlines.h"
 #include "jscompartment.h"
 
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/BytecodeEmitter.h"
 #include "gc/Marking.h"
-#include "methodjit/Retcon.h"
 #include "ion/BaselineJIT.h"
 #include "js/Vector.h"
 
 #include "gc/FindSCCs-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 
@@ -232,23 +231,16 @@ BreakpointSite::BreakpointSite(JSScript 
 {
     JS_ASSERT(!script->hasBreakpointsAt(pc));
     JS_INIT_CLIST(&breakpoints);
 }
 
 void
 BreakpointSite::recompile(FreeOp *fop)
 {
-#ifdef JS_METHODJIT
-    if (script->hasMJITInfo()) {
-        mjit::Recompiler::clearStackReferences(fop, script);
-        mjit::ReleaseScriptCode(fop, script);
-    }
-#endif
-
 #ifdef JS_ION
     if (script->hasBaselineScript())
         script->baselineScript()->toggleDebugTraps(script, pc);
 #endif
 }
 
 void
 BreakpointSite::inc(FreeOp *fop)
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -22,20 +22,16 @@
 #include "frontend/BytecodeEmitter.h"
 
 #include "jsobjinlines.h"
 
 #include "vm/GlobalObject-inl.h"
 #include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 
-#ifdef JS_METHODJIT
-#include "methodjit/Retcon.h"
-#endif
-
 using namespace js;
 
 JSObject *
 js_InitObjectClass(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(obj->isNative());
 
     return obj->asGlobal().getOrCreateObjectPrototype(cx);
--- a/js/src/vm/RegExpObject-inl.h
+++ b/js/src/vm/RegExpObject-inl.h
@@ -99,17 +99,17 @@ RegExpObject::setSticky(bool enabled)
     setSlot(STICKY_FLAG_SLOT, BooleanValue(enabled));
 }
 
 /* This function should be deleted once bad Android platforms phase out. See bug 604774. */
 inline bool
 RegExpShared::isJITRuntimeEnabled(JSContext *cx)
 {
 #if ENABLE_YARR_JIT
-# if defined(ANDROID) && defined(JS_METHODJIT)
+# if defined(ANDROID)
     return !cx->jitIsBroken;
 # else
     return true;
 # endif
 #else
     return false;
 #endif
 }
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -4,19 +4,16 @@
  * 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 "mozilla/DebugOnly.h"
 
 #include "jsnum.h"
 #include "jsscript.h"
 
-#include "methodjit/MethodJIT.h"
-#include "methodjit/Compiler.h"
-
 #include "vm/SPSProfiler.h"
 #include "vm/StringBuffer.h"
 
 #include "ion/BaselineJIT.h"
 
 #include "jsscriptinlines.h"
 
 using namespace js;
@@ -35,22 +32,16 @@ SPSProfiler::SPSProfiler(JSRuntime *rt)
 }
 
 SPSProfiler::~SPSProfiler()
 {
     if (strings.initialized()) {
         for (ProfileStringMap::Enum e(strings); !e.empty(); e.popFront())
             js_free(const_cast<char *>(e.front().value));
     }
-#ifdef JS_METHODJIT
-    if (jminfo.initialized()) {
-        for (JITInfoMap::Enum e(jminfo); !e.empty(); e.popFront())
-            js_delete(e.front().value);
-    }
-#endif
 }
 
 void
 SPSProfiler::setProfilingStack(ProfileEntry *stack, uint32_t *size, uint32_t max)
 {
     JS_ASSERT_IF(size_ && *size_ != 0, !enabled());
     if (!strings.initialized())
         strings.init();
@@ -247,198 +238,16 @@ SPSProfiler::allocProfileString(JSContex
     for (size_t i = 0; i < len; i++)
         cstr[i] = ptr[i];
     cstr[len] = 0;
 
     JS_ASSERT(gcBefore == cx->runtime->gcNumber);
     return cstr;
 }
 
-#ifdef JS_METHODJIT
-typedef SPSProfiler::JMChunkInfo JMChunkInfo;
-
-JMChunkInfo::JMChunkInfo(mjit::JSActiveFrame *frame,
-                         mjit::PCLengthEntry *pcLengths,
-                         mjit::JITChunk *chunk)
-  : mainStart(frame->mainCodeStart),
-    mainEnd(frame->mainCodeEnd),
-    stubStart(frame->stubCodeStart),
-    stubEnd(frame->stubCodeEnd),
-    pcLengths(pcLengths),
-    chunk(chunk)
-{}
-
-jsbytecode*
-SPSProfiler::ipToPC(JSScript *script, size_t ip)
-{
-    if (!jminfo.initialized())
-        return NULL;
-
-    JITInfoMap::Ptr ptr = jminfo.lookup(script);
-    if (!ptr)
-        return NULL;
-    JMScriptInfo *info = ptr->value;
-
-    /* First check if this ip is in any of the ICs compiled for the script */
-    for (unsigned i = 0; i < info->ics.length(); i++) {
-        ICInfo &ic = info->ics[i];
-        if (ic.base <= ip && ip < ic.base + ic.size)
-            return ic.pc;
-    }
-
-    /* Otherwise if it's not in any of the chunks, then we can't find it */
-    for (unsigned i = 0; i < info->chunks.length(); i++) {
-        jsbytecode *pc = info->chunks[i].convert(script, ip);
-        if (pc != NULL)
-            return pc;
-    }
-
-    return NULL;
-}
-
-jsbytecode*
-JMChunkInfo::convert(JSScript *script, size_t ip)
-{
-    if (mainStart <= ip && ip < mainEnd) {
-        size_t offset = 0;
-        uint32_t i;
-        for (i = 0; i < script->length - 1; i++) {
-            offset += (uint32_t) pcLengths[i].inlineLength;
-            if (mainStart + offset > ip)
-                break;
-        }
-        return &script->code[i];
-    } else if (stubStart <= ip && ip < stubEnd) {
-        size_t offset = 0;
-        uint32_t i;
-        for (i = 0; i < script->length - 1; i++) {
-            offset += (uint32_t) pcLengths[i].stubLength;
-            if (stubStart + offset > ip)
-                break;
-        }
-        return &script->code[i];
-    }
-
-    return NULL;
-}
-
-bool
-SPSProfiler::registerMJITCode(mjit::JITChunk *chunk,
-                              mjit::JSActiveFrame *outerFrame,
-                              mjit::JSActiveFrame **inlineFrames)
-{
-    if (!jminfo.initialized() && !jminfo.init(100))
-        return false;
-
-    JS_ASSERT(chunk->pcLengths != NULL);
-
-    JMChunkInfo *info = registerScript(outerFrame, chunk->pcLengths, chunk);
-    if (!info)
-        return false;
-
-    /*
-     * The pcLengths array has entries for both the outerFrame's script and also
-     * all of the inlineFrames' scripts. The layout is something like:
-     *
-     *    [ outerFrame info ] [ inline frame 1 ] [ inline frame 2 ] ...
-     *
-     * This local pcLengths pointer tracks the position of each inline frame's
-     * pcLengths array. Each section of the array has length script->length for
-     * the corresponding script for that frame.
-     */
-    mjit::PCLengthEntry *pcLengths = chunk->pcLengths + outerFrame->script->length;
-    for (unsigned i = 0; i < chunk->nInlineFrames; i++) {
-        JMChunkInfo *child = registerScript(inlineFrames[i], pcLengths, chunk);
-        if (!child)
-            return false;
-        /*
-         * When JM tells us about new code, each inline ActiveFrame only has the
-         * start/end listed relative to the start of the main instruction
-         * streams. This is corrected here so the addresses listed on the
-         * JMChunkInfo structure are absolute and can be tested directly.
-         */
-        child->mainStart += info->mainStart;
-        child->mainEnd   += info->mainStart;
-        child->stubStart += info->stubStart;
-        child->stubEnd   += info->stubStart;
-
-        pcLengths += inlineFrames[i]->script->length;
-    }
-
-    return true;
-}
-
-JMChunkInfo*
-SPSProfiler::registerScript(mjit::JSActiveFrame *frame,
-                            mjit::PCLengthEntry *entries,
-                            mjit::JITChunk *chunk)
-{
-    /*
-     * An inlined script could possibly be compiled elsewhere as not having been
-     * inlined, so each JSScript* must be associated with a list of chunks
-     * instead of just one. Also, our script may already be in the map.
-     */
-    JITInfoMap::AddPtr ptr = jminfo.lookupForAdd(frame->script);
-    JMScriptInfo *info;
-    if (ptr) {
-        info = ptr->value;
-        JS_ASSERT(info->chunks.length() > 0);
-    } else {
-        info = rt->new_<JMScriptInfo>();
-        if (info == NULL || !jminfo.add(ptr, frame->script, info))
-            return NULL;
-    }
-    if (!info->chunks.append(JMChunkInfo(frame, entries, chunk)))
-        return NULL;
-    return info->chunks.end() - 1;
-}
-
-bool
-SPSProfiler::registerICCode(mjit::JITChunk *chunk,
-                            JSScript *script, jsbytecode *pc,
-                            void *base, size_t size)
-{
-    JS_ASSERT(jminfo.initialized());
-    JITInfoMap::Ptr ptr = jminfo.lookup(script);
-    JS_ASSERT(ptr);
-    return ptr->value->ics.append(ICInfo(base, size, pc));
-}
-
-void
-SPSProfiler::discardMJITCode(mjit::JITScript *jscr,
-                             mjit::JITChunk *chunk, void* address)
-{
-    if (!jminfo.initialized())
-        return;
-
-    unregisterScript(jscr->script, chunk);
-    for (unsigned i = 0; i < chunk->nInlineFrames; i++)
-        unregisterScript(chunk->inlineFrames()[i].fun->nonLazyScript(), chunk);
-}
-
-void
-SPSProfiler::unregisterScript(JSScript *script, mjit::JITChunk *chunk)
-{
-    JITInfoMap::Ptr ptr = jminfo.lookup(script);
-    if (!ptr)
-        return;
-    JMScriptInfo *info = ptr->value;
-    for (unsigned i = 0; i < info->chunks.length(); i++) {
-        if (info->chunks[i].chunk == chunk) {
-            info->chunks.erase(&info->chunks[i]);
-            break;
-        }
-    }
-    if (info->chunks.length() == 0) {
-        jminfo.remove(ptr);
-        js_delete(info);
-    }
-}
-#endif
-
 SPSEntryMarker::SPSEntryMarker(JSRuntime *rt
                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     : profiler(&rt->spsProfiler)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     if (!profiler->enabled()) {
         profiler = NULL;
         return;
--- a/js/src/vm/SPSProfiler.h
+++ b/js/src/vm/SPSProfiler.h
@@ -104,25 +104,16 @@
  */
 
 class JSFunction;
 
 namespace js {
 
 class ProfileEntry;
 
-#ifdef JS_METHODJIT
-namespace mjit {
-    struct JITChunk;
-    struct JITScript;
-    struct JSActiveFrame;
-    struct PCLengthEntry;
-}
-#endif
-
 typedef HashMap<JSScript*, const char*, DefaultHasher<JSScript*>, SystemAllocPolicy>
         ProfileStringMap;
 
 class SPSEntryMarker;
 
 class SPSProfiler
 {
     friend class SPSEntryMarker;
@@ -185,87 +176,17 @@ class SPSProfiler
             stack_[*size_ - 1].setPC(pc);
         }
     }
 
     /* Enter a C++ function. */
     void enterNative(const char *string, void *sp);
     void exitNative() { pop(); }
 
-#ifdef JS_METHODJIT
-    struct ICInfo
-    {
-        size_t base;
-        size_t size;
-        jsbytecode *pc;
-
-        ICInfo(void *base, size_t size, jsbytecode *pc)
-          : base(size_t(base)), size(size), pc(pc)
-        {}
-    };
-
-    struct JMChunkInfo
-    {
-        size_t mainStart;               // bounds for the inline code
-        size_t mainEnd;
-        size_t stubStart;               // bounds of the ool code
-        size_t stubEnd;
-        mjit::PCLengthEntry *pcLengths; // pcLengths for this chunk
-        mjit::JITChunk *chunk;          // stored to test when removing
-
-        JMChunkInfo(mjit::JSActiveFrame *frame,
-                    mjit::PCLengthEntry *pcLengths,
-                    mjit::JITChunk *chunk);
-
-        jsbytecode *convert(JSScript *script, size_t ip);
-    };
-
-    struct JMScriptInfo
-    {
-        Vector<ICInfo, 0, SystemAllocPolicy> ics;
-        Vector<JMChunkInfo, 1, SystemAllocPolicy> chunks;
-    };
-
-    typedef HashMap<JSScript*, JMScriptInfo*, DefaultHasher<JSScript*>,
-                    SystemAllocPolicy> JITInfoMap;
-
-    /*
-     * This is the mapping which facilitates translation from an ip to a
-     * jsbytecode*. The mapping is from a JSScript* to a set of chunks and ics
-     * which are associated with the script. This way lookup/translation doesn't
-     * have to do something like iterate the entire map.
-     *
-     * Each IC is easy to test because they all have only one pc associated with
-     * them, and the range is easy to check. The main chunks of code are a bit
-     * harder because there are both the inline and out of line streams which
-     * need to be tested. Each of these streams is described by the pcLengths
-     * array stored within each chunk. This array describes the width of each
-     * opcode of the corresponding JSScript, and has the same number of entries
-     * as script->length.
-     */
-    JITInfoMap jminfo;
-
-    bool registerMJITCode(mjit::JITChunk *chunk,
-                          mjit::JSActiveFrame *outerFrame,
-                          mjit::JSActiveFrame **inlineFrames);
-    void discardMJITCode(mjit::JITScript *jscr,
-                         mjit::JITChunk *chunk, void* address);
-    bool registerICCode(mjit::JITChunk *chunk, JSScript *script, jsbytecode* pc,
-                        void *start, size_t size);
-    jsbytecode *ipToPC(JSScript *script, size_t ip);
-
-  private:
-    JMChunkInfo *registerScript(mjit::JSActiveFrame *frame,
-                                mjit::PCLengthEntry *lenths,
-                                mjit::JITChunk *chunk);
-    void unregisterScript(JSScript *script, mjit::JITChunk *chunk);
-  public:
-#else
     jsbytecode *ipToPC(JSScript *script, size_t ip) { return NULL; }
-#endif
 
     void setProfilingStack(ProfileEntry *stack, uint32_t *size, uint32_t max);
     const char *profileString(JSContext *cx, JSScript *script, JSFunction *maybeFun);
     void onScriptFinalized(JSScript *script);
 
     /* meant to be used for testing, not recommended to call in normal code */
     size_t stringsCount() { return strings.count(); }
     void stringsReset() { strings.clear(); }
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -7,17 +7,16 @@
 #ifndef Stack_inl_h__
 #define Stack_inl_h__
 
 #include "mozilla/PodOperations.h"
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
-#include "methodjit/MethodJIT.h"
 #include "vm/Stack.h"
 #ifdef JS_ION
 #include "ion/BaselineFrame.h"
 #include "ion/BaselineFrame-inl.h"
 #include "ion/IonFrameIterator-inl.h"
 #endif
 #include "jsscriptinlines.h"
 
@@ -68,80 +67,44 @@ StackFrame::varObj()
 
 inline JSCompartment *
 StackFrame::compartment() const
 {
     JS_ASSERT(scopeChain()->compartment() == script()->compartment());
     return scopeChain()->compartment();
 }
 
-#ifdef JS_METHODJIT
-inline mjit::JITScript *
-StackFrame::jit()
-{
-    return script()->getJIT(isConstructing(), script()->zone()->compileBarriers());
-}
-#endif
-
 inline void
 StackFrame::initPrev(JSContext *cx)
 {
     JS_ASSERT(flags_ & HAS_PREVPC);
     if (FrameRegs *regs = cx->maybeRegs()) {
         prev_ = regs->fp();
         prevpc_ = regs->pc;
-        prevInline_ = regs->inlined();
         JS_ASSERT(uint32_t(prevpc_ - prev_->script()->code) < prev_->script()->length);
     } else {
         prev_ = NULL;
 #ifdef DEBUG
         prevpc_ = (jsbytecode *)0xbadc;
-        prevInline_ = (InlinedSite *)0xbadc;
 #endif
     }
 }
 
 inline void
 StackFrame::resetGeneratorPrev(JSContext *cx)
 {
     flags_ |= HAS_PREVPC;
     initPrev(cx);
 }
 
 inline void
-StackFrame::initInlineFrame(JSFunction *fun, StackFrame *prevfp, jsbytecode *prevpc)
-{
-    /*
-     * Note: no need to ensure the scopeChain is instantiated for inline
-     * frames. Functions which use the scope chain are never inlined.
-     */
-    flags_ = StackFrame::FUNCTION;
-    exec.fun = fun;
-    resetInlinePrev(prevfp, prevpc);
-
-    if (prevfp->hasPushedSPSFrame())
-        setPushedSPSFrame();
-}
-
-inline void
-StackFrame::resetInlinePrev(StackFrame *prevfp, jsbytecode *prevpc)
-{
-    JS_ASSERT_IF(flags_ & StackFrame::HAS_PREVPC, prevInline_);
-    flags_ |= StackFrame::HAS_PREVPC;
-    prev_ = prevfp;
-    prevpc_ = prevpc;
-    prevInline_ = NULL;
-}
-
-inline void
 StackFrame::initCallFrame(JSContext *cx, JSFunction &callee,
                           JSScript *script, uint32_t nactual, StackFrame::Flags flagsArg)
 {
     JS_ASSERT((flagsArg & ~(CONSTRUCTING |
-                            LOWERED_CALL_APPLY |
                             OVERFLOW_ARGS |
                             UNDERFLOW_ARGS)) == 0);
     JS_ASSERT(callee.nonLazyScript() == script);
 
     /* Initialize stack frame members. */
     flags_ = FUNCTION | HAS_PREVPC | HAS_SCOPECHAIN | HAS_BLOCKCHAIN | flagsArg;
     exec.fun = &callee;
     u.nactual = nactual;
@@ -158,17 +121,16 @@ StackFrame::initCallFrame(JSContext *cx,
 /*
  * Reinitialize the StackFrame fields that have been initialized up to the
  * point of FixupArity in the function prologue.
  */
 inline void
 StackFrame::initFixupFrame(StackFrame *prev, StackFrame::Flags flags, void *ncode, unsigned nactual)
 {
     JS_ASSERT((flags & ~(CONSTRUCTING |
-                         LOWERED_CALL_APPLY |
                          FUNCTION |
                          OVERFLOW_ARGS |
                          UNDERFLOW_ARGS)) == 0);
 
     flags_ = FUNCTION | flags;
     prev_ = prev;
     ncode_ = ncode;
     u.nactual = nactual;
@@ -458,37 +420,16 @@ ContextStack::pushInlineFrame(JSContext 
                               InitialFrameFlags initial, Value **stackLimit)
 {
     if (!pushInlineFrame(cx, regs, args, callee, script, initial))
         return false;
     *stackLimit = space().conservativeEnd_;
     return true;
 }
 
-JS_ALWAYS_INLINE StackFrame *
-ContextStack::getFixupFrame(JSContext *cx, MaybeReportError report,
-                            const CallArgs &args, JSFunction *fun, HandleScript script,
-                            void *ncode, InitialFrameFlags initial, Value **stackLimit)
-{
-    JS_ASSERT(onTop());
-    JS_ASSERT(fun->nonLazyScript() == args.callee().toFunction()->nonLazyScript());
-    JS_ASSERT(fun->nonLazyScript() == script);
-
-    StackFrame::Flags flags = ToFrameFlags(initial);
-    StackFrame *fp = getCallFrame(cx, report, args, fun, script, &flags);
-    if (!fp)
-        return NULL;
-
-    /* Do not init late prologue or regs; this is done by jit code. */
-    fp->initFixupFrame(cx->fp(), flags, ncode, args.length());
-
-    *stackLimit = space().conservativeEnd_;
-    return fp;
-}
-
 JS_ALWAYS_INLINE void
 ContextStack::popInlineFrame(FrameRegs &regs)
 {
     JS_ASSERT(onTop());
     JS_ASSERT(&regs == &seg_->regs());
 
     StackFrame *fp = regs.fp();
     Value *newsp = fp->actuals() - 1;
@@ -525,31 +466,16 @@ ContextStack::currentScript(jsbytecode *
         JSScript *script = NULL;
         ion::GetPcScript(cx_, &script, ppc);
         if (!allowCrossCompartment && script->compartment() != cx_->compartment)
             return NULL;
         return script;
     }
 #endif
 
-#ifdef JS_METHODJIT
-    mjit::CallSite *inlined = regs.inlined();
-    if (inlined) {
-        mjit::JITChunk *chunk = fp->jit()->chunk(regs.pc);
-        JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
-        mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
-        JSScript *script = frame->fun->nonLazyScript();
-        if (!allowCrossCompartment && script->compartment() != cx_->compartment)
-            return NULL;
-        if (ppc)
-            *ppc = script->code + inlined->pcOffset;
-        return script;
-    }
-#endif
-
     JSScript *script = fp->script();
     if (!allowCrossCompartment && script->compartment() != cx_->compartment)
         return NULL;
 
     if (ppc)
         *ppc = fp->pcQuadratic(*this);
     return script;
 }
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -4,17 +4,16 @@
  * 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 "mozilla/DebugOnly.h"
 #include "mozilla/PodOperations.h"
 
 #include "jscntxt.h"
 #include "gc/Marking.h"
-#include "methodjit/MethodJIT.h"
 #ifdef JS_ION
 #include "ion/BaselineFrame.h"
 #include "ion/IonFrames.h"
 #include "ion/IonCompartment.h"
 #include "ion/Bailouts.h"
 #endif
 #include "Stack.h"
 #include "ForkJoin.h"
@@ -89,17 +88,16 @@ StackFrame::initExecuteFrame(JSScript *s
 #ifdef DEBUG
         u.evalScript = (JSScript *)0xbad;
 #endif
     }
 
     scopeChain_ = &scopeChain;
     prev_ = prevLink;
     prevpc_ = regs ? regs->pc : (jsbytecode *)0xbad;
-    prevInline_ = regs ? regs->inlined() : NULL;
     blockChain_ = NULL;
 
 #ifdef JS_ION
     /* Set prevBaselineFrame_ if this is an eval frame. */
     JS_ASSERT_IF(isDebuggerFrame(), isEvalFrame());
     prevBaselineFrame_ = (isEvalFrame() && prev.isBaselineFrame()) ? prev.asBaselineFrame() : NULL;
 #endif
 
@@ -191,35 +189,16 @@ StackFrame::maybeSuspendedGenerator(JSRu
     char *vp = reinterpret_cast<char *>(generatorArgsSnapshotBegin());
     char *p = vp - offsetof(JSGenerator, stackSnapshot);
     JSGenerator *gen = reinterpret_cast<JSGenerator *>(p);
     JS_ASSERT(gen->fp == this);
     return gen;
 }
 
 jsbytecode *
-StackFrame::prevpcSlow(InlinedSite **pinlined)
-{
-    JS_ASSERT(!(flags_ & HAS_PREVPC));
-#if defined(JS_METHODJIT) && defined(JS_MONOIC)
-    StackFrame *p = prev();
-    mjit::JITScript *jit = p->script()->getJIT(p->isConstructing(),
-                                               p->compartment()->zone()->compileBarriers());
-    prevpc_ = jit->nativeToPC(ncode_, &prevInline_);
-    flags_ |= HAS_PREVPC;
-    if (pinlined)
-        *pinlined = prevInline_;
-    return prevpc_;
-#else
-    JS_NOT_REACHED("Unknown PC for frame");
-    return NULL;
-#endif
-}
-
-jsbytecode *
 StackFrame::pcQuadratic(const ContextStack &stack, size_t maxDepth)
 {
     StackSegment &seg = stack.space().containingSegment(this);
     FrameRegs &regs = seg.regs();
 
     /*
      * This isn't just an optimization; seg->computeNextFrame(fp) is only
      * defined if fp != seg->regs->fp.
@@ -668,20 +647,16 @@ StackSpace::mark(JSTracer *trc)
          */
         Value *slotsEnd = nextSegEnd;
         for (StackFrame *fp = seg->maybefp(); (Value *)fp > (Value *)seg; fp = fp->prev()) {
             /* Mark from fp->slots() to slotsEnd. */
             markFrame(trc, fp, slotsEnd);
 
             fp->mark(trc);
             slotsEnd = (Value *)fp;
-
-            InlinedSite *site;
-            fp->prevpc(&site);
-            JS_ASSERT_IF(fp->prev(), !site);
         }
         gc::MarkValueRootRange(trc, seg->slotsBegin(), slotsEnd, "vm_stack");
         nextSegEnd = (Value *)seg;
     }
 }
 
 void
 StackSpace::markActiveCompartments()
@@ -860,53 +835,16 @@ ContextStack::onTop() const
  */
 Value *
 ContextStack::ensureOnTop(JSContext *cx, MaybeReportError report, unsigned nvars,
                           MaybeExtend extend, bool *pushedSeg)
 {
     Value *firstUnused = space().firstUnused();
     FrameRegs *regs = cx->maybeRegs();
 
-#ifdef JS_METHODJIT
-    /*
-     * The only calls made by inlined methodjit frames can be to other JIT
-     * frames associated with the same VMFrame. If we try to Invoke(),
-     * Execute() or so forth, any topmost inline frame will need to be
-     * expanded (along with other inline frames in the compartment).
-     * To avoid pathological behavior here, make sure to mark any topmost
-     * function as uninlineable, which will expand inline frames if there are
-     * any and prevent the function from being inlined in the future.
-     *
-     * Note: When called from pushBailoutFrame, error = DONT_REPORT_ERROR. Use
-     * this to deny potential invalidation, which would read from
-     * runtime->ionTop.
-     */
-    if (regs && report != DONT_REPORT_ERROR) {
-        RootedFunction fun(cx);
-        if (InlinedSite *site = regs->inlined()) {
-            mjit::JITChunk *chunk = regs->fp()->jit()->chunk(regs->pc);
-            fun = chunk->inlineFrames()[site->inlineIndex].fun;
-        } else {
-            StackFrame *fp = regs->fp();
-            if (fp->isFunctionFrame()) {
-                JSFunction *f = fp->fun();
-                if (f->isInterpreted())
-                    fun = f;
-            }
-        }
-
-        if (fun) {
-            AutoCompartment ac(cx, fun);
-            fun->nonLazyScript()->uninlineable = true;
-            types::MarkTypeObjectFlags(cx, fun, types::OBJECT_FLAG_UNINLINEABLE);
-        }
-    }
-    JS_ASSERT_IF(cx->hasfp(), !cx->regs().inlined());
-#endif
-
     if (onTop() && extend) {
         if (!space().ensureSpace(cx, report, firstUnused, nvars))
             return NULL;
         return firstUnused;
     }
 
     if (!space().ensureSpace(cx, report, firstUnused, VALUES_PER_STACK_SEGMENT + nvars))
         return NULL;
@@ -1219,23 +1157,20 @@ ScriptFrameIter::poisonRegs()
 
 void
 ScriptFrameIter::popFrame()
 {
     StackFrame *oldfp = data_.fp_;
     JS_ASSERT(data_.seg_->contains(oldfp));
     data_.fp_ = data_.fp_->prev();
 
-    if (data_.seg_->contains(data_.fp_)) {
-        InlinedSite *inline_;
-        data_.pc_ = oldfp->prevpc(&inline_);
-        JS_ASSERT(!inline_);
-    } else {
+    if (data_.seg_->contains(data_.fp_))
+        data_.pc_ = oldfp->prevpc();
+    else
         poisonRegs();
-    }
 }
 
 void
 ScriptFrameIter::settleOnNewSegment()
 {
     if (FrameRegs *regs = data_.seg_->maybeRegs())
         data_.pc_ = regs->pc;
     else
@@ -1393,39 +1328,30 @@ ScriptFrameIter::Data::Data(const Script
 }
 
 ScriptFrameIter::ScriptFrameIter(JSContext *cx, SavedOption savedOption)
   : data_(cx, &cx->runtime->mainThread, savedOption)
 #ifdef JS_ION
     , ionInlineFrames_(cx, (js::ion::IonFrameIterator*) NULL)
 #endif
 {
-#ifdef JS_METHODJIT
-    for (ZonesIter zone(cx->runtime); !zone.done(); zone.next())
-        mjit::ExpandInlineFrames(zone);
-#endif
-
     if (StackSegment *seg = cx->stack.seg_) {
         startOnSegment(seg);
         settleOnNewState();
     } else {
         data_.state_ = DONE;
     }
 }
 
 ScriptFrameIter::ScriptFrameIter(JSRuntime *rt, StackSegment &seg)
   : data_(seg.cx(), rt, &seg)
 #ifdef JS_ION
     , ionInlineFrames_(seg.cx(), (js::ion::IonFrameIterator*) NULL)
 #endif
 {
-#ifdef JS_METHODJIT
-    for (ZonesIter zone(rt); !zone.done(); zone.next())
-        mjit::ExpandInlineFrames(zone);
-#endif
     startOnSegment(&seg);
     settleOnNewState();
 }
 
 ScriptFrameIter::ScriptFrameIter(const ScriptFrameIter &other)
   : data_(other.data_)
 #ifdef JS_ION
     , ionInlineFrames_(other.data_.seg_->cx(),
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -37,31 +37,16 @@ class ScriptFrameIter;
 class AllFramesIter;
 
 class ArgumentsObject;
 class ScopeObject;
 class StaticBlockObject;
 
 struct ScopeCoordinate;
 
-#ifdef JS_METHODJIT
-namespace mjit {
-    class CallCompiler;
-    class GetPropCompiler;
-    struct CallSite;
-    struct JITScript;
-    jsbytecode *NativeToPC(JITScript *jit, void *ncode, CallSite **pinline);
-    namespace ic { struct GetElementIC; }
-}
-typedef mjit::CallSite InlinedSite;
-#else
-struct InlinedSite {};
-#endif
-typedef size_t FrameRejoinState;
-
 namespace ion {
     class IonBailoutIterator;
     class SnapshotIterator;
 }
 
 /*****************************************************************************/
 
 /*
@@ -273,17 +258,16 @@ class NullFramePtr : public AbstractFram
 };
 
 /*****************************************************************************/
 
 /* Flags specified for a frame as it is constructed. */
 enum InitialFrameFlags {
     INITIAL_NONE           =          0,
     INITIAL_CONSTRUCT      =       0x20, /* == StackFrame::CONSTRUCTING, asserted below */
-    INITIAL_LOWERED        =    0x40000  /* == StackFrame::LOWERED_CALL_APPLY, asserted below */
 };
 
 enum ExecuteType {
     EXECUTE_GLOBAL         =        0x1, /* == StackFrame::GLOBAL */
     EXECUTE_DIRECT_EVAL    =        0x4, /* == StackFrame::EVAL */
     EXECUTE_INDIRECT_EVAL  =        0x5, /* == StackFrame::GLOBAL | EVAL */
     EXECUTE_DEBUG          =        0xc, /* == StackFrame::EVAL | DEBUGGER */
     EXECUTE_DEBUG_GLOBAL   =        0xd  /* == StackFrame::EVAL | DEBUGGER | GLOBAL */
@@ -319,34 +303,28 @@ class StackFrame
 
         /* Lazy frame initialization */
         HAS_HOOK_DATA      =     0x1000,  /* frame has hookData_ set */
         HAS_RVAL           =     0x2000,  /* frame has rval_ set */
         HAS_SCOPECHAIN     =     0x4000,  /* frame has scopeChain_ set */
         HAS_PREVPC         =     0x8000,  /* frame has prevpc_ and prevInline_ set */
         HAS_BLOCKCHAIN     =    0x10000,  /* frame has blockChain_ set */
 
-        /* Method JIT state */
-        DOWN_FRAMES_EXPANDED =  0x20000,  /* inlining in down frames has been expanded */
-        LOWERED_CALL_APPLY   =  0x40000,  /* Pushed by a lowered call/apply */
-
         /* Debugger state */
-        PREV_UP_TO_DATE    =    0x80000,  /* see DebugScopes::updateLiveScopes */
+        PREV_UP_TO_DATE    =    0x20000,  /* see DebugScopes::updateLiveScopes */
 
         /* Used in tracking calls and profiling (see vm/SPSProfiler.cpp) */
-        HAS_PUSHED_SPS_FRAME = 0x100000,  /* SPS was notified of enty */
+        HAS_PUSHED_SPS_FRAME =  0x40000,  /* SPS was notified of enty */
 
         /* Ion frame state */
-        RUNNING_IN_ION     =   0x200000,  /* frame is running in Ion */
-        CALLING_INTO_ION   =   0x400000,  /* frame is calling into Ion */
-
-        JIT_REVISED_STACK  =   0x800000,  /* sp was revised by JIT for lowered apply */
+        RUNNING_IN_ION     =    0x80000,  /* frame is running in Ion */
+        CALLING_INTO_ION   =   0x100000,  /* frame is calling into Ion */
 
         /* Miscellaneous state. */
-        USE_NEW_TYPE       =  0x1000000   /* Use new type for constructed |this| object. */
+        USE_NEW_TYPE       =   0x200000   /* Use new type for constructed |this| object. */
     };
 
   private:
     mutable uint32_t    flags_;         /* bits described by Flags */
     union {                             /* describes what code is executing in a */
         JSScript        *script;        /*   global frame */
         JSFunction      *fun;           /*   function frame, pre GetScopeChain */
     } exec;
@@ -356,32 +334,28 @@ class StackFrame
     } u;
     mutable JSObject    *scopeChain_;   /* if HAS_SCOPECHAIN, current scope chain */
     StackFrame          *prev_;         /* if HAS_PREVPC, previous cx->regs->fp */
     void                *ncode_;        /* for a jit frame, return address for method JIT */
     Value               rval_;          /* if HAS_RVAL, return value of the frame */
     StaticBlockObject   *blockChain_;   /* if HAS_BLOCKCHAIN, innermost let block */
     ArgumentsObject     *argsObj_;      /* if HAS_ARGS_OBJ, the call's arguments object */
     jsbytecode          *prevpc_;       /* if HAS_PREVPC, pc of previous frame*/
-    InlinedSite         *prevInline_;   /* for a jit frame, inlined site in previous frame */
     void                *hookData_;     /* if HAS_HOOK_DATA, closure returned by call hook */
-    FrameRejoinState    rejoin_;        /* for a jit frame rejoining the interpreter
-                                         * from JIT code, state at rejoin. */
 #ifdef JS_ION
     ion::BaselineFrame  *prevBaselineFrame_; /* for an eval/debugger frame, the baseline frame
                                               * to use as prev. */
 #endif
 
     static void staticAsserts() {
         JS_STATIC_ASSERT(offsetof(StackFrame, rval_) % sizeof(Value) == 0);
         JS_STATIC_ASSERT(sizeof(StackFrame) % sizeof(Value) == 0);
     }
 
     inline void initPrev(JSContext *cx);
-    jsbytecode *prevpcSlow(InlinedSite **pinlined);
     void writeBarrierPost();
 
     /*
      * These utilities provide raw access to the values associated with a
      * StackFrame (see "VM stack layout" comment). The utilities are private
      * since they are not able to assert that only unaliased vars/formals are
      * accessed. Normal code should prefer the StackFrame::unaliased* members
      * (or FrameRegs::stackDepth for the usual "depth is at least" assertions).
@@ -396,21 +370,16 @@ class StackFrame
   private:
     friend class FrameRegs;
     friend class ContextStack;
     friend class StackSpace;
     friend class ScriptFrameIter;
     friend class CallObject;
     friend class ClonedBlockObject;
     friend class ArgumentsObject;
-#ifdef JS_METHODJIT
-    friend class mjit::CallCompiler;
-    friend class mjit::GetPropCompiler;
-    friend struct mjit::ic::GetElementIC;
-#endif
 
     /*
      * Frame initialization, called by ContextStack operations after acquiring
      * the raw memory for the frame:
      */
 
     /* Used for Invoke, Interpret, trace-jit LeaveTree, and method-jit stubs. */
     void initCallFrame(JSContext *cx, JSFunction &callee,
@@ -710,28 +679,19 @@ class StackFrame
      *  - if you know the next frame (i.e., next s.t. next->prev == fp
      *  - pcQuadratic will only iterate maxDepth frames (before giving up and
      *    returning fp->script->code), making it O(1), but incorrect.
      */
 
     jsbytecode *pcQuadratic(const ContextStack &stack, size_t maxDepth = SIZE_MAX);
 
     /* Return the previous frame's pc. Unlike pcQuadratic, this is O(1). */
-    jsbytecode *prevpc(InlinedSite **pinlined = NULL) {
-        if (flags_ & HAS_PREVPC) {
-            if (pinlined)
-                *pinlined = prevInline_;
-            return prevpc_;
-        }
-        return prevpcSlow(pinlined);
-    }
-
-    InlinedSite *prevInline() {
+    jsbytecode *prevpc() {
         JS_ASSERT(flags_ & HAS_PREVPC);
-        return prevInline_;
+        return prevpc_;
     }
 
     /*
      * Function
      *
      * All function frames have an associated interpreted JSFunction. The
      * function returned by fun() and maybeFun() is not necessarily the
      * original canonical function which the frame's script was compiled
@@ -820,36 +780,16 @@ class StackFrame
      * Frame compartment
      *
      * A stack frame's compartment is the frame's containing context's
      * compartment when the frame was pushed.
      */
 
     inline JSCompartment *compartment() const;
 
-    /* JIT rejoin state */
-
-    FrameRejoinState rejoin() const {
-        return rejoin_;
-    }
-
-    void setRejoin(FrameRejoinState state) {
-        rejoin_ = state;
-    }
-
-    /* Down frame expansion state */
-
-    void setDownFramesExpanded() {
-        flags_ |= DOWN_FRAMES_EXPANDED;
-    }
-
-    bool downFramesExpanded() {
-        return !!(flags_ & DOWN_FRAMES_EXPANDED);
-    }
-
     /* Debugger hook data */
 
     bool hasHookData() const {
         return !!(flags_ & HAS_HOOK_DATA);
     }
 
     void* hookData() const {
         JS_ASSERT(hasHookData());
@@ -978,18 +918,17 @@ class StackFrame
 
     /*
      * Other flags
      */
 
     InitialFrameFlags initialFlags() const {
         JS_STATIC_ASSERT((int)INITIAL_NONE == 0);
         JS_STATIC_ASSERT((int)INITIAL_CONSTRUCT == (int)CONSTRUCTING);
-        JS_STATIC_ASSERT((int)INITIAL_LOWERED == (int)LOWERED_CALL_APPLY);
-        uint32_t mask = CONSTRUCTING | LOWERED_CALL_APPLY;
+        uint32_t mask = CONSTRUCTING;
         JS_ASSERT((flags_ & mask) != mask);
         return InitialFrameFlags(flags_ & mask);
     }
 
     void setConstructing() {
         flags_ |= CONSTRUCTING;
     }
 
@@ -1023,26 +962,16 @@ class StackFrame
         JS_ASSERT(isConstructing());
         flags_ |= USE_NEW_TYPE;
     }
     bool useNewType() const {
         JS_ASSERT(isConstructing());
         return flags_ & USE_NEW_TYPE;
     }
 
-    /*
-     * The method JIT call/apply optimization can erase Function.{call,apply}
-     * invocations from the stack and push the callee frame directly. The base
-     * of these frames will be offset by one value, however, which the
-     * interpreter needs to account for if it ends up popping the frame.
-     */
-    bool loweredCallOrApply() const {
-        return !!(flags_ & LOWERED_CALL_APPLY);
-    }
-
     bool isDebuggerFrame() const {
         return !!(flags_ & DEBUGGER);
     }
 
     bool prevUpToDate() const {
         return !!(flags_ & PREV_UP_TO_DATE);
     }
 
@@ -1070,79 +999,47 @@ class StackFrame
         flags_ |= FINISHED_IN_INTERP;
     }
 
     bool finishedInInterpreter() const {
         return !!(flags_ & FINISHED_IN_INTERP);
     }
 
   public:
-    /* Public, but only for JIT use: */
-
-    inline void resetInlinePrev(StackFrame *prevfp, jsbytecode *prevpc);
-    inline void initInlineFrame(JSFunction *fun, StackFrame *prevfp, jsbytecode *prevpc);
-
     static size_t offsetOfFlags() {
         return offsetof(StackFrame, flags_);
     }
 
     static size_t offsetOfExec() {
         return offsetof(StackFrame, exec);
     }
 
     static size_t offsetOfNumActual() {
         return offsetof(StackFrame, u.nactual);
     }
 
     static size_t offsetOfScopeChain() {
         return offsetof(StackFrame, scopeChain_);
     }
 
-    static size_t offsetOfPrev() {
-        return offsetof(StackFrame, prev_);
-    }
-
-    static size_t offsetOfReturnValue() {
-        return offsetof(StackFrame, rval_);
-    }
-
-    static ptrdiff_t offsetOfNcode() {
-        return offsetof(StackFrame, ncode_);
-    }
-
-    static ptrdiff_t offsetOfArgsObj() {
-        return offsetof(StackFrame, argsObj_);
-    }
-
-    static ptrdiff_t offsetOfCallee(JSFunction *fun) {
-        JS_ASSERT(fun != NULL);
-        return -(fun->nargs + 2) * sizeof(Value);
-    }
-
     static ptrdiff_t offsetOfThis(JSFunction *fun) {
         return fun == NULL
                ? -1 * ptrdiff_t(sizeof(Value))
                : -(fun->nargs + 1) * ptrdiff_t(sizeof(Value));
     }
 
     static ptrdiff_t offsetOfFormalArg(JSFunction *fun, unsigned i) {
         JS_ASSERT(i < fun->nargs);
         return (-(int)fun->nargs + i) * sizeof(Value);
     }
 
     static size_t offsetOfFixed(unsigned i) {
         return sizeof(StackFrame) + i * sizeof(Value);
     }
 
-#ifdef JS_METHODJIT
-    inline mjit::JITScript *jit();
-#endif
-
-    void methodjitStaticAsserts();
-
   public:
     void mark(JSTracer *trc);
 
     // Entered IonMonkey from the interpreter.
     bool runningInIon() const {
         return !!(flags_ & RUNNING_IN_ION);
     }
     // Entered IonMonkey from JaegerMonkey.
@@ -1160,23 +1057,16 @@ class StackFrame
         flags_ |= CALLING_INTO_ION;
     }
     void clearRunningInIon() {
         flags_ &= ~RUNNING_IN_ION;
     }
     void clearCallingIntoIon() {
         flags_ &= ~CALLING_INTO_ION;
     }
-
-    bool jitRevisedStack() const {
-        return !!(flags_ & JIT_REVISED_STACK);
-    }
-    void setJitRevisedStack() const {
-        flags_ |= JIT_REVISED_STACK;
-    }
 };
 
 static const size_t VALUES_PER_STACK_FRAME = sizeof(StackFrame) / sizeof(Value);
 
 static inline StackFrame::Flags
 ToFrameFlags(InitialFrameFlags initial)
 {
     return StackFrame::Flags(initial);
@@ -1189,70 +1079,52 @@ InitialFrameFlagsFromConstructing(bool b
 }
 
 static inline bool
 InitialFrameFlagsAreConstructing(InitialFrameFlags initial)
 {
     return !!(initial & INITIAL_CONSTRUCT);
 }
 
-static inline bool
-InitialFrameFlagsAreLowered(InitialFrameFlags initial)
-{
-    return !!(initial & INITIAL_LOWERED);
-}
-
 inline AbstractFramePtr Valueify(JSAbstractFramePtr frame) { return AbstractFramePtr(frame); }
 static inline JSAbstractFramePtr Jsvalify(AbstractFramePtr frame)   { return JSAbstractFramePtr(frame.raw()); }
 
 /*****************************************************************************/
 
 class FrameRegs
 {
   public:
     Value *sp;
     jsbytecode *pc;
   private:
-    InlinedSite *inlined_;
     StackFrame *fp_;
   public:
     StackFrame *fp() const { return fp_; }
-    InlinedSite *inlined() const { return inlined_; }
-
-    /* For jit use (need constant): */
-    static const size_t offsetOfFp = 3 * sizeof(void *);
-    static const size_t offsetOfInlined = 2 * sizeof(void *);
-    static void staticAssert() {
-        JS_STATIC_ASSERT(offsetOfFp == offsetof(FrameRegs, fp_));
-        JS_STATIC_ASSERT(offsetOfInlined == offsetof(FrameRegs, inlined_));
-    }
-    void clearInlined() { inlined_ = NULL; }
 
     unsigned stackDepth() const {
         JS_ASSERT(sp >= fp_->base());
         return sp - fp_->base();
     }
 
     Value *spForStackDepth(unsigned depth) const {
         JS_ASSERT(fp_->script()->nfixed + depth <= fp_->script()->nslots);
         return fp_->base() + depth;
     }
 
     /* For generator: */
     void rebaseFromTo(const FrameRegs &from, StackFrame &to) {
         fp_ = &to;
         sp = to.slots() + (from.sp - from.fp_->slots());
         pc = from.pc;
-        inlined_ = from.inlined_;
         JS_ASSERT(fp_);
     }
 
     /* For ContextStack: */
     void popFrame(Value *newsp) {
-        pc = fp_->prevpc(&inlined_);
+        pc = fp_->prevpc();
         sp = newsp;
         fp_ = fp_->prev();
         JS_ASSERT(fp_);
     }
 
     /* For FixupArity: */
     void popPartialFrame(Value *newsp) {
         sp = newsp;
@@ -1260,49 +1132,29 @@ class FrameRegs
         JS_ASSERT(fp_);
     }
 
     /* For InternalInterpret: */
     void restorePartialFrame(Value *newfp) {
         fp_ = (StackFrame *) newfp;
     }
 
-    /* For EnterMethodJIT: */
-    void refreshFramePointer(StackFrame *fp) {
-        fp_ = fp;
-    }
-
     /* For stubs::CompileFunction, ContextStack: */
     void prepareToRun(StackFrame &fp, JSScript *script) {
         pc = script->code;
         sp = fp.slots() + script->nfixed;
         fp_ = &fp;
-        inlined_ = NULL;
     }
 
     void setToEndOfScript() {
         JSScript *script = fp()->script();
         sp = fp()->base();
         pc = script->code + script->length - JSOP_STOP_LENGTH;
         JS_ASSERT(*pc == JSOP_STOP);
     }
-
-    /* For expandInlineFrames: */
-    void expandInline(StackFrame *innerfp, jsbytecode *innerpc) {
-        pc = innerpc;
-        fp_ = innerfp;
-        inlined_ = NULL;
-    }
-
-#ifdef JS_METHODJIT
-    /* For LimitCheck: */
-    void updateForNcode(mjit::JITScript *jit, void *ncode) {
-        pc = mjit::NativeToPC(jit, ncode, &inlined_);
-    }
-#endif
 };
 
 /*****************************************************************************/
 
 class StackSegment
 {
     JSContext *cx_;
 
@@ -1689,25 +1541,16 @@ class ContextStack
         ALLOW_CROSS_COMPARTMENT = true
     };
     inline JSScript *currentScript(jsbytecode **pc = NULL,
                                    MaybeAllowCrossCompartment = DONT_ALLOW_CROSS_COMPARTMENT) const;
 
     /* Get the scope chain for the topmost scripted call on the stack. */
     inline HandleObject currentScriptedScopeChain() const;
 
-    /*
-     * Called by the methodjit for an arity mismatch. Arity mismatch can be
-     * hot, so getFixupFrame avoids doing call setup performed by jit code when
-     * FixupArity returns.
-     */
-    StackFrame *getFixupFrame(JSContext *cx, MaybeReportError report,
-                              const CallArgs &args, JSFunction *fun, HandleScript script,
-                              void *ncode, InitialFrameFlags initial, Value **stackLimit);
-
     bool saveFrameChain();
     void restoreFrameChain();
 
     /*
      * As an optimization, the interpreter/mjit can operate on a local
      * FrameRegs instance repoint the ContextStack to this local instance.
      */
     inline void repointRegs(FrameRegs *regs) { JS_ASSERT(hasfp()); seg_->repointRegs(regs); }
--- a/layout/base/nsCounterManager.h
+++ b/layout/base/nsCounterManager.h
@@ -4,16 +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/. */
 
 /* implementation of CSS counters (for numbering things) */
 
 #ifndef nsCounterManager_h_
 #define nsCounterManager_h_
 
+#include "mozilla/Attributes.h"
 #include "nsGenConList.h"
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "mozilla/Likely.h"
 
 class nsCounterList;
 struct nsCounterUseNode;
 struct nsCounterChangeNode;
@@ -89,17 +90,17 @@ struct nsCounterUseNode : public nsCount
         : nsCounterNode(aContentIndex, USE)
         , mCounterStyle(aCounterStyle)
         , mAllCounters(aAllCounters)
     {
         NS_ASSERTION(aContentIndex <= INT32_MAX, "out of range");
     }
     
     virtual bool InitTextFrame(nsGenConList* aList,
-            nsIFrame* aPseudoFrame, nsIFrame* aTextFrame);
+            nsIFrame* aPseudoFrame, nsIFrame* aTextFrame) MOZ_OVERRIDE;
 
     // assign the correct |mValueAfter| value to a node that has been inserted
     // Should be called immediately after calling |Insert|.
     void Calc(nsCounterList* aList);
 
     // The text that should be displayed for this counter.
     void GetText(nsString& aResult);
 };
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1601,28 +1601,54 @@ nsDisplayBackgroundImage::WriteDebugInfo
 {
   if (mIsThemed) {
     fprintf(aOutput, "(themed, appearance:%d) ", mFrame->StyleDisplay()->mAppearance);
   }
 
 }
 #endif
 
+static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame)
+{
+  nsStyleContext *sc;
+  if (!nsCSSRendering::FindBackground(aFrame, &sc)) {
+    // We don't want to bail out if moz-appearance is set on a root
+    // node. If it has a parent content node, bail because it's not
+    // a root, other wise keep going in order to let the theme stuff
+    // draw the background. The canvas really should be drawing the
+    // bg, but there's no way to hook that up via css.
+    if (!aFrame->StyleDisplay()->mAppearance) {
+      return nullptr;
+    }
+
+    nsIContent* content = aFrame->GetContent();
+    if (!content || content->GetParent()) {
+      return nullptr;
+    }
+
+    sc = aFrame->StyleContext();
+  }
+  return sc;
+}
+
 /*static*/ nsresult
 nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
                                                      nsIFrame* aFrame,
                                                      nsDisplayList* aList,
                                                      nsDisplayBackgroundImage** aBackground)
 {
   nsStyleContext* bgSC = nullptr;
   const nsStyleBackground* bg = nullptr;
   nsPresContext* presContext = aFrame->PresContext();
   bool isThemed = aFrame->IsThemed();
-  if (!isThemed && nsCSSRendering::FindBackground(aFrame, &bgSC)) {
-    bg = bgSC->StyleBackground();
+  if (!isThemed) {
+    bgSC = GetBackgroundStyleContext(aFrame);
+    if (bgSC) {
+      bg = bgSC->StyleBackground();
+    }
   }
 
   bool drawBackgroundColor = false;
   nscolor color;
   if (!nsCSSRendering::IsCanvasFrame(aFrame) && bg) {
     bool drawBackgroundImage;
     color =
       nsCSSRendering::DetermineBackgroundColor(presContext, bgSC, aFrame,
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -1656,17 +1656,17 @@ public:
   nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     : nsDisplayItem(aBuilder, aFrame)
   {}
 
   virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
                                                         nsDisplayListBuilder* aBuilder) = 0;
   virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
 
-  virtual bool SupportsOptimizingToImage() { return true; }
+  virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return true; }
 };
 
 /**
  * Use this class to implement not-very-frequently-used display items
  * that are not opaque, do not receive events, and are bounded by a frame's
  * border-rect.
  * 
  * This should not be used for display items which are created frequently,
@@ -1841,17 +1841,17 @@ public:
                                    nsRegion* aVisibleRegion,
                                    const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
   
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder);
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion);
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
 };
 
 /**
  * A simple display item that just renders a solid color across the
  * specified bounds. For canvas frames (in the CSS sense) we split off the
  * drawing of the background color into this class (from nsDisplayBackground
  * via nsDisplayCanvasBackground). This is done so that we can always draw a
  * background color to avoid ugly flashes of white when we can't draw a full
@@ -1897,17 +1897,17 @@ public:
 
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayItemBoundsGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion)
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
   }
 
   NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
 
 private:
@@ -1996,17 +1996,17 @@ public:
   virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
                                                         nsDisplayListBuilder *aBuilder) MOZ_OVERRIDE;
   virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
 
   static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip,
                                       const nsRect& aRect, bool* aSnap);
 
 #ifdef MOZ_DUMP_PAINTING
-  virtual void WriteDebugInfo(FILE *aOutput);
+  virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE;
 #endif
 protected:
   typedef class mozilla::layers::ImageContainer ImageContainer;
   typedef class mozilla::layers::ImageLayer ImageLayer;
 
   bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
   bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aClipRect,
@@ -2060,17 +2060,17 @@ public:
 
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayItemBoundsGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion)
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
   }
 
   NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
 #ifdef MOZ_DUMP_PAINTING
   virtual void WriteDebugInfo(FILE *aOutput) {
@@ -2154,17 +2154,17 @@ public:
   
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
   {
     return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion)
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
     if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
       // nsDisplayBoxShadowInner is based around the padding rect, but it can
       // touch pixels outside of this. We should invalidate the entire bounds.
       bool snap;
       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
     }
@@ -2270,17 +2270,17 @@ public:
   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE {
     NS_WARNING("This list should already have been flattened!!!");
     return false;
   }
   virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) MOZ_OVERRIDE
   {
     aFrames->AppendElements(mMergedFrames);
   }
-  virtual bool IsInvalid(nsRect& aRect)
+  virtual bool IsInvalid(nsRect& aRect) MOZ_OVERRIDE
   {
     if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
       return true;
     }
     nsRect temp;
     for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
       if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
         aRect.SetEmpty();
@@ -2408,17 +2408,17 @@ public:
   }
   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
 #ifdef MOZ_DUMP_PAINTING
   virtual void WriteDebugInfo(FILE *aOutput) {
     fprintf(aOutput, "(opacity %f)", mFrame->StyleDisplay()->mOpacity);
   }
 #endif
 
-  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder);
+  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
 };
 
 /**
  * A display item that has no purpose but to ensure its contents get
  * their own layer.
  */
 class nsDisplayOwnLayer : public nsDisplayWrapList {
 public:
--- a/layout/base/nsDisplayListInvalidation.h
+++ b/layout/base/nsDisplayListInvalidation.h
@@ -1,16 +1,17 @@
 /*-*- Mode: C++; 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/. */
 
 #ifndef NSDISPLAYLISTINVALIDATION_H_
 #define NSDISPLAYLISTINVALIDATION_H_
 
+#include "mozilla/Attributes.h"
 #include "nsRect.h"
 
 class nsDisplayItem;
 class nsDisplayListBuilder;
 class nsDisplayBackgroundImage;
 
 /**
  * This stores the geometry of an nsDisplayItem, and the area
@@ -53,54 +54,54 @@ public:
  *
  * This should be sufficient for the majority of display items.
  */
 class nsDisplayItemGenericGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayItemGenericGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
 
-  virtual void MoveBy(const nsPoint& aOffset);
+  virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
 
   nsRect mBorderRect;
 };
 
 class nsDisplayItemBoundsGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayItemBoundsGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
 
-  virtual void MoveBy(const nsPoint& aOffset);
+  virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
 
   bool mHasRoundedCorners;
 };
 
 class nsDisplayBorderGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayBorderGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
 
-  virtual void MoveBy(const nsPoint& aOffset);
+  virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
 
   nsRect mContentRect;
 };
 
 class nsDisplayBackgroundGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayBackgroundGeometry(nsDisplayBackgroundImage* aItem, nsDisplayListBuilder* aBuilder);
 
-  virtual void MoveBy(const nsPoint& aOffset);
+  virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
 
   nsRect mPositioningArea;
 };
 
 class nsDisplayBoxShadowInnerGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayBoxShadowInnerGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
   
-  virtual void MoveBy(const nsPoint& aOffset);
+  virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
 
   nsRect mPaddingRect;
 };
 
 #endif /*NSDISPLAYLISTINVALIDATION_H_*/
--- a/layout/base/nsFrameTraversal.h
+++ b/layout/base/nsFrameTraversal.h
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; 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/. */
 #ifndef NSFRAMETRAVERSAL_H
 #define NSFRAMETRAVERSAL_H
 
+#include "mozilla/Attributes.h"
 #include "nsIFrame.h"
 #include "nsIFrameTraversal.h"
 
 nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                               nsPresContext* aPresContext,
                               nsIFrame *aStart,
                               nsIteratorType aType,
                               bool aVisual,
@@ -27,12 +28,12 @@ public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                                nsPresContext* aPresContext,
                                nsIFrame *aStart,
                                int32_t aType,
                                bool aVisual,
                                bool aLockInScrollView,
-                               bool aFollowOOFs);
+                               bool aFollowOOFs) MOZ_OVERRIDE;
 };
 
 #endif //NSFRAMETRAVERSAL_H
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1386,16 +1386,36 @@ public:
   virtual void BackingScaleFactorChanged() = 0;
 
   nscoord MaxLineBoxWidth() {
     return mMaxLineBoxWidth;
   }
 
   void SetMaxLineBoxWidth(nscoord aMaxLineBoxWidth);
 
+  /**
+   * Returns whether or not there is a reflow on zoom event pending. A reflow
+   * on zoom event is a change to the max line box width, followed by a reflow.
+   * This subsequent reflow event should treat all frames as though they resized
+   * horizontally (and thus reflow all their descendants), rather than marking
+   * all frames dirty from the root. This is the way the pres shell indicates
+   * that an hresize reflow should take place during reflow state construction.
+   */
+  bool IsReflowOnZoomPending() {
+    return mReflowOnZoomPending;
+  }
+
+  /**
+   * Clear the flag indicating whether a reflow on zoom event is pending. This
+   * is performed at the very end of DoReflow().
+   */
+  void ClearReflowOnZoomPending() {
+    mReflowOnZoomPending = false;
+  }
+
 protected:
   friend class nsRefreshDriver;
 
   // IMPORTANT: The ownership implicit in the following member variables
   // has been explicitly checked.  If you add any members to this class,
   // please make the ownership explicit (pinkerton, scc).
 
   // These are the same Document and PresContext owned by the DocViewer.
@@ -1494,14 +1514,18 @@ protected:
   // Cached font inflation values. This is done to prevent changing of font
   // inflation until a page is reloaded.
   uint32_t mFontSizeInflationEmPerLine;
   uint32_t mFontSizeInflationMinTwips;
   uint32_t mFontSizeInflationLineThreshold;
   bool mFontSizeInflationForceEnabled;
   bool mFontSizeInflationDisabledInMasterProcess;
 
+  // Flag to indicate whether or not there is a reflow on zoom event pending.
+  // See IsReflowOnZoomPending() for more information.
+  bool mReflowOnZoomPending;
+
   // The maximum width of a line box. Text on a single line that exceeds this
   // width will be wrapped. A value of 0 indicates that no limit is enforced.
   nscoord mMaxLineBoxWidth;
 };
 
 #endif /* nsIPresShell_h___ */
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1872,17 +1872,17 @@ PresShell::ResizeReflowIgnoreOverride(ns
         // Kick off a top-down reflow
         AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
         nsViewManager::AutoDisableRefresh refreshBlocker(mViewManager);
 
         mDirtyRoots.RemoveElement(rootFrame);
         DoReflow(rootFrame, true);
       }
 
-      DidDoReflow(true);
+      DidDoReflow(true, false);
     }
   }
 
   rootFrame = mFrameConstructor->GetRootFrame();
   if (aHeight == NS_UNCONSTRAINEDSIZE && rootFrame) {
     mPresContext->SetVisibleArea(
       nsRect(0, 0, aWidth, rootFrame->GetRect().height));
   }
@@ -2221,17 +2221,17 @@ PresShell::ScrollCharacter(bool aRight)
 NS_IMETHODIMP
 PresShell::CompleteScroll(bool aForward)
 {
   nsIScrollableFrame* scrollFrame =
     GetFrameToScrollAsScrollable(nsIPresShell::eVertical);
   if (scrollFrame) {
     scrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
                           nsIScrollableFrame::WHOLE,
-                          nsIScrollableFrame::INSTANT);
+                          nsIScrollableFrame::SMOOTH);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresShell::CompleteMove(bool aForward, bool aExtend)
 {
   // Beware! This may flush notifications via synchronous
@@ -6546,16 +6546,17 @@ PresShell::HandleEventWithTarget(nsEvent
   MOZ_ASSERT(!aFrame || aFrame->PresContext()->GetPresShell() == this,
              "wrong shell");
   if (aContent) {
     nsIDocument* doc = aContent->GetCurrentDoc();
     NS_ASSERTION(doc, "event for content that isn't in a document");
     NS_ASSERTION(!doc || doc->GetShell() == this, "wrong shell");
   }
 #endif
+  NS_ENSURE_STATE(!aContent || aContent->GetCurrentDoc() == mDocument);
 
   PushCurrentEventInfo(aFrame, aContent);
   nsresult rv = HandleEventInternal(aEvent, aStatus);
   PopCurrentEventInfo();
   return rv;
 }
 
 static bool CanHandleContextMenuEvent(nsMouseEvent* aMouseEvent,
@@ -7622,30 +7623,34 @@ PresShell::WillDoReflow()
   }
 
   mPresContext->FlushUserFontSet();
 
   mFrameConstructor->BeginUpdate();
 }
 
 void
-PresShell::DidDoReflow(bool aInterruptible)
+PresShell::DidDoReflow(bool aInterruptible, bool aWasInterrupted)
 {
   mFrameConstructor->EndUpdate();
   
   HandlePostedReflowCallbacks(aInterruptible);
   if (sSynthMouseMove) {
     SynthesizeMouseMove(false);
   }
   if (mCaret) {
     // Update the caret's position now to account for any changes created by
     // the reflow.
     mCaret->InvalidateOutsideCaret();
     mCaret->UpdateCaretPosition();
   }
+
+  if (!aWasInterrupted) {
+    ClearReflowOnZoomPending();
+  }
 }
 
 static PLDHashOperator
 MarkFramesDirtyToRoot(nsPtrHashKey<nsIFrame>* p, void* closure)
 {
   nsIFrame* target = static_cast<nsIFrame*>(closure);
   for (nsIFrame* f = p->GetKey(); f && !NS_SUBTREE_DIRTY(f);
        f = f->GetParent()) {
@@ -7928,17 +7933,17 @@ PresShell::ProcessReflowCommands(bool aI
       } while (!interrupted && !mDirtyRoots.IsEmpty() &&
                (!aInterruptible || PR_IntervalNow() < deadline));
 
       interrupted = !mDirtyRoots.IsEmpty();
     }
 
     // Exiting the scriptblocker might have killed us
     if (!mIsDestroying) {
-      DidDoReflow(aInterruptible);
+      DidDoReflow(aInterruptible, interrupted);
     }
 
     // DidDoReflow might have killed us
     if (!mIsDestroying) {
 #ifdef DEBUG
       if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
         printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n",
                (void*)this);
@@ -9471,11 +9476,12 @@ PresShell::SetupFontInflation()
 
 void
 nsIPresShell::SetMaxLineBoxWidth(nscoord aMaxLineBoxWidth)
 {
   NS_ASSERTION(aMaxLineBoxWidth >= 0, "attempting to set max line box width to a negative value");
 
   if (mMaxLineBoxWidth != aMaxLineBoxWidth) {
     mMaxLineBoxWidth = aMaxLineBoxWidth;
-    FrameNeedsReflow(GetRootFrame(), eResize, NS_FRAME_IS_DIRTY);
-  }
-}
+    mReflowOnZoomPending = true;
+    FrameNeedsReflow(GetRootFrame(), eResize, NS_FRAME_HAS_DIRTY_CHILDREN);
+  }
+}
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -65,159 +65,159 @@ public:
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
             nsViewManager* aViewManager, nsStyleSet* aStyleSet,
             nsCompatibility aCompatMode);
-  virtual NS_HIDDEN_(void) Destroy();
-  virtual NS_HIDDEN_(void) MakeZombie();
+  virtual NS_HIDDEN_(void) Destroy() MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) MakeZombie() MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(nsresult) SetPreferenceStyleRules(bool aForceReflow);
+  virtual NS_HIDDEN_(nsresult) SetPreferenceStyleRules(bool aForceReflow) MOZ_OVERRIDE;
 
   NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection);
-  virtual mozilla::Selection* GetCurrentSelection(SelectionType aType);
+  virtual mozilla::Selection* GetCurrentSelection(SelectionType aType) MOZ_OVERRIDE;
 
   NS_IMETHOD SetDisplaySelection(int16_t aToggle);
   NS_IMETHOD GetDisplaySelection(int16_t *aToggle);
   NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion,
                                      int16_t aFlags);
   NS_IMETHOD RepaintSelection(SelectionType aType);
 
-  virtual NS_HIDDEN_(void) BeginObservingDocument();
-  virtual NS_HIDDEN_(void) EndObservingDocument();
-  virtual NS_HIDDEN_(nsresult) Initialize(nscoord aWidth, nscoord aHeight);
-  virtual NS_HIDDEN_(nsresult) ResizeReflow(nscoord aWidth, nscoord aHeight);
-  virtual NS_HIDDEN_(nsresult) ResizeReflowOverride(nscoord aWidth, nscoord aHeight);
-  virtual NS_HIDDEN_(nsIPageSequenceFrame*) GetPageSequenceFrame() const;
-  virtual NS_HIDDEN_(nsIFrame*) GetRealPrimaryFrameFor(nsIContent* aContent) const;
+  virtual NS_HIDDEN_(void) BeginObservingDocument() MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) EndObservingDocument() MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsresult) Initialize(nscoord aWidth, nscoord aHeight) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsresult) ResizeReflow(nscoord aWidth, nscoord aHeight) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsresult) ResizeReflowOverride(nscoord aWidth, nscoord aHeight) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsIPageSequenceFrame*) GetPageSequenceFrame() const MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsIFrame*) GetRealPrimaryFrameFor(nsIContent* aContent) const MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(nsIFrame*) GetPlaceholderFrameFor(nsIFrame* aFrame) const;
+  virtual NS_HIDDEN_(nsIFrame*) GetPlaceholderFrameFor(nsIFrame* aFrame) const MOZ_OVERRIDE;
   virtual NS_HIDDEN_(void) FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
-                                            nsFrameState aBitToAdd);
-  virtual NS_HIDDEN_(void) FrameNeedsToContinueReflow(nsIFrame *aFrame);
-  virtual NS_HIDDEN_(void) CancelAllPendingReflows();
-  virtual NS_HIDDEN_(bool) IsSafeToFlush() const;
-  virtual NS_HIDDEN_(void) FlushPendingNotifications(mozFlushType aType);
-  virtual NS_HIDDEN_(void) FlushPendingNotifications(mozilla::ChangesToFlush aType);
+                                            nsFrameState aBitToAdd) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) FrameNeedsToContinueReflow(nsIFrame *aFrame) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) CancelAllPendingReflows() MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(bool) IsSafeToFlush() const MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) FlushPendingNotifications(mozFlushType aType) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) FlushPendingNotifications(mozilla::ChangesToFlush aType) MOZ_OVERRIDE;
 
   /**
    * Recreates the frames for a node
    */
-  virtual NS_HIDDEN_(nsresult) RecreateFramesFor(nsIContent* aContent);
+  virtual NS_HIDDEN_(nsresult) RecreateFramesFor(nsIContent* aContent) MOZ_OVERRIDE;
 
   /**
    * Post a callback that should be handled after reflow has finished.
    */
-  virtual NS_HIDDEN_(nsresult) PostReflowCallback(nsIReflowCallback* aCallback);
-  virtual NS_HIDDEN_(void) CancelReflowCallback(nsIReflowCallback* aCallback);
+  virtual NS_HIDDEN_(nsresult) PostReflowCallback(nsIReflowCallback* aCallback) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) CancelReflowCallback(nsIReflowCallback* aCallback) MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(void) ClearFrameRefs(nsIFrame* aFrame);
+  virtual NS_HIDDEN_(void) ClearFrameRefs(nsIFrame* aFrame) MOZ_OVERRIDE;
   virtual NS_HIDDEN_(already_AddRefed<nsRenderingContext>) GetReferenceRenderingContext();
-  virtual NS_HIDDEN_(nsresult) GoToAnchor(const nsAString& aAnchorName, bool aScroll);
-  virtual NS_HIDDEN_(nsresult) ScrollToAnchor();
+  virtual NS_HIDDEN_(nsresult) GoToAnchor(const nsAString& aAnchorName, bool aScroll) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsresult) ScrollToAnchor() MOZ_OVERRIDE;
 
   virtual NS_HIDDEN_(nsresult) ScrollContentIntoView(nsIContent* aContent,
                                                      ScrollAxis  aVertical,
                                                      ScrollAxis  aHorizontal,
-                                                     uint32_t    aFlags);
+                                                     uint32_t    aFlags) MOZ_OVERRIDE;
   virtual bool ScrollFrameRectIntoView(nsIFrame*     aFrame,
                                        const nsRect& aRect,
                                        ScrollAxis    aVertical,
                                        ScrollAxis    aHorizontal,
-                                       uint32_t      aFlags);
+                                       uint32_t      aFlags) MOZ_OVERRIDE;
   virtual nsRectVisibility GetRectVisibility(nsIFrame *aFrame,
                                              const nsRect &aRect,
-                                             nscoord aMinTwips) const;
+                                             nscoord aMinTwips) const MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(void) SetIgnoreFrameDestruction(bool aIgnore);
-  virtual NS_HIDDEN_(void) NotifyDestroyingFrame(nsIFrame* aFrame);
+  virtual NS_HIDDEN_(void) SetIgnoreFrameDestruction(bool aIgnore) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) NotifyDestroyingFrame(nsIFrame* aFrame) MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(nsresult) CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
+  virtual NS_HIDDEN_(nsresult) CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(void) UnsuppressPainting();
+  virtual NS_HIDDEN_(void) UnsuppressPainting() MOZ_OVERRIDE;
 
-  virtual nsresult GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets);
-  virtual nsresult SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets);
+  virtual nsresult GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets) MOZ_OVERRIDE;
+  virtual nsresult SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets) MOZ_OVERRIDE;
 
-  virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet);
-  virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet);
+  virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet) MOZ_OVERRIDE;
+  virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet) MOZ_OVERRIDE;
 
   virtual NS_HIDDEN_(nsresult) HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame,
                                                      nsIContent* aContent,
-                                                     nsEventStatus* aStatus);
-  virtual NS_HIDDEN_(nsIFrame*) GetEventTargetFrame();
-  virtual NS_HIDDEN_(already_AddRefed<nsIContent>) GetEventTargetContent(nsEvent* aEvent);
+                                                     nsEventStatus* aStatus) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(nsIFrame*) GetEventTargetFrame() MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(already_AddRefed<nsIContent>) GetEventTargetContent(nsEvent* aEvent) MOZ_OVERRIDE;
 
 
   virtual nsresult ReconstructFrames(void);
-  virtual void Freeze();
-  virtual void Thaw();
-  virtual void FireOrClearDelayedEvents(bool aFireEvents);
+  virtual void Freeze() MOZ_OVERRIDE;
+  virtual void Thaw() MOZ_OVERRIDE;
+  virtual void FireOrClearDelayedEvents(bool aFireEvents) MOZ_OVERRIDE;
 
   virtual NS_HIDDEN_(nsresult) RenderDocument(const nsRect& aRect, uint32_t aFlags,
                                               nscolor aBackgroundColor,
-                                              gfxContext* aThebesContext);
+                                              gfxContext* aThebesContext) MOZ_OVERRIDE;
 
   virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode,
                                                    nsIntRegion* aRegion,
                                                    nsIntPoint& aPoint,
-                                                   nsIntRect* aScreenRect);
+                                                   nsIntRect* aScreenRect) MOZ_OVERRIDE;
 
   virtual already_AddRefed<gfxASurface> RenderSelection(nsISelection* aSelection,
                                                         nsIntPoint& aPoint,
-                                                        nsIntRect* aScreenRect);
+                                                        nsIntRect* aScreenRect) MOZ_OVERRIDE;
 
-  virtual already_AddRefed<nsPIDOMWindow> GetRootWindow();
+  virtual already_AddRefed<nsPIDOMWindow> GetRootWindow() MOZ_OVERRIDE;
 
-  virtual LayerManager* GetLayerManager();
+  virtual LayerManager* GetLayerManager() MOZ_OVERRIDE;
 
-  virtual void SetIgnoreViewportScrolling(bool aIgnore);
+  virtual void SetIgnoreViewportScrolling(bool aIgnore) MOZ_OVERRIDE;
 
   virtual void SetDisplayPort(const nsRect& aDisplayPort);
 
-  virtual nsresult SetResolution(float aXResolution, float aYResolution);
+  virtual nsresult SetResolution(float aXResolution, float aYResolution) MOZ_OVERRIDE;
 
   //nsIViewObserver interface
 
   virtual void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
-                     uint32_t aFlags);
+                     uint32_t aFlags) MOZ_OVERRIDE;
   virtual nsresult HandleEvent(nsIFrame*       aFrame,
                                nsGUIEvent*     aEvent,
                                bool            aDontRetargetEvents,
-                               nsEventStatus*  aEventStatus);
+                               nsEventStatus*  aEventStatus) MOZ_OVERRIDE;
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsEvent* aEvent,
-                                                        nsEventStatus* aStatus);
+                                                        nsEventStatus* aStatus) MOZ_OVERRIDE;
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsIDOMEvent* aEvent,
-                                                        nsEventStatus* aStatus);
-  virtual bool ShouldIgnoreInvalidation();
-  virtual void WillPaint();
-  virtual void WillPaintWindow();
-  virtual void DidPaintWindow();
-  virtual void ScheduleViewManagerFlush();
-  virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange);
-  virtual void ClearMouseCaptureOnView(nsView* aView);
-  virtual bool IsVisible();
+                                                        nsEventStatus* aStatus) MOZ_OVERRIDE;
+  virtual bool ShouldIgnoreInvalidation() MOZ_OVERRIDE;
+  virtual void WillPaint() MOZ_OVERRIDE;
+  virtual void WillPaintWindow() MOZ_OVERRIDE;
+  virtual void DidPaintWindow() MOZ_OVERRIDE;
+  virtual void ScheduleViewManagerFlush() MOZ_OVERRIDE;
+  virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) MOZ_OVERRIDE;
+  virtual void ClearMouseCaptureOnView(nsView* aView) MOZ_OVERRIDE;
+  virtual bool IsVisible() MOZ_OVERRIDE;
 
   // caret handling
-  virtual NS_HIDDEN_(already_AddRefed<nsCaret>) GetCaret() const;
-  virtual NS_HIDDEN_(void) MaybeInvalidateCaretPosition();
+  virtual NS_HIDDEN_(already_AddRefed<nsCaret>) GetCaret() const MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) MaybeInvalidateCaretPosition() MOZ_OVERRIDE;
   NS_IMETHOD SetCaretEnabled(bool aInEnable);
   NS_IMETHOD SetCaretReadOnly(bool aReadOnly);
   NS_IMETHOD GetCaretEnabled(bool *aOutEnabled);
   NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility);
   NS_IMETHOD GetCaretVisible(bool *_retval);
-  virtual void SetCaret(nsCaret *aNewCaret);
-  virtual void RestoreCaret();
+  virtual void SetCaret(nsCaret *aNewCaret) MOZ_OVERRIDE;
+  virtual void RestoreCaret() MOZ_OVERRIDE;
 
-  NS_IMETHOD SetSelectionFlags(int16_t aInEnable);
+  NS_IMETHOD SetSelectionFlags(int16_t aInEnable) MOZ_OVERRIDE;
   NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable);
 
   // nsISelectionController
 
   NS_IMETHOD CharacterMove(bool aForward, bool aExtend);
   NS_IMETHOD CharacterExtendForDelete();
   NS_IMETHOD CharacterExtendForBackspace();
   NS_IMETHOD WordMove(bool aForward, bool aExtend);
@@ -256,91 +256,91 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   NS_DECL_NSIOBSERVER
 
 #ifdef MOZ_REFLOW_PERF
   virtual NS_HIDDEN_(void) DumpReflows();
-  virtual NS_HIDDEN_(void) CountReflows(const char * aName, nsIFrame * aFrame);
+  virtual NS_HIDDEN_(void) CountReflows(const char * aName, nsIFrame * aFrame) MOZ_OVERRIDE;
   virtual NS_HIDDEN_(void) PaintCount(const char * aName,
                                       nsRenderingContext* aRenderingContext,
                                       nsPresContext* aPresContext,
                                       nsIFrame * aFrame,
                                       const nsPoint& aOffset,
-                                      uint32_t aColor);
-  virtual NS_HIDDEN_(void) SetPaintFrameCount(bool aOn);
-  virtual bool IsPaintingFrameCounts();
+                                      uint32_t aColor) MOZ_OVERRIDE;
+  virtual NS_HIDDEN_(void) SetPaintFrameCount(bool aOn) MOZ_OVERRIDE;
+  virtual bool IsPaintingFrameCounts() MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG
   virtual void ListStyleContexts(nsIFrame *aRootFrame, FILE *out,
-                                 int32_t aIndent = 0);
+                                 int32_t aIndent = 0) MOZ_OVERRIDE;
 
-  virtual void ListStyleSheets(FILE *out, int32_t aIndent = 0);
-  virtual void VerifyStyleTree();
+  virtual void ListStyleSheets(FILE *out, int32_t aIndent = 0) MOZ_OVERRIDE;
+  virtual void VerifyStyleTree() MOZ_OVERRIDE;
 #endif
 
 #ifdef PR_LOGGING
   static PRLogModuleInfo* gLog;
 #endif
 
-  virtual NS_HIDDEN_(void) DisableNonTestMouseEvents(bool aDisable);
+  virtual NS_HIDDEN_(void) DisableNonTestMouseEvents(bool aDisable) MOZ_OVERRIDE;
 
-  virtual void UpdateCanvasBackground();
+  virtual void UpdateCanvasBackground() MOZ_OVERRIDE;
 
   virtual void AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
                                             nsDisplayList& aList,
                                             nsIFrame* aFrame,
                                             const nsRect& aBounds,
                                             nscolor aBackstopColor,
-                                            uint32_t aFlags);
+                                            uint32_t aFlags) MOZ_OVERRIDE;
 
   virtual void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
                                              nsDisplayList& aList,
                                              nsIFrame* aFrame,
-                                             const nsRect& aBounds);
+                                             const nsRect& aBounds) MOZ_OVERRIDE;
 
-  virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot);
+  virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) MOZ_OVERRIDE;
 
-  virtual NS_HIDDEN_(nsresult) SetIsActive(bool aIsActive);
+  virtual NS_HIDDEN_(nsresult) SetIsActive(bool aIsActive) MOZ_OVERRIDE;
 
-  virtual bool GetIsViewportOverridden() { return mViewportOverridden; }
+  virtual bool GetIsViewportOverridden() MOZ_OVERRIDE { return mViewportOverridden; }
 
-  virtual bool IsLayoutFlushObserver()
+  virtual bool IsLayoutFlushObserver() MOZ_OVERRIDE
   {
     return GetPresContext()->RefreshDriver()->
       IsLayoutFlushObserver(this);
   }
 
   void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                            nsArenaMemoryStats *aArenaObjectsSize,
                            size_t *aPresShellSize,
                            size_t *aStyleSetsSize,
                            size_t *aTextRunsSize,
-                           size_t *aPresContextSize);
+                           size_t *aPresContextSize) MOZ_OVERRIDE;
   size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
 
-  virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver);
+  virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) MOZ_OVERRIDE;
 
 
   // This data is stored as a content property (nsGkAtoms::scrolling) on
   // mContentToScrollTo when we have a pending ScrollIntoView.
   struct ScrollIntoViewData {
     ScrollAxis mContentScrollVAxis;
     ScrollAxis mContentScrollHAxis;
     uint32_t   mContentToScrollToFlags;
   };
 
-  virtual void ScheduleImageVisibilityUpdate();
+  virtual void ScheduleImageVisibilityUpdate() MOZ_OVERRIDE;
 
-  virtual void RebuildImageVisibility(const nsDisplayList& aList);
+  virtual void RebuildImageVisibility(const nsDisplayList& aList) MOZ_OVERRIDE;
 
-  virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage);
+  virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) MOZ_OVERRIDE;
 
 protected:
   virtual ~PresShell();
 
   void HandlePostedReflowCallbacks(bool aInterruptible);
   void CancelPostedReflowCallbacks();
 
   void UnsuppressAndInvalidate();
@@ -354,17 +354,25 @@ protected:
 
   bool TouchesAreEqual(nsIDOMTouch *aTouch1, nsIDOMTouch *aTouch2);
   void DispatchTouchEvent(nsEvent *aEvent,
                           nsEventStatus* aStatus,
                           nsPresShellEventCB* aEventCB,
                           bool aTouchIsNew);
 
   void     WillDoReflow();
-  void     DidDoReflow(bool aInterruptible);
+
+  /**
+   * Callback handler for whether reflow happened.
+   *
+   * @param aInterruptible Whether or not reflow interruption is allowed.
+   * @param aWasInterrupted Whether or not the reflow was interrupted earlier.
+   *
+   */
+  void     DidDoReflow(bool aInterruptible, bool aWasInterrupted);
   // ProcessReflowCommands returns whether we processed all our dirty roots
   // without interruptions.
   bool     ProcessReflowCommands(bool aInterruptible);
   // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
   // the last reflow was interrupted. In the interrupted case ScheduleReflow is
   // called off a timer, otherwise it is called directly.
   void     MaybeScheduleReflow();
   // Actually schedules a reflow.  This should only be called by
@@ -682,34 +690,34 @@ protected:
                                            nsIContent **aTargetToUse,
                                            nsIntPoint& aTargetPt,
                                            nsIWidget *aRootWidget);
 
   void FireResizeEvent();
   void FireBeforeResizeEvent();
   static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);
 
-  virtual void SynthesizeMouseMove(bool aFromScroll);
+  virtual void SynthesizeMouseMove(bool aFromScroll) MOZ_OVERRIDE;
 
   PresShell* GetRootPresShell();
 
   nscolor GetDefaultBackgroundColorToDraw();
 
   // The callback for the mPaintSuppressionTimer timer.
   static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);
 
   // The callback for the mReflowContinueTimer timer.
   static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
   bool ScheduleReflowOffTimer();
 
   // Widget notificiations
-  virtual void WindowSizeMoveDone();
-  virtual void SysColorChanged() { mPresContext->SysColorChanged(); }
-  virtual void ThemeChanged() { mPresContext->ThemeChanged(); }
-  virtual void BackingScaleFactorChanged() { mPresContext->UIResolutionChanged(); }
+  virtual void WindowSizeMoveDone() MOZ_OVERRIDE;
+  virtual void SysColorChanged() MOZ_OVERRIDE { mPresContext->SysColorChanged(); }
+  virtual void ThemeChanged() MOZ_OVERRIDE { mPresContext->ThemeChanged(); }
+  virtual void BackingScaleFactorChanged() MOZ_OVERRIDE { mPresContext->UIResolutionChanged(); }
 
   void UpdateImageVisibility();
 
   nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;
 
   void ClearVisibleImagesList();
   static void ClearImageVisibilityVisited(nsView* aView, bool aClear);
   static void MarkImagesInListVisible(const nsDisplayList& aList);
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -54,17 +54,17 @@ public:
 
   nsComboboxControlFrame(nsStyleContext* aContext);
   ~nsComboboxControlFrame();
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
-  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
+  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
@@ -118,20 +118,20 @@ public:
   /**
    * Inform the control that it got (or lost) focus.
    * If it lost focus, the dropdown menu will be rolled up if needed,
    * and FireOnChange() will be called.
    * @param aOn true if got focus, false if lost focus.
    * @param aRepaint if true then force repaint (NOTE: we always force repaint currently)
    * @note This method might destroy |this|.
    */
-  virtual void SetFocus(bool aOn, bool aRepaint);
+  virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE;
 
   //nsIComboboxControlFrame
-  virtual bool IsDroppedDown() { return mDroppedDown; }
+  virtual bool IsDroppedDown() MOZ_OVERRIDE { return mDroppedDown; }
   /**
    * @note This method might destroy |this|.
    */
   virtual void ShowDropDown(bool aDoDropDown) MOZ_OVERRIDE;
   virtual nsIFrame* GetDropDown() MOZ_OVERRIDE;
   virtual void SetDropDown(nsIFrame* aDropDownFrame) MOZ_OVERRIDE;
   /**
    * @note This method might destroy |this|.
@@ -151,17 +151,17 @@ public:
   /**
    * @note This method might destroy |this|.
    */
   NS_IMETHOD RedisplaySelectedText() MOZ_OVERRIDE;
   virtual int32_t UpdateRecentIndex(int32_t aIndex) MOZ_OVERRIDE;
   virtual void OnContentReset() MOZ_OVERRIDE;
 
   // nsISelectControlFrame
-  NS_IMETHOD AddOption(int32_t index);
+  NS_IMETHOD AddOption(int32_t index) MOZ_OVERRIDE;
   NS_IMETHOD RemoveOption(int32_t index) MOZ_OVERRIDE;
   NS_IMETHOD DoneAddingChildren(bool aIsDone) MOZ_OVERRIDE;
   NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) MOZ_OVERRIDE;
   NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE;
 
   //nsIRollupListener
   /**
    * Hide the dropdown menu and stop capturing mouse events.
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -30,18 +30,18 @@ public:
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIFormControlFrame
-  virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
-  virtual void SetFocus(bool aOn, bool aRepaint);
+  virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
+  virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE;
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
--- a/layout/forms/nsFormControlFrame.h
+++ b/layout/forms/nsFormControlFrame.h
@@ -21,19 +21,19 @@ class nsFormControlFrame : public nsLeaf
 public:
   /**
     * Main constructor
     * @param aContent the content representing this frame
     * @param aParentFrame the parent frame
     */
   nsFormControlFrame(nsStyleContext*);
 
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsLeafFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
@@ -51,21 +51,21 @@ public:
     * Respond to the request to resize and/or reflow
     * @see nsIFrame::Reflow
     */
   NS_IMETHOD Reflow(nsPresContext*      aCX,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   // new behavior
 
-  virtual void SetFocus(bool aOn = true, bool aRepaint = false);
+  virtual void SetFocus(bool aOn = true, bool aRepaint = false) MOZ_OVERRIDE;
 
   // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
 
   // AccessKey Helper function
   static nsresult RegUnRegAccessKey(nsIFrame * aFrame, bool aDoReg);
 
   /**
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -26,35 +26,35 @@ public:
   nsGfxButtonControlFrame(nsStyleContext* aContext);
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
                          nsGUIEvent* aEvent,
                          nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   NS_DECL_QUERYFRAME
 
   // nsIAnonymousContentCreator
-  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
+  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t         aNameSpaceID,
                               nsIAtom*        aAttribute,
-                              int32_t         aModType);
+                              int32_t         aModType) MOZ_OVERRIDE;
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
 
   virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
 
 protected:
   nsresult GetDefaultLabel(nsXPIDLString& aLabel) const;
 
   nsresult GetLabel(nsXPIDLString& aLabel);
 
--- a/layout/forms/nsHTMLButtonControlFrame.h
+++ b/layout/forms/nsHTMLButtonControlFrame.h
@@ -51,17 +51,17 @@ public:
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
                          nsGUIEvent* aEvent,
                          nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        asPrevInFlow) MOZ_OVERRIDE;
 
-  virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const;
+  virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
   virtual void SetAdditionalStyleContext(int32_t aIndex, 
                                          nsStyleContext* aStyleContext) MOZ_OVERRIDE;
  
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
@@ -77,28 +77,28 @@ public:
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("HTMLButtonControl"), aResult);
   }
 #endif
 
-  virtual bool HonorPrintBackgroundSettings() { return false; }
+  virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE { return false; }
 
   // nsIFormControlFrame
-  void SetFocus(bool aOn, bool aRepaint);
+  void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE;
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
 
   // Inserted child content gets its frames parented by our child block
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
 protected:
   virtual bool IsInput() { return false; }
   void ReflowButtonContents(nsPresContext* aPresContext,
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -46,17 +46,17 @@ public:
   friend nsIFrame* NS_NewListControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
     // nsIFrame
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
                          nsGUIEvent* aEvent,
-                         nsEventStatus* aEventStatus);
+                         nsEventStatus* aEventStatus) MOZ_OVERRIDE;
   
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*          aCX,
@@ -65,56 +65,56 @@ public:
                     nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
   NS_IMETHOD DidReflow(nsPresContext*           aPresContext, 
                        const nsHTMLReflowState*  aReflowState, 
-                       nsDidReflowStatus         aStatus);
+                       nsDidReflowStatus         aStatus) MOZ_OVERRIDE;
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame();
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::scrollFrame
    */
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsHTMLScrollFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
     // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
-  virtual void SetFocus(bool aOn = true, bool aRepaint = false);
+  virtual void SetFocus(bool aOn = true, bool aRepaint = false) MOZ_OVERRIDE;
 
   virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE;
   virtual bool ShouldPropagateComputedHeightToScrolledContent() const MOZ_OVERRIDE;
 
     // for accessibility purposes
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
     // nsIListControlFrame
-  virtual void SetComboboxFrame(nsIFrame* aComboboxFrame);
+  virtual void SetComboboxFrame(nsIFrame* aComboboxFrame) MOZ_OVERRIDE;
   virtual int32_t GetSelectedIndex() MOZ_OVERRIDE;
   virtual already_AddRefed<nsIContent> GetCurrentOption() MOZ_OVERRIDE;
 
   /**
    * Gets the text of the currently selected item.
    * If the there are zero items then an empty string is returned
    * If there is nothing selected, then the 0th item's text is returned.
    */
@@ -139,17 +139,17 @@ public:
   /**
    * Makes aIndex the selected option of a combobox list.
    * @note This method might destroy |this|.
    */
   virtual void ComboboxFinish(int32_t aIndex) MOZ_OVERRIDE;
   virtual void OnContentReset() MOZ_OVERRIDE;
 
   // nsISelectControlFrame
-  NS_IMETHOD AddOption(int32_t index);
+  NS_IMETHOD AddOption(int32_t index) MOZ_OVERRIDE;
   NS_IMETHOD RemoveOption(int32_t index) MOZ_OVERRIDE;
   NS_IMETHOD DoneAddingChildren(bool aIsDone) MOZ_OVERRIDE;
 
   /**
    * Gets the content (an option) by index and then set it as
    * being selected or not selected.
    */
   NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) MOZ_OVERRIDE;
@@ -233,17 +233,17 @@ public:
    * Return true if the drop-down list can display more rows.
    * (always false if not in drop-down mode)
    */
   bool GetDropdownCanGrow() const { return mDropdownCanGrow; }
 
   /**
    * Dropdowns need views
    */
-  virtual bool NeedsView() { return IsInDropDownMode(); }
+  virtual bool NeedsView() MOZ_OVERRIDE { return IsInDropDownMode(); }
 
   /**
    * Frees statics owned by this class.
    */
   static void Shutdown();
 
 #ifdef ACCESSIBILITY
   /**
--- a/layout/forms/nsMeterFrame.h
+++ b/layout/forms/nsMeterFrame.h
@@ -23,44 +23,44 @@ public:
   nsMeterFrame(nsStyleContext* aContext);
   virtual ~nsMeterFrame();
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*           aCX,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const {
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("Meter"), aResult);
   }
 #endif
 
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t  aNameSpaceID,
                               nsIAtom* aAttribute,
-                              int32_t  aModType);
+                              int32_t  aModType) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   /**
    * Returns whether the frame and its child should use the native style.
    */
--- a/layout/forms/nsProgressFrame.h
+++ b/layout/forms/nsProgressFrame.h
@@ -28,44 +28,44 @@ public:
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*           aCX,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const {
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("Progress"), aResult);
   }
 #endif
 
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t  aNameSpaceID,
                               nsIAtom* aAttribute,
-                              int32_t  aModType);
+                              int32_t  aModType) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   /**
    * Returns whether the frame and its child should use the native style.
    */
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -39,53 +39,53 @@ public:
 
   NS_DECLARE_FRAME_PROPERTY(ContentScrollPos, DestroyPoint)
 
   nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aContext);
   virtual ~nsTextControlFrame();
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
-  virtual nsIScrollableFrame* GetScrollTargetFrame() {
+  virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE {
     if (!IsScrollable())
       return nullptr;
     return do_QueryFrame(GetFirstPrincipalChild());
   }
 
-  virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual bool IsCollapsed();
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual bool IsCollapsed() MOZ_OVERRIDE;
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
   
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     aResult.AssignLiteral("nsTextControlFrame");
     return NS_OK;
   }
 #endif
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // nsStackFrame is already both of these, but that's somewhat bogus,
     // and we really mean it.
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   // nsIAnonymousContentCreator
@@ -98,18 +98,18 @@ public:
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
 //==== BEGIN NSIFORMCONTROLFRAME
-  virtual void SetFocus(bool aOn , bool aRepaint); 
-  virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
+  virtual void SetFocus(bool aOn , bool aRepaint) MOZ_OVERRIDE; 
+  virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
 
 //==== END NSIFORMCONTROLFRAME
 
 //==== NSITEXTCONTROLFRAME
 
   NS_IMETHOD    GetEditor(nsIEditor **aEditor) MOZ_OVERRIDE;
   NS_IMETHOD    SetSelectionStart(int32_t aSelectionStart) MOZ_OVERRIDE;
   NS_IMETHOD    SetSelectionEnd(int32_t aSelectionEnd) MOZ_OVERRIDE;
@@ -136,26 +136,26 @@ public:
 //==== NSISTATEFULFRAME
 
   NS_IMETHOD SaveState(nsPresState** aState) MOZ_OVERRIDE;
   NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE;
 
 //=== END NSISTATEFULFRAME
 
 //==== OVERLOAD of nsIFrame
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   /** handler for attribute changes to mContent */
   NS_IMETHOD AttributeChanged(int32_t         aNameSpaceID,
                               nsIAtom*        aAttribute,
-                              int32_t         aModType);
+                              int32_t         aModType) MOZ_OVERRIDE;
 
   nsresult GetText(nsString& aText);
 
-  NS_IMETHOD PeekOffset(nsPeekOffsetStruct *aPos);
+  NS_IMETHOD PeekOffset(nsPeekOffsetStruct *aPos) MOZ_OVERRIDE;
 
   NS_DECL_QUERYFRAME
 
   // Temp reference to scriptrunner
   // We could make these auto-Revoking via the "delete" entry for safety
   NS_DECLARE_FRAME_PROPERTY(TextControlInitializer, nullptr)
 
 protected:
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -49,17 +49,17 @@ public:
     : nsFrame(aContext)
   {
   }
   virtual ~nsBulletFrame();
 
   NS_IMETHOD Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
 
   // nsIFrame
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -34,17 +34,17 @@ public:
     mDoPaintFocus(false),
     mAddedScrollPositionListener(false) {}
 
   NS_DECL_QUERYFRAME_TARGET(nsCanvasFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
@@ -52,17 +52,17 @@ public:
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus) MOZ_OVERRIDE;
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
              ~(nsIFrame::eCanContainOverflowContainers));
   }
 
   /** SetHasFocus tells the CanvasFrame to draw with focus ring
    *  @param aHasFocus true to show focus ring, false to hide it
    */
@@ -70,18 +70,18 @@ public:
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt);
 
   // nsIScrollPositionListener
-  virtual void ScrollPositionWillChange(nscoord aX, nscoord aY);
-  virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) {}
+  virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) MOZ_OVERRIDE;
+  virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) MOZ_OVERRIDE {}
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::canvasFrame
    */
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
@@ -162,17 +162,17 @@ public:
 
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayItemBoundsGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion)
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
   }
 
   virtual void NotifyRenderingChanged() MOZ_OVERRIDE
   {
     mFrame->Properties().Delete(nsIFrame::CachedBackgroundImage());
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; 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/. */
 
 /* rendering object for css3 multi-column layout */
 
+#include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsISupports.h"
 #include "nsIAtom.h"
 #include "nsPresContext.h"
 #include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
@@ -22,69 +23,69 @@
 
 class nsColumnSetFrame : public nsContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsColumnSetFrame(nsStyleContext* aContext);
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
-                                 nsFrameList&    aChildList);
+                                 nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext* aPresContext,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus& aStatus);
+                    nsReflowStatus& aStatus) MOZ_OVERRIDE;
 
   NS_IMETHOD  AppendFrames(ChildListID     aListID,
-                           nsFrameList&    aFrameList);
+                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD  InsertFrames(ChildListID     aListID,
                            nsIFrame*       aPrevFrame,
-                           nsFrameList&    aFrameList);
+                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
-                          nsIFrame*       aOldFrame);
+                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     nsIFrame* frame = GetFirstPrincipalChild();
 
     // if no children return nullptr
     if (!frame)
       return nullptr;
 
     return frame->GetContentInsertionFrame();
   }
 
   virtual nsresult StealFrame(nsPresContext* aPresContext,
                               nsIFrame*      aChild,
-                              bool           aForceNormal)
+                              bool           aForceNormal) MOZ_OVERRIDE
   { // nsColumnSetFrame keeps overflow containers in main child list
     return nsContainerFrame::StealFrame(aPresContext, aChild, true);
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
    {
      return nsContainerFrame::IsFrameOfType(aFlags &
               ~(nsIFrame::eCanContainOverflowContainers));
    }
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual void PaintColumnRule(nsRenderingContext* aCtx,
                                const nsRect&        aDirtyRect,
                                const nsPoint&       aPt);
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const {
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
   }
 #endif
 
 protected:
   nscoord        mLastBalanceHeight;
   nsReflowStatus mLastFrameStatus;
 
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -53,29 +53,29 @@ public:
 
   // nsIFrame overrides
   virtual void Init(nsIContent* aContent,
                     nsIFrame*   aParent,
                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
   NS_IMETHOD SetInitialChildList(ChildListID  aListID,
                                  nsFrameList& aChildList) MOZ_OVERRIDE;
   NS_IMETHOD AppendFrames(ChildListID  aListID,
-                          nsFrameList& aFrameList);
+                          nsFrameList& aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD InsertFrames(ChildListID aListID,
                           nsIFrame* aPrevFrame,
-                          nsFrameList& aFrameList);
+                          nsFrameList& aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD RemoveFrame(ChildListID aListID,
                          nsIFrame* aOldFrame) MOZ_OVERRIDE;
 
   virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
   virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) MOZ_OVERRIDE;
   
 #ifdef DEBUG
   void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
 #endif  
 
@@ -304,17 +304,17 @@ public:
                                            nsOverflowAreas&         aOverflowRects,
                                            uint32_t                 aFlags,
                                            nsReflowStatus&          aStatus);
 
   /**
    * Move any frames on our overflow list to the end of our principal list.
    * @return true if there were any overflow frames
    */
-  virtual bool DrainSelfOverflowList();
+  virtual bool DrainSelfOverflowList() MOZ_OVERRIDE;
 
   /**
    * Removes aChild without destroying it and without requesting reflow.
    * Continuations are not affected. Checks the primary and overflow
    * or overflow containers and excess overflow containers lists, depending
    * on whether the NS_FRAME_IS_OVERFLOW_CONTAINER flag is set. Does not
    * check any other auxiliary lists.
    * Returns NS_ERROR_UNEXPECTED if we failed to remove aChild.
--- a/layout/generic/nsFirstLetterFrame.h
+++ b/layout/generic/nsFirstLetterFrame.h
@@ -30,17 +30,17 @@ public:
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   bool IsFloating() const { return GetStateBits() & NS_FRAME_OUT_OF_FLOW; }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     if (!IsFloating())
       aFlags = aFlags & ~(nsIFrame::eLineParticipant);
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eBidiInlineContainer));
   }
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -141,130 +141,130 @@ public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIFrame
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        asPrevInFlow) MOZ_OVERRIDE;
   NS_IMETHOD  SetInitialChildList(ChildListID        aListID,
-                                  nsFrameList&       aChildList);
+                                  nsFrameList&       aChildList) MOZ_OVERRIDE;
   NS_IMETHOD  AppendFrames(ChildListID     aListID,
-                           nsFrameList&    aFrameList);
+                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD  InsertFrames(ChildListID     aListID,
                            nsIFrame*       aPrevFrame,
-                           nsFrameList&    aFrameList);
+                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
-                          nsIFrame*       aOldFrame);
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
-  virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const;
+                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
+  virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
   virtual void SetAdditionalStyleContext(int32_t aIndex,
-                                         nsStyleContext* aStyleContext);
-  virtual void SetParent(nsIFrame* aParent);
+                                         nsStyleContext* aStyleContext) MOZ_OVERRIDE;
+  virtual void SetParent(nsIFrame* aParent) MOZ_OVERRIDE;
   virtual nscoord GetBaseline() const MOZ_OVERRIDE;
-  virtual const nsFrameList& GetChildList(ChildListID aListID) const;
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
+  virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
+  virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
 
   NS_IMETHOD  HandleEvent(nsPresContext* aPresContext, 
                           nsGUIEvent*     aEvent,
-                          nsEventStatus*  aEventStatus);
+                          nsEventStatus*  aEventStatus) MOZ_OVERRIDE;
   NS_IMETHOD  GetContentForEvent(nsEvent* aEvent,
-                                 nsIContent** aContent);
+                                 nsIContent** aContent) MOZ_OVERRIDE;
   NS_IMETHOD  GetCursor(const nsPoint&    aPoint,
                         nsIFrame::Cursor& aCursor);
 
   NS_IMETHOD  GetPointFromOffset(int32_t                inOffset,
-                                 nsPoint*               outPoint);
+                                 nsPoint*               outPoint) MOZ_OVERRIDE;
 
   NS_IMETHOD  GetChildFrameContainingOffset(int32_t     inContentOffset,
                                  bool                   inHint,
                                  int32_t*               outFrameContentOffset,
-                                 nsIFrame*              *outChildFrame);
+                                 nsIFrame*              *outChildFrame) MOZ_OVERRIDE;
 
   static nsresult  GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
                                         nsPeekOffsetStruct *aPos, 
                                         nsIFrame *aBlockFrame, 
                                         int32_t aLineStart, 
                                         int8_t aOutSideLimit
                                         );
 
-  NS_IMETHOD  CharacterDataChanged(CharacterDataChangeInfo* aInfo);
+  NS_IMETHOD  CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
   NS_IMETHOD  AttributeChanged(int32_t         aNameSpaceID,
                                nsIAtom*        aAttribute,
-                               int32_t         aModType);
-  virtual nsSplittableType GetSplittableType() const;
-  virtual nsIFrame* GetPrevContinuation() const;
-  NS_IMETHOD  SetPrevContinuation(nsIFrame*);
-  virtual nsIFrame* GetNextContinuation() const;
-  NS_IMETHOD  SetNextContinuation(nsIFrame*);
-  virtual nsIFrame* GetPrevInFlowVirtual() const;
-  NS_IMETHOD  SetPrevInFlow(nsIFrame*);
-  virtual nsIFrame* GetNextInFlowVirtual() const;
-  NS_IMETHOD  SetNextInFlow(nsIFrame*);
-  NS_IMETHOD  GetOffsetFromView(nsPoint& aOffset, nsView** aView) const;
-  virtual nsIAtom* GetType() const;
+                               int32_t         aModType) MOZ_OVERRIDE;
+  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
+  virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE;
+  NS_IMETHOD  SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE;
+  virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE;
+  NS_IMETHOD  SetNextContinuation(nsIFrame*) MOZ_OVERRIDE;
+  virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE;
+  NS_IMETHOD  SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE;
+  virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE;
+  NS_IMETHOD  SetNextInFlow(nsIFrame*) MOZ_OVERRIDE;
+  NS_IMETHOD  GetOffsetFromView(nsPoint& aOffset, nsView** aView) const MOZ_OVERRIDE;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  NS_IMETHOD  IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const;
+  NS_IMETHOD  IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const MOZ_OVERRIDE;
 
-  NS_IMETHOD  GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon);
+  NS_IMETHOD  GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) MOZ_OVERRIDE;
 
-  virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset);
+  virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset,
-                                     bool aRespectClusters = true);
+                                     bool aRespectClusters = true) MOZ_OVERRIDE;
   virtual bool PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
-                                int32_t* aOffset, PeekWordState *aState);
+                                int32_t* aOffset, PeekWordState *aState) MOZ_OVERRIDE;
   /**
    * Check whether we should break at a boundary between punctuation and
    * non-punctuation. Only call it at a punctuation boundary
    * (i.e. exactly one of the previous and next characters are punctuation).
    * @param aForward true if we're moving forward in content order
    * @param aPunctAfter true if the next character is punctuation
    * @param aWhitespaceAfter true if the next character is whitespace
    */
   bool BreakWordBetweenPunctuation(const PeekWordState* aState,
                                      bool aForward,
                                      bool aPunctAfter, bool aWhitespaceAfter,
                                      bool aIsKeyboardSelect);
 
-  NS_IMETHOD  CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval);
+  NS_IMETHOD  CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
 
-  NS_IMETHOD  GetOffsets(int32_t &aStart, int32_t &aEnd) const;
-  virtual void ChildIsDirty(nsIFrame* aChild);
+  NS_IMETHOD  GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
+  virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
-  virtual nsIFrame* GetParentStyleContextFrame() const {
+  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE {
     return DoGetParentStyleContextFrame();
   }
 
   /**
    * Do the work for getting the parent style context frame so that
    * other frame's |GetParentStyleContextFrame| methods can call this
    * method on *another* frame.  (This function handles out-of-flow
    * frames by using the frame manager's placeholder map and it also
    * handles block-within-inline and generated content wrappers.)
    */
   nsIFrame* DoGetParentStyleContextFrame() const;
 
-  virtual bool IsEmpty();
-  virtual bool IsSelfEmpty();
+  virtual bool IsEmpty() MOZ_OVERRIDE;
+  virtual bool IsSelfEmpty() MOZ_OVERRIDE;
 
-  virtual void MarkIntrinsicWidthsDirty();
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
-                                 InlineMinWidthData *aData);
+                                 InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
-                                  InlinePrefWidthData *aData);
+                                  InlinePrefWidthData *aData) MOZ_OVERRIDE;
   virtual IntrinsicWidthOffsetData
-    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext);
-  virtual IntrinsicSize GetIntrinsicSize();
-  virtual nsSize GetIntrinsicRatio();
+    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
+  virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
+  virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
 
   // Compute tight bounds assuming this frame honours its border, background
   // and outline, its children's tight bounds, and nothing else.
@@ -292,17 +292,17 @@ public:
 
   /**
    * Utility function for ComputeAutoSize implementations.  Return
    * max(GetMinWidth(), min(aWidthInCB, GetPrefWidth()))
    */
   nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
                            nscoord aWidthInCB);
 
-  NS_IMETHOD  WillReflow(nsPresContext* aPresContext);
+  NS_IMETHOD  WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE;
   /**
    * Calculates the size of this frame after reflowing (calling Reflow on, and
    * updating the size and position of) its children, as necessary.  The
    * calculated size is returned to the caller via the nsHTMLReflowMetrics
    * outparam.  (The caller is responsible for setting the actual size and
    * position of this frame.)
    *
    * A frame's children must _all_ be reflowed if the frame is dirty (the
@@ -318,39 +318,39 @@ public:
    * over-reflow.)
    *
    * Note: if it's only the overflow rect(s) of a frame that need to be
    * updated, then UpdateOverflow should be called instead of Reflow.
    */
   NS_IMETHOD  Reflow(nsPresContext*          aPresContext,
                      nsHTMLReflowMetrics&     aDesiredSize,
                      const nsHTMLReflowState& aReflowState,
-                     nsReflowStatus&          aStatus);
+                     nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   NS_IMETHOD  DidReflow(nsPresContext*           aPresContext,
                         const nsHTMLReflowState*  aReflowState,
-                        nsDidReflowStatus         aStatus);
+                        nsDidReflowStatus         aStatus) MOZ_OVERRIDE;
 
   /**
    * NOTE: aStatus is assumed to be already-initialized. The reflow statuses of
    * any reflowed absolute children will be merged into aStatus; aside from
    * that, this method won't modify aStatus.
    */
   void ReflowAbsoluteFrames(nsPresContext*           aPresContext,
                             nsHTMLReflowMetrics&     aDesiredSize,
                             const nsHTMLReflowState& aReflowState,
                             nsReflowStatus&          aStatus,
                             bool                     aConstrainHeight = true);
   void FinishReflowWithAbsoluteFrames(nsPresContext*           aPresContext,
                                       nsHTMLReflowMetrics&     aDesiredSize,
                                       const nsHTMLReflowState& aReflowState,
                                       nsReflowStatus&          aStatus,
                                       bool                     aConstrainHeight = true);
-  virtual bool CanContinueTextRun() const;
+  virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow();
+  virtual bool UpdateOverflow() MOZ_OVERRIDE;
 
   // Selection Methods
 
   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
                          nsGUIEvent *    aEvent,
                          nsEventStatus*  aEventStatus);
 
   NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
@@ -381,20 +381,20 @@ public:
                                nsSelectionAmount aEndAmountType,
                                uint32_t aSelectFlags);
 
   // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
   // in this function assumes there is no child frame that can be targeted.
   virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
 
   // Box layout methods
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
-  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState);
+  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   // We compute and store the HTML content's overflow area. So don't
   // try to compute it in the box code.
   virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; }
 
   //--------------------------------------------------
   // Additional methods
@@ -408,17 +408,17 @@ public:
                             nsHTMLReflowMetrics& aMetrics,
                             nsReflowStatus& aStatus);
 
   // Incorporate the child overflow areas into aOverflowAreas.
   // If the child does not have a overflow, use the child area.
   void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
                              nsIFrame* aChildFrame);
 
-  virtual const void* StyleDataExternal(nsStyleStructID aSID) const;
+  virtual const void* StyleDataExternal(nsStyleStructID aSID) const MOZ_OVERRIDE;
 
 
   /**
    * @return true if we should avoid a page/column break in this frame.
    */
   bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const {
     return !aReflowState.mFlags.mIsTopOfPage &&
            NS_STYLE_PAGE_BREAK_AVOID == StyleDisplay()->mBreakInside &&
@@ -552,17 +552,17 @@ protected:
    * which kind of content this is for
    */
   void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
       nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
 
   int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false);
   
   // Style post processing hook
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
 public:
   //given a frame five me the first/last leaf available
   //XXX Robert O'Callahan wants to move these elsewhere
   static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
   static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
 
   // Return the line number of the aFrame, and (optionally) the containing block
@@ -652,40 +652,40 @@ private:
                      nscoord aX,
                      nscoord aY,
                      nscoord aWidth,
                      nscoord aHeight,
                      bool aMoveFrame = true);
 
   NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
 
-  virtual nsILineIterator* GetLineIterator();
+  virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE;
 
 #ifdef DEBUG
 public:
   /**
    * Get a printable from of the name of the frame type.
    * XXX This should be eliminated and we use GetType() instead...
    */
-  NS_IMETHOD  GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD  GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   /**
    * Return the state bits that are relevant to regression tests (that
    * is, those bits which indicate a real difference when they differ
    */
-  NS_IMETHOD_(nsFrameState)  GetDebugStateBits() const;
+  NS_IMETHOD_(nsFrameState)  GetDebugStateBits() const MOZ_OVERRIDE;
   /**
    * Called to dump out regression data that describes the layout
    * of the frame and its children, and so on. The format of the
    * data is dictated to be XML (using a specific DTD); the
    * specific kind of data dumped is up to the frame itself, with
    * the caveat that some base types are defined.
    * For more information, see XXX.
    */
   NS_IMETHOD  DumpRegressionData(nsPresContext* aPresContext,
-                                 FILE* out, int32_t aIndent);
+                                 FILE* out, int32_t aIndent) MOZ_OVERRIDE;
 
   /**
    * See if style tree verification is enabled. To enable style tree
    * verification add "styleverifytree:1" to your NSPR_LOG_MODULES
    * environment variable (any non-zero debug level will work). Or,
    * call SetVerifyStyleTreeEnable with true.
    */
   static bool GetVerifyStyleTreeEnable();
--- a/layout/generic/nsFrameSetFrame.h
+++ b/layout/generic/nsFrameSetFrame.h
@@ -78,17 +78,17 @@ public:
 
   virtual ~nsHTMLFramesetFrame();
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
   NS_IMETHOD SetInitialChildList(ChildListID  aListID,
-                                 nsFrameList& aChildList);
+                                 nsFrameList& aChildList) MOZ_OVERRIDE;
 
   static bool    gDragInProgress;
 
   void GetSizeOfChild(nsIFrame* aChild, nsSize& aSize);
 
   void GetSizeOfChildAt(int32_t  aIndexInParent, 
                         nsSize&  aSize, 
                         nsIntPoint& aCellIndex);
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -401,29 +401,29 @@ public:
                                nsHTMLReflowMetrics* aMetrics,
                                bool aFirstPass);
   nsresult ReflowContents(ScrollReflowState* aState,
                           const nsHTMLReflowMetrics& aDesiredSize);
   void PlaceScrollArea(const ScrollReflowState& aState,
                        const nsPoint& aScrollPosition);
   nscoord GetIntrinsicVScrollbarWidth(nsRenderingContext *aRenderingContext);
 
-  virtual bool GetBorderRadii(nscoord aRadii[8]) const {
+  virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE {
     return mInner.GetBorderRadii(aRadii);
   }
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
-  NS_IMETHOD GetPadding(nsMargin& aPadding);
-  virtual bool IsCollapsed();
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  NS_IMETHOD GetPadding(nsMargin& aPadding) MOZ_OVERRIDE;
+  virtual bool IsCollapsed() MOZ_OVERRIDE;
   
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual bool UpdateOverflow() MOZ_OVERRIDE {
     return mInner.UpdateOverflow();
   }
 
   // Because there can be only one child frame, these two function return
   // NS_ERROR_FAILURE
   NS_IMETHOD AppendFrames(ChildListID     aListID,
@@ -433,45 +433,45 @@ public:
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
 
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIScrollableFrame* GetScrollTargetFrame() {
+  virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE {
     return this;
   }
 
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return mInner.GetScrolledFrame()->GetContentInsertionFrame();
   }
 
-  virtual bool DoesClipChildren() { return true; }
-  virtual nsSplittableType GetSplittableType() const;
+  virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; }
+  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
 
-  virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
+  virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild) MOZ_OVERRIDE
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mInner.GetScrolledFrame()) pt += GetScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     return mInner.GetScrollbarBox(aVertical);
   }
 
   // nsIScrollableFrame
-  virtual nsIFrame* GetScrolledFrame() const {
+  virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mInner.GetScrolledFrame();
   }
   virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const {
     return mInner.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
     return mInner.GetScrollbarVisibility();
   }
@@ -538,17 +538,17 @@ public:
   }
   NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE {
     mInner.PostScrolledAreaEvent();
     return NS_OK;
   }
   virtual bool IsScrollingActive() MOZ_OVERRIDE {
     return mInner.IsScrollingActive();
   }
-  virtual void ResetScrollPositionForLayerPixelAlignment() {
+  virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
     mInner.ResetScrollPositionForLayerPixelAlignment();
   }
   virtual bool DidHistoryRestore() MOZ_OVERRIDE {
     return mInner.mDidHistoryRestore;
   }
   virtual void ClearDidHistoryRestore() MOZ_OVERRIDE {
     mInner.mDidHistoryRestore = false;
   }
@@ -565,20 +565,20 @@ public:
     return NS_OK;
   }
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::scrollFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
 protected:
   nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, bool aIsRoot);
@@ -625,17 +625,17 @@ public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
-                                 nsFrameList&    aChildList);
+                                 nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE {
     mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists);
   }
 
   // XXXldb Is this actually used?
@@ -655,48 +655,48 @@ public:
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIScrollableFrame* GetScrollTargetFrame() {
+  virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE {
     return this;
   }
 
   virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return mInner.GetScrolledFrame()->GetContentInsertionFrame();
   }
 
-  virtual bool DoesClipChildren() { return true; }
-  virtual nsSplittableType GetSplittableType() const;
+  virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; }
+  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
 
-  virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
+  virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild) MOZ_OVERRIDE
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mInner.GetScrolledFrame())
       pt += mInner.GetLogicalScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
-  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
-  NS_IMETHOD GetPadding(nsMargin& aPadding);
+  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  NS_IMETHOD GetPadding(nsMargin& aPadding) MOZ_OVERRIDE;
 
-  virtual bool GetBorderRadii(nscoord aRadii[8]) const {
+  virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE {
     return mInner.GetBorderRadii(aRadii);
   }
 
   nsresult Layout(nsBoxLayoutState& aState);
   void LayoutScrollArea(nsBoxLayoutState& aState, const nsPoint& aScrollPosition);
 
   static bool AddRemoveScrollbar(bool& aHasScrollbar, 
                                    nscoord& aXY, 
@@ -719,17 +719,17 @@ public:
   static void AdjustReflowStateBack(nsBoxLayoutState& aState, bool aSetBack);
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     return mInner.GetScrollbarBox(aVertical);
   }
 
   // nsIScrollableFrame
-  virtual nsIFrame* GetScrolledFrame() const {
+  virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mInner.GetScrolledFrame();
   }
   virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const {
     return mInner.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
     return mInner.GetScrollbarVisibility();
   }
@@ -796,17 +796,17 @@ public:
   }
   NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE {
     mInner.PostScrolledAreaEvent();
     return NS_OK;
   }
   virtual bool IsScrollingActive() MOZ_OVERRIDE {
     return mInner.IsScrollingActive();
   }
-  virtual void ResetScrollPositionForLayerPixelAlignment() {
+  virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
     mInner.ResetScrollPositionForLayerPixelAlignment();
   }
   virtual bool DidHistoryRestore() MOZ_OVERRIDE {
     return mInner.mDidHistoryRestore;
   }
   virtual void ClearDidHistoryRestore() MOZ_OVERRIDE {
     mInner.mDidHistoryRestore = false;
   }
--- a/layout/generic/nsHTMLCanvasFrame.h
+++ b/layout/generic/nsHTMLCanvasFrame.h
@@ -73,27 +73,27 @@ public:
   nsRect GetInnerArea() const;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   }
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   // Inserted child content gets its frames parented by our child block
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   }
 
 protected:
   virtual ~nsHTMLCanvasFrame();
 
   nscoord GetContinuationOffset(nscoord* aWidth = 0) const;
 
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -419,18 +419,19 @@ IsQuirkContainingBlockHeight(const nsHTM
   }
   return true;
 }
 
 
 void
 nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType)
 {
-  bool isHResize = frame->GetSize().width !=
-                     mComputedWidth + mComputedBorderPadding.LeftRight();
+  bool isHResize = (frame->GetSize().width !=
+                     mComputedWidth + mComputedBorderPadding.LeftRight()) ||
+                     aPresContext->PresShell()->IsReflowOnZoomPending();
 
   if ((frame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT) &&
       nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) {
     // Create our font inflation data if we don't have it already, and
     // give it our current width information.
     bool dirty = nsFontInflationData::UpdateFontInflationDataWidthFor(*this) &&
                  // Avoid running this at the box-to-block interface
                  // (where we shouldn't be inflating anyway, and where
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -179,17 +179,17 @@ protected:
  */
 class nsFirstLineFrame : public nsInlineFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewFirstLineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   NS_IMETHOD Reflow(nsPresContext* aPresContext,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus& aStatus) MOZ_OVERRIDE;
 
   virtual void Init(nsIContent* aContent, nsIFrame* aParent,
--- a/layout/generic/nsLeafFrame.h
+++ b/layout/generic/nsLeafFrame.h
@@ -29,26 +29,26 @@ public:
     DO_GLOBAL_REFLOW_COUNT_DSP("nsLeafFrame");
     DisplayBorderBackgroundOutline(aBuilder, aLists);
   }
 
   /**
    * Both GetMinWidth and GetPrefWidth will return whatever GetIntrinsicWidth
    * returns.
    */
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   /**
    * Our auto size is just intrinsic width and intrinsic height.
    */
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
-                                 nsSize aPadding, bool aShrinkWrap);
+                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
   /**
    * Reflow our frame.  This will use the computed width plus borderpadding for
    * the desired width, and use the return value of GetIntrinsicHeight plus
    * borderpadding for the desired height.  Ascent will be set to the height,
    * and descent will be set to 0.
    */
   NS_IMETHOD Reflow(nsPresContext*      aPresContext,
@@ -59,17 +59,17 @@ public:
   /**
    * This method does most of the work that Reflow() above need done.
    */
   NS_IMETHOD DoReflow(nsPresContext*      aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&      aStatus);
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // We don't actually contain a block, but we do always want a
     // computed width, so tell a little white lie here.
     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplacedContainsBlock));
   }
 
 protected:
   nsLeafFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -1604,38 +1604,38 @@ nsLineList_const_reverse_iterator::opera
 //----------------------------------------------------------------------
 
 class nsLineIterator MOZ_FINAL : public nsILineIterator
 {
 public:
   nsLineIterator();
   ~nsLineIterator();
 
-  virtual void DisposeLineIterator();
+  virtual void DisposeLineIterator() MOZ_OVERRIDE;
 
-  virtual int32_t GetNumLines();
-  virtual bool GetDirection();
+  virtual int32_t GetNumLines() MOZ_OVERRIDE;
+  virtual bool GetDirection() MOZ_OVERRIDE;
   NS_IMETHOD GetLine(int32_t aLineNumber,
                      nsIFrame** aFirstFrameOnLine,
                      int32_t* aNumFramesOnLine,
                      nsRect& aLineBounds,
-                     uint32_t* aLineFlags);
-  virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0);
+                     uint32_t* aLineFlags) MOZ_OVERRIDE;
+  virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
   NS_IMETHOD FindFrameAt(int32_t aLineNumber,
                          nscoord aX,
                          nsIFrame** aFrameFound,
                          bool* aXIsBeforeFirstFrame,
-                         bool* aXIsAfterLastFrame);
+                         bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
 
-  NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber);
+  NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) MOZ_OVERRIDE;
 #ifdef IBMBIDI
   NS_IMETHOD CheckLineOrder(int32_t                  aLine,
                             bool                     *aIsReordered,
                             nsIFrame                 **aFirstVisual,
-                            nsIFrame                 **aLastVisual);
+                            nsIFrame                 **aLastVisual) MOZ_OVERRIDE;
 #endif
   nsresult Init(nsLineList& aLines, bool aRightToLeft);
 
 private:
   nsLineBox* PrevLine() {
     if (0 == mIndex) {
       return nullptr;
     }
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -20,17 +20,17 @@ public:
   friend class nsPageFrame;
 
   // nsIFrame
   NS_IMETHOD  Reflow(nsPresContext*      aPresContext,
                      nsHTMLReflowMetrics& aDesiredSize,
                      const nsHTMLReflowState& aMaxSize,
                      nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return ViewportFrame::IsFrameOfType(aFlags &
              ~(nsIFrame::eCanContainOverflowContainers));
   }
 
   virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; }
 
   virtual bool HasTransformGetter() const MOZ_OVERRIDE { return true; }
--- a/layout/generic/nsPageFrame.h
+++ b/layout/generic/nsPageFrame.h
@@ -17,17 +17,17 @@ class nsPageFrame : public nsContainerFr
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewPageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD  Reflow(nsPresContext*      aPresContext,
                      nsHTMLReflowMetrics& aDesiredSize,
                      const nsHTMLReflowState& aMaxSize,
-                     nsReflowStatus&      aStatus);
+                     nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
@@ -45,17 +45,17 @@ public:
 
   // Tell the page which page number it is out of how many
   virtual void  SetPageNumInfo(int32_t aPageNumber, int32_t aTotalPages);
 
   virtual void SetSharedPageData(nsSharedPageData* aPD);
 
   // We must allow Print Preview UI to have a background, no matter what the
   // user's settings
-  virtual bool HonorPrintBackgroundSettings() { return false; }
+  virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE { return false; }
 
   void PaintHeaderFooter(nsRenderingContext& aRenderingContext,
                          nsPoint aPt);
 
 protected:
   nsPageFrame(nsStyleContext* aContext);
   virtual ~nsPageFrame();
 
--- a/layout/generic/nsSimplePageSequence.h
+++ b/layout/generic/nsSimplePageSequence.h
@@ -51,17 +51,17 @@ public:
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIFrame
   NS_IMETHOD  Reflow(nsPresContext*      aPresContext,
                      nsHTMLReflowMetrics& aDesiredSize,
                      const nsHTMLReflowState& aMaxSize,
-                     nsReflowStatus&      aStatus);
+                     nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsIPageSequenceFrame
   NS_IMETHOD SetPageNo(int32_t aPageNo) { return NS_OK;}
   NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) MOZ_OVERRIDE { mYSelOffset = aYOffset; mSelectionHeight = aHeight; return NS_OK; }
@@ -69,41 +69,41 @@ public:
   
   // For Shrink To Fit
   NS_IMETHOD GetSTFPercent(float& aSTFPercent) MOZ_OVERRIDE;
 
   // Async Printing
   NS_IMETHOD StartPrint(nsPresContext*  aPresContext,
                         nsIPrintSettings* aPrintSettings,
                         PRUnichar*        aDocTitle,
-                        PRUnichar*        aDocURL);
+                        PRUnichar*        aDocURL) MOZ_OVERRIDE;
   NS_IMETHOD PrePrintNextPage(nsITimerCallback* aCallback, bool* aDone) MOZ_OVERRIDE;
   NS_IMETHOD PrintNextPage() MOZ_OVERRIDE;
   NS_IMETHOD ResetPrintCanvasList() MOZ_OVERRIDE;
   NS_IMETHOD GetCurrentPageNum(int32_t* aPageNum) MOZ_OVERRIDE;
   NS_IMETHOD GetNumPages(int32_t* aNumPages) MOZ_OVERRIDE;
   NS_IMETHOD IsDoingPrintRange(bool* aDoing) MOZ_OVERRIDE;
   NS_IMETHOD GetPrintRange(int32_t* aFromPage, int32_t* aToPage) MOZ_OVERRIDE;
   NS_IMETHOD DoPageEnd() MOZ_OVERRIDE;
 
   // We must allow Print Preview UI to have a background, no matter what the
   // user's settings
-  virtual bool HonorPrintBackgroundSettings() { return false; }
+  virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE { return false; }
 
   virtual bool HasTransformGetter() const MOZ_OVERRIDE { return true; }
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::sequenceFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  NS_IMETHOD  GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD  GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 protected:
   nsSimplePageSequenceFrame(nsStyleContext* aContext);
   virtual ~nsSimplePageSequenceFrame();
 
   void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, bool aPageNumOnly);
 
--- a/layout/generic/nsSplittableFrame.h
+++ b/layout/generic/nsSplittableFrame.h
@@ -19,19 +19,19 @@ class nsSplittableFrame : public nsFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
   
-  virtual nsSplittableType GetSplittableType() const;
+  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   /*
    * Frame continuations can be either fluid or not:
    * Fluid continuations ("in-flows") are the result of line breaking, 
    * column breaking, or page breaking.
    * Other (non-fluid) continuations can be the result of BiDi frame splitting.
    * A "flow" is a chain of fluid continuations.
    */
@@ -40,18 +40,18 @@ public:
   virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE;
   virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE;
 
   // Set a previous/next non-fluid continuation.
   NS_IMETHOD SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE;
   NS_IMETHOD SetNextContinuation(nsIFrame*) MOZ_OVERRIDE;
 
   // Get the first/last continuation for this frame.
-  virtual nsIFrame* GetFirstContinuation() const;
-  virtual nsIFrame* GetLastContinuation() const;
+  virtual nsIFrame* GetFirstContinuation() const MOZ_OVERRIDE;
+  virtual nsIFrame* GetLastContinuation() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
   // Can aFrame2 be reached from aFrame1 by following prev/next continuations?
   static bool IsInPrevContinuationChain(nsIFrame* aFrame1, nsIFrame* aFrame2);
   static bool IsInNextContinuationChain(nsIFrame* aFrame1, nsIFrame* aFrame2);
 #endif
   
   // Get the previous/next continuation, only if it is fluid (an "in-flow").
@@ -61,18 +61,18 @@ public:
   virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE { return GetPrevInFlow(); }
   virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE { return GetNextInFlow(); }
   
   // Set a previous/next fluid continuation.
   NS_IMETHOD  SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE;
   NS_IMETHOD  SetNextInFlow(nsIFrame*) MOZ_OVERRIDE;
 
   // Get the first/last frame in the current flow.
-  virtual nsIFrame* GetFirstInFlow() const;
-  virtual nsIFrame* GetLastInFlow() const;
+  virtual nsIFrame* GetFirstInFlow() const MOZ_OVERRIDE;
+  virtual nsIFrame* GetLastInFlow() const MOZ_OVERRIDE;
 
   // Remove the frame from the flow. Connects the frame's prev-in-flow
   // and its next-in-flow. This should only be called in frame Destroy() methods.
   static void RemoveFromFlow(nsIFrame* aFrame);
 
 protected:
   nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
 
--- a/layout/generic/nsSubDocumentFrame.h
+++ b/layout/generic/nsSubDocumentFrame.h
@@ -19,47 +19,47 @@ class nsSubDocumentFrame : public nsLeaf
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsSubDocumentFrame)
   NS_DECL_FRAMEARENA_HELPERS
 
   nsSubDocumentFrame(nsStyleContext* aContext);
 
 #ifdef DEBUG
-  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   NS_DECL_QUERYFRAME
 
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // nsLeafFrame is already eReplacedContainsBlock, but that's somewhat bogus
     return nsLeafFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual IntrinsicSize GetIntrinsicSize();
-  virtual nsSize  GetIntrinsicRatio();
+  virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
+  virtual nsSize  GetIntrinsicRatio() MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
-                                 nsSize aPadding, bool aShrinkWrap);
+                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
@@ -67,23 +67,23 @@ public:
                     nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
-                              int32_t aModType);
+                              int32_t aModType) MOZ_OVERRIDE;
 
   // if the content is "visibility:hidden", then just hide the view
   // and all our contents. We don't extend "visibility:hidden" to
   // the child content ourselves, since it belongs to a different
   // document and CSS doesn't inherit in there.
-  virtual bool SupportsVisibilityHidden() { return false; }
+  virtual bool SupportsVisibilityHidden() MOZ_OVERRIDE { return false; }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   nsresult GetDocShell(nsIDocShell **aDocShell);
   nsresult BeginSwapDocShells(nsIFrame* aOther);
   void EndSwapDocShells(nsIFrame* aOther);
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -44,42 +44,42 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
-                              int32_t aModType);
+                              int32_t aModType) MOZ_OVERRIDE;
 
   /* get the size of the video's display */
   nsSize GetVideoIntrinsicSize(nsRenderingContext *aRenderingContext);
-  virtual nsSize GetIntrinsicRatio();
+  virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   virtual bool IsLeaf() const MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   }
   
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilters) MOZ_OVERRIDE;
 
@@ -87,17 +87,17 @@ public:
 
   // Returns true if we should display the poster. Note that once we show
   // a video frame, the poster will never be displayed again.
   bool ShouldDisplayPoster();
 
   nsIContent *GetCaptionOverlay() { return mCaptionDiv; }
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                      LayerManager* aManager,
                                      nsDisplayItem* aItem,
                                      const ContainerParameters& aContainerParameters);
 
 protected:
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -78,17 +78,17 @@ public:
    */
   nsRect AdjustReflowStateAsContainingBlock(nsHTMLReflowState* aReflowState) const;
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 private:
-  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kFixedList; }
+  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const MOZ_OVERRIDE { return kFixedList; }
 
 protected:
   /**
    * Calculate how much room is available for fixed frames. That means
    * determining if the viewport is scrollable and whether the vertical and/or
    * horizontal scrollbars are visible.  Adjust the computed width/height and
    * available width for aReflowState accordingly.
    * @return the current scroll position, or 0,0 if not scrollable
--- a/layout/inspector/src/inDOMUtils.cpp
+++ b/layout/inspector/src/inDOMUtils.cpp
@@ -384,18 +384,18 @@ inDOMUtils::GetCSSPropertyNames(uint32_t
       ++propCount;                                                      \
     }                                                                   \
   PR_END_MACRO
 
   // prop is the property id we're considering; propCount is how many properties
   // we've put into props so far.
   uint32_t prop = 0, propCount = 0;
   for ( ; prop < eCSSProperty_COUNT_no_shorthands; ++prop) {
-    if (!nsCSSProps::PropHasFlags(nsCSSProperty(prop),
-                                  CSS_PROPERTY_PARSE_INACCESSIBLE)) {
+    if (nsCSSProps::PropertyParseType(nsCSSProperty(prop)) !=
+        CSS_PROPERTY_PARSE_INACCESSIBLE) {
       DO_PROP(prop);
     }
   }
 
   if (!(aFlags & EXCLUDE_SHORTHANDS)) {
     for ( ; prop < eCSSProperty_COUNT; ++prop) {
       // Some shorthands are also aliases
       if ((aFlags & INCLUDE_ALIASES) ||
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -42,23 +42,23 @@ public:
 
   // --------------------------------------------------------------------------
   // Overloaded nsMathMLFrame methods -- see documentation in nsIMathMLFrame.h
 
   NS_IMETHOD
   Stretch(nsRenderingContext& aRenderingContext,
           nsStretchDirection   aStretchDirection,
           nsBoundingMetrics&   aContainerSize,
-          nsHTMLReflowMetrics& aDesiredStretchSize);
+          nsHTMLReflowMetrics& aDesiredStretchSize) MOZ_OVERRIDE;
 
   NS_IMETHOD
   UpdatePresentationDataFromChildAt(int32_t         aFirstIndex,
                                     int32_t         aLastIndex,
                                     uint32_t        aFlagsValues,
-                                    uint32_t        aFlagsToUpdate)
+                                    uint32_t        aFlagsToUpdate) MOZ_OVERRIDE
   {
     PropagatePresentationDataFromChildAt(this, aFirstIndex, aLastIndex,
       aFlagsValues, aFlagsToUpdate);
     return NS_OK;
   }
   
   // helper to set the "increment script level" flag on the element belonging
   // to a child frame given by aChildIndex.
@@ -70,76 +70,76 @@ public:
   // to ensure that restyle and reflow happens immediately after the current
   // reflow.
   void
   SetIncrementScriptLevel(int32_t aChildIndex, bool aIncrement);
 
   // --------------------------------------------------------------------------
   // Overloaded nsContainerFrame methods -- see documentation in nsIFrame.h
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return !(aFlags & nsIFrame::eLineParticipant) &&
       nsContainerFrame::IsFrameOfType(aFlags &
               ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
   NS_IMETHOD
   AppendFrames(ChildListID     aListID,
-               nsFrameList&    aFrameList);
+               nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD
   InsertFrames(ChildListID     aListID,
                nsIFrame*       aPrevFrame,
                nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD
   RemoveFrame(ChildListID     aListID,
               nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   /**
    * Both GetMinWidth and GetPrefWidth return whatever
    * GetIntrinsicWidth returns.
    */
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
   /**
    * Return the intrinsic width of the frame's content area.
    */
   virtual nscoord GetIntrinsicWidth(nsRenderingContext *aRenderingContext);
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
-         nsReflowStatus&          aStatus);
+         nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  WillReflow(nsPresContext* aPresContext)
+  WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE
   {
     mPresentationData.flags &= ~NS_MATHML_ERROR;
     return nsContainerFrame::WillReflow(aPresContext);
   }
 
   NS_IMETHOD
   DidReflow(nsPresContext*           aPresContext,
             const nsHTMLReflowState*  aReflowState,
-            nsDidReflowStatus         aStatus)
+            nsDidReflowStatus         aStatus) MOZ_OVERRIDE
 
   {
     mPresentationData.flags &= ~NS_MATHML_STRETCH_DONE;
     return nsContainerFrame::DidReflow(aPresContext, aReflowState, aStatus);
   }
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow();
+  virtual bool UpdateOverflow() MOZ_OVERRIDE;
 
   // Notification when an attribute is changed. The MathML module uses the
   // following paradigm:
   //
   // 1. If the MathML frame class doesn't have any cached automatic data that
   //    depends on the attribute: we just reflow (e.g., this happens with <msub>,
   //    <msup>, <mmultiscripts>, etc). This is the default behavior implemented
   //    by this base class.
@@ -151,17 +151,17 @@ public:
   //        (e.g., this happens with <ms>).
   //    2b. If the automatic data to update affects us in some way, we ask our parent
   //        to re-layout its children using ReLayoutChildren(mParent);
   //        Therefore, there is an overhead here in that our siblings are re-laid
   //        too (e.g., this happens with <mstyle>, <munder>, <mover>, <munderover>). 
   NS_IMETHOD
   AttributeChanged(int32_t         aNameSpaceID,
                    nsIAtom*        aAttribute,
-                   int32_t         aModType);
+                   int32_t         aModType) MOZ_OVERRIDE;
 
   // helper function to apply mirroring to a horizontal coordinate, if needed.
   nscoord
   MirrorIfRTL(nscoord aParentWidth, nscoord aChildWidth, nscoord aChildLeading)
   {
     return (NS_MATHML_IS_RTL(mPresentationData.flags) ?
             aParentWidth - aChildWidth - aChildLeading : aChildLeading);
   }
@@ -400,28 +400,28 @@ public:
 
   friend nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell,
           nsStyleContext* aContext, uint32_t aFlags);
 
   // beware, mFrames is not set by nsBlockFrame
   // cannot use mFrames{.FirstChild()|.etc} since the block code doesn't set mFrames
   NS_IMETHOD
   SetInitialChildList(ChildListID     aListID,
-                      nsFrameList&    aChildList)
+                      nsFrameList&    aChildList) MOZ_OVERRIDE
   {
     NS_ASSERTION(aListID == kPrincipalList, "unexpected frame list");
     nsresult rv = nsBlockFrame::SetInitialChildList(aListID, aChildList);
     // re-resolve our subtree to set any mathml-expected data
     nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this);
     return rv;
   }
 
   NS_IMETHOD
   AppendFrames(ChildListID     aListID,
-               nsFrameList&    aFrameList)
+               nsFrameList&    aFrameList) MOZ_OVERRIDE
   {
     NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
                  "unexpected frame list");
     nsresult rv = nsBlockFrame::AppendFrames(aListID, aFrameList);
     if (MOZ_LIKELY(aListID == kPrincipalList))
       nsMathMLContainerFrame::ReLayoutChildren(this);
     return rv;
   }
@@ -516,17 +516,17 @@ public:
     NS_ASSERTION(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
                  "unexpected frame list");
     nsresult rv = nsInlineFrame::RemoveFrame(aListID, aOldFrame);
     if (MOZ_LIKELY(aListID == kPrincipalList))
       nsMathMLContainerFrame::ReLayoutChildren(this);
     return rv;
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const {
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE {
       return nsInlineFrame::IsFrameOfType(aFlags &
                 ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
 protected:
   nsMathMLmathInlineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {}
   virtual ~nsMathMLmathInlineFrame() {}
 };
--- a/layout/mathml/nsMathMLFrame.h
+++ b/layout/mathml/nsMathMLFrame.h
@@ -23,17 +23,17 @@ class nsMathMLChar;
 
 // Concrete base class with default methods that derived MathML frames can override
 class nsMathMLFrame : public nsIMathMLFrame {
 public:
 
   // nsIMathMLFrame ---
 
   virtual bool
-  IsSpaceLike() {
+  IsSpaceLike() MOZ_OVERRIDE {
     return NS_MATHML_IS_SPACE_LIKE(mPresentationData.flags);
   }
 
   NS_IMETHOD
   GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) MOZ_OVERRIDE {
     aBoundingMetrics = mBoundingMetrics;
     return NS_OK;
   }
--- a/layout/mathml/nsMathMLTokenFrame.h
+++ b/layout/mathml/nsMathMLTokenFrame.h
@@ -16,29 +16,29 @@
 
 class nsMathMLTokenFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLTokenFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData() {
+  TransmitAutomaticData() MOZ_OVERRIDE {
     // The REC defines the following elements to be space-like:
     // * an mtext, mspace, maligngroup, or malignmark element;
     if (mContent->Tag() == nsGkAtoms::mtext_) {
       mPresentationData.flags |= NS_MATHML_SPACE_LIKE;
     }
     return NS_OK;
   }
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
-  virtual eMathMLFrameType GetMathMLFrameType();
+  virtual eMathMLFrameType GetMathMLFrameType() MOZ_OVERRIDE;
 
   NS_IMETHOD
   SetInitialChildList(ChildListID     aListID,
                       nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AppendFrames(ChildListID            aListID,
                nsFrameList&           aChildList) MOZ_OVERRIDE;
@@ -54,17 +54,17 @@ public:
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
         nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
-  virtual void MarkIntrinsicWidthsDirty();
+  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
 
   virtual nsresult
   ChildListChanged(int32_t aModType) MOZ_OVERRIDE
   {
     ProcessTextData();
     return nsMathMLContainerFrame::ChildListChanged(aModType);
   }
 
--- a/layout/mathml/nsMathMLmencloseFrame.h
+++ b/layout/mathml/nsMathMLmencloseFrame.h
@@ -46,32 +46,32 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmencloseFrame(nsIPresShell*   aPresShell,
                                              nsStyleContext* aContext);
   
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
   
   virtual nsresult
   MeasureForWidth(nsRenderingContext& aRenderingContext,
                   nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
   
   NS_IMETHOD
   AttributeChanged(int32_t         aNameSpaceID,
                    nsIAtom*        aAttribute,
                    int32_t         aModType) MOZ_OVERRIDE;
   
   virtual void
   SetAdditionalStyleContext(int32_t          aIndex, 
-                            nsStyleContext*  aStyleContext);
+                            nsStyleContext*  aStyleContext) MOZ_OVERRIDE;
   virtual nsStyleContext*
-  GetAdditionalStyleContext(int32_t aIndex) const;
+  GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD
   InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
--- a/layout/mathml/nsMathMLmfencedFrame.h
+++ b/layout/mathml/nsMathMLmfencedFrame.h
@@ -17,19 +17,19 @@
 class nsMathMLmfencedFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual void
   SetAdditionalStyleContext(int32_t          aIndex, 
-                            nsStyleContext*  aStyleContext);
+                            nsStyleContext*  aStyleContext) MOZ_OVERRIDE;
   virtual nsStyleContext*
-  GetAdditionalStyleContext(int32_t aIndex) const;
+  GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
 
   NS_IMETHOD
   InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
   SetInitialChildList(ChildListID     aListID,
                       nsFrameList&    aChildList) MOZ_OVERRIDE;
 
--- a/layout/mathml/nsMathMLmfracFrame.h
+++ b/layout/mathml/nsMathMLmfracFrame.h
@@ -51,21 +51,21 @@ element.
 */
 
 class nsMathMLmfracFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  virtual eMathMLFrameType GetMathMLFrameType();
+  virtual eMathMLFrameType GetMathMLFrameType() MOZ_OVERRIDE;
 
   virtual nsresult
   MeasureForWidth(nsRenderingContext& aRenderingContext,
-                  nsHTMLReflowMetrics& aDesiredSize);
+                  nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
         nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
--- a/layout/mathml/nsMathMLmmultiscriptsFrame.h
+++ b/layout/mathml/nsMathMLmmultiscriptsFrame.h
@@ -1,36 +1,37 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef nsMathMLmmultiscriptsFrame_h___
 #define nsMathMLmmultiscriptsFrame_h___
 
+#include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsMathMLContainerFrame.h"
 
 //
 // <mmultiscripts> -- attach prescripts and tensor indices to a base 
 //
 
 class nsMathMLmmultiscriptsFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData();
+  TransmitAutomaticData() MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
 protected:
   nsMathMLmmultiscriptsFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
   virtual ~nsMathMLmmultiscriptsFrame();
   
 private:
   nscoord mSubScriptShift;
   nscoord mSupScriptShift;
--- a/layout/mathml/nsMathMLmoFrame.h
+++ b/layout/mathml/nsMathMLmoFrame.h
@@ -15,23 +15,23 @@
 //
 
 class nsMathMLmoFrame : public nsMathMLTokenFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  virtual eMathMLFrameType GetMathMLFrameType();
+  virtual eMathMLFrameType GetMathMLFrameType() MOZ_OVERRIDE;
 
   virtual void
   SetAdditionalStyleContext(int32_t          aIndex, 
-                            nsStyleContext*  aStyleContext);
+                            nsStyleContext*  aStyleContext) MOZ_OVERRIDE;
   virtual nsStyleContext*
-  GetAdditionalStyleContext(int32_t aIndex) const;
+  GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD
   InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
--- a/layout/mathml/nsMathMLmpaddedFrame.h
+++ b/layout/mathml/nsMathMLmpaddedFrame.h
@@ -16,20 +16,20 @@
 
 class nsMathMLmpaddedFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  TransmitAutomaticData() {
+  TransmitAutomaticData() MOZ_OVERRIDE {
     return TransmitAutomaticDataForMrowLikeElement();
   }
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
--- a/layout/mathml/nsMathMLmphantomFrame.h
+++ b/layout/mathml/nsMathMLmphantomFrame.h
@@ -16,20 +16,20 @@
 
 class nsMathMLmphantomFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmphantomFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  TransmitAutomaticData() {
+  TransmitAutomaticData() MOZ_OVERRIDE {
     return TransmitAutomaticDataForMrowLikeElement();
   }
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE {}
 
 protected:
--- a/layout/mathml/nsMathMLmrootFrame.h
+++ b/layout/mathml/nsMathMLmrootFrame.h
@@ -17,19 +17,19 @@
 class nsMathMLmrootFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual void
   SetAdditionalStyleContext(int32_t          aIndex, 
-                            nsStyleContext*  aStyleContext);
+                            nsStyleContext*  aStyleContext) MOZ_OVERRIDE;
   virtual nsStyleContext*
-  GetAdditionalStyleContext(int32_t aIndex) const;
+  GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
 
   virtual void
   Init(nsIContent*      aContent,
        nsIFrame*        aParent,
        nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
   NS_IMETHOD
   TransmitAutomaticData() MOZ_OVERRIDE;
--- a/layout/mathml/nsMathMLmrowFrame.h
+++ b/layout/mathml/nsMathMLmrowFrame.h
@@ -18,20 +18,20 @@ class nsMathMLmrowFrame : public nsMathM
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmrowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
-                   int32_t  aModType);
+                   int32_t  aModType) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
   TransmitAutomaticData() MOZ_OVERRIDE {
     return TransmitAutomaticDataForMrowLikeElement();
   }
 
 protected:
   nsMathMLmrowFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
--- a/layout/mathml/nsMathMLmspaceFrame.h
+++ b/layout/mathml/nsMathMLmspaceFrame.h
@@ -16,24 +16,24 @@
 
 class nsMathMLmspaceFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmspaceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData() {
+  TransmitAutomaticData() MOZ_OVERRIDE {
     // The REC defines the following elements to be space-like:
     // * an mtext, mspace, maligngroup, or malignmark element;
     mPresentationData.flags |= NS_MATHML_SPACE_LIKE;
     return NS_OK;
   }
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   
 protected:
--- a/layout/mathml/nsMathMLmstyleFrame.h
+++ b/layout/mathml/nsMathMLmstyleFrame.h
@@ -18,20 +18,20 @@ class nsMathMLmstyleFrame : public nsMat
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
   AttributeChanged(int32_t         aNameSpaceID,
                    nsIAtom*        aAttribute,
-                   int32_t         aModType);
+                   int32_t         aModType) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
   TransmitAutomaticData() MOZ_OVERRIDE;
 
   NS_IMETHOD
   UpdatePresentationData(uint32_t        aFlagsValues,
                          uint32_t        aFlagsToUpdate) MOZ_OVERRIDE;
 
--- a/layout/mathml/nsMathMLmsubFrame.h
+++ b/layout/mathml/nsMathMLmsubFrame.h
@@ -1,36 +1,37 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef nsMathMLmsubFrame_h___
 #define nsMathMLmsubFrame_h___
 
+#include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsMathMLContainerFrame.h"
 
 //
 // <msub> -- attach a subscript to a base
 //
 
 class nsMathMLmsubFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData();
+  TransmitAutomaticData() MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   static nsresult
   PlaceSubScript (nsPresContext*      aPresContext,
                   nsRenderingContext& aRenderingContext,
                   bool                 aPlaceOrigin,
                   nsHTMLReflowMetrics& aDesiredSize,
                   nsMathMLContainerFrame* aForFrame,
                   nscoord              aUserSubScriptShift,
--- a/layout/mathml/nsMathMLmsubsupFrame.h
+++ b/layout/mathml/nsMathMLmsubsupFrame.h
@@ -1,36 +1,37 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef nsMathMLmsubsupFrame_h___
 #define nsMathMLmsubsupFrame_h___
 
+#include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsMathMLContainerFrame.h"
 
 //
 // <msubsup> -- attach a subscript-superscript pair to a base
 //
 
 class nsMathMLmsubsupFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData();
+  TransmitAutomaticData() MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   static nsresult
   PlaceSubSupScript(nsPresContext*      aPresContext,
                     nsRenderingContext& aRenderingContext,
                     bool                 aPlaceOrigin,
                     nsHTMLReflowMetrics& aDesiredSize,
                     nsMathMLContainerFrame* aForFrame,
                     nscoord              aUserSubScriptShift,
--- a/layout/mathml/nsMathMLmsupFrame.h
+++ b/layout/mathml/nsMathMLmsupFrame.h
@@ -1,36 +1,37 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef nsMathMLmsupFrame_h___
 #define nsMathMLmsupFrame_h___
 
+#include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsMathMLContainerFrame.h"
 
 //
 // <msup> -- attach a superscript to a base
 //
 
 class nsMathMLmsupFrame : public nsMathMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
-  TransmitAutomaticData();
+  TransmitAutomaticData() MOZ_OVERRIDE;
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   static nsresult
   PlaceSuperScript (nsPresContext*      aPresContext,
                     nsRenderingContext& aRenderingContext,
                     bool                 aPlaceOrigin,
                     nsHTMLReflowMetrics& aDesiredSize,
                     nsMathMLContainerFrame* aForFrame,
                     nscoord              aUserSupScriptShift,
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -25,17 +25,17 @@ public:
 
   // Overloaded nsIMathMLFrame methods
 
   NS_IMETHOD
   InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
   UpdatePresentationData(uint32_t aFlagsValues,
-                         uint32_t aWhichFlags);
+                         uint32_t aWhichFlags) MOZ_OVERRIDE;
 
   NS_IMETHOD
   UpdatePresentationDataFromChildAt(int32_t         aFirstIndex,
                                     int32_t         aLastIndex,
                                     uint32_t        aFlagsValues,
                                     uint32_t        aWhichFlags) MOZ_OVERRIDE;
 
   // overloaded nsTableOuterFrame methods
@@ -44,19 +44,19 @@ public:
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
-                   int32_t  aModType);
+                   int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsTableOuterFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
 protected:
   nsMathMLmtableOuterFrame(nsStyleContext* aContext) : nsTableOuterFrame(aContext) {}
   virtual ~nsMathMLmtableOuterFrame();
 
@@ -76,47 +76,47 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   // Overloaded nsTableFrame methods
 
   NS_IMETHOD
   SetInitialChildList(ChildListID  aListID,
-                      nsFrameList& aChildList);
+                      nsFrameList& aChildList) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AppendFrames(ChildListID  aListID,
-               nsFrameList& aFrameList)
+               nsFrameList& aFrameList) MOZ_OVERRIDE
   {
     nsresult rv = nsTableFrame::AppendFrames(aListID, aFrameList);
     RestyleTable();
     return rv;
   }
 
   NS_IMETHOD
   InsertFrames(ChildListID aListID,
                nsIFrame* aPrevFrame,
-               nsFrameList& aFrameList)
+               nsFrameList& aFrameList) MOZ_OVERRIDE
   {
     nsresult rv = nsTableFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
     RestyleTable();
     return rv;
   }
 
   NS_IMETHOD
   RemoveFrame(ChildListID aListID,
-              nsIFrame* aOldFrame)
+              nsIFrame* aOldFrame) MOZ_OVERRIDE
   {
     nsresult rv = nsTableFrame::RemoveFrame(aListID, aOldFrame);
     RestyleTable();
     return rv;
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsTableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
   // helper to restyle and reflow the table when a row is changed -- since MathML
   // attributes are inter-dependent and row/colspan can affect the table, it is
   // safer (albeit grossly suboptimal) to just relayout the whole thing.
   void RestyleTable();
@@ -135,17 +135,17 @@ public:
 
   friend nsIFrame* NS_NewMathMLmtrFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   // overloaded nsTableRowFrame methods
 
   NS_IMETHOD
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
-                   int32_t  aModType);
+                   int32_t  aModType) MOZ_OVERRIDE;
 
   NS_IMETHOD
   AppendFrames(ChildListID  aListID,
                nsFrameList& aFrameList) MOZ_OVERRIDE
   {
     nsresult rv = nsTableRowFrame::AppendFrames(aListID, aFrameList);
     RestyleTable();
     return rv;
@@ -165,17 +165,17 @@ public:
   RemoveFrame(ChildListID aListID,
               nsIFrame* aOldFrame) MOZ_OVERRIDE
   {
     nsresult rv = nsTableRowFrame::RemoveFrame(aListID, aOldFrame);
     RestyleTable();
     return rv;
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsTableRowFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
   // helper to restyle and reflow the table -- @see nsMathMLmtableFrame.
   void RestyleTable()
   {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
@@ -199,21 +199,21 @@ public:
 
   friend nsIFrame* NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   // overloaded nsTableCellFrame methods
 
   NS_IMETHOD
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
-                   int32_t  aModType);
+                   int32_t  aModType) MOZ_OVERRIDE;
 
   virtual int32_t GetRowSpan() MOZ_OVERRIDE;
   virtual int32_t GetColSpan() MOZ_OVERRIDE;
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
 protected:
   nsMathMLmtdFrame(nsStyleContext* aContext) : nsTableCellFrame(aContext) {}
   virtual ~nsMathMLmtdFrame();
 }; // class nsMathMLmtdFrame
@@ -240,19 +240,19 @@ public:
       aFirstIndex, aLastIndex, aFlagsValues, aFlagsToUpdate);
     return NS_OK;
   }
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
-         nsReflowStatus&          aStatus);
+         nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
 protected:
   nsMathMLmtdInnerFrame(nsStyleContext* aContext) : nsBlockFrame(aContext) {}
   virtual ~nsMathMLmtdInnerFrame();
--- a/layout/mathml/nsMathMLmunderoverFrame.h
+++ b/layout/mathml/nsMathMLmunderoverFrame.h
@@ -18,20 +18,20 @@ class nsMathMLmunderoverFrame : public n
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual nsresult
   Place(nsRenderingContext& aRenderingContext,
         bool                 aPlaceOrigin,
-        nsHTMLReflowMetrics& aDesiredSize);
+        nsHTMLReflowMetrics& aDesiredSize) MOZ_OVERRIDE;
 
   NS_IMETHOD
-  InheritAutomaticData(nsIFrame* aParent);
+  InheritAutomaticData(nsIFrame* aParent) MOZ_OVERRIDE;
 
   NS_IMETHOD
   TransmitAutomaticData() MOZ_OVERRIDE;
 
   NS_IMETHOD
   UpdatePresentationData(uint32_t        aFlagsValues,
                          uint32_t        aFlagsToUpdate) MOZ_OVERRIDE;
 
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -32,17 +32,17 @@ class CommonAnimationManager : public ns
 public:
   CommonAnimationManager(nsPresContext *aPresContext);
   virtual ~CommonAnimationManager();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIStyleRuleProcessor (parts)
-  virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData);
+  virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE;
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE;
   virtual nsRestyleHint
     HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE;
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE;
   virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
     const MOZ_MUST_OVERRIDE MOZ_OVERRIDE;
   virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf)
     const MOZ_MUST_OVERRIDE MOZ_OVERRIDE;
@@ -78,17 +78,17 @@ protected:
  */
 class AnimValuesStyleRule MOZ_FINAL : public nsIStyleRule
 {
 public:
   // nsISupports implementation
   NS_DECL_ISUPPORTS
 
   // nsIStyleRule implementation
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   void AddValue(nsCSSProperty aProperty, nsStyleAnimation::Value &aStartValue)
   {
     PropertyValuePair v = { aProperty, aStartValue };
     mPropertyValuePairs.AppendElement(v);
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -6,16 +6,17 @@
 /*
  * internal interface representing CSS style rules that contain other
  * rules, such as @media rules
  */
 
 #ifndef mozilla_css_GroupRule_h__
 #define mozilla_css_GroupRule_h__
 
+#include "mozilla/Attributes.h"
 #include "mozilla/css/Rule.h"
 #include "nsCOMArray.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsPresContext;
 class nsMediaQueryResultCacheKey;
 
@@ -38,17 +39,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // implement part of nsIStyleRule and Rule
   DECL_STYLE_RULE_INHERIT_NO_DOMRULE
   virtual void SetStyleSheet(nsCSSStyleSheet* aSheet);
 
   // to help implement nsIStyleRule
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
 public:
   void AppendStyleRule(Rule* aRule);
 
   int32_t StyleRuleCount() const { return mRules.Count(); }
   Rule* GetStyleRuleAt(int32_t aIndex) const;
 
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -35,17 +35,17 @@ public:
   DECL_STYLE_RULE_INHERIT
 
 #ifdef HAVE_CPP_AMBIGUITY_RESOLVING_USING
   using Rule::GetStyleSheet; // unhide since nsIDOMCSSImportRule has its own GetStyleSheet
 #endif
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<Rule> Clone() const;
 
   void SetSheet(nsCSSStyleSheet*);
 
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -36,17 +36,17 @@ public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
   NS_DECL_ISUPPORTS
 
   DECL_STYLE_RULE_INHERIT
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<Rule> Clone() const;
 
   nsIAtom* GetPrefix() const { return mPrefix; }
 
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -276,17 +276,17 @@ class StyleRule;
 
 class ImportantRule : public nsIStyleRule {
 public:
   ImportantRule(Declaration *aDeclaration);
 
   NS_DECL_ISUPPORTS
 
   // nsIStyleRule interface
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
 protected:
   virtual ~ImportantRule();
 
   // Not an owning reference; the StyleRule that owns this
@@ -354,20 +354,20 @@ public:
 
   virtual already_AddRefed<Rule> Clone() const;
 
   virtual nsIDOMCSSRule* GetDOMRule();
 
   virtual nsIDOMCSSRule* GetExistingDOMRule();
 
   // The new mapping function.
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
 private:
   ~StyleRule();
 
 private:
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -223,16 +223,20 @@ public:
 private:
   static const uint32_t        kFlagsTable[eCSSProperty_COUNT];
 
 public:
   static inline bool PropHasFlags(nsCSSProperty aProperty, uint32_t aFlags)
   {
     NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
                       "out of range");
+    MOZ_ASSERT(!(aFlags & CSS_PROPERTY_PARSE_PROPERTY_MASK),
+               "The CSS_PROPERTY_PARSE_* values are not bitflags; don't pass "
+               "them to PropHasFlags.  You probably want PropertyParseType "
+               "instead.");
     return (nsCSSProps::kFlagsTable[aProperty] & aFlags) == aFlags;
   }
 
   static inline uint32_t PropertyParseType(nsCSSProperty aProperty)
   {
     NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
                       "out of range");
     return nsCSSProps::kFlagsTable[aProperty] &
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -51,17 +51,17 @@ private:
   MediaRule(const MediaRule& aCopy);
   ~MediaRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual void SetStyleSheet(nsCSSStyleSheet* aSheet); //override GroupRule
   virtual int32_t GetType() const;
   virtual already_AddRefed<Rule> Clone() const;
   virtual nsIDOMCSSRule* GetDOMRule()
   {
@@ -109,17 +109,17 @@ private:
   DocumentRule(const DocumentRule& aCopy);
   ~DocumentRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<Rule> Clone() const;
   virtual nsIDOMCSSRule* GetDOMRule()
   {
     return this;
@@ -236,23 +236,23 @@ public:
     : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSFontFaceRule,
                                                          mozilla::css::Rule)
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   DECL_STYLE_RULE_INHERIT
 
-  virtual int32_t GetType() const;
+  virtual int32_t GetType() const MOZ_OVERRIDE;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const;
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSFontFaceRule interface
   NS_DECL_NSIDOMCSSFONTFACERULE
 
@@ -357,17 +357,17 @@ private:
 
 public:
   NS_DECL_ISUPPORTS
 
   DECL_STYLE_RULE_INHERIT
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<Rule> Clone() const;
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
@@ -399,17 +399,17 @@ public:
   virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE;
   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE;
   virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSKeyframeStyleDeclaration,
                                                          nsICSSDeclaration)
 
-  virtual nsINode* GetParentObject();
+  virtual nsINode* GetParentObject() MOZ_OVERRIDE;
 
 protected:
   // This reference is not reference-counted. The rule object tells us
   // when it's about to go away.
   nsCSSKeyframeRule *mRule;
 };
 
 class nsCSSKeyframeRule MOZ_FINAL : public mozilla::css::Rule,
@@ -427,22 +427,22 @@ private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSKeyframeRule, nsIStyleRule)
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   DECL_STYLE_RULE_INHERIT
-  virtual int32_t GetType() const;
+  virtual int32_t GetType() const MOZ_OVERRIDE;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const;
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMMozCSSKeyframeRule interface
   NS_DECL_NSIDOMMOZCSSKEYFRAMERULE
 
@@ -473,17 +473,17 @@ public:
 private:
   nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
   ~nsCSSKeyframesRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const;
   virtual nsIDOMCSSRule* GetDOMRule()
   {
     return this;
@@ -527,17 +527,17 @@ public:
   virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE;
   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE;
   virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSPageStyleDeclaration,
                                                          nsICSSDeclaration)
 
-  virtual nsINode *GetParentObject();
+  virtual nsINode *GetParentObject() MOZ_OVERRIDE;
 
 protected:
   // This reference is not reference-counted. The rule object tells us
   // when it's about to go away.
   nsCSSPageRule *mRule;
 };
 
 class nsCSSPageRule MOZ_FINAL : public mozilla::css::Rule,
@@ -553,37 +553,37 @@ public:
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
   NS_DECL_ISUPPORTS
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   DECL_STYLE_RULE_INHERIT
-  virtual int32_t GetType() const;
+  virtual int32_t GetType() const MOZ_OVERRIDE;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const;
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSPageRule interface
   NS_DECL_NSIDOMCSSPAGERULE
 
   mozilla::css::Declaration* Declaration()   { return mDeclaration; }
 
   void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
 
   mozilla::css::ImportantRule* GetImportantRule();
 
-  virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+  virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE;
 private:
   nsAutoPtr<mozilla::css::Declaration>    mDeclaration;
   // lazily created when needed:
   nsRefPtr<nsCSSPageStyleDeclaration>     mDOMDeclaration;
   nsRefPtr<mozilla::css::ImportantRule>   mImportantRule;
 };
 
 namespace mozilla {
@@ -592,17 +592,17 @@ class CSSSupportsRule : public css::Grou
                         public nsIDOMCSSSupportsRule
 {
 public:
   CSSSupportsRule(bool aConditionMet, const nsString& aCondition);
   CSSSupportsRule(const CSSSupportsRule& aCopy);
 
   // nsIStyleRule methods
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
   virtual int32_t GetType() const;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const;
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                   nsMediaQueryResultCacheKey& aKey);
   virtual nsIDOMCSSRule* GetDOMRule()
--- a/layout/style/nsCSSStyleSheet.h
+++ b/layout/style/nsCSSStyleSheet.h
@@ -113,17 +113,17 @@ public:
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSStyleSheet,
                                                          nsIStyleSheet)
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
 
   // nsIStyleSheet interface
-  virtual nsIURI* GetSheetURI() const;
+  virtual nsIURI* GetSheetURI() const MOZ_OVERRIDE;
   virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE;
   virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE;
   virtual void GetType(nsString& aType) const MOZ_OVERRIDE;
   virtual bool HasRules() const MOZ_OVERRIDE;
   virtual bool IsApplicable() const MOZ_OVERRIDE;
   virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE;
   virtual bool IsComplete() const MOZ_OVERRIDE;
   virtual void SetComplete() MOZ_OVERRIDE;
@@ -206,17 +206,17 @@ public:
                               uint32_t aIndex, uint32_t* aReturn);
 
   /* Get the URI this sheet was originally loaded from, if any.  Can
      return null */
   virtual nsIURI* GetOriginalURI() const;
 
   // nsICSSLoaderObserver interface
   NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
-                              nsresult aStatus);
+                              nsresult aStatus) MOZ_OVERRIDE;
 
   enum EnsureUniqueInnerResult {
     // No work was needed to ensure a unique inner.
     eUniqueInner_AlreadyUnique,
     // A clone was done to ensure a unique inner (which means the style
     // rules in this sheet have changed).
     eUniqueInner_ClonedInner,
     // A clone was attempted, but it failed.
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -40,17 +40,17 @@ public:
 
   NS_DECL_NSICSSDECLARATION
 
   NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER
   virtual already_AddRefed<mozilla::dom::CSSValue>
   GetPropertyCSSValue(const nsAString& aProp, mozilla::ErrorResult& aRv)
     MOZ_OVERRIDE;
   using nsICSSDeclaration::GetPropertyCSSValue;
-  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) MOZ_OVERRIDE;
 
   enum StyleType {
     eDefaultOnly, // Only includes UA and user sheets
     eAll // Includes all stylesheets
   };
 
   nsComputedDOMStyle(mozilla::dom::Element* aElement,
                      const nsAString& aPseudoElt,
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -37,26 +37,26 @@ public:
   NS_IMETHOD_(nsrefcnt) AddRef() = 0;
   NS_IMETHOD_(nsrefcnt) Release() = 0;
 
   NS_DECL_NSICSSDECLARATION
   using nsICSSDeclaration::GetLength;
 
   // Require subclasses to implement |GetParentRule|.
   //NS_DECL_NSIDOMCSSSTYLEDECLARATION
-  NS_IMETHOD GetCssText(nsAString & aCssText);
+  NS_IMETHOD GetCssText(nsAString & aCssText) MOZ_OVERRIDE;
   NS_IMETHOD SetCssText(const nsAString & aCssText) MOZ_OVERRIDE;
   NS_IMETHOD GetPropertyValue(const nsAString & propertyName,
                               nsAString & _retval) MOZ_OVERRIDE;
   virtual already_AddRefed<mozilla::dom::CSSValue>
     GetPropertyCSSValue(const nsAString & propertyName,
                         mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
   using nsICSSDeclaration::GetPropertyCSSValue;
   NS_IMETHOD RemoveProperty(const nsAString & propertyName,
-                            nsAString & _retval);
+                            nsAString & _retval) MOZ_OVERRIDE;
   NS_IMETHOD GetPropertyPriority(const nsAString & propertyName,
                                  nsAString & _retval) MOZ_OVERRIDE;
   NS_IMETHOD SetProperty(const nsAString & propertyName,
                          const nsAString & value, const nsAString & priority) MOZ_OVERRIDE;
   NS_IMETHOD GetLength(uint32_t *aLength) MOZ_OVERRIDE;
   NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) MOZ_OVERRIDE = 0;
 
   // WebIDL interface for CSS2Properties
@@ -85,17 +85,17 @@ public:
 #include "nsCSSPropAliasList.h"
 #undef CSS_PROP_ALIAS
 
 #undef CSS_PROP_SHORTHAND
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 #undef CSS_PROP
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
-  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) MOZ_OVERRIDE;
 
   virtual JSObject* WrapObject(JSContext *cx,
                                JS::Handle<JSObject*> scope) MOZ_OVERRIDE
   {
     return mozilla::dom::CSS2PropertiesBinding::Wrap(cx, scope, this);
   }
 
 protected:
--- a/layout/style/nsHTMLCSSStyleSheet.h
+++ b/layout/style/nsHTMLCSSStyleSheet.h
@@ -26,17 +26,17 @@ public:
   nsHTMLCSSStyleSheet(nsIURI* aURL, nsIDocument* aDocument);
   ~nsHTMLCSSStyleSheet();
 
   NS_DECL_ISUPPORTS
 
   void Reset(nsIURI* aURL);
 
   // nsIStyleSheet
-  virtual nsIURI* GetSheetURI() const;
+  virtual nsIURI* GetSheetURI() const MOZ_OVERRIDE;
   virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE;
   virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE;
   virtual void GetType(nsString& aType) const MOZ_OVERRIDE;
   virtual bool HasRules() const MOZ_OVERRIDE;
   virtual bool IsApplicable() const MOZ_OVERRIDE;
   virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE;
   virtual bool IsComplete() const MOZ_OVERRIDE;
   virtual void SetComplete() MOZ_OVERRIDE;
--- a/layout/style/nsHTMLStyleSheet.h
+++ b/layout/style/nsHTMLStyleSheet.h
@@ -27,17 +27,17 @@ class nsHTMLStyleSheet MOZ_FINAL : publi
                                    public nsIStyleRuleProcessor
 {
 public:
   nsHTMLStyleSheet(nsIURI* aURL, nsIDocument* aDocument);
 
   NS_DECL_ISUPPORTS
 
   // nsIStyleSheet api
-  virtual nsIURI* GetSheetURI() const;
+  virtual nsIURI* GetSheetURI() const MOZ_OVERRIDE;
   virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE;
   virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE;
   virtual void GetType(nsString& aType) const MOZ_OVERRIDE;
   virtual bool HasRules() const MOZ_OVERRIDE;
   virtual bool IsApplicable() const MOZ_OVERRIDE;
   virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE;
   virtual bool IsComplete() const MOZ_OVERRIDE;
   virtual void SetComplete() MOZ_OVERRIDE;
@@ -86,17 +86,17 @@ private:
   friend class HTMLColorRule;
   class HTMLColorRule MOZ_FINAL : public nsIStyleRule {
   public:
     HTMLColorRule() {}
 
     NS_DECL_ISUPPORTS
 
     // nsIStyleRule interface
-    virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+    virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
   #ifdef DEBUG
     virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
   #endif
 
     nscolor             mColor;
   };
 
   // Implementation of SetLink/VisitedLink/ActiveLinkColor
@@ -107,38 +107,38 @@ private:
   class GenericTableRule : public nsIStyleRule {
   public:
     GenericTableRule() {}
     virtual ~GenericTableRule() {}
 
     NS_DECL_ISUPPORTS
 
     // nsIStyleRule interface
-    virtual void MapRuleInfoInto(nsRuleData* aRuleData) = 0;
+    virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE = 0;
   #ifdef DEBUG
     virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
   #endif
   };
 
   // this rule handles <th> inheritance
   class TableTHRule;
   friend class TableTHRule;
   class TableTHRule MOZ_FINAL : public GenericTableRule {
   public:
     TableTHRule() {}
 
-    virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+    virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
   };
 
   // Rule to handle quirk table colors
   class TableQuirkColorRule MOZ_FINAL : public GenericTableRule {
   public:
     TableQuirkColorRule() {}
 
-    virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+    virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
   };
 
   nsCOMPtr<nsIURI>        mURL;
   nsIDocument*            mDocument;
   nsRefPtr<HTMLColorRule> mLinkRule;
   nsRefPtr<HTMLColorRule> mVisitedRule;
   nsRefPtr<HTMLColorRule> mActiveRule;
   nsRefPtr<TableQuirkColorRule> mTableQuirkColorRule;
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -32,26 +32,26 @@ class nsCSSFontFeatureValuesRule;
 class nsCSSPageRule;
 class nsRuleWalker;
 struct ElementDependentRuleProcessorData;
 struct TreeMatchContext;
 
 class nsEmptyStyleRule MOZ_FINAL : public nsIStyleRule
 {
   NS_DECL_ISUPPORTS
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 };
 
 class nsInitialStyleRule MOZ_FINAL : public nsIStyleRule
 {
   NS_DECL_ISUPPORTS
-  virtual void MapRuleInfoInto(nsRuleData* aRuleData);
+  virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE;
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 };
 
 // The style set object is created by the document viewer and ownership is
 // then handed off to the PresShell.  Only the PresShell should delete a
 // style set.
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -161,17 +161,17 @@ public:
    * @return the filter frame, or null if there is no filter frame
    */
   nsSVGFilterFrame *GetFilterFrame();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsISVGFilterProperty
-  virtual void Invalidate() { DoUpdate(); }
+  virtual void Invalidate() MOZ_OVERRIDE { DoUpdate(); }
 
 private:
   // nsSVGRenderingObserver
   virtual void DoUpdate() MOZ_OVERRIDE;
 };
 
 class nsSVGMarkerProperty : public nsSVGIDRenderingObserver {
 public:
--- a/layout/svg/nsSVGForeignObjectFrame.h
+++ b/layout/svg/nsSVGForeignObjectFrame.h
@@ -74,17 +74,17 @@ public:
   NS_IMETHOD GetFrameName(nsAString& aResult) const
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGForeignObject"), aResult);
   }
 #endif
 
   // nsISVGChildFrame interface:
   NS_IMETHOD PaintSVG(nsRenderingContext *aContext,
-                      const nsIntRect *aDirtyRect);
+                      const nsIntRect *aDirtyRect) MOZ_OVERRIDE;
   NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE;
   NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return true; }
 
--- a/layout/svg/nsSVGGlyphFrame.h
+++ b/layout/svg/nsSVGGlyphFrame.h
@@ -224,32 +224,32 @@ public:
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsISVGChildFrame interface:
   // These four always use the global transform, even if NS_STATE_NONDISPLAY_CHILD
   NS_IMETHOD PaintSVG(nsRenderingContext *aContext,
-                      const nsIntRect *aDirtyRect);
+                      const nsIntRect *aDirtyRect) MOZ_OVERRIDE;
   NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
 
   NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return false; }
 
   // nsSVGGeometryFrame methods
   gfxMatrix GetCanvasTM(uint32_t aFor);
 
   // nsISVGGlyphFragmentNode interface:
   // These do not use the global transform if NS_STATE_NONDISPLAY_CHILD
-  virtual uint32_t GetNumberOfChars();
+  virtual uint32_t GetNumberOfChars() MOZ_OVERRIDE;
   virtual float GetComputedTextLength() MOZ_OVERRIDE;
   virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars) MOZ_OVERRIDE;
   virtual int32_t GetCharNumAtPosition(mozilla::nsISVGPoint *point) MOZ_OVERRIDE;
   NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame() MOZ_OVERRIDE;
   NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame() MOZ_OVERRIDE;
   NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace) MOZ_OVERRIDE {
     if (mCompressWhitespace != aCompressWhitespace) {
       mCompressWhitespace = aCompressWhitespace;
--- a/layout/svg/nsSVGInnerSVGFrame.h
+++ b/layout/svg/nsSVGInnerSVGFrame.h
@@ -1,13 +1,14 @@
 /* -*- Mode: C++; 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/. */
 
+#include "mozilla/Attributes.h"
 #include "nsSVGContainerFrame.h"
 #include "nsISVGSVGFrame.h"
 #include "gfxMatrix.h"
 
 class nsRenderingContext;
 
 typedef nsSVGDisplayContainerFrame nsSVGInnerSVGFrameBase;
 
@@ -56,14 +57,14 @@ public:
   NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
 
   // nsSVGContainerFrame methods:
   virtual gfxMatrix GetCanvasTM(uint32_t aFor);
 
   virtual bool HasChildrenOnlyTransform(gfxMatrix *aTransform) const;
 
   // nsISVGSVGFrame interface:
-  virtual void NotifyViewportOrTransformChanged(uint32_t aFlags);
+  virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) MOZ_OVERRIDE;
 
 protected:
 
   nsAutoPtr<gfxMatrix> mCanvasTM;
 };
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef __NS_SVGOUTERSVGFRAME_H__
 #define __NS_SVGOUTERSVGFRAME_H__
 
+#include "mozilla/Attributes.h"
 #include "gfxMatrix.h"
 #include "nsISVGSVGFrame.h"
 #include "nsSVGContainerFrame.h"
 
 class nsSVGForeignObjectFrame;
 
 ////////////////////////////////////////////////////////////////////////
 // nsSVGOuterSVGFrame class
@@ -98,17 +99,17 @@ public:
                                 gfxMatrix *aFromParentTransform) const {
     // Our anonymous wrapper performs the transforms. We simply
     // return whether we are transformed here but don't apply the transforms
     // themselves.
     return GetFirstPrincipalChild()->IsSVGTransformed();
   }
 
   // nsISVGSVGFrame interface:
-  virtual void NotifyViewportOrTransformChanged(uint32_t aFlags);
+  virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) MOZ_OVERRIDE;
 
   // nsISVGChildFrame methods:
   NS_IMETHOD PaintSVG(nsRenderingContext* aContext,
                       const nsIntRect *aDirtyRect);
 
   virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
                                       uint32_t aFlags);
 
--- a/layout/svg/nsSVGPathGeometryFrame.h
+++ b/layout/svg/nsSVGPathGeometryFrame.h
@@ -80,17 +80,17 @@ public:
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsSVGGeometryFrame methods
   gfxMatrix GetCanvasTM(uint32_t aFor);
 
 protected:
   // nsISVGChildFrame interface:
   NS_IMETHOD PaintSVG(nsRenderingContext *aContext,
-                      const nsIntRect *aDirtyRect);
+                      const nsIntRect *aDirtyRect) MOZ_OVERRIDE;
   NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE;
   NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return false; }
 
--- a/layout/svg/nsSVGTSpanFrame.h
+++ b/layout/svg/nsSVGTSpanFrame.h
@@ -63,17 +63,17 @@ public:
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGTSpan"), aResult);
   }
 #endif
   // nsSVGContainerFrame methods:
   virtual gfxMatrix GetCanvasTM(uint32_t aFor);
   
   // nsISVGGlyphFragmentNode interface:
-  virtual uint32_t GetNumberOfChars();
+  virtual uint32_t GetNumberOfChars() MOZ_OVERRIDE;
   virtual float GetComputedTextLength() MOZ_OVERRIDE;
   virtual float GetSubStringLength(uint32_t charnum, uint32_t fragmentChars) MOZ_OVERRIDE;
   virtual int32_t GetCharNumAtPosition(mozilla::nsISVGPoint *point) MOZ_OVERRIDE;
   NS_IMETHOD_(nsSVGGlyphFrame *) GetFirstGlyphFrame() MOZ_OVERRIDE;
   NS_IMETHOD_(nsSVGGlyphFrame *) GetNextGlyphFrame() MOZ_OVERRIDE;
   NS_IMETHOD_(void) SetWhitespaceCompression(bool aCompressWhitespace) MOZ_OVERRIDE;
 };
 
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -55,39 +55,39 @@ public:
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   NS_IMETHOD  AttributeChanged(int32_t         aNameSpaceID,
                                nsIAtom*        aAttribute,
-                               int32_t         aModType);
+                               int32_t         aModType) MOZ_OVERRIDE;
 
   /** @see nsIFrame::DidSetStyleContext */
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
   // table cells contain a block frame which does most of the work, and
   // so these functions should never be called. They assert and return
   // NS_ERROR_NOT_IMPLEMENTED
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   }
 
-  virtual nsMargin GetUsedMargin() const;
+  virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
 
-  virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState);
+  virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE;
 
   virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE;
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
@@ -96,35 +96,35 @@ public:
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   void PaintCellBackground(nsRenderingContext& aRenderingContext,
                            const nsRect& aDirtyRect, nsPoint aPt,
                            uint32_t aFlags);
 
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual IntrinsicWidthOffsetData
-    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext);
+    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*      aPresContext,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&      aStatus);
+                    nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsLayoutAtoms::tableCellFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   void VerticallyAlignChild(nscoord aMaxAscent);
 
   /*
    * Get the value of vertical-align adjusted for CSS 2's rules for a
    * table cell, which means the result is always
    * NS_STYLE_VERTICAL_ALIGN_{TOP,MIDDLE,BOTTOM,BASELINE}.
@@ -157,17 +157,17 @@ public:
 
   /*---------------- nsITableCellLayout methods ------------------------*/
 
   /**
    * return the cell's starting row index (starting at 0 for the first row).
    * for continued cell frames the row index is that of the cell's first-in-flow
    * and the column index (starting at 0 for the first column
    */
-  NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex);
+  NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex) MOZ_OVERRIDE;
 
   /** return the mapped cell's row index (starting at 0 for the first row) */
   virtual nsresult GetRowIndex(int32_t &aRowIndex) const MOZ_OVERRIDE;
 
   /**
    * return the cell's specified col span. this is what was specified in the
    * content model or in the style info, and is always >= 1.
    * to get the effective col span (the actual value that applies), use GetEffectiveColSpan()
@@ -204,19 +204,19 @@ public:
   virtual void PaintBackground(nsRenderingContext& aRenderingContext,
                                const nsRect&        aDirtyRect,
                                nsPoint              aPt,
                                uint32_t             aFlags);
 
   void DecorateForSelection(nsRenderingContext& aRenderingContext,
                             nsPoint              aPt);
 
-  virtual bool UpdateOverflow();
+  virtual bool UpdateOverflow() MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
   }
   
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
 
@@ -292,18 +292,18 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsBCTableCellFrame(nsStyleContext* aContext);
 
   ~nsBCTableCellFrame();
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual nsMargin GetUsedBorder() const;
-  virtual bool GetBorderRadii(nscoord aRadii[8]) const;
+  virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
+  virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE;
 
   // Get the *inner half of the border only*, in twips.
   virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const MOZ_OVERRIDE;
 
   // Get the *inner half of the border only*, in pixels.
   BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const;
 
   // Set the full (both halves) width of the border
--- a/layout/tables/nsTableColFrame.h
+++ b/layout/tables/nsTableColFrame.h
@@ -259,17 +259,17 @@ public:
   }
   void SetFinalWidth(nscoord aFinalWidth) {
     mFinalWidth = aFinalWidth;
   }
   nscoord GetFinalWidth() {
     return mFinalWidth;
   }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
   }
   
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
 
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -192,17 +192,17 @@ public:
   void GetContinuousBCBorderWidth(nsMargin& aBorder);
   /**
    * Set full border widths before collapsing with cell borders
    * @param aForSide - side to set; only accepts top and bottom
    */
   void SetContinuousBCBorderWidth(uint8_t     aForSide,
                                   BCPixelSize aPixelValue);
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
   }
   
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
 
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; 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/. */
 #ifndef nsTableFrame_h__
 #define nsTableFrame_h__
 
+#include "mozilla/Attributes.h"
 #include "celldata.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
 #include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
 #include "nsTableColFrame.h"
 #include "nsTableColGroupFrame.h"
 #include "nsCellMap.h"
@@ -45,22 +46,22 @@ static inline bool FrameHasBorderOrBackg
 class nsDisplayTableItem : public nsDisplayItem
 {
 public:
   nsDisplayTableItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : 
       nsDisplayItem(aBuilder, aFrame),
       mPartHasFixedBackground(false) {}
 
   virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
-                                                nsIFrame* aFrame);
+                                                nsIFrame* aFrame) MOZ_OVERRIDE;
   // With collapsed borders, parts of the collapsed border can extend outside
   // the table part frames, so allow this display element to blow out to our
   // overflow rect. This is also useful for row frames that have spanning
   // cells extending outside them.
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
 
   void UpdateForFrameBackground(nsIFrame* aFrame);
 
 private:
   bool mPartHasFixedBackground;
 };
 
 class nsAutoPushCurrentTableItem
@@ -150,32 +151,32 @@ public:
   /*
    * Notification that aAttribute has changed for content inside a table (cell, row, etc)
    */
   void AttributeChangedFor(nsIFrame*       aFrame,
                            nsIContent*     aContent, 
                            nsIAtom*        aAttribute); 
 
   /** @see nsIFrame::DestroyFrom */
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   
   /** @see nsIFrame::DidSetStyleContext */
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
   NS_IMETHOD AppendFrames(ChildListID     aListID,
-                          nsFrameList&    aFrameList);
+                          nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
-                          nsFrameList&    aFrameList);
+                          nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
-                         nsIFrame*       aOldFrame);
+                         nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsMargin GetUsedBorder() const;
-  virtual nsMargin GetUsedPadding() const;
-  virtual nsMargin GetUsedMargin() const;
+  virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
 
   // Get the offset from the border box to the area where the row groups fit
   nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
 
   /** helper method to find the table parent of any table frame object */
   static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
                                  
   typedef void (* DisplayGenericTablePartTraversal)
@@ -213,20 +214,20 @@ public:
     * (header, footer, or body)
     */
   bool IsRowGroup(int32_t aDisplayType) const;
 
   /** Initialize the table frame with a set of children.
     * @see nsIFrame::SetInitialChildList 
     */
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
-                                 nsFrameList&    aChildList);
+                                 nsFrameList&    aChildList) MOZ_OVERRIDE;
 
-  virtual const nsFrameList& GetChildList(ChildListID aListID) const;
-  virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
+  virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
+  virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   /**
    * Paint the background of the table and its parts (column groups,
    * columns, row groups, rows, and cells), and the table border, and all
@@ -269,32 +270,32 @@ public:
   friend class nsDelayedCalcBCBorders;
   
   void AddBCDamageArea(const nsIntRect& aValue);
   bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
                         nsStyleContext* aNewStyleContext);
   void PaintBCBorders(nsRenderingContext& aRenderingContext,
                       const nsRect&        aDirtyRect);
 
-  virtual void MarkIntrinsicWidthsDirty();
+  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   // For border-collapse tables, the caller must not add padding and
   // border to the results of these functions.
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual IntrinsicWidthOffsetData
-    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext);
+    IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
-                                 nsSize aPadding, bool aShrinkWrap);
+                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
   /**
    * A copy of nsFrame::ShrinkWidthToFit that calls a different
    * GetPrefWidth, since tables have two different ones.
    */
   nscoord TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
                                 nscoord aWidthInCB);
 
   // XXXldb REWRITE THIS COMMENT!
@@ -310,46 +311,46 @@ public:
     *     use column widths to Reflow cells
     * </pre>
     *
     * @see nsIFrame::Reflow
     */
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   nsresult ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
                        const nsHTMLReflowState& aReflowState,
                        nscoord                  aAvailHeight,
                        nsIFrame*&               aLastChildReflowed,
                        nsReflowStatus&          aStatus);
 
   nsFrameList& GetColGroups();
 
-  virtual nsIFrame* GetParentStyleContextFrame() const;
+  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     if (aFlags & eSupportsCSSTransforms) {
       return false;
     }
     return nsContainerFrame::IsFrameOfType(aFlags);
   }
 
 #ifdef DEBUG
   /** @see nsIFrame::GetFrameName */
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   /** return the width of the column at aColIndex    */
   int32_t GetColumnWidth(int32_t aColIndex);
 
   /** helper to get the cell spacing X style value */
   nscoord GetCellSpacingX();
 
@@ -482,17 +483,17 @@ public:
    * @param aIsFirstReflow True if the size/position change is due to the
    *                       first reflow of aFrame.
    */
   static void InvalidateTableFrame(nsIFrame* aFrame,
                                    const nsRect& aOrigRect,
                                    const nsRect& aOrigVisualOverflow,
                                    bool aIsFirstReflow);
 
-  virtual bool UpdateOverflow();
+  virtual bool UpdateOverflow() MOZ_OVERRIDE;
 
 protected:
 
   /** protected constructor. 
     * @see NewFrame
     */
   nsTableFrame(nsStyleContext* aContext);
 
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -13,17 +13,17 @@
 #include "nsTableFrame.h"
 
 class nsTableCaptionFrame : public nsBlockFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsISupports
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   friend nsIFrame* NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext*  aContext);
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap);
 
   virtual nsIFrame* GetParentStyleContextFrame() const;
@@ -63,35 +63,35 @@ public:
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   
   // nsIFrame overrides - see there for a description
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
  
-  virtual const nsFrameList& GetChildList(ChildListID aListID) const;
+  virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
 
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame() {
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
@@ -272,17 +272,17 @@ protected:
   // Get the margin.  aMarginNoAuto is aMargin, but with auto 
   // margins set to 0
   void GetChildMargin(nsPresContext*           aPresContext,
                       const nsHTMLReflowState& aOuterRS,
                       nsIFrame*                aChildFrame,
                       nscoord                  aAvailableWidth,
                       nsMargin&                aMargin);
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
                                            (~eCanContainOverflowContainers));
   }
 
   nsTableFrame* InnerTableFrame() const {
     return static_cast<nsTableFrame*>(mFrames.FirstChild());
   }
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -41,36 +41,36 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual ~nsTableRowFrame();
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
   /** @see nsIFrame::DidSetStyleContext */
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  virtual nsMargin GetUsedMargin() const;
-  virtual nsMargin GetUsedBorder() const;
-  virtual nsMargin GetUsedPadding() const;
+  virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   nsTableCellFrame* GetFirstCell() ;
 
   /** calls Reflow for all of its child cells.
@@ -219,17 +219,17 @@ public:
   nscoord GetOuterTopContBCBorderWidth();
   /**
    * Sets full border widths before collapsing with cell borders
    * @param aForSide - side to set; only accepts right, left, and top
    */
   void SetContinuousBCBorderWidth(uint8_t     aForSide,
                                   BCPixelSize aPixelValue);
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
   }
 
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
 
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -72,31 +72,31 @@ public:
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   virtual ~nsTableRowGroupFrame();
   /** @see nsIFrame::DidSetStyleContext */
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   
   NS_IMETHOD AppendFrames(ChildListID     aListID,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
   
   NS_IMETHOD InsertFrames(ChildListID     aListID,
                           nsIFrame*       aPrevFrame,
                           nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsMargin GetUsedMargin() const;
-  virtual nsMargin GetUsedBorder() const;
-  virtual nsMargin GetUsedPadding() const;
+  virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
+  virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
    /** calls Reflow for all of its child rows.
     * Rows are all set to the same width and stacked vertically.
     * <P> rows are not split unless absolutely necessary.
@@ -104,29 +104,29 @@ public:
     * @param aDesiredSize width set to width of rows, height set to 
     *                     sum of height of rows that fit in aMaxSize.height.
     *
     * @see nsIFrame::Reflow
     */
   NS_IMETHOD Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
-                    nsReflowStatus&          aStatus);
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableRowGroupFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   nsTableRowFrame* GetFirstRow();
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   /** return the number of child rows (not necessarily == number of child frames) */
   int32_t GetRowCount();
 
   /** return the table-relative row index of the first row in this rowgroup.
     * if there are no rows, -1 is returned.
     */
@@ -318,19 +318,19 @@ public:
    * Set up the row cursor. After this, call AppendFrame for every
    * child frame in sibling order. Ensure that the child frame y and YMost values
    * form non-decreasing sequences (should always be true for table rows);
    * if this is violated, call ClearRowCursor(). If we return nullptr, then we
    * decided not to use a cursor or we already have one set up.
    */
   FrameCursorData* SetupRowCursor();
 
-  virtual nsILineIterator* GetLineIterator() { return this; }
+  virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE { return this; }
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
   }
 
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); }
 
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -37,16 +37,18 @@ var gFailureTimeout = null;
 var gFailureReason;
 var gAssertionCount = 0;
 
 var gDebug;
 
 var gCurrentTestStartTime;
 var gClearingForAssertionCheck = false;
 
+const TYPE_LOAD = 'load';  // test without a reference (just test that it does
+                           // not assert, crash, hang, or leak)
 const TYPE_SCRIPT = 'script'; // test contains individual test results
 
 function markupDocumentViewer() {
     return docShell.contentViewer.QueryInterface(CI.nsIMarkupDocumentViewer);
 }
 
 function webNavigation() {
     return docShell.QueryInterface(CI.nsIWebNavigation);
@@ -633,16 +635,22 @@ function LogInfo(str)
 {
     sendAsyncMessage("reftest:Log", { type: "info", msg: str });
 }
 
 const SYNC_DEFAULT = 0x0;
 const SYNC_ALLOW_DISABLE = 0x1;
 function SynchronizeForSnapshot(flags)
 {
+    if (gCurrentTestType == TYPE_SCRIPT ||
+        gCurrentTestType == TYPE_LOAD) {
+        // Script tests or load-only tests do not need any snapshotting
+        return;
+    }
+
     if (flags & SYNC_ALLOW_DISABLE) {
         var docElt = content.document.documentElement;
         if (docElt && docElt.hasAttribute("reftest-no-sync-layers")) {
             LogInfo("Test file chose to skip SynchronizeForSnapshot");
             return;
         }
     }
 
--- a/layout/xul/base/src/nsBox.h
+++ b/layout/xul/base/src/nsBox.h
@@ -1,60 +1,61 @@
 /* -*- Mode: C++; 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/. */
 
 #ifndef nsBox_h___
 #define nsBox_h___
 
+#include "mozilla/Attributes.h"
 #include "nsIFrame.h"
 
 class nsITheme;
 
 #define NS_STATE_IS_ROOT        NS_FRAME_STATE_BIT(24)
 #define NS_STATE_SET_TO_DEBUG   NS_FRAME_STATE_BIT(26)
 #define NS_STATE_DEBUG_WAS_SET  NS_FRAME_STATE_BIT(27)
 
 class nsBox : public nsIFrame {
 
 public:
 
   friend class nsIFrame;
 
   static void Shutdown();
 
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
-  virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
-  virtual bool IsCollapsed();
+  virtual bool IsCollapsed() MOZ_OVERRIDE;
 
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
-                         bool aRemoveOverflowAreas = false);
+                         bool aRemoveOverflowAreas = false) MOZ_OVERRIDE;
 
-  NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding);
-  NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding);
-  NS_IMETHOD GetMargin(nsMargin& aMargin);
+  NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding) MOZ_OVERRIDE;
+  NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding) MOZ_OVERRIDE;
+  NS_IMETHOD GetMargin(nsMargin& aMargin) MOZ_OVERRIDE;
 
-  virtual Valignment GetVAlign() const { return vAlign_Top; }
-  virtual Halignment GetHAlign() const { return hAlign_Left; }
+  virtual Valignment GetVAlign() const MOZ_OVERRIDE { return vAlign_Top; }
+  virtual Halignment GetHAlign() const MOZ_OVERRIDE { return hAlign_Left; }
 
-  NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild);
+  NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) MOZ_OVERRIDE;
 
 #ifdef DEBUG_LAYOUT
   NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIFrame** aBox);
-  NS_IMETHOD GetDebug(bool& aDebug);
-  NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug);
+  NS_IMETHOD GetDebug(bool& aDebug) MOZ_OVERRIDE;
+  NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug) MOZ_OVERRIDE;
 
-  NS_IMETHOD DumpBox(FILE* out);
+  NS_IMETHOD DumpBox(FILE* out) MOZ_OVERRIDE;
   NS_HIDDEN_(void) PropagateDebug(nsBoxLayoutState& aState);
 #endif
 
   nsBox();
   virtual ~nsBox();
 
   /**
    * Returns true if this box clips its children, e.g., if this box is an sc
--- a/layout/xul/base/src/nsBoxFrame.h
+++ b/layout/xul/base/src/nsBoxFrame.h
@@ -54,33 +54,33 @@ public:
                                   bool aIsRoot,
                                   nsBoxLayout* aLayoutManager);
   friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell,
                                   nsStyleContext* aContext);
 
   // gets the rect inside our border and debug border. If you wish to paint inside a box
   // call this method to get the rect so you don't draw on the debug border or outer border.
 
-  virtual void SetLayoutManager(nsBoxLayout* aLayout) { mLayoutManager = aLayout; }
-  virtual nsBoxLayout* GetLayoutManager() { return mLayoutManager; }
+  virtual void SetLayoutManager(nsBoxLayout* aLayout) MOZ_OVERRIDE { mLayoutManager = aLayout; }
+  virtual nsBoxLayout* GetLayoutManager() MOZ_OVERRIDE { return mLayoutManager; }
 
-  NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild);
+  NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) MOZ_OVERRIDE;
 
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 #ifdef DEBUG_LAYOUT
-  NS_IMETHOD SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug);
+  NS_IMETHOD SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug) MOZ_OVERRIDE;
   NS_IMETHOD GetDebug(bool& aDebug) MOZ_OVERRIDE;
 #endif
   virtual Valignment GetVAlign() const MOZ_OVERRIDE { return mValign; }
   virtual Halignment GetHAlign() const MOZ_OVERRIDE { return mHalign; }
-  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
+  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; }
 
   // ----- child and sibling operations ---
 
   // ----- public methods -------
   
   virtual void Init(nsIContent*      aContent,
@@ -106,26 +106,26 @@ public:
 
   NS_IMETHOD  InsertFrames(ChildListID     aListID,
                            nsIFrame*       aPrevFrame,
                            nsFrameList&    aFrameList) MOZ_OVERRIDE;
 
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame();
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
 
   NS_IMETHOD  SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // record that children that are ignorable whitespace should be excluded 
     // (When content was loaded via the XUL content sink, it's already
     // been excluded, but we need this for when the XUL namespace is used
     // in other MIME types or when the XUL CSS display types are used with
     // non-XUL elements.)
 
     // This is bogus, but it's what we've always done.
@@ -140,17 +140,17 @@ public:
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   NS_IMETHOD DidReflow(nsPresContext*           aPresContext,
                        const nsHTMLReflowState*  aReflowState,
                        nsDidReflowStatus         aStatus) MOZ_OVERRIDE;
 
-  virtual bool HonorPrintBackgroundSettings();
+  virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE;
 
   virtual ~nsBoxFrame();
   
   nsBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot = false, nsBoxLayout* aLayoutManager = nullptr);
 
   // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame
   // can override it
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
--- a/layout/xul/base/src/nsBoxObject.h
+++ b/layout/xul/base/src/nsBoxObject.h
@@ -26,17 +26,17 @@ class nsBoxObject : public nsPIBoxObject
   NS_DECL_CYCLE_COLLECTION_CLASS(nsBoxObject)
   NS_DECL_NSIBOXOBJECT
 
 public:
   nsBoxObject();
   virtual ~nsBoxObject();
 
   // nsPIBoxObject
-  virtual nsresult Init(nsIContent* aContent);
+  virtual nsresult Init(nsIContent* aContent) MOZ_OVERRIDE;
   virtual void Clear() MOZ_OVERRIDE;
   virtual void ClearCachedValues() MOZ_OVERRIDE;
 
   nsIFrame* GetFrame(bool aFlushLayout);
   nsIPresShell* GetPresShell(bool aFlushLayout);
   nsresult GetOffsetRect(nsIntRect& aRect);
   nsresult GetScreenPosition(nsIntPoint& aPoint);
 
--- a/layout/xul/base/src/nsImageBoxFrame.h
+++ b/layout/xul/base/src/nsImageBoxFrame.h
@@ -39,18 +39,18 @@ private:
 class nsImageBoxFrame : public nsLeafBoxFrame
 {
 public:
   typedef mozilla::layers::LayerManager LayerManager;
 
   friend class nsDisplayXULImage;
   NS_DECL_FRAMEARENA_HELPERS
 
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
 
   nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
 
   friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual void Init(nsIContent*      aContent,
@@ -58,17 +58,17 @@ public:
                     nsIFrame*        asPrevInFlow) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
                               int32_t aModType) MOZ_OVERRIDE;
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   /** 
    * Update mUseSrcAttr from appropriate content attributes or from
@@ -135,22 +135,22 @@ public:
   virtual ~nsDisplayXULImage() {
     MOZ_COUNT_DTOR(nsDisplayXULImage);
   }
 #endif
 
   virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
                                                         nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
   virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = true;
     return nsRect(ToReferenceFrame(), Frame()->GetSize());
   }
 
   // Doesn't handle HitTest because nsLeafBoxFrame already creates an
   // event receiver for us
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE)
 };
 
 #endif /* nsImageBoxFrame_h___ */
--- a/layout/xul/base/src/nsLeafBoxFrame.h
+++ b/layout/xul/base/src/nsLeafBoxFrame.h
@@ -13,18 +13,18 @@ class nsAccessKeyInfo;
 
 class nsLeafBoxFrame : public nsLeafFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewLeafBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aState);
-  virtual nsSize GetMinSize(nsBoxLayoutState& aState);
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual nscoord GetFlex(nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aState) MOZ_OVERRIDE;
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // This is bogus, but it's what we've always done.
--- a/layout/xul/base/src/nsListBoxBodyFrame.h
+++ b/layout/xul/base/src/nsListBoxBodyFrame.h
@@ -51,29 +51,29 @@ public:
   virtual void Init(nsIContent*     aContent,
                     nsIFrame*       aParent, 
                     nsIFrame*       aPrevInFlow) MOZ_OVERRIDE;
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE;
 
   // nsIScrollbarMediator
-  NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex);
+  NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) MOZ_OVERRIDE;
   NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE;
   NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE;
 
   // nsIReflowCallback
   virtual bool ReflowFinished() MOZ_OVERRIDE;
   virtual void ReflowCallbackCanceled() MOZ_OVERRIDE;
 
-  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
+  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
 
-  virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   // size calculation 
   int32_t GetRowCount();
   int32_t GetRowHeightAppUnits() { return mRowHeight; }
   int32_t GetFixedRowSize();
   void SetRowHeight(nscoord aRowHeight);
   nscoord GetYPosition();
   nscoord GetAvailableHeight();
--- a/layout/xul/base/src/nsListBoxLayout.h
+++ b/layout/xul/base/src/nsListBoxLayout.h
@@ -16,17 +16,17 @@ class nsBoxLayoutState;
 class nsListBoxLayout : public nsGridRowGroupLayout
 {
 public:
   nsListBoxLayout();
 
   // nsBoxLayout
   NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
-  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
 protected:
   NS_IMETHOD LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState);
 };
 
 #endif
 
--- a/layout/xul/base/src/nsMenuBarFrame.h
+++ b/layout/xul/base/src/nsMenuBarFrame.h
@@ -35,19 +35,19 @@ public:
   virtual nsMenuFrame* GetCurrentMenuItem() MOZ_OVERRIDE;
   NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE;
   virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE;
   NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE;
 
   NS_IMETHOD SetActive(bool aActiveFlag) MOZ_OVERRIDE; 
 
   virtual bool IsMenuBar() MOZ_OVERRIDE { return true; }
-  virtual bool IsContextMenu() { return false; }
+  virtual bool IsContextMenu() MOZ_OVERRIDE { return false; }
   virtual bool IsActive() MOZ_OVERRIDE { return mIsActive; }
-  virtual bool IsMenu() { return false; }
+  virtual bool IsMenu() MOZ_OVERRIDE { return false; }
   virtual bool IsOpen() MOZ_OVERRIDE { return true; } // menubars are considered always open
 
   bool IsMenuOpen() { return mCurrentMenu && mCurrentMenu->IsOpen(); }
 
   void InstallKeyboardNavigator();
   void RemoveKeyboardNavigator();
 
   virtual void Init(nsIContent*      aContent,
--- a/layout/xul/base/src/nsMenuFrame.h
+++ b/layout/xul/base/src/nsMenuFrame.h
@@ -94,18 +94,18 @@ public:
 #endif
 
   // The following methods are all overridden so that the menupopup
   // can be stored in a separate list, so that it doesn't impact reflow of the
   // actual menu item at all.
   virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
-                                 nsFrameList&    aChildList);
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+                                 nsFrameList&    aChildList) MOZ_OVERRIDE;
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   // Overridden to prevent events from going to children of the menu.
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists) MOZ_OVERRIDE;
                                          
   // this method can destroy the frame
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
@@ -121,17 +121,17 @@ public:
 
   NS_IMETHOD  RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE { return nsGkAtoms::menuFrame; }
 
   NS_IMETHOD SelectMenu(bool aActivateFlag);
 
-  virtual nsIScrollableFrame* GetScrollTargetFrame();
+  virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE;
 
   /**
    * NOTE: OpenMenu will open the menu asynchronously.
    */
   void OpenMenu(bool aSelectFirstItem);
   // CloseMenu closes the menu asynchronously
   void CloseMenu(bool aDeselectMenu);
 
@@ -141,17 +141,17 @@ public:
   NS_IMETHOD SetActiveChild(nsIDOMElement* aChild);
 
   // called when the Enter key is pressed while the menuitem is the current
   // one in its parent popup. This will carry out the command attached to
   // the menuitem. If the menu should be opened, this frame will be returned,
   // otherwise null will be returned.
   nsMenuFrame* Enter(nsGUIEvent* aEvent);
 
-  virtual void SetParent(nsIFrame* aParent);
+  virtual void SetParent(nsIFrame* aParent) MOZ_OVERRIDE;
 
   virtual nsMenuParent *GetMenuParent() { return mMenuParent; }
   const nsAString& GetRadioGroupName() { return mGroupName; }
   nsMenuType GetMenuType() { return mType; }
   nsMenuPopupFrame* GetPopup();
 
   /**
    * @return true if this frame has a popup child frame.
--- a/layout/xul/base/src/nsMenuPopupFrame.h
+++ b/layout/xul/base/src/nsMenuPopupFrame.h
@@ -115,27 +115,27 @@ class nsMenuPopupFrame : public nsBoxFra
 public:
   NS_DECL_QUERYFRAME_TARGET(nsMenuPopupFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContext);
 
   // nsMenuParent interface
-  virtual nsMenuFrame* GetCurrentMenuItem();
+  virtual nsMenuFrame* GetCurrentMenuItem() MOZ_OVERRIDE;
   NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE;
   virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE;
   NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE;
 
   // as popups are opened asynchronously, the popup pending state is used to
   // prevent multiple requests from attempting to open the same popup twice
   nsPopupState PopupState() { return mPopupState; }
   void SetPopupState(nsPopupState aPopupState) { mPopupState = aPopupState; }
 
-  NS_IMETHOD SetActive(bool aActiveFlag) { return NS_OK; } // We don't care.
+  NS_IMETHOD SetActive(bool aActiveFlag) MOZ_OVERRIDE { return NS_OK; } // We don't care.
   virtual bool IsActive() MOZ_OVERRIDE { return false; }
   virtual bool IsMenuBar() MOZ_OVERRIDE { return false; }
 
   /*
    * When this popup is open, should clicks outside of it be consumed?
    * Return true if the popup should rollup on an outside click, 
    * but consume that click so it can't be used for anything else.
    * Return false to allow clicks outside the popup to activate content 
@@ -187,17 +187,17 @@ public:
   void EnsureWidget();
 
   nsresult CreateWidgetForView(nsView* aView);
   uint8_t GetShadowStyle();
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList) MOZ_OVERRIDE;
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
 
   // layout, position and display the popup as needed
   void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, bool aSizedToPopup);
 
   nsView* GetRootViewForPopup(nsIFrame* aStartFrame);
 
   // set the position of the popup either relative to the anchor aAnchorFrame
   // (or the frame for mAnchorContent if aAnchorFrame is null) or at a specific
@@ -213,17 +213,17 @@ public:
   // just pass the call down to the current menu, if any. If a current menu
   // should be opened as a result, this method should return the frame for
   // that menu, or null if no menu should be opened. Also, calling Enter will
   // reset the current incremental search string, calculated in
   // FindMenuWithShortcut.
   nsMenuFrame* Enter(nsGUIEvent* aEvent);
 
   nsPopupType PopupType() const { return mPopupType; }
-  bool IsMenu() { return mPopupType == ePopupTypeMenu; }
+  bool IsMenu() MOZ_OVERRIDE { return mPopupType == ePopupTypeMenu; }
   bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; }
 
   bool IsDragPopup() { return mIsDragPopup; }
 
   static nsIContent* GetTriggerContent(nsMenuPopupFrame* aMenuPopupFrame);
   void ClearTriggerContent() { mTriggerContent = nullptr; }
 
   // returns true if the popup is in a content shell, or false for a popup in
@@ -337,17 +337,17 @@ public:
   // Return the offset applied to the alignment of the popup
   nscoord GetAlignmentOffset() const { return mAlignmentOffset; }
 protected:
 
   // returns the popup's level.
   nsPopupLevel PopupLevel(bool aIsNoAutoHide) const;
 
   // redefine to tell the box system not to move the views.
-  virtual void GetLayoutFlags(uint32_t& aFlags);
+  virtual void GetLayoutFlags(uint32_t& aFlags) MOZ_OVERRIDE;
 
   void InitPositionFromAnchorAlign(const nsAString& aAnchor,
                                    const nsAString& aAlign);
 
   // return the position where the popup should be, when it should be
   // anchored at anchorRect. aHFlip and aVFlip will be set if the popup may be
   // flipped in that direction if there is not enough space available.
   nsPoint AdjustPositionForAnchorAlign(nsRect& anchorRect,
--- a/layout/xul/base/src/nsProgressMeterFrame.h
+++ b/layout/xul/base/src/nsProgressMeterFrame.h
@@ -22,17 +22,17 @@
 
 class nsProgressMeterFrame : public nsBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewProgressMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
+  NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
                               int32_t aModType) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
--- a/layout/xul/base/src/nsScrollbarFrame.h
+++ b/layout/xul/base/src/nsScrollbarFrame.h
@@ -21,17 +21,17 @@ class nsScrollbarFrame : public nsBoxFra
 {
 public:
     nsScrollbarFrame(nsIPresShell* aShell, nsStyleContext* aContext):
       nsBoxFrame(aShell, aContext), mScrollbarMediator(nullptr) {}
 
   NS_DECL_QUERYFRAME_TARGET(nsScrollbarFrame)
 
 #ifdef DEBUG
-  NS_IMETHOD GetFrameName(nsAString& aResult) const {
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("ScrollbarFrame"), aResult);
   }
 #endif
 
   // nsIFrame overrides
   NS_IMETHOD AttributeChanged(int32_t aNameSpaceID,
                               nsIAtom* aAttribute,
                               int32_t aModType) MOZ_OVERRIDE;
--- a/layout/xul/base/src/nsSprocketLayout.h
+++ b/layout/xul/base/src/nsSprocketLayout.h
@@ -63,22 +63,22 @@ nsresult NS_NewSprocketLayout(nsIPresShe
 
 class nsSprocketLayout : public nsBoxLayout {
 
 public:
 
   friend nsresult NS_NewSprocketLayout(nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout>& aNewLayout);
   static void Shutdown();
 
-  NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState);
+  NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
 
   virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
-  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   nsSprocketLayout();
 
   static bool IsHorizontal(nsIFrame* aBox);
 
   static void SetLargestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal);
   static void SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal);
 
--- a/layout/xul/base/src/nsStackLayout.h
+++ b/layout/xul/base/src/nsStackLayout.h
@@ -27,17 +27,17 @@ class nsStackLayout : public nsBoxLayout
 {
 public:
 
   friend nsresult NS_NewStackLayout(nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout>& aNewLayout);
   static void Shutdown();
 
   nsStackLayout();
 
-  NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState);
+  NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
 
   virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   // get the child offsets for aChild and set them in aMargin. Returns a
   // bitfield mask of the SPECIFIED_LEFT, SPECIFIED_RIGHT, SPECIFIED_TOP and
--- a/layout/xul/grid/nsGridLayout2.h
+++ b/layout/xul/grid/nsGridLayout2.h
@@ -28,43 +28,43 @@ class nsGridLayout2 : public nsStackLayo
 {
 public:
 
   friend nsresult NS_NewGridLayout2(nsIPresShell* aPresShell, nsBoxLayout** aNewLayout);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
-  virtual void IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
+  virtual void IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
-  virtual nsGridRowGroupLayout* CastToRowGroupLayout() { return nullptr; }
+  virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return nullptr; }
   virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return this; }
   virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE;
   virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE {
     NS_NOTREACHED("Should not be called"); return nullptr;
   }
   virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE { aRowCount++; }
   virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE { }
   virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE;
   virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE;
   virtual Type GetType() MOZ_OVERRIDE { return eGrid; }
   virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState,
                                 nsIFrame* aPrevBox,
-                                const nsFrameList::Slice& aNewChildren);
+                                const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE;
   virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState,
-                                const nsFrameList::Slice& aNewChildren);
+                                const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE;
   virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState,
-                               nsIFrame* aChildList);
+                               nsIFrame* aChildList) MOZ_OVERRIDE;
   virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState,
-                           nsIFrame* aChildList);
+                           nsIFrame* aChildList) MOZ_OVERRIDE;
 
-  virtual nsIGridPart* AsGridPart() { return this; }
+  virtual nsIGridPart* AsGridPart() MOZ_OVERRIDE { return this; }
 
   static void AddOffset(nsBoxLayoutState& aState, nsIFrame* aChild, nsSize& aSize);
 
 protected:
 
   nsGridLayout2(nsIPresShell* aShell);
   nsGrid mGrid;
 
--- a/layout/xul/grid/nsGridRowGroupLayout.h
+++ b/layout/xul/grid/nsGridRowGroupLayout.h
@@ -20,20 +20,20 @@
  * The nsBoxLayout implementation for nsGridRowGroupFrame.
  */
 class nsGridRowGroupLayout : public nsGridRowLayout
 {
 public:
 
   friend already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout();
 
-  virtual nsGridRowGroupLayout* CastToRowGroupLayout() { return this; }
-  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
+  virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return this; }
+  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE;
   virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE;
   virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE;
   virtual int32_t GetRowCount() MOZ_OVERRIDE { return mRowCount; }
   virtual Type GetType() MOZ_OVERRIDE { return eRowGroup; }
 
 protected:
--- a/layout/xul/grid/nsGridRowLayout.h
+++ b/layout/xul/grid/nsGridRowLayout.h
@@ -29,30 +29,30 @@ class nsGrid;
 // XXXldb This needs a name that indicates that it's a base class for
 // both row and rows (row-group).
 class nsGridRowLayout : public nsSprocketLayout,
                         public nsIGridPart
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  virtual nsGridRowGroupLayout* CastToRowGroupLayout() { return nullptr; }
+  virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return nullptr; }
   virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return nullptr; }
   virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE;
   virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE;
   virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState,
                                 nsIFrame* aPrevBox,
-                                const nsFrameList::Slice& aNewChildren);
+                                const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE;
   virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState,
-                                const nsFrameList::Slice& aNewChildren);
-  virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList);
-  virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList);
+                                const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE;
+  virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) MOZ_OVERRIDE;
+  virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) MOZ_OVERRIDE;
   virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE;
 
-  virtual nsIGridPart* AsGridPart() { return this; }
+  virtual nsIGridPart* AsGridPart() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState)=0;
 
   nsGridRowLayout();
 };
 
 #endif
--- a/layout/xul/grid/nsGridRowLeafFrame.h
+++ b/layout/xul/grid/nsGridRowLeafFrame.h
@@ -40,16 +40,16 @@ public:
 #endif
 
   nsGridRowLeafFrame(nsIPresShell* aPresShell,
                      nsStyleContext* aContext,
                      bool aIsRoot,
                      nsBoxLayout* aLayoutManager):
     nsBoxFrame(aPresShell, aContext, aIsRoot, aLayoutManager) {}
 
-  NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
+  NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding) MOZ_OVERRIDE;
 
 }; // class nsGridRowLeafFrame
 
 
 
 #endif
 
--- a/layout/xul/grid/nsGridRowLeafLayout.h
+++ b/layout/xul/grid/nsGridRowLeafLayout.h
@@ -23,20 +23,20 @@
 // XXXldb This needs a better name that indicates that it's for any grid
 // row.
 class nsGridRowLeafLayout : public nsGridRowLayout
 {
 public:
 
   friend already_AddRefed<nsBoxLayout> NS_NewGridRowLeafLayout();
 
-  virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState);
-  virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState);
+  virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
+  virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
   NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE;
   virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE;
   virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE;
   virtual Type GetType() MOZ_OVERRIDE { return eRowLeaf; }
 
 protected:
 
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -115,56 +115,56 @@ public:
                                 int32_t *aX, int32_t *aY,
                                 int32_t *aWidth, int32_t *aHeight);
   nsresult IsCellCropped(int32_t aRow, nsITreeColumn *aCol, bool *aResult);
   nsresult RowCountChanged(int32_t aIndex, int32_t aCount);
   nsresult BeginUpdateBatch();
   nsresult EndUpdateBatch();
   nsresult ClearStyleAndImageCaches();
 
-  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
+  virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
-                         bool aRemoveOverflowArea = false);
+                         bool aRemoveOverflowArea = false) MOZ_OVERRIDE;
 
   // nsIReflowCallback
   virtual bool ReflowFinished() MOZ_OVERRIDE;
   virtual void ReflowCallbackCanceled() MOZ_OVERRIDE;
 
   // nsICSSPseudoComparator
   virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE;
 
   // nsIScrollbarMediator
-  NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex);
+  NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) MOZ_OVERRIDE;
   NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE;
   NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); return NS_OK; }
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     ScrollParts parts = GetScrollParts();
     return aVertical ? parts.mVScrollbar : parts.mHScrollbar;
   }
 
   // Overridden from nsIFrame to cache our pres context.
   virtual void Init(nsIContent*     aContent,
                     nsIFrame*       aParent,
                     nsIFrame*       aPrevInFlow) MOZ_OVERRIDE;
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   NS_IMETHOD GetCursor(const nsPoint& aPoint,
-                       nsIFrame::Cursor& aCursor);
+                       nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
 
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
                          nsGUIEvent* aEvent,
-                         nsEventStatus* aEventStatus);
+                         nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
   friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell);
   friend class nsTreeColumn;
 
   struct ScrollParts {
     nsScrollbarFrame*    mVScrollbar;
     nsCOMPtr<nsIContent> mVScrollbarContent;
     nsScrollbarFrame*    mHScrollbar;
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -142,22 +142,25 @@ MediaConduitErrorCode WebrtcAudioConduit
 #ifdef MOZ_WIDGET_ANDROID
       jobject context = jsjni_GetGlobalContextRef();
 
       // get the JVM
       JavaVM *jvm = jsjni_GetVM();
 
       JNIEnv* env;
       if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
-          CSFLogError(logTag,  "%s: could not get Java environment", __FUNCTION__);
-          return kMediaConduitSessionNotInited;
+        CSFLogError(logTag,  "%s: could not get Java environment", __FUNCTION__);
+        return kMediaConduitSessionNotInited;
       }
       jvm->AttachCurrentThread(&env, NULL);
 
-      webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
+      if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
+        CSFLogError(logTag, "%s Unable to set Android objects", __FUNCTION__);
+        return kMediaConduitSessionNotInited;
+      }
 
       env->DeleteGlobalRef(context);
 #endif
 
     //Per WebRTC APIs below function calls return NULL on failure
     if(!(mVoiceEngine = webrtc::VoiceEngine::Create()))
     {
       CSFLogError(logTag, "%s Unable to create voice engine", __FUNCTION__);
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -112,17 +112,20 @@ MediaConduitErrorCode WebrtcVideoConduit
 
   JNIEnv* env;
   if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
       CSFLogError(logTag,  "%s: could not get Java environment", __FUNCTION__);
       return kMediaConduitSessionNotInited;
   }
   jvm->AttachCurrentThread(&env, nullptr);
 
-  webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context);
+  if (webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
+    CSFLogError(logTag,  "%s: could not set Android objects", __FUNCTION__);
+    return kMediaConduitSessionNotInited;
+  }
 
   env->DeleteGlobalRef(context);
 #endif
 
   if( !(mVideoEngine = webrtc::VideoEngine::Create()) )
   {
     CSFLogError(logTag, "%s Unable to create video engine ", __FUNCTION__);
      return kMediaConduitSessionNotInited;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -141,25 +141,31 @@ public:
    * Raw I420 Frames are delivred to the VideoConduit by the VideoEngine
    */
   virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
 
   virtual int DeliverFrame(unsigned char*,int, uint32_t , int64_t);
 
 
   WebrtcVideoConduit():
-                      mVideoEngine(NULL),
-                      mTransport(NULL),
-                      mRenderer(NULL),
+                      mVideoEngine(nullptr),
+                      mTransport(nullptr),
+                      mRenderer(nullptr),
                       mEngineTransmitting(false),
                       mEngineReceiving(false),
                       mChannel(-1),
                       mCapId(-1),
-                      mCurSendCodecConfig(NULL)
-
+                      mCurSendCodecConfig(nullptr),
+                      mPtrViEBase(nullptr),
+                      mPtrViECapture(nullptr),
+                      mPtrViECodec(nullptr),
+                      mPtrViENetwork(nullptr),
+                      mPtrViERender(nullptr),
+                      mPtrExtCapture(nullptr),
+                      mPtrRTP(nullptr)
   {
   }
 
 
   virtual ~WebrtcVideoConduit() ;
 
 
 
--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_config.c
+++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_config.c
@@ -18,17 +18,18 @@ static const char* logTag = "sdp_config"
  *              str       String containing function name to print.
  * Returns:	TRUE or FALSE.
  */
 tinybool sdp_verify_conf_ptr (sdp_conf_options_t *conf_p)
 {
     if ((conf_p != NULL) && (conf_p->magic_num == SDP_MAGIC_NUM)) {
         return (TRUE);
     } else {
-        CSFLogError(logTag, "SDP: Invalid Config pointer.");
+        CSFLogError(logTag, "SDP: Invalid Config pointer: %p (magic=0x%X)",
+                    conf_p, conf_p ? conf_p->magic_num : 0);
         return (FALSE);
     }
 }
 
 /* Function:    void *sdp_init_config()
  * Description: Initialize SDP configuration structure with the
  *              following defaults:
  *              All debug levels turned OFF.
@@ -91,16 +92,19 @@ void *sdp_init_config ()
     /* Initialize statistics counts */
     conf_p->num_parses              = 0;
     conf_p->num_builds              = 0;
     conf_p->num_not_sdp_desc        = 0;
     conf_p->num_invalid_token_order = 0;
     conf_p->num_invalid_param       = 0;
     conf_p->num_no_resource         = 0;
 
+    CSFLogInfo(logTag, "SDP: Initialized config pointer: %p (magic=0x%X)",
+                conf_p, conf_p ? conf_p->magic_num : 0);
+
     return (conf_p);
 }
 
 
 /* Function:    void sdp_appl_debug(void *config_p, sdp_debug_e debug_type,
  *                                  tinybool my_bool);
  * Description:	Define the default type of debug for the application.
  *              Valid debug types are ERRORS, WARNINGS, and TRACE.  Each
--- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c
+++ b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c
@@ -18,16 +18,18 @@
 #include "phntask.h"
 #include "phone_debug.h"
 #include "util_string.h"
 #include "ccsip_platform_tcp.h"
 #include "ccsip_task.h"
 #include "sip_socket_api.h"
 #include "platform_api.h"
 #include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
 #include "prprf.h"
 #include "thread_monitor.h"
 
 /*---------------------------------------------------------
  *
  * Definitions
  *
  */
@@ -42,17 +44,17 @@
 #ifdef __ANDROID__
 /* Note that for unit tests to work, this directory currently _must_ be
    world-writable or the tests must be run as root. See bug 823741 for the
    gory details.  */
 #define SIP_IPC_TEMP_BASEPATH "/data/local/tmp"
 #else
 #define SIP_IPC_TEMP_BASEPATH "/tmp"
 #endif
-#define SIP_IPC_TEMP_DIRNAME "SIP-%d"
+#define SIP_IPC_TEMP_DIRNAME "SIP-XXXXXXXX"
 #define SIP_MSG_SERV_SUFFIX "/Main"
 #define SIP_MSG_CLNT_SUFFIX "/MsgQ"
 
 #define SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME   50  /* 50ms. */
 #define SIP_MAX_WAIT_FOR_IPC_LISTEN_READY    1200  /* 50 * 1200 = 1 minutes */
 
 /*---------------------------------------------------------
  *
@@ -132,49 +134,62 @@ sip_platform_task_init (void)
      * Initialize cprSelect call parameters
      */
     FD_ZERO(&read_fds);
     FD_ZERO(&write_fds);
     return;
 }
 
 /**
- * sip_get_sock_dir_tmpl creates a template for the name of a directory
- * where IPC sockets will live. If the TMPDIR environment is set, that is used
- * as a base; otherwise SIP_IPC_TEMP_BASEPATH is used as a fallback.
- * SIP_IPC_TEMP_DIRNAME is added as a child directory, and if suffix is non-null,
- * that is appended to the end.
+ * sip_get_sock_dir returns the name of a temporary directory
+ * where IPC sockets will live, creating one if it does not yet exist.
+ *
+ * If the TMPDIR environment is set, that is used as a base; otherwise
+ * SIP_IPC_TEMP_BASEPATH is used as a fallback. SIP_IPC_TEMP_DIRAME is
+ * added as a child directory, and if suffix is non-null, that is
+ * appended to the end.
  *
  * The primary motivation for using TMPDIR is that that is how Fennec
  * (GeckoAppShell.java) passes in a scratch directory that is guaranteed to be
  * writable on Android, and there's no other reliable way to get such a thing.
  *
  * @param[out] out    buffer to be written to
  * @param[in] outlen  length of out buffer so we don't overrun
  * @param[in] suffix  if non-NULL, appended to the template
  *
  * @return            The length of the written output not including the NULL
  *                    terminator, or -1 if an error occurs.
  */
-static uint32_t sip_get_sock_dir_tmpl(char *out, uint32_t outlen,
-                                      const char *suffix) {
-
-    char *tmpdir;
-    tmpdir = getenv("TMPDIR");
+static char sip_sock_dir[sizeof(sip_serv_sock_addr.sun_path)] = "\0";
+static size_t sip_sock_dir_len = 0;
+static uint32_t sip_get_sock_dir(char *out, uint32_t outlen,
+                                 const char *suffix) {
+    const char *fname = "sip_get_sock_dir";
+    // Initialize the base string and create the directory
+    // if it hasn't been created yet.
+    if (!sip_sock_dir_len) {
+        char *tmpdir;
+        tmpdir = getenv("TMPDIR");
+        if (!tmpdir) {
+          tmpdir = SIP_IPC_TEMP_BASEPATH;
+        }
+        sip_sock_dir_len = PR_snprintf(sip_sock_dir, sizeof(sip_sock_dir),
+                                       "%s/%s", tmpdir, SIP_IPC_TEMP_DIRNAME);
 
-    if (suffix) {
-        return PR_snprintf(out, outlen, "%s/%s%s",
-                           tmpdir ? tmpdir : SIP_IPC_TEMP_BASEPATH,
-                           SIP_IPC_TEMP_DIRNAME,
-                           suffix);
+        // Note that mkdtemp modifies the string passed to it.
+        if (!mkdtemp(sip_sock_dir))
+        {
+          CCSIP_DEBUG_ERROR(SIP_F_PREFIX"mkdtemp() returned error"
+                            " errno=%d\n", fname, cpr_errno);
+          sip_sock_dir_len = 0;
+          return -1;
+        }
     }
 
-    return PR_snprintf(out, outlen, "%s/%s",
-                       tmpdir ? tmpdir : SIP_IPC_TEMP_BASEPATH,
-                       SIP_IPC_TEMP_DIRNAME);
+    return PR_snprintf(out, outlen, "%s%s", sip_sock_dir, suffix ? suffix : "");
 }
 
 /**
  *  sip_create_IPC_sock creates and bind the socket for IPC.
  *
  *  @param[in]name - pointer to the const. character for the
  *                  IPC address (name) to be bound when the
  *                  IPC socket is successfully created.
@@ -244,17 +259,17 @@ void sip_platform_task_msgqwait (void *a
     const char    *fname = "sip_platform_task_msgqwait";
     cprMsgQueue_t *msgq = (cprMsgQueue_t *)arg;
     unsigned int  wait_main_thread = 0;
     phn_syshdr_t  *syshdr;
     void          *msg;
     uint8_t       num_messages = 0;
     uint8_t       response = 0;
     boolean       quit_thread = FALSE;
-    char          template[sizeof(sip_serv_sock_addr.sun_path)];
+    char          tempdir[sizeof(sip_serv_sock_addr.sun_path)];
 
     if (msgq == NULL) {
         CCSIP_DEBUG_ERROR(SIP_F_PREFIX"task msgq is null, exiting", fname);
         return;
     }
 
     if (platThreadInit("SIP IPCQ task") != 0) {
         CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname);
@@ -281,18 +296,18 @@ void sip_platform_task_msgqwait (void *a
      * Adjust relative priority of SIP thread.
      */
     (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);
 
     /*
      * The main thread is ready. set global client socket address
      * so that the server can send back response.
      */
-    sip_get_sock_dir_tmpl(template, sizeof(template), SIP_MSG_CLNT_SUFFIX);
-    cpr_set_sockun_addr(&sip_clnt_sock_addr, template, getpid());
+    sip_get_sock_dir(tempdir, sizeof(tempdir), SIP_MSG_CLNT_SUFFIX);
+    cpr_set_sockun_addr(&sip_clnt_sock_addr, tempdir, 0);
 
     sip_ipc_clnt_socket = sip_create_IPC_sock(sip_clnt_sock_addr.sun_path);
 
     if (sip_ipc_clnt_socket == INVALID_SOCKET) {
         CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed,"
                           "  exiting\n", fname);
         return;
     }
@@ -405,28 +420,26 @@ static void sip_process_int_msg (void)
 
     /* process messages */
     int_msg = &sip_int_msgq_buf[0];
     while (num_messages) {
         msg    = int_msg->msg;
         syshdr = int_msg->syshdr;
         if (msg != NULL && syshdr != NULL) {
             if (syshdr->Cmd == THREAD_UNLOAD) {
-                char template[sizeof(sip_serv_sock_addr.sun_path)];
                 char stmpdir[sizeof(sip_serv_sock_addr.sun_path)];
 
                 /*
                  * Cleanup here, as SIPTaskProcessListEvent wont return.
                  * - Remove last tmp file and tmp dir.
                  */
                 cprCloseSocket(sip_ipc_serv_socket);
                 unlink(sip_serv_sock_addr.sun_path);
 
-                sip_get_sock_dir_tmpl(template, sizeof(template), NULL);
-                PR_snprintf(stmpdir, sizeof(stmpdir), template, getpid());
+                sip_get_sock_dir(stmpdir, sizeof(stmpdir), NULL);
                 if (rmdir(stmpdir) != 0) {
                     CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to remove temp dir",
                                       fname);
                 }
             }
             SIPTaskProcessListEvent(syshdr->Cmd, msg, syshdr->Usr.UsrPtr,
                 syshdr->Len);
             cprReleaseSysHeader(syshdr);
@@ -493,29 +506,19 @@ sip_platform_task_loop (void *arg)
      * Adjust relative priority of SIP thread.
      */
     (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);
 
     /*
      * Setup IPC socket addresses for main thread (server)
      */
     {
-      char template[sizeof(sip_serv_sock_addr.sun_path)];
       char stmpdir[sizeof(sip_serv_sock_addr.sun_path)];
-
-      sip_get_sock_dir_tmpl(template, sizeof(template), NULL);
-      PR_snprintf(stmpdir, sizeof(stmpdir), template, getpid());
-
-      if (mkdir(stmpdir, 0700) != 0) {
-          CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to create temp dir", fname);
-          return;
-      }
-
-      sip_get_sock_dir_tmpl(template, sizeof(template), SIP_MSG_SERV_SUFFIX);
-      cpr_set_sockun_addr(&sip_serv_sock_addr, template, getpid());
+      sip_get_sock_dir(stmpdir, sizeof(stmpdir), SIP_MSG_SERV_SUFFIX);
+      cpr_set_sockun_addr(&sip_serv_sock_addr, stmpdir, 0);
     }
 
     /*
      * Create IPC between the message queue thread and this main
      * thread.
      */
     sip_ipc_serv_socket = sip_create_IPC_sock(sip_serv_sock_addr.sun_path);
 
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/java/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/java/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
@@ -113,37 +113,51 @@ public class VideoCaptureDeviceInfoAndro
 
                     camera = Camera.open(i);
                     Camera.Parameters parameters = camera.getParameters();
                     AddDeviceInfo(newDevice, parameters);
                     camera.release();
                     camera = null;
                     deviceList.add(newDevice);
                 }
+            } else {
+                camera = Camera.open();
+                Camera.Parameters parameters = camera.getParameters();
+                AndroidVideoCaptureDevice newDevice = new AndroidVideoCaptureDevice();
+                AddDeviceInfo(newDevice, parameters);
+                newDevice.deviceUniqueName = "Camera";
+                camera.release();
+                camera = null;
+                deviceList.add(newDevice);
             }
         }
         catch (Exception ex) {
-            Log.e(TAG, "Failed to init VideoCaptureDeviceInfo ex" +
-                    ex.getLocalizedMessage());
+            Log.e(TAG, "Failed to init VideoCaptureDeviceInfo exception: " +
+                    ex.getMessage());
+            if (camera != null) {
+                camera.release();
+            }
             return -1;
         }
         VerifyCapabilities();
         return 0;
     }
 
     // Adds the capture capabilities of the currently opened device
     private void AddDeviceInfo(AndroidVideoCaptureDevice newDevice,
             Camera.Parameters parameters) {
 
         List<Size> sizes = parameters.getSupportedPreviewSizes();
         List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
         int maxFPS = 0;
-        for(Integer frameRate:frameRates) {
-            if(frameRate > maxFPS) {
-                maxFPS = frameRate;
+        if (frameRates != null) {
+            for(Integer frameRate:frameRates) {
+                if(frameRate > maxFPS) {
+                    maxFPS = frameRate;
+                }
             }
         }
 
         newDevice.captureCapabilies = new CaptureCapabilityAndroid[sizes.size()];
         for(int i = 0; i < sizes.size(); ++i) {
             Size s = sizes.get(i);
             newDevice.captureCapabilies[i] = new CaptureCapabilityAndroid();
             newDevice.captureCapabilies[i].height = s.height;
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
@@ -389,43 +389,45 @@ VideoCaptureAndroid::~VideoCaptureAndroi
                      "%s: Could not attach thread to JVM (%d, %p)",
                      __FUNCTION__, res, env);
       }
       else {
         isAttached = true;
       }
     }
 
-    // get the method ID for the Android Java CaptureClass static
-    // DeleteVideoCaptureAndroid  method. Call this to release the camera so
-    // another application can use it.
-    jmethodID cid = env->GetStaticMethodID(
-        g_javaCmClass,
-        "DeleteVideoCaptureAndroid",
-        "(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
-    if (cid != NULL) {
-      WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
-                   "%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
-      // Close the camera by calling the static destruct function.
-      env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
+    if (env) {
+      // get the method ID for the Android Java CaptureClass static
+      // DeleteVideoCaptureAndroid  method. Call this to release the camera so
+      // another application can use it.
+      jmethodID cid = env->GetStaticMethodID(
+          g_javaCmClass,
+          "DeleteVideoCaptureAndroid",
+          "(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
+      if (cid != NULL) {
+        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
+                     "%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
+        // Close the camera by calling the static destruct function.
+        env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
 
-      // Delete global object ref to the camera.
-      env->DeleteGlobalRef(_javaCaptureObj);
-      // Clean up the global class references
-      env->DeleteGlobalRef(g_javaCmClass);
-      env->DeleteGlobalRef(g_javaCmDevInfoClass);
+        // Delete global object ref to the camera.
+        env->DeleteGlobalRef(_javaCaptureObj);
+        // Clean up the global class references
+        env->DeleteGlobalRef(g_javaCmClass);
+        env->DeleteGlobalRef(g_javaCmDevInfoClass);
 
-      _javaCaptureObj = NULL;
-      VideoCaptureAndroid::g_javaCmClass = NULL;
-      VideoCaptureAndroid::g_javaCmDevInfoClass = NULL;
-    }
-    else {
-      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
-                   "%s: Failed to find DeleteVideoCaptureAndroid id",
-                   __FUNCTION__);
+        _javaCaptureObj = NULL;
+        VideoCaptureAndroid::g_javaCmClass = NULL;
+        VideoCaptureAndroid::g_javaCmDevInfoClass = NULL;
+      }
+      else {
+        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
+                     "%s: Failed to find DeleteVideoCaptureAndroid id",
+                     __FUNCTION__);
+      }
     }
 
     // Detach this thread if it was attached
     if (isAttached) {
       if (g_jvm->DetachCurrentThread() < 0) {
         WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice,
                      _id, "%s: Could not detach thread from JVM",
                      __FUNCTION__);
new file mode 100644
--- /dev/null
+++ b/media/webvtt/868629.patch
@@ -0,0 +1,61 @@
+# HG changeset patch
+# User Caitlin Potter <snowball@defpixel.com>
+# Date 1367954476 14400
+# Node ID 2becb21900559e271175e08d7ec33ed35b034967
+# Parent  41ff3b67b69232297191c8f8ef78e5facc1c1d19
+Bug 868629 - webvtt no longer needs -DWEBVTT_NO_CONFIG_H. r=rillian
+
+diff --git a/media/webvtt/include/webvtt/util.h b/media/webvtt/include/webvtt/util.h
+--- a/media/webvtt/include/webvtt/util.h
++++ b/media/webvtt/include/webvtt/util.h
+@@ -32,16 +32,21 @@
+ extern "C" {
+ #endif
+ 
+-# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
+-#   if !WEBVTT_NO_CONFIG_H
+-#     include "webvtt-config-win32.h"
+-#   endif
++# if !defined(_MSC_VER) || _MSC_VER >= 1600
++/**
++ * For non-MSVC compilers, or MSVC2010 or later, assume we have
++ * stdint.h
++ */
++#   define WEBVTT_HAVE_STDINT 1
++#   include <stdint.h>
++# endif
++
++# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) ||\
++     defined(__WINDOWS__)
+ #   define WEBVTT_OS_WIN32 1
+ #   if defined(_WIN64)
+ #     define WEBVTT_OS_WIN64 1
+ #   endif
+-# elif !WEBVTT_NO_CONFIG_H
+-#   include <webvtt/webvtt-config.h>
+ # endif
+ 
+ # if defined(_MSC_VER)
+@@ -54,12 +59,8 @@
+ #   else
+ #     define WEBVTT_EXPORT
+ #   endif
+-#   if _MSC_VER >= 1600
+-#     define WEBVTT_HAVE_STDINT 1
+-#   endif
+ # elif defined(__GNUC__)
+ #   define WEBVTT_CC_GCC 1
+-#   define WEBVTT_HAVE_STDINT 1
+ #   if WEBVTT_OS_WIN32
+ #     if WEBVTT_BUILD_LIBRARY
+ #       define WEBVTT_EXPORT __declspec(dllexport)
+@@ -96,8 +97,7 @@
+ #   define WEBVTT_INLINE __inline__
+ # endif
+ 
+-# if WEBVTT_HAVE_STDINT
+-#   include <stdint.h>
++# ifdef WEBVTT_HAVE_STDINT
+   typedef int8_t webvtt_int8;
+   typedef int16_t webvtt_int16;
+   typedef int32_t webvtt_int32;
--- a/media/webvtt/README_MOZILLA
+++ b/media/webvtt/README_MOZILLA
@@ -1,7 +1,6 @@
 These files are from the WebVTT library, and are extracted from rev
 c93accafb2087df7c678748e25bca21f1173979f of the git repository at
 https://github.com/mozilla/webvtt.
 
 The following CPPFLAGS are used in order to build and link in Mozilla
--DWEBVTT_NO_CONFIG_H=1 -- Prevent inclusion of generated headers
 -DWEBVTT_STATIC=1      -- Compile as a static library
--- a/media/webvtt/include/webvtt/util.h
+++ b/media/webvtt/include/webvtt/util.h
@@ -27,44 +27,45 @@
 
 #ifndef __WEBVTT_UTIL_H__
 # define __WEBVTT_UTIL_H__
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
-# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
-#   if !WEBVTT_NO_CONFIG_H
-#     include "webvtt-config-win32.h"
-#   endif
+# if !defined(_MSC_VER) || _MSC_VER >= 1600
+/**
+ * For non-MSVC compilers, or MSVC2010 or later, assume we have
+ * stdint.h
+ */
+#   define WEBVTT_HAVE_STDINT 1
+#   include <stdint.h>
+# endif
+
+# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) ||\
+     defined(__WINDOWS__)
 #   define WEBVTT_OS_WIN32 1
 #   if defined(_WIN64)
 #     define WEBVTT_OS_WIN64 1
 #   endif
-# elif !WEBVTT_NO_CONFIG_H
-#   include <webvtt/webvtt-config.h>
 # endif
 
 # if defined(_MSC_VER)
 #   define WEBVTT_CC_MSVC 1
 #   define WEBVTT_CALLBACK __cdecl
 #   if WEBVTT_BUILD_LIBRARY
 #     define WEBVTT_EXPORT __declspec(dllexport)
 #   elif !WEBVTT_STATIC
 #     define WEBVTT_EXPORT __declspec(dllimport)
 #   else
 #     define WEBVTT_EXPORT
 #   endif
-#   if _MSC_VER >= 1600
-#     define WEBVTT_HAVE_STDINT 1
-#   endif
 # elif defined(__GNUC__)
 #   define WEBVTT_CC_GCC 1
-#   define WEBVTT_HAVE_STDINT 1
 #   if WEBVTT_OS_WIN32
 #     if WEBVTT_BUILD_LIBRARY
 #       define WEBVTT_EXPORT __declspec(dllexport)
 #     elif !WEBVTT_STATIC
 #       define WEBVTT_EXPORT __declspec(dllimport)
 #     else
 #       define WEBVTT_EXPORT
 #     endif
@@ -91,18 +92,17 @@ extern "C" {
 # if defined(__cplusplus) || defined(c_plusplus)
 #   define WEBVTT_INLINE inline
 # elif WEBVTT_CC_MSVC
 #   define WEBVTT_INLINE __inline
 # elif WEBVTT_CC_GCC
 #   define WEBVTT_INLINE __inline__
 # endif
 
-# if WEBVTT_HAVE_STDINT
-#   include <stdint.h>
+# ifdef WEBVTT_HAVE_STDINT
   typedef int8_t webvtt_int8;
   typedef int16_t webvtt_int16;
   typedef int32_t webvtt_int32;
   typedef int64_t webvtt_int64;
   typedef uint8_t webvtt_uint8;
   typedef uint16_t webvtt_uint16;
   typedef uint32_t webvtt_uint32;
   typedef uint64_t webvtt_uint64;
old mode 100644
new mode 100755
--- a/media/webvtt/update.sh
+++ b/media/webvtt/update.sh
@@ -1,9 +1,9 @@
-#!/bin/sh
+#!/bin/bash
 # 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/.
 
 # Usage: ./update.sh <webvtt_git_repository> <optional revision/branch/refspec>
 #
 # Copies the needed files from a directory containing the original
 # libwebvtt source, and applies any local patches we're carrying.
@@ -72,8 +72,14 @@ find ${repo_dir}/src/libwebvtt -type f -
     ${webvtt_dir}/ \;
 cp ${repo_dir}/LICENSE ${webvtt_dir}/
 rm -rf ${repo_dir}
 
 # addremove automatically if mercurial is used
 if [ ${have_hg} -eq 0 -a -d ${start_dir}/.hg ]; then
   hg addremove ${webvtt_dir}/
 fi
+
+# apply patches
+cd ${webvtt_dir}
+patch -p3 < 868629.patch
+
+cd ${start_dir}
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -654,21 +654,18 @@ pref("dom.min_background_timeout_value",
 
 // The default state of reader mode works on loaded a page.
 pref("reader.parse-on-load.enabled", true);
 
 // Force to enable reader mode to parse on loaded a page.
 // Allow reader mode even on low-memory platforms
 pref("reader.parse-on-load.force-enabled", false);
 
-// The default of font size in reader (1-7)
-pref("reader.font_size", 4);
-
-// The default of margin size in reader (5%-25%)
-pref("reader.margin_size", 5);
+// The default of font size in reader (1-5)
+pref("reader.font_size", 3);
 
 // The default color scheme in reader (light, dark, sepia, auto)
 // auto = color automatically adjusts according to ambient light level
 pref("reader.color_scheme", "auto");
 
 // The font type in reader (sans-serif, serif)
 pref("reader.font_type", "sans-serif");
 
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -38,16 +38,17 @@ import android.graphics.drawable.BitmapD
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.nfc.NdefMessage;
 import android.nfc.NdefRecord;
 import android.nfc.NfcAdapter;
 import android.nfc.NfcEvent;
 import android.os.Build;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
@@ -70,16 +71,18 @@ abstract public class BrowserApp extends
                                             View.OnKeyListener,
                                             GeckoLayerClient.OnMetricsChangedListener,
                                             AboutHome.UriLoadListener,
                                             AboutHome.LoadCompleteListener {
     private static final String LOGTAG = "GeckoBrowserApp";
 
     private static final String PREF_CHROME_DYNAMICTOOLBAR = "browser.chrome.dynamictoolbar";
 
+    private static final String ABOUT_HOME = "about:home";
+
     private static final int TABS_ANIMATION_DURATION = 450;
 
     private static final int READER_ADD_SUCCESS = 0;
     private static final int READER_ADD_FAILED = 1;
     private static final int READER_ADD_DUPLICATE = 2;
 
     public static BrowserToolbar mBrowserToolbar;
     private AboutHome mAboutHome;
@@ -137,17 +140,17 @@ abstract public class BrowserApp extends
         switch(msg) {
             case LOCATION_CHANGE:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
                     maybeCancelFaviconLoad(tab);
                 }
                 // fall through
             case SELECTED:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
-                    if ("about:home".equals(tab.getURL())) {
+                    if (isAboutHome(tab)) {
                         showAboutHome();
 
                         if (isDynamicToolbarEnabled()) {
                             // Show the toolbar.
                             mLayerView.getLayerMarginsAnimator().showMargins(false);
                         }
                     } else {
                         hideAboutHome();
@@ -471,16 +474,124 @@ abstract public class BrowserApp extends
 
         refreshToolbarHeight();
     }
 
     private boolean isDynamicToolbarEnabled() {
         return mDynamicToolbarEnabled && !mAccessibilityEnabled;
     }
 
+    private boolean isAboutHome(Tab tab) {
+        return TextUtils.equals(ABOUT_HOME, tab.getURL());
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        return showAwesomebar(AwesomeBar.Target.CURRENT_TAB);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.pasteandgo: {
+                String text = GeckoAppShell.getClipboardText();
+                if (!TextUtils.isEmpty(text)) {
+                    Tabs.getInstance().loadUrl(text);
+                }
+                return true;
+            }
+            case R.id.site_settings: {
+                GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Permissions:Get", null));
+                return true;
+            }
+            case R.id.paste: {
+                String text = GeckoAppShell.getClipboardText();
+                if (!TextUtils.isEmpty(text)) {
+                    showAwesomebar(AwesomeBar.Target.CURRENT_TAB, text);
+                }
+                return true;
+            }
+            case R.id.share: {
+                shareCurrentUrl();
+                return true;
+            }
+            case R.id.subscribe: {
+                Tab tab = Tabs.getInstance().getSelectedTab();
+                if (tab != null && tab.getFeedsEnabled()) {
+                    JSONObject args = new JSONObject();
+                    try {
+                        args.put("tabId", tab.getId());
+                    } catch (JSONException e) {
+                        Log.e(LOGTAG, "error building json arguments");
+                    }
+                    GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Feeds:Subscribe", args.toString()));
+                }
+                return true;
+            }
+            case R.id.copyurl: {
+                Tab tab = Tabs.getInstance().getSelectedTab();
+                if (tab != null) {
+                    String url = tab.getURL();
+                    if (url != null) {
+                        GeckoAppShell.setClipboardText(url);
+                    }
+                }
+                return true;
+            }
+            case R.id.add_to_launcher: {
+                Tab tab = Tabs.getInstance().getSelectedTab();
+                if (tab != null) {
+                    String url = tab.getURL();
+                    String title = tab.getDisplayTitle();
+                    Bitmap favicon = tab.getFavicon();
+                    if (url != null && title != null) {
+                        GeckoAppShell.createShortcut(title, url, url, favicon == null ? null : favicon, "");
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean showAwesomebar(AwesomeBar.Target aTarget) {
+        return showAwesomebar(aTarget, null);
+    }
+
+    public boolean showAwesomebar(AwesomeBar.Target aTarget, String aUrl) {
+        Intent intent = new Intent(getBaseContext(), AwesomeBar.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+        intent.putExtra(AwesomeBar.TARGET_KEY, aTarget.name());
+
+        // If we were passed in a URL, show it.
+        if (aUrl != null && !TextUtils.isEmpty(aUrl)) {
+            intent.putExtra(AwesomeBar.CURRENT_URL_KEY, aUrl);
+        } else if (aTarget == AwesomeBar.Target.CURRENT_TAB) {
+            // Otherwise, if we're editing the current tab, show its URL.
+            Tab tab = Tabs.getInstance().getSelectedTab();
+            if (tab != null) {
+                // Check to see if there's a user-entered search term, which we save
+                // whenever the user performs a search.
+                aUrl = tab.getUserSearch();
+                if (TextUtils.isEmpty(aUrl)) {
+                    aUrl = tab.getURL();
+                }
+                if (aUrl != null) {
+                    intent.putExtra(AwesomeBar.CURRENT_URL_KEY, aUrl);
+                }
+            }
+        }
+
+        int requestCode = GeckoAppShell.sActivityHelper.makeRequestCodeForAwesomebar();
+        startActivityForResult(intent, requestCode);
+        overridePendingTransition (R.anim.awesomebar_fade_in, R.anim.awesomebar_hold_still);
+        return true;
+    }
+
+
     @Override
     public void setAccessibilityEnabled(boolean enabled) {
         if (mAccessibilityEnabled == enabled) {
             return;
         }
 
         // Disable the dynamic toolbar when accessibility features are enabled,
         // and re-read the preference when they're disabled.
@@ -549,17 +660,17 @@ abstract public class BrowserApp extends
         if (isExternalURL || mRestoreMode != RESTORE_NONE) {
             mAboutHomeStartupTimer.cancel();
         }
 
         if (!mIsRestoringActivity) {
             if (!isExternalURL) {
                 // show about:home if we aren't restoring previous session
                 if (mRestoreMode == RESTORE_NONE) {
-                    Tab tab = Tabs.getInstance().loadUrl("about:home", Tabs.LOADURL_NEW_TAB);
+                    Tab tab = Tabs.getInstance().loadUrl(ABOUT_HOME, Tabs.LOADURL_NEW_TAB);
                 }
             } else {
                 int flags = Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_USER_ENTERED;
                 Tabs.getInstance().loadUrl(uri, flags);
             }
         }
 
         // Listen to margin changes to position the toolbar correctly
@@ -568,16 +679,32 @@ abstract public class BrowserApp extends
             mLayerView.getLayerMarginsAnimator().showMargins(true);
             mLayerView.getLayerClient().setOnMetricsChangedListener(this);
         }
 
         // Intercept key events for gamepad shortcuts
         mLayerView.setOnKeyListener(this);
     }
 
+    private void shareCurrentUrl() {
+        Tab tab = Tabs.getInstance().getSelectedTab();
+        if (tab == null)
+          return;
+
+        String url = tab.getURL();
+        if (url == null)
+            return;
+
+        if (ReaderModeUtils.isAboutReader(url))
+            url = ReaderModeUtils.getUrlFromAboutReader(url);
+
+        GeckoAppShell.openUriExternal(url, "text/plain", "", "",
+                                      Intent.ACTION_SEND, tab.getDisplayTitle());
+    }
+
     private void setToolbarMargin(int margin) {
         ((RelativeLayout.LayoutParams) mGeckoLayout.getLayoutParams()).topMargin = margin;
         mGeckoLayout.requestLayout();
     }
 
     @Override
     public void onMetricsChanged(ImmutableViewportMetrics aMetrics) {
         if (mAboutHome.getUserVisibleHint() || mBrowserToolbar == null) {
@@ -1371,17 +1498,17 @@ abstract public class BrowserApp extends
         share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") ||
                            scheme.equals("file") || scheme.equals("resource")));
 
         // Disable save as PDF for about:home and xul pages
         saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
                                tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
 
         // Disable find in page for about:home, since it won't work on Java content
-        findInPage.setEnabled(!tab.getURL().equals("about:home"));
+        findInPage.setEnabled(!isAboutHome(tab));
 
         charEncoding.setVisible(GeckoPreferences.getCharEncodingState());
 
         return true;
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -61,17 +61,17 @@ import java.util.List;
 
 public class BrowserToolbar implements Tabs.OnTabsChangedListener,
                                        GeckoMenu.ActionItemBarPresenter,
                                        Animation.AnimationListener {
     private static final String LOGTAG = "GeckoToolbar";
     public static final String PREF_TITLEBAR_MODE = "browser.chrome.titlebarMode";
     private GeckoRelativeLayout mLayout;
     private LayoutParams mAwesomeBarParams;
-    private View mAwesomeBarContent;
+    private View mUrlDisplayContainer;
     private View mAwesomeBarEntry;
     private ImageView mAwesomeBarRightEdge;
     private BrowserToolbarBackground mAddressBarBg;
     private GeckoTextView mTitle;
     private int mTitlePadding;
     private boolean mSiteSecurityVisible;
     private boolean mSwitchingTabs;
     private ShapedButton mTabs;
@@ -146,20 +146,17 @@ public class BrowserToolbar implements T
                 if (shouldShowUrl == mShowUrl) {
                     return;
                 }
                 mShowUrl = shouldShowUrl;
 
                 ThreadUtils.postToUiThread(new Runnable() {
                     @Override
                     public void run() {
-                        Tab tab = Tabs.getInstance().getSelectedTab();
-                        if (tab != null) {
-                            setTitle(tab.getDisplayTitle());
-                        }
+                        updateTitle();
                     }
                 });
             }
 
             @Override
             public boolean isObserver() {
                 // We want to be notified of changes to be able to switch mode
                 // without restarting.
@@ -192,17 +189,17 @@ public class BrowserToolbar implements T
 
         mLayout.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
             @Override
             public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                 MenuInflater inflater = mActivity.getMenuInflater();
                 inflater.inflate(R.menu.titlebar_contextmenu, menu);
 
                 String clipboard = GeckoAppShell.getClipboardText();
-                if (clipboard == null || TextUtils.isEmpty(clipboard)) {
+                if (TextUtils.isEmpty(clipboard)) {
                     menu.findItem(R.id.pasteandgo).setVisible(false);
                     menu.findItem(R.id.paste).setVisible(false);
                 }
 
                 Tab tab = Tabs.getInstance().getSelectedTab();
                 if (tab != null) {
                     String url = tab.getURL();
                     if (url == null) {
@@ -226,17 +223,17 @@ public class BrowserToolbar implements T
         mShowSiteSecurity = false;
         mShowReader = false;
 
         mAnimatingEntry = false;
 
         mAddressBarBg = (BrowserToolbarBackground) mLayout.findViewById(R.id.address_bar_bg);
         mAddressBarViewOffset = mActivity.getResources().getDimensionPixelSize(R.dimen.addressbar_offset_left);
         mDefaultForwardMargin = mActivity.getResources().getDimensionPixelSize(R.dimen.forward_default_offset);
-        mAwesomeBarContent = mLayout.findViewById(R.id.awesome_bar_content);
+        mUrlDisplayContainer = mLayout.findViewById(R.id.awesome_bar_display_container);
         mAwesomeBarEntry = mLayout.findViewById(R.id.awesome_bar_entry);
 
         // This will clip the right edge's image at half of its width
         mAwesomeBarRightEdge = (ImageView) mLayout.findViewById(R.id.awesome_bar_right_edge);
         if (mAwesomeBarRightEdge != null) {
             mAwesomeBarRightEdge.getDrawable().setLevel(5000);
         }
 
@@ -441,17 +438,17 @@ public class BrowserToolbar implements T
         return mLayout;
     }
 
     @Override
     public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
         switch(msg) {
             case TITLE:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
-                    setTitle(tab.getDisplayTitle());
+                    updateTitle();
                 }
                 break;
             case START:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
                     updateBackButton(tab.canDoBack());
                     updateForwardButton(tab.canDoForward());
                     Boolean showProgress = (Boolean)data;
                     if (showProgress && tab.getState() == Tab.STATE_LOADING)
@@ -461,17 +458,17 @@ public class BrowserToolbar implements T
                 }
                 break;
             case STOP:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
                     updateBackButton(tab.canDoBack());
                     updateForwardButton(tab.canDoForward());
                     setProgressVisibility(false);
                     // Reset the title in case we haven't navigated to a new page yet.
-                    setTitle(tab.getDisplayTitle());
+                    updateTitle();
                 }
                 break;
             case RESTORED:
                 updateTabCount(Tabs.getInstance().getDisplayCount());
                 break;
             case SELECTED:
                 mSwitchingTabs = true;
                 // fall through
@@ -893,52 +890,56 @@ public class BrowserToolbar implements T
                      !url.equals("about:blank")));
 
         if ((mShadow.getVisibility() == View.VISIBLE) != visible) {
             mShadow.setVisibility(visible ? View.VISIBLE : View.GONE);
         }
     }
 
     private void setTitle(CharSequence title) {
-        Tab tab = Tabs.getInstance().getSelectedTab();
+        mTitle.setText(title);
+        mLayout.setContentDescription(title != null ? title : mTitle.getHint());
+    }
 
-        if (tab != null) {
-            // Keep the title unchanged if the tab is entering reader mode
-            if (tab.isEnteringReaderMode()) {
-                return;
-            }
-
-            // Setting a null title will ensure we just see the "Enter Search or Address"
-            // placeholder text. Because "about:home" and "about:privatebrowsing" don't
-            // have titles, their display titles will always match their URLs.
-            if ("about:home".equals(title) || "about:privatebrowsing".equals(title)) {
-                title = null;
-            }
+    // Sets the toolbar title according to the selected tab, obeying the mShowUrl prference.
+    private void updateTitle() {
+        Tab tab = Tabs.getInstance().getSelectedTab();
+        // Keep the title unchanged if there's no selected tab, or if the tab is entering reader mode.
+        if (tab == null || tab.isEnteringReaderMode()) {
+            return;
+        }
 
-            if (mShowUrl && title != null) {
-                title = StringUtils.stripScheme(tab.getURL());
-                title = StringUtils.stripCommonSubdomains(title.toString());
+        String url = tab.getURL();
+        // Setting a null title will ensure we just see the "Enter Search or Address" placeholder text.
+        if ("about:home".equals(url) || "about:privatebrowsing".equals(url)) {
+            setTitle(null);
+            return;
+        }
 
-                // highlight the domain name if we find one
-                String baseDomain = tab.getBaseDomain();
-                if (!TextUtils.isEmpty(baseDomain)) {
-                    SpannableStringBuilder builder = new SpannableStringBuilder(title);
-                    int index = title.toString().indexOf(baseDomain);
-                    if (index > -1) {
-                        builder.setSpan(mUrlColor, 0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-                        builder.setSpan(tab.isPrivate() ? mPrivateDomainColor : mDomainColor, index, index+baseDomain.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+        // If the pref to show the URL isn't set, just use the tab's display title.
+        if (!mShowUrl || url == null) {
+            setTitle(tab.getDisplayTitle());
+            return;
+        }
+
+        url = StringUtils.stripScheme(url);
+        CharSequence title = StringUtils.stripCommonSubdomains(url);
 
-                        title = builder;
-                    }
-                }
+        String baseDomain = tab.getBaseDomain();
+        if (!TextUtils.isEmpty(baseDomain)) {
+            SpannableStringBuilder builder = new SpannableStringBuilder(title);
+            int index = title.toString().indexOf(baseDomain);
+            if (index > -1) {
+                builder.setSpan(mUrlColor, 0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+                builder.setSpan(tab.isPrivate() ? mPrivateDomainColor : mDomainColor, index, index+baseDomain.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+                title = builder;
             }
         }
 
-        mTitle.setText(title);
-        mLayout.setContentDescription(title != null ? title : mTitle.getHint());
+        setTitle(title);
     }
 
     private void setFavicon(Bitmap image) {
         if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING)
             return;
 
         if (image != null) {
             image = Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, false);
@@ -1029,43 +1030,43 @@ public class BrowserToolbar implements T
 
         mForwardAnim.setPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
             @Override
             public void onPropertyAnimationStart() {
                 if (!enabled) {
                     // Set the margin before the transition when hiding the forward button. We
                     // have to do this so that the favicon isn't clipped during the transition
                     ViewGroup.MarginLayoutParams layoutParams =
-                        (ViewGroup.MarginLayoutParams)mAwesomeBarContent.getLayoutParams();
+                        (ViewGroup.MarginLayoutParams)mUrlDisplayContainer.getLayoutParams();
                     layoutParams.leftMargin = 0;
-                    mAwesomeBarContent.requestLayout();
+                    mUrlDisplayContainer.requestLayout();
                     // Note, we already translated the favicon, site security, and text field
                     // in prepareForwardAnimation, so they should appear to have not moved at
                     // all at this point.
                 }
             }
 
             @Override
             public void onPropertyAnimationEnd() {
                 if (enabled) {
                     ViewGroup.MarginLayoutParams layoutParams =
-                        (ViewGroup.MarginLayoutParams)mAwesomeBarContent.getLayoutParams();
+                        (ViewGroup.MarginLayoutParams)mUrlDisplayContainer.getLayoutParams();
                     layoutParams.leftMargin = mAddressBarViewOffset;
 
                     ViewHelper.setTranslationX(mTitle, 0);
                     ViewHelper.setTranslationX(mFavicon, 0);
                     ViewHelper.setTranslationX(mSiteSecurity, 0);
                 }
 
                 ViewGroup.MarginLayoutParams layoutParams =
                     (ViewGroup.MarginLayoutParams)mForward.getLayoutParams();
                 layoutParams.leftMargin = mDefaultForwardMargin + (mForward.isEnabled() ? mForward.getWidth() / 2 : 0);
                 ViewHelper.setTranslationX(mForward, 0);
 
-                mAwesomeBarContent.requestLayout();
+                mUrlDisplayContainer.requestLayout();
                 mForwardAnim = null;
             }
         });
 
         prepareForwardAnimation(mForwardAnim, enabled, width);
         mForwardAnim.start();
     }
 
@@ -1137,18 +1138,17 @@ public class BrowserToolbar implements T
 
     public void hide() {
         mLayout.setVisibility(View.GONE);
     }
 
     public void refresh() {
         Tab tab = Tabs.getInstance().getSelectedTab();
         if (tab != null) {
-            String url = tab.getURL();
-            setTitle(tab.getDisplayTitle());
+            updateTitle();
             setFavicon(tab.getFavicon());
             setProgressVisibility(tab.getState() == Tab.STATE_LOADING);
             setSecurityMode(tab.getSecurityMode());
             setReaderMode(tab.getReaderEnabled());
             setShadowVisibility(true);
             updateBackButton(tab.canDoBack());
             updateForwardButton(tab.canDoForward());
 
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -578,32 +578,16 @@ abstract public class GeckoApp
         if (Build.VERSION.SDK_INT >= 11 && keyCode == KeyEvent.KEYCODE_MENU) {
             openOptionsMenu();
             return true;
         }
 
         return super.onKeyDown(keyCode, event);
     }
 
-    protected void shareCurrentUrl() {
-        Tab tab = Tabs.getInstance().getSelectedTab();
-        if (tab == null)
-          return;
-
-        String url = tab.getURL();
-        if (url == null)
-            return;
-
-        if (ReaderModeUtils.isAboutReader(url))
-            url = ReaderModeUtils.getUrlFromAboutReader(url);
-
-        GeckoAppShell.openUriExternal(url, "text/plain", "", "",
-                                      Intent.ACTION_SEND, tab.getDisplayTitle());
-    }
-
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
         if (outState == null)
             outState = new Bundle();
 
         outState.putBoolean(SAVED_STATE_IN_BACKGROUND, isApplicationInBackground());
@@ -2174,55 +2158,16 @@ abstract public class GeckoApp
             }
         }
     }
 
     PromptService getPromptService() {
         return mPromptService;
     }
 
-    @Override
-    public boolean onSearchRequested() {
-        return showAwesomebar(AwesomeBar.Target.CURRENT_TAB);
-    }
-
-    public boolean showAwesomebar(AwesomeBar.Target aTarget) {
-        return showAwesomebar(aTarget, null);
-    }
-
-    public boolean showAwesomebar(AwesomeBar.Target aTarget, String aUrl) {
-        Intent intent = new Intent(getBaseContext(), AwesomeBar.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
-        intent.putExtra(AwesomeBar.TARGET_KEY, aTarget.name());
-
-        // If we were passed in a URL, show it.
-        if (aUrl != null && !TextUtils.isEmpty(aUrl)) {
-            intent.putExtra(AwesomeBar.CURRENT_URL_KEY, aUrl);
-        } else if (aTarget == AwesomeBar.Target.CURRENT_TAB) {
-            // Otherwise, if we're editing the current tab, show its URL.
-            Tab tab = Tabs.getInstance().getSelectedTab();
-            if (tab != null) {
-                // Check to see if there's a user-entered search term, which we save
-                // whenever the user performs a search.
-                aUrl = tab.getUserSearch();
-                if (TextUtils.isEmpty(aUrl)) {
-                    aUrl = tab.getURL();
-                }
-                if (aUrl != null) {
-                    intent.putExtra(AwesomeBar.CURRENT_URL_KEY, aUrl);
-                }
-            }
-        }
-
-        int requestCode = GeckoAppShell.sActivityHelper.makeRequestCodeForAwesomebar();
-        startActivityForResult(intent, requestCode);
-        overridePendingTransition (R.anim.awesomebar_fade_in, R.anim.awesomebar_hold_still);
-        return true;
-    }
-
     public void showReadingList() {
         Intent intent = new Intent(getBaseContext(), AwesomeBar.class);
         intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
         intent.putExtra(AwesomeBar.TARGET_KEY, AwesomeBar.Target.CURRENT_TAB.toString());
         intent.putExtra(AwesomeBar.READING_LIST_KEY, true);
 
         int requestCode = GeckoAppShell.sActivityHelper.makeRequestCodeForAwesomebar();
         startActivityForResult(intent, requestCode);
@@ -2494,78 +2439,14 @@ abstract public class GeckoApp
 
         @Override
         public boolean onTrackballEvent(MotionEvent event) {
             mFullScreenPluginView.onTrackballEvent(event);
             return true;
         }
     }
 
-    @Override
-    public boolean onContextItemSelected(MenuItem item) {
-        switch(item.getItemId()) {
-            case R.id.pasteandgo: {
-                String text = GeckoAppShell.getClipboardText();
-                if (text != null && !TextUtils.isEmpty(text)) {
-                    Tabs.getInstance().loadUrl(text);
-                }
-                return true;
-            }
-            case R.id.site_settings: {
-                GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Permissions:Get", null));
-                return true;
-            }
-            case R.id.paste: {
-                String text = GeckoAppShell.getClipboardText();
-                if (text != null && !TextUtils.isEmpty(text)) {
-                    showAwesomebar(AwesomeBar.Target.CURRENT_TAB, text);
-                }
-                return true;
-            }
-            case R.id.share: {
-                shareCurrentUrl();
-                return true;
-            }
-            case R.id.subscribe: {
-                Tab tab = Tabs.getInstance().getSelectedTab();
-                if (tab != null && tab.getFeedsEnabled()) {
-                    JSONObject args = new JSONObject();
-                    try {
-                        args.put("tabId", tab.getId());
-                    } catch (JSONException e) {
-                        Log.e(LOGTAG, "error building json arguments");
-                    }
-                    GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Feeds:Subscribe", args.toString()));
-                }
-                return true;
-            }
-            case R.id.copyurl: {
-                Tab tab = Tabs.getInstance().getSelectedTab();
-                if (tab != null) {
-                    String url = tab.getURL();
-                    if (url != null) {
-                        GeckoAppShell.setClipboardText(url);
-                    }
-                }
-                return true;
-            }
-            case R.id.add_to_launcher: {
-                Tab tab = Tabs.getInstance().getSelectedTab();
-                if (tab != null) {
-                    String url = tab.getURL();
-                    String title = tab.getDisplayTitle();
-                    Bitmap favicon = tab.getFavicon();
-                    if (url != null && title != null) {
-                        GeckoAppShell.createShortcut(title, url, url, favicon == null ? null : favicon, "");
-                    }
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
     protected NotificationClient makeNotificationClient() {
         // Don't use a notification service; we may be killed in the background
         // during downloads.
         return new AppNotificationClient(getApplicationContext());
     }
 }
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -1189,41 +1189,40 @@ public class GeckoAppShell
             if (cm.hasText()) {
                 return cm.getText().toString();
             }
         }
         return null;
     }
 
     private static SynchronousQueue<String> sClipboardQueue = new SynchronousQueue<String>();
-    private static String EMPTY_STRING = new String();
 
     static String getClipboardText() {
         // If we're on the UI thread or the background thread, we have a looper on the thread
         // and can just call this directly. For any other threads, post the call to the
         // background thread.
 
         if (ThreadUtils.isOnUiThread() || ThreadUtils.isOnBackgroundThread()) {
             return getClipboardTextImpl();
         }
 
         ThreadUtils.postToBackgroundThread(new Runnable() { 
             @Override
             public void run() {
                 String text = getClipboardTextImpl();
                 try {
-                    sClipboardQueue.put(text != null ? text : EMPTY_STRING);
+                    sClipboardQueue.put(text != null ? text : "");
                 } catch (InterruptedException ie) {}
             }
         });
         try {
-            String ret = sClipboardQueue.take();
-            return (EMPTY_STRING.equals(ret) ? null : ret);
-        } catch (InterruptedException ie) {}
-        return null;
+            return sClipboardQueue.take();
+        } catch (InterruptedException ie) {
+            return "";
+        }
     }
 
     static void setClipboardText(final String text) {
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             @SuppressWarnings("deprecation")
             public void run() {
                 Context context = GeckoApp.mAppContext;
--- a/mobile/android/base/GeckoPreferenceFragment.java
+++ b/mobile/android/base/GeckoPreferenceFragment.java
@@ -14,23 +14,32 @@ import android.util.Log;
 
 /* A simple implementation of PreferenceFragment for large screen devices
  * This will strip category headers (so that they aren't shown to the user twice)
  * as well as initializing Gecko prefs when a fragment is shown.
 */
 public class GeckoPreferenceFragment extends PreferenceFragment {
 
     private static final String LOGTAG = "GeckoPreferenceFragment";
+    private int mPrefsRequestId = 0;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         String resource = getArguments().getString("resource");
         int res = getActivity().getResources().getIdentifier(resource,
                                                              "xml",
                                                              getActivity().getPackageName());
         addPreferencesFromResource(res);
 
         PreferenceScreen screen = getPreferenceScreen();
         setPreferenceScreen(screen);
-        ((GeckoPreferences)getActivity()).setupPreferences(screen);
+        mPrefsRequestId = ((GeckoPreferences)getActivity()).setupPreferences(screen);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mPrefsRequestId > 0) {
+            PrefsHelper.removeObserver(mPrefsRequestId);
+        }
     }
 }
--- a/mobile/android/base/GeckoPreferences.java
+++ b/mobile/android/base/GeckoPreferences.java
@@ -52,16 +52,17 @@ public class GeckoPreferences
     private static final String LOGTAG = "GeckoPreferences";
 
     private static final String NON_PREF_PREFIX = "android.not_a_preference.";
     public static final String INTENT_EXTRA_RESOURCES = "resource";
     public static String PREFS_HEALTHREPORT_UPLOAD_ENABLED = NON_PREF_PREFIX + "healthreport.uploadEnabled";
 
     private static boolean sIsCharEncodingEnabled = false;
     private boolean mInitialized = false;
+    private int mPrefsRequestId = 0;
 
     // These match keys in resources/xml/preferences.xml.in.
     private static String PREFS_ANNOUNCEMENTS_ENABLED = NON_PREF_PREFIX + "privacy.announcements.enabled";
     private static String PREFS_DATA_REPORTING_PREFERENCES = NON_PREF_PREFIX + "datareporting.preferences";
     private static String PREFS_TELEMETRY_ENABLED = "datareporting.telemetry.enabled";
     private static String PREFS_CRASHREPORTER_ENABLED = "datareporting.crashreporter.submitEnabled";
     private static String PREFS_MENU_CHAR_ENCODING = "browser.menu.showCharacterEncoding";
     private static String PREFS_MP_ENABLED = "privacy.masterpassword.enabled";
@@ -129,24 +130,27 @@ public class GeckoPreferences
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
         if (!hasFocus || mInitialized)
             return;
 
         mInitialized = true;
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
             PreferenceScreen screen = getPreferenceScreen();
-            setupPreferences(screen);
+            mPrefsRequestId = setupPreferences(screen);
         }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
         unregisterEventListener("Sanitize:Finished");
+        if (mPrefsRequestId > 0) {
+            PrefsHelper.removeObserver(mPrefsRequestId);
+        }
     }
 
     @Override
     public void onPause() {
         super.onPause();
 
         if (getApplication() instanceof GeckoApplication) {
             ((GeckoApplication) getApplication()).onActivityPause(this);
@@ -176,22 +180,39 @@ public class GeckoPreferences
                     }
                 });
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
-    public void setupPreferences(PreferenceGroup prefs) {
+    /**
+      * Initialize all of the preferences (native of Gecko ones) for this screen.
+      *
+      * @param prefs The android.preference.PreferenceGroup to initialize
+      * @return The integer id for the PrefsHelper.PrefHandlerBase listener added
+      *         to monitor changes to Gecko prefs.
+      */
+    public int setupPreferences(PreferenceGroup prefs) {
         ArrayList<String> list = new ArrayList<String>();
         setupPreferences(prefs, list);
-        getGeckoPreferences(prefs, list);
+        return getGeckoPreferences(prefs, list);
     }
 
+    /**
+      * Recursively loop through a PreferenceGroup. Initialize native Android prefs,
+      * and build a list of Gecko preferences in the passed in prefs array
+      *
+      * @param preferences The android.preference.PreferenceGroup to initialize
+      * @param prefs An ArrayList to fill with Gecko preferences that need to be
+      *        initialized
+      * @return The integer id for the PrefsHelper.PrefHandlerBase listener added
+      *         to monitor changes to Gecko prefs.
+      */
     private void setupPreferences(PreferenceGroup preferences, ArrayList<String> prefs) {
         for (int i = 0; i < preferences.getPreferenceCount(); i++) {
             Preference pref = preferences.getPreference(i);
             String key = pref.getKey();
             if (pref instanceof PreferenceGroup) {
                 // If no datareporting is enabled, remove UI.
                 if (PREFS_DATA_REPORTING_PREFERENCES.equals(key)) {
                     if (!AppConstants.MOZ_DATA_REPORTING) {
@@ -500,20 +521,20 @@ public class GeckoPreferences
             default:
                 return null;
         }
 
         return dialog;
     }
 
     // Initialize preferences by requesting the preference values from Gecko
-    private void getGeckoPreferences(final PreferenceGroup screen, ArrayList<String> prefs) {
+    private int getGeckoPreferences(final PreferenceGroup screen, ArrayList<String> prefs) {
         JSONArray jsonPrefs = new JSONArray(prefs);
 
-        PrefsHelper.getPrefs(jsonPrefs, new PrefsHelper.PrefHandlerBase() {
+        return PrefsHelper.getPrefs(jsonPrefs, new PrefsHelper.PrefHandlerBase() {
             private Preference getField(String prefName) {
                 return screen.findPreference(prefName);
             }
 
             // Handle v14 TwoStatePreference with backwards compatibility.
             class CheckBoxPrefSetter {
                 public void setBooleanPref(Preference preference, boolean value) {
                     if ((preference instanceof CheckBoxPreference) &&
@@ -578,16 +599,21 @@ public class GeckoPreferences
                         public void run() {
                             fontSizePref.setSummary(fontSizeName); // Ex: "Small".
                         }
                     });
                 }
             }
 
             @Override
+            public boolean isObserver() {
+                return true;
+            }
+
+            @Override
             public void finish() {
                 // enable all preferences once we have them from gecko
                 ThreadUtils.postToUiThread(new Runnable() {
                     @Override
                     public void run() {
                         screen.setEnabled(true);
                     }
                 });
--- a/mobile/android/base/WebAppImpl.java
+++ b/mobile/android/base/WebAppImpl.java
@@ -155,27 +155,40 @@ public class WebAppImpl extends GeckoApp
     }
 
     @Override
     public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
         switch(msg) {
             case SELECTED:
             case LOCATION_CHANGE:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
+                    final String urlString = tab.getURL();
+                    final URL url;
+
                     try {
-                        String title = tab.getURL();
-                        URL page = new URL(title);
-                        mTitlebarText.setText(page.getProtocol() + "://" + page.getHost());
+                        url = new URL(urlString);
+                    } catch (java.net.MalformedURLException ex) {
+                        mTitlebarText.setText(urlString);
 
-                        if (mOrigin != null && mOrigin.getHost().equals(page.getHost()))
+                        // If we can't parse the url, and its an app protocol hide
+                        // the titlebar and return, otherwise show the titlebar
+                        // and the full url
+                        if (!urlString.startsWith("app://")) {
+                            mTitlebar.setVisibility(View.VISIBLE);
+                        } else {
                             mTitlebar.setVisibility(View.GONE);
-                        else
-                            mTitlebar.setVisibility(View.VISIBLE);
-                    } catch (java.net.MalformedURLException ex) {
-                        Log.e(LOGTAG, "Unable to parse url: ", ex);
+                        }
+                        return;
+                    }
+
+                    if (mOrigin != null && mOrigin.getHost().equals(url.getHost())) {
+                        mTitlebar.setVisibility(View.GONE);
+                    } else {
+                        mTitlebarText.setText(url.getProtocol() + "://" + url.getHost());
+                        mTitlebar.setVisibility(View.VISIBLE);
                     }
                 }
                 break;
             case LOADED:
                 if (mSplashscreen != null && mSplashscreen.getVisibility() == View.VISIBLE) {
                     Animation fadeout = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
                     fadeout.setAnimationListener(new Animation.AnimationListener() {
                         @Override
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -145,20 +145,19 @@ size. -->
      en-US/chrome/browser/preferences/advanced.dtd (healthReportSection.label,
      healthReportDesc.label, telemetrySection.label, telemetryDesc.label,
      crashReporterDesc.label). -->
 <!ENTITY datareporting_fhr_title "&brandShortName; Health Report">
 <!ENTITY datareporting_fhr_summary "Helps you understand your browser performance and shares data with &vendorShortName; about your browser health">
 <!ENTITY datareporting_telemetry_title "Telemetry">
 <!ENTITY datareporting_telemetry_summary "Shares performance, usage, hardware and customization data about your browser with &vendorShortName; to help us make &brandShortName; better">
 <!ENTITY datareporting_crashreporter_summary "&brandShortName; submits crash reports to help &vendorShortName; make your browser more stable and secure">
-<!-- Localization note (datareporting_crashreporter_title) : This string matches
+<!-- Localization note (datareporting_crashreporter_title_short) : This string matches
      (crashReporterSection.label) in en-US/chrome/browser/preferences/advanced.dtd.-->
-<!ENTITY datareporting_crashreporter_title2 "&brandShortName; Crash Reporter">
-<!ENTITY datareporting_crashreporter_title "Crash Reporter">
+<!ENTITY datareporting_crashreporter_title_short "Crash Reporter">
 
 <!ENTITY pref_update_autodownload "Automatic updates">
 <!ENTITY pref_update_autodownload_wifi "Only over Wi-Fi">
 <!ENTITY pref_update_autodownload_disabled "Disabled">
 <!ENTITY pref_update_autodownload_enabled "Enabled">
 
 <!ENTITY quit "Quit">
 
index 811168736a3ab00f5c629475c705aa1ab88f0db7..d3a63e3ee423074616a0ed17fd597f61cd396999
GIT binary patch
literal 1418
zc%17D@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBBuiW)N`mv#O3D+9QW+dm@{>{(
zJaZG%Q-e|yQz{EjrrIztFlS_jM3hAM`dB6B=jtVb)aX^@7BGN-jeSKyVsdtBi9%9p
zdS;%j()-=}l@u~lY?Z=IeGPmIoKrJ0J*tXQgRA^PlB=?lEmM^2?G$V(tbhjOrj{fs
zROII56<bx<DuK<l0<uBE`br95B_-LmN)Sgy_y#CA=NF|anCcnpCL0(UDwvt+8Jd`y
znHlOR7#SEE=^Fr%nXaLUm8qGPk+}jCC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DRmzV36
z8|&p4rRy77T3Uk4Ff!5ws?aU2%qvN((9J7WhMC}!TAW;zSx}OhpQixgCnn{Wme?vO
z!Mu=L;Oh%FIIkEQP{1J5uShJ=H`FuG&&}0`sV*)FN=?JBx;Uh=AXPsowK%`DC>a<Z
zY05}e;nxaM2y~5=e^DkdQWA4q@{>z*Q}aqZU2K(rGI}YQDOPS4=5B_D<|YQ_Mh0dU
zhK3df7RGK)MwX72&aOsA#)dF6u<12%b~H6IG&OfJaW*wHbTx7^FafeHES-&v98Fy;
z;d(vuic1pnl2c)NGZA{t@ana4E=o--$uA1Y&(DFSfPjqrlKkR~`~n5%U^4{`-^Aq1
zJdl7UD1xAFO)bhSOHFYr%Fk5*hp<&978e*;S{R`F+|tz2%+1Bw)!EG4SP7~(g`7~+
z2RcR{ExEvifN2oKgeQI=2cCUW^MHA#2$(r$I~v3=Ffi`$ba4!+xRvzh|9|_#2~0jb
z%{)C;8CM(^^DQz>I4Cgl)DC_RE1{MDwFTxgJd)Bl%W>qR!yKj~QVu#k4*%=g-u(AF
z!PFzc`Z&a`$m>+TLk{baLWdZaN$1}D@A=`}VRL}>$XbUto_{qCKl`<^XGe$zb0M36
zIKxJ16W=(-M_CH@n0YNHSh^f%TH5(bPhdLJM)@iAA|1Mo6~cE6L(ZoLOFnIQ!mjYI
zpSAgj<EPt=JGeWX8-H-WUBtum&$;-ry-tz+gd1NS{!HJN$szQ=zj2|8Z%btT%8Ax(
z37)o71LZvG4oz%xc<DOtUMTy%rcd&Wl~NWOzyB*MoMc}scEQl&&qa>)Zxx?jSm5Qn
zU`66F<>MajO}+?t6g~EER`|%iC6|Ap+jIrN)`#jcMNJ;h0@g06b8nICU-<Qgh{80c
zM|=w3+MhYBYPldUblY>2gN<azeda<*f!7lke3v)md&T<5M2Yu_v)6~-3*Q8J{-`Z_
z7T-G2yW`dE$9~Lv9AtQoymioF6piNY-Nt?4!m*qMfj9mfV7Fub$fR(O`^fRe3PFMJ
zi@R)(IHVlvV|;XYiqsJcD;eWg3m!gGXkcJwh<7N^{w<}r4^%pOy85}Sb4q9e05{w3
Ae*gdg
index 3b9aa76d116b57d0495bb9ee8a3b8c63dc90c3e7..4deea98d8ff05a78d4055b852bc9600d30382522
GIT binary patch
literal 1219
zc%17D@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk?
zp1FzXsX?iUDV2pMQ*9U+m@_g%B1$5BeXNr6bM+EIYV;~{3m8Da#=fE;F*!T6L?J0P
zJu}Z%>HY5gN(z}Nwo2iqz6QPp&Z!xh9#uuD!Bu`C$yM3OmMKd1b_zBXRzL%CQ%e#R
zDspr3imfVamB8j&0ofp7eI*63l9Fs&C5WRUd;=7m^NUgyO!bU)lMM_F70k@^3{6bU
z%nWrDj0_Bo^bLT>OxMuF%GAut$Xo#mlz_GsrKDK}xwt{?0`hE?GD=Dctn~HE%ggo3
zjrH=2()A53EiFN27#ZmTRp=I1=9MH?=;jqG!%T2VElw`VEGWs$&r<;L6O-~wOKg>t
zU|z^A@b!fooL3ADC}5E3S0onb8|oS8=jQ6eR2P>7rKaImT^v$bkg6Y)TAW{6lnjiI
zG-V{K@M{Gr1iHq`zbF$JDTz5Q`N^fZsd*)yF1AWQ8NHOu6e~9ib2mdna}xt|BLg!F
zLqiJ#3u8AYBTGk1XICR5V?&r3*z}q>JDM69ni@NqIGY+8x*9ndn3y}6SXeq689AD|
zSi<#s<`tJD<|U`X^kyRT8sXJz<y@4SSdw29lAoUgO925H`6c<q8TkbY&cS918or6i
znRy@qO;7|u-I`jIS(cjOR+OKs01jcROe`)iu(U8h_qnC1rJ0+Hv#Yb2xv>&dZwfh~
zrVn(CK3Z~t2?5g}hzU>pKn^_nq~-zhOc5}16xNh~1!k;|o-U3d6}OW9{QqyytjqX#
z1#9z}rj<SYjZ1jMO6wbbNC}8DeiT=D$DUNH@a)i{Z=BBG>LVrES$%`p+MOL<eQBt$
z6Zp@X#A?$w&GC8%=cfP0i#{wjDq{A`SD42l%E|s{twU-2#Vdc0KQlVSkaR(70ps}t
zb|?PT&$(f7AopO%v37?bKF=qD7ZNIilxMQ`uYS66VwYR3!3Vp9qy>fv2L)|jNIsJn
zxX<v&N8umq*@6Xg&ibulHE)cNZTH{WP{FumMZm%2XUvzpFR$#`<8X<)Bfa4ZL!p&G
zKJ&55>954D2TR^<e3HN5;BU9=Een$w9U2%J7R^ey7V^O;7F4Wwy85}Sb4q9e0N|~e
AcmMzZ
index 83bbd50e4770ca5501334781cb28425b59132af6..2af9d58080c19169f89ad902dc1a039fcb5e0dd7
GIT binary patch
literal 1494
zc%17D@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%o&*>5hW46K32*3xq68pHF_1f1q>iyV_#8_n4FzjqL7rD
zo|$K>^nUk#C56lsTcvPQUjyF)=hTc$kE){7;3~h6<f`ms%M>MhI|Z8xE1&_nsU?XD
z6}dTi#a0!zN?>!XfNYSkzLEl1NlCV?62wsvz5xo(`9-M;rh3M@$p(go3T9?{h9;(F
zW`;TnMh1pP`UXH`rfX<oWol++WUc@ON<iC+Qqrt~T-=~`0eQAc86_nJR{Hwo<>h+i
z#(Mch>H3D2mX;thjEr=FDs+o0^GXscbn}XpVJ5hw7AF^F7L;V>=P7{riAnjTCALaR
zFfZg5`1-;P&MSrn6fns2D-sLz4fPE4b941!s*6j4Qq%COE)J<INYxKYEzU13N(RP9
znlh4A__cx*0$pR}Uz7=ql*AmD{N&Qy)VvZ;7h5Huj9yA+ij|v%xtpP(xru?fk%5_o
zp`nF=g|VBHk)@-hv#XJju_4S1Y<f+c9Zii4O`V)foJ|c4U5%U!Ow653EG(Ukj2ul}
zEa7@R^NLFn^O93xdNUDv9r5b5axO|uEXgkl$<NP$rGS8p{F40QjQj!x=U_7h4d2A%
z%sh~QCMbfSZcQ!9EK5ysE6UGR0Ee(uCKeYMSXvmM``psh(#*}p+11(1+*k>!H-(%~
z(+4_6A1%4Sgn(%f#Dph)AP1g(QuBa$rU;lhoQ@@WGB7Z)c)B=-RNQ(qbHDdt2a)6N
zb2c_D_`y84q_9xPk!7mbmIn$PuT;7o<T<+hVU}@??P|-*lVxEq6_Sw=xg#4B!gBXd
z=!f!yQv2EcIW8_yn{LK=ui4+CYW?x*_wVjLjoq>Cwa%HKgHC#<7@sy2Ian@`3E*pq
zS~Sg8%Kx!t^6JmQ_YSJwU|juRUfp_@-~^eH1~vABzZoQ_T}rQi{bbsECn@pz9uJo1
zQeT?VH}LOLJ*IV_am8lI3C3|A+!0LvlaAfKC8YaNNcM|@fL`$d9nHD7zh&FF1<EsV
zFAz16Hd%Lo>&D`zQ_Xwx<^1)(>#6Wqv1c!kP2sJL{FOVm<kQpnjOm})mN_oIp|K+N
zLpkTpo0bx@&9_7v$XxiLIParUl)D0>-{C5u;{X0hukUIk8XCWfT@hnh(39>jsJrm8
zxDUI;ZpNKTR^^W88U?2^D_XHLSu)>Imc3u3uny?g5BlYbz4j4bu1GO`<T!Ug%p*AV
zgX{`U15PVP+ZBuU&GF&0^nA3-{>7CBJ*Sw3UoLMwq37Y%^ZFEH;J2eH$HXSaEs6B-
zS~tbt+;YPkM^#fdZ})3IcuzAQ-`rm#wf@*<-X5mH?rRAg4lQvXTn_H%)jQDrc5Ms4
z=|+PWEhid$4IFCOrwDIP)O^*t@NkH@LDv4Zw_#2aHt8ADm;DHn-!+vP5+!c?SR@#t
XX5<NO-TTiPRML97`njxgN@xNA)6ELB
--- a/mobile/android/base/resources/layout-large-v11/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout-large-v11/browser_toolbar.xml
@@ -64,17 +64,17 @@
                                   android:layout_toRightOf="@id/tabs"
                                   android:layout_marginLeft="-28dp"
                                   android:layout_centerVertical="true"
                                   android:padding="13dp"
                                   android:src="@drawable/ic_menu_back"
                                   android:contentDescription="@string/back"
                                   android:background="@drawable/address_bar_nav_button"/>
 
-    <LinearLayout android:id="@+id/awesome_bar_content"
+    <LinearLayout android:id="@+id/awesome_bar_display_container"
                   style="@style/AddressBar.Button.Container"
                   android:layout_toRightOf="@id/back"
                   android:layout_toLeftOf="@id/menu_items">
 
         <ImageButton android:id="@+id/favicon"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="@dimen/browser_toolbar_favicon_size"
                      android:layout_height="fill_parent"
--- a/mobile/android/base/resources/layout/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout/browser_toolbar.xml
@@ -92,17 +92,17 @@
                         style="@style/AddressBar.ImageButton.TabCount"
                         android:layout_width="24dip"
                         android:layout_height="24dip"
                         android:layout_marginLeft="40dip"
                         android:layout_marginRight="8dip"
                         android:layout_marginTop="12dip"
                         android:layout_alignRight="@id/tabs"/>
 
-    <LinearLayout android:id="@+id/awesome_bar_content"
+    <LinearLayout android:id="@+id/awesome_bar_display_container"
                   style="@style/AddressBar.Button"
                   android:layout_toLeftOf="@id/tabs"
                   android:layout_marginRight="-24dp"
                   android:orientation="horizontal">
 
         <ImageButton android:id="@+id/favicon"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="@dimen/browser_toolbar_favicon_size"
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -85,63 +85,63 @@
         <item name="android:textSize">16sp</item>
         <item name="android:textStyle">normal</item>
     </style>
 
     <style name="TextAppearance.Inverse">
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
         <item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
-        <item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
+        <item name="android:textColorLink">?android:attr/textColorLink</item>
     </style>
 
     <style name="TextAppearance.Large">
         <item name="android:textSize">22sp</item>
     </style>
 
     <style name="TextAppearance.Large.Inverse">
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
         <item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
-        <item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
+        <item name="android:textColorLink">?android:attr/textColorLink</item>
     </style>
 
     <style name="TextAppearance.Medium">
         <item name="android:textSize">18sp</item>
     </style>
 
     <style name="TextAppearance.Medium.Inverse">
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
         <item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
-        <item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
+        <item name="android:textColorLink">?android:attr/textColorLink</item>
     </style>
 
     <style name="TextAppearance.Small">
         <item name="android:textSize">14sp</item>
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Small.Inverse">
         <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
         <item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
-        <item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
+        <item name="android:textColorLink">?android:attr/textColorLink</item>
     </style>
 
     <style name="TextAppearance.Micro">
         <item name="android:textSize">12sp</item>
         <item name="android:textColor">?android:attr/textColorTertiary</item>
     </style>
 
     <style name="TextAppearance.Micro.Inverse">
         <item name="android:textColor">?android:attr/textColorTertiaryInverse</item>
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
         <item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
-        <item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
+        <item name="android:textColorLink">?android:attr/textColorLink</item>
     </style>
 
     <style name="TextAppearance.Widget" />
 
     <style name="TextAppearance.Widget.Button" parent="TextAppearance.Small">
         <item name="android:textColor">@color/primary_text</item>
     </style>
 
--- a/mobile/android/base/resources/xml/preferences_datareporting.xml
+++ b/mobile/android/base/resources/xml/preferences_datareporting.xml
@@ -14,13 +14,13 @@
                         android:summary="@string/datareporting_telemetry_summary" />
 
     <CheckBoxPreference android:key="android.not_a_preference.healthreport.uploadEnabled"
                         android:title="@string/datareporting_fhr_title"
                         android:summary="@string/datareporting_fhr_summary"
                         android:defaultValue="true" />
 
     <CheckBoxPreference android:key="datareporting.crashreporter.submitEnabled"
-                        android:title="@string/datareporting_crashreporter_title"
+                        android:title="@string/datareporting_crashreporter_title_short"
                         android:summary="@string/datareporting_crashreporter_summary"
                         android:defaultValue="false" />
 
 </PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -139,17 +139,17 @@
   <string name="datareporting_notification_summary">&datareporting_notification_summary;</string>
   <string name="datareporting_notification_summary_short">&datareporting_notification_summary_short;</string>
   <string name="datareporting_notification_ticker_text">&datareporting_notification_ticker_text;</string>
 
   <string name="datareporting_telemetry_title">&datareporting_telemetry_title;</string>
   <string name="datareporting_telemetry_summary">&datareporting_telemetry_summary;</string>
   <string name="datareporting_fhr_title">&datareporting_fhr_title;</string>
   <string name="datareporting_fhr_summary">&datareporting_fhr_summary;</string>
-  <string name="datareporting_crashreporter_title">&datareporting_crashreporter_title;</string>
+  <string name="datareporting_crashreporter_title_short">&datareporting_crashreporter_title_short;</string>
   <string name="datareporting_crashreporter_summary">&datareporting_crashreporter_summary;</string>
 
   <string name="go">&go;</string>
   <string name="search">&search;</string>
   <string name="reload">&reload;</string>
   <string name="forward">&forward;</string>
   <string name="menu">&menu;</string>
   <string name="back">&back;</string>
--- a/mobile/android/base/tests/testHistoryTab.java.in
+++ b/mobile/android/base/tests/testHistoryTab.java.in
@@ -208,38 +208,40 @@ public class testHistoryTab extends Pixe
         listview = getHistoryList("Today|Yesterday");
         waitForText(url);
 
         View child = listview.getChildAt(0);
         mAsserter.ok(child != null, "first list item can be retrieved", child != null ? child.toString() : "null!");
         mSolo.clickOnView(child);
         // nothing should happen
 
-        Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
         mChild = null;
         boolean success = waitForTest(new BooleanTest() {
             @Override
             public boolean test() {
                 // Avoid clicking on the first entry, which is already open and will just switch to the tab
                 mChild = listview.getChildAt(2);
                 if (mChild == null) {
                     return false;
                 }
                 return true;
             }
         }, MAX_WAIT_MS);
         if (success == true && mChild != null) {
+            Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
             mSolo.clickOnView(mChild);
             contentEventExpecter.blockForEvent();
-            mSolo.sleep(500);
+            contentEventExpecter.unregisterListener();
+            // TODO: Find a better way to wait for update before checking
+            // awesome bar; lesser waits result in intermittent failures
+            mSolo.sleep(2000);
             verifyUrl(url);
         } else {
             mAsserter.ok(false, "waiting for history item", "history item available");
         }
-        contentEventExpecter.unregisterListener();
     }
 
     @Override
     public void tearDown() throws Exception {
         ContentResolver resolver = getActivity().getContentResolver();
         Uri uri = Uri.parse("content://@ANDROID_PACKAGE_NAME@.db.browser/history");
         uri = uri.buildUpon().appendQueryParameter("profile", "default")
                              .appendQueryParameter("sync", "true").build();
--- a/mobile/android/chrome/content/MasterPassword.js
+++ b/mobile/android/chrome/content/MasterPassword.js
@@ -37,46 +37,31 @@ var MasterPassword = {
 
       let token = this._pk11DB.findTokenByName(this._tokenName);
 
       if (status == Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED)
         token.initPassword(aPassword);
       else if (status == Ci.nsIPKCS11Slot.SLOT_READY)
         token.changePassword("", aPassword);
 
-      this.updatePref();
+      BrowserApp.notifyPrefObservers(this.pref);
       return true;
     } catch(e) {
       dump("MasterPassword.setPassword: " + e);
     }
     return false;
   },
 
   removePassword: function removePassword(aOldPassword) {
     try {
       let token = this._pk11DB.getInternalKeyToken();
       if (token.checkPassword(aOldPassword)) {
         token.changePassword(aOldPassword, "");
-        this.updatePref();
+        BrowserApp.notifyPrefObservers(this.pref);
         return true;
       }
     } catch(e) {
       dump("MasterPassword.removePassword: " + e + "\n");
     }
     NativeWindow.toast.show(Strings.browser.GetStringFromName("masterPassword.incorrect"), "short");
     return false;
-  },
-
-  updatePref: function() {
-    var prefs = [];
-    let pref = {
-      name: this.pref,
-      type: "bool",
-      value: this.enabled
-    };
-    prefs.push(pref);
-
-    sendMessageToJava({
-      type: "Preferences:Data",
-      preferences: prefs
-    });
   }
 };
--- a/mobile/android/chrome/content/aboutReader.html
+++ b/mobile/android/chrome/content/aboutReader.html
@@ -21,23 +21,21 @@
   <div id="reader-message" class="message">
   </div>
 
   <ul id="reader-toolbar" class="toolbar toolbar-hidden">
     <li><a id="share-button" class="button share-button" href="#"></a></li>
     <ul class="dropdown">
       <li><a class="dropdown-toggle button style-button" href="#"></a></li>
       <li class="dropdown-popup">
-        <ul id="color-scheme-buttons" class="segmented-button"></ul>
-        <hr></hr>
-        <ul id="font-type-buttons" class="segmented-button"></ul>
+        <ul id="font-type-buttons"></ul>
         <hr></hr>
-        <div id="font-size-control" class="step-control"></div>
+        <ul id="font-size-buttons" class="segmented-button"></ul>
         <hr></hr>
-        <div id="margin-size-control" class="step-control"></div>
+        <ul id="color-scheme-buttons" class="segmented-button"></ul>
       </li>
     </ul>
     <li><a id="list-button" class="button list-button" href="#"></a></li>
     <li><a id="toggle-button" class="button toggle-button" href="#"></a></li>
   </ul>
 
 </body>
 
--- a/mobile/android/chrome/content/aboutReader.js
+++ b/mobile/android/chrome/content/aboutReader.js
@@ -57,50 +57,67 @@ let AboutReader = function(doc, win) {
   win.addEventListener("resize", this, false);
 
   this._setupAllDropdowns();
   this._setupButton("toggle-button", this._onReaderToggle.bind(this));
   this._setupButton("list-button", this._onList.bind(this));
   this._setupButton("share-button", this._onShare.bind(this));
 
   let colorSchemeOptions = [
+    { name: gStrings.GetStringFromName("aboutReader.colorSchemeDark"),
+      value: "dark"},
     { name: gStrings.GetStringFromName("aboutReader.colorSchemeLight"),
       value: "light"},
-    { name: gStrings.GetStringFromName("aboutReader.colorSchemeDark"),
-      value: "dark"},
     { name: gStrings.GetStringFromName("aboutReader.colorSchemeAuto"),
       value: "auto"}
   ];
 
   let colorScheme = Services.prefs.getCharPref("reader.color_scheme");
   this._setupSegmentedButton("color-scheme-buttons", colorSchemeOptions, colorScheme, this._setColorSchemePref.bind(this));
   this._setColorSchemePref(colorScheme);
 
+  let fontTypeSample = gStrings.GetStringFromName("aboutReader.fontTypeSample");
   let fontTypeOptions = [
-    { name: gStrings.GetStringFromName("aboutReader.fontTypeSansSerif"),
-      value: "sans-serif"},
-    { name: gStrings.GetStringFromName("aboutReader.fontTypeSerif"),
-      value: "serif"}
+    { name: fontTypeSample,
+      description: gStrings.GetStringFromName("aboutReader.fontTypeCharis"),
+      value: "serif",
+      linkClass: "serif" },
+    { name: fontTypeSample,
+      description: gStrings.GetStringFromName("aboutReader.fontTypeOpenSans"),
+      value: "sans-serif",
+      linkClass: "sans-serif"
+    },
   ];
 
   let fontType = Services.prefs.getCharPref("reader.font_type");
   this._setupSegmentedButton("font-type-buttons", fontTypeOptions, fontType, this._setFontType.bind(this));
   this._setFontType(fontType);
 
-  let fontTitle = gStrings.GetStringFromName("aboutReader.textTitle");
-  this._fontSize = 0;
-  this._setupStepControl("font-size-control", fontTitle,
-    this._FONT_SIZE_MIN, this._FONT_SIZE_MAX, this._FONT_SIZE_STEP, Services.prefs.getIntPref("reader.font_size"),
-    this._onFontSizeChange.bind(this));
+  let fontSizeSample = gStrings.GetStringFromName("aboutReader.fontSizeSample");
+  let fontSizeOptions = [
+    { name: fontSizeSample,
+      value: 1,
+      linkClass: "font-size1-sample" },
+    { name: fontSizeSample,
+      value: 2,
+      linkClass: "font-size2-sample" },
+    { name: fontSizeSample,
+      value: 3,
+      linkClass: "font-size3-sample" },
+    { name: fontSizeSample,
+      value: 4,
+      linkClass: "font-size4-sample" },
+    { name: fontSizeSample,
+      value: 5,
+      linkClass: "font-size5-sample" }
+  ];
 
-  let marginTitle = gStrings.GetStringFromName("aboutReader.marginTitle");
-  this._marginSize = 0;
-  this._setupStepControl("margin-size-control", marginTitle,
-    this._MARGIN_SIZE_MIN, this._MARGIN_SIZE_MAX, this._MARGIN_SIZE_STEP, Services.prefs.getIntPref("reader.margin_size"),
-    this._onMarginSizeChange.bind(this));
+  let fontSize = Services.prefs.getIntPref("reader.font_size");
+  this._setupSegmentedButton("font-size-buttons", fontSizeOptions, fontSize, this._setFontSize.bind(this));
+  this._setFontSize(fontSize);
 
   dump("Decoding query arguments");
   let queryArgs = this._decodeQueryString(win.location.href);
 
   this._isReadingListItem = (queryArgs.readingList == "1");
   this._updateToggleButton();
 
   let url = queryArgs.url;
@@ -110,23 +127,16 @@ let AboutReader = function(doc, win) {
     this._loadFromTab(tabId, url);
   } else {
     dump("Fetching page with URL: " + url);
     this._loadFromURL(url);
   }
 }
 
 AboutReader.prototype = {
-  _FONT_SIZE_MIN: 1,
-  _FONT_SIZE_MAX: 7,
-  _FONT_SIZE_STEP: 1,
-  _MARGIN_SIZE_MIN: 5,
-  _MARGIN_SIZE_MAX: 25,
-  _MARGIN_SIZE_STEP: 5,
-
   _BLOCK_IMAGES_SELECTOR: ".content p > img:only-child, " +
                           ".content p > a:only-child > img:only-child, " +
                           ".content .wp-caption img, " +
                           ".content figure img",
 
   get _doc() {
     return this._docRef.get();
   },
@@ -293,29 +303,17 @@ AboutReader.prototype = {
 
     gChromeWin.sendMessageToJava({
       type: "Reader:Share",
       url: this._article.url,
       title: this._article.title
     });
   },
 
-  _onMarginSizeChange: function Reader_onMarginSizeChange(newMarginSize) {
-    let doc = this._doc;
-
-    this._marginSize = newMarginSize;
-    doc.body.style.marginLeft = this._marginSize + "%";
-    doc.body.style.marginRight = this._marginSize + "%";
-
-    this._updateImageMargins();
-
-    Services.prefs.setIntPref("reader.margin_size", this._marginSize);
-  },
-
-  _onFontSizeChange: function Reader_onFontSizeChange(newFontSize) {
+  _setFontSize: function Reader_setFontSize(newFontSize) {
     let bodyClasses = this._doc.body.classList;
 
     if (this._fontSize > 0)
       bodyClasses.remove("font-size" + this._fontSize);
 
     this._fontSize = newFontSize;
     bodyClasses.add("font-size" + this._fontSize);
 
@@ -574,91 +572,37 @@ AboutReader.prototype = {
         let [name, value] = pairs[i].split("=");
         result[name] = decodeURIComponent(value);
       }
     }
 
     return result;
   },
 
-  _setupStepControl: function Reader_setupStepControl(id, name, min, max, step, initial, callback) {
-    let doc = this._doc;
-    let stepControl = doc.getElementById(id);
-
-    let title = this._doc.createElement("h1");
-    title.innerHTML = name;
-    stepControl.appendChild(title);
-
-    let plusButton = doc.createElement("div");
-    plusButton.className = "button plus-button";
-    stepControl.appendChild(plusButton);
-
-    let minusButton = doc.createElement("div");
-    minusButton.className = "button minus-button";
-    stepControl.appendChild(minusButton);
-
-    let updateControls = function() {
-      current = Math.max(min, Math.min(max, current));
-      if (current == min) {
-        minusButton.classList.add("disabled");
-      } else {
-        minusButton.classList.remove("disabled");
-      }
-      if (current == max) {
-        plusButton.classList.add("disabled");
-      } else {
-        plusButton.classList.remove("disabled");
-      }
-    }
-
-    let current = initial;
-    updateControls();
-
-    plusButton.addEventListener("click", function(aEvent) {
-      if (!aEvent.isTrusted)
-        return;
-
-      aEvent.stopPropagation();
-
-      if (current < max) {
-        current += step;
-        updateControls();
-        callback(current);
-      }
-    }.bind(this), true);
-
-    minusButton.addEventListener("click", function(aEvent) {
-      if (!aEvent.isTrusted)
-        return;
-
-      aEvent.stopPropagation();
-
-      if (current > min) {
-        current -= step;
-        updateControls();
-        callback(current);
-      }
-    }.bind(this), true);
-
-    // Always callback initial current setting
-    callback(current);
-  },
-
   _setupSegmentedButton: function Reader_setupSegmentedButton(id, options, initialValue, callback) {
     let doc = this._doc;
     let segmentedButton = doc.getElementById(id);
 
     for (let i = 0; i < options.length; i++) {
       let option = options[i];
 
       let item = doc.createElement("li");
       let link = doc.createElement("a");
-      link.innerHTML = option.name;
+      link.textContent = option.name;
       item.appendChild(link);
 
+      if (option.linkClass !== undefined)
+        link.classList.add(option.linkClass);
+
+      if (option.description !== undefined) {
+        let description = doc.createElement("div");
+        description.textContent = option.description;
+        item.appendChild(description);
+      }
+
       link.style.MozUserSelect = 'none';
       segmentedButton.appendChild(item);
 
       link.addEventListener("click", function(aEvent) {
         if (!aEvent.isTrusted)
           return;
 
         aEvent.stopPropagation();
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -943,16 +943,24 @@ var BrowserApp = {
     let download = dm.addDownload(Ci.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD,
                                   aBrowser.currentURI,
                                   Services.io.newFileURI(file), "", mimeInfo,
                                   Date.now() * 1000, null, cancelable, isPrivate);
 
     webBrowserPrint.print(printSettings, download);
   },
 
+  notifyPrefObservers: function(aPref) {
+    this._prefObservers[aPref].forEach(function(aRequestId) {
+      let request = { requestId : aRequestId,
+                      preferences : [aPref] };
+      this.getPreferences(request);
+    }, this);
+  },
+
   getPreferences: function getPreferences(aPrefsRequest, aListen) {
     let prefs = [];
 
     for each (let prefName in aPrefsRequest.preferences) {
       let pref = {
         name: prefName,
         type: "",
         value: null
@@ -1437,21 +1445,17 @@ var BrowserApp = {
         break;
 
       case "Viewport:FixedMarginsChanged":
         gViewportMargins = JSON.parse(aData);
         this.selectedTab.updateViewportSize(gScreenWidth);
         break;
 
       case "nsPref:changed":
-        for each (let requestId in this._prefObservers[aData]) {
-          let request = { requestId : requestId,
-                          preferences : [ aData ] };
-          this.getPreferences(request, false);
-        }
+        this.notifyPrefObservers(aData);
         break;
 
       default:
         dump('BrowserApp.observe: unexpected topic "' + aTopic + '"\n');
         break;
 
     }
   },
--- a/mobile/android/locales/en-US/chrome/aboutReader.properties
+++ b/mobile/android/locales/en-US/chrome/aboutReader.properties
@@ -1,19 +1,25 @@
 # 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/.
 
 aboutReader.loading=Loading...
 aboutReader.loadError=Failed to load article from page
 
-aboutReader.textTitle=Text
-aboutReader.marginTitle=Margins
-
 aboutReader.colorSchemeLight=Light
 aboutReader.colorSchemeDark=Dark
 aboutReader.colorSchemeSepia=Sepia
 aboutReader.colorSchemeAuto=Auto
 
-aboutReader.fontTypeSansSerif=Sans
-aboutReader.fontTypeSerif=Serif
+# LOCALIZATION NOTE (aboutReader.fontTypeCharis, aboutReader.fontTypeOpenSans):
+# These are the names of the fonts that are used.
+aboutReader.fontTypeCharis=Charis
+aboutReader.fontTypeOpenSans=Open Sans
+
+# LOCALIZATION NOTE (aboutReader.fontTypeSample): String used to sample font types.
+aboutReader.fontTypeSample=Aa
+
+# LOCALIZATION NOTE (aboutReader.fontSizeSample): String used to sample a relative font size
+# for the font size setting. Tapping different samples will change the font size.
+aboutReader.fontSizeSample=A
 
 aboutReader.toolbarTip=Tap the screen to show reader options
--- a/mobile/android/themes/core/aboutReader.css
+++ b/mobile/android/themes/core/aboutReader.css
@@ -88,94 +88,73 @@ body {
   color: #eeeeee;
 }
 
 .dark > .header > .credits {
   color: #aaaaaa;
 }
 
 .font-size1 > .header > h1 {
-  font-size: 23px;
+  font-size: 25px;
 }
 
 .font-size2 > .header > h1 {
-  font-size: 25px;
+  font-size: 27px;
 }
 
 .font-size3 > .header > h1 {
-  font-size: 27px;
+  font-size: 29px;
 }
 
 .font-size4 > .header > h1 {
-  font-size: 29px;
-}
-
-.font-size5 > .header > h1 {
   font-size: 31px;
 }
 
-.font-size6 > .header > h1 {
+.font-size5 > .header > h1 {
   font-size: 33px;
 }
 
-.font-size7 > .header > h1 {
-  font-size: 35px;
-}
-
 /* This covers caption, domain, and credits
    texts in the reader UI */
+
 .font-size1 > .content .wp-caption-text,
 .font-size1 > .content figcaption,
 .font-size1 > .header > .domain,
 .font-size1 > .header > .credits {
-  font-size: 6px;
+  font-size: 8px;
 }
 
 .font-size2 > .content .wp-caption-text,
 .font-size2 > .content figcaption,
 .font-size2 > .header > .domain,
 .font-size2 > .header > .credits {
-  font-size: 8px;
+  font-size: 11px;
 }
 
 .font-size3 > .content .wp-caption-text,
 .font-size3 > .content figcaption,
 .font-size3 > .header > .domain,
 .font-size3 > .header > .credits {
-  font-size: 11px;
+  font-size: 13px;
 }
 
 .font-size4 > .content .wp-caption-text,
 .font-size4 > .content figcaption,
 .font-size4 > .header > .domain,
 .font-size4 > .header > .credits {
-  font-size: 13px;
+  font-size: 15px;
 }
 
 .font-size5 > .content .wp-caption-text,
 .font-size5 > .content figcaption,
 .font-size5 > .header > .domain,
 .font-size5 > .header > .credits {
-  font-size: 15px;
-}
-
-.font-size6 > .content .wp-caption-text,
-.font-size6 > .content figcaption,
-.font-size6 > .header > .domain,
-.font-size6 > .header > .credits {
   font-size: 17px;
 }
 
-.font-size7 > .content .wp-caption-text,
-.font-size7 > .content figcaption,
-.font-size7 > .header > .domain,
-.font-size7 > .header > .credits {
-  font-size: 19px;
-}
-
 .content {
   display: none;
 }
 
 .content a {
   text-decoration: underline !important;
   font-weight: normal;
 }
@@ -295,44 +274,41 @@ body {
   list-style: disk !important;
 }
 
 .content ol {
   -moz-padding-start: 35px !important;
   list-style: decimal !important;
 }
 
+.font-size1-sample,
 .font-size1 > .content {
-  font-size: 10px !important;
-}
-
-.font-size2 > .content {
   font-size: 12px !important;
 }
 
-.font-size3 > .content {
+.font-size2-sample,
+.font-size2 > .content {
   font-size: 14px !important;
 }
 
-.font-size4 > .content {
+.font-size3-sample,
+.font-size3 > .content {
   font-size: 16px !important;
 }
 
-.font-size5 > .content {
+.font-size4-sample,
+.font-size4 > .content {
   font-size: 18px !important;
 }
 
-.font-size6 > .content {
+.font-size5-sample,
+.font-size5 > .content {
   font-size: 20px !important;
 }
 
-.font-size7 > .content {
-  font-size: 22px !important;
-}
-
 .toolbar {
   font-family: "Droid Sans",helvetica,arial,clean,sans-serif;
   -moz-transition-property: visibility, opacity;
   -moz-transition-duration: 0.7s;
   visibility: visible;
   opacity: 1.0;
   position: fixed;
   width: 100%;
@@ -394,38 +370,28 @@ body {
   float: left;
   background: #dde2e7;
   margin-top: 12px;
   margin-bottom: 10px;
   padding-top: 4px;
   padding-bottom: 8px;
   font-size: 14px;
   box-shadow: 0px -1px 12px #333;
+  border-radius: 3px;
   visibility: hidden;
 }
 
 .dropdown-popup > hr {
   width: 100%;
   height: 0px;
   border: 0px;
-  border-top: 1px solid #ccc;
-  border-bottom: 1px solid white;
-  margin: 0px 0px 10px 0px;
-  float: left;
-}
-
-.dropdown-popup > hr:first-of-type {
-  float: none;
+  border-top: 1px solid #C5D0DA;
   margin: 0;
 }
 
-.dropdown-popup .button:active {
-  background-color: #ccc;
-}
-
 .open > .dropdown-popup {
   margin-top: 0px;
   margin-bottom: 6px;
   bottom: 100%;
   visibility: visible;
 }
 
 .dropdown-arrow {
@@ -434,88 +400,84 @@ body {
   height: 18px;
   bottom: -18px;
   background-image: url('chrome://browser/skin/images/reader-dropdown-arrow-mdpi.png');
   background-size: 40px 18px;
   background-position: center;
   display: block;
 }
 
+#font-type-buttons,
 .segmented-button {
   display: flex;
   flex-direction: row;
   list-style: none;
-  margin: 0;
-  padding: 5px;
+  padding: 10px 5px;
   white-space: nowrap;
 }
 
+#font-type-buttons > li,
 .segmented-button > li {
-  flex: 1 1 auto;
+  width: 50px; /* combined with flex, this acts as a minimum width */
+  flex: 1 0 auto;
   text-align: center;
-  padding: 1px 5px;
-  border-left: 1px solid #ccc;
+  line-height: 20px;
+}
+
+#font-type-buttons > li {
+  padding: 10px 0;
+}
+
+.segmented-button > li {
+  border-left: 1px solid #C5D0DA;
 }
 
 .segmented-button > li:first-child {
   border-left: 0px;
 }
 
-.segmented-button > li > a,
-.segmented-button > li > a:hover
-.segmented-button > li > a:visited {
-  display: block;
-  padding: 10px 16px;
+#font-type-buttons > li > a,
+.segmented-button > li > a {
+  vertical-align: middle;
   text-decoration: none;
   color: black;
-  border-radius: 4px;
+}
+
+#font-type-buttons > li > a {
+  display: inline-block;
+  font-size: 48px;
+  line-height: 50px;
+  margin-bottom: 5px;
+  border-bottom: 3px solid transparent;
+}
+
+.segmented-button > li > a {
+  display: block;
+  padding: 5px 0;
+  font-family: "Roboto",sans-serif;
+  font-weight: lighter;
+}
+
+#font-type-buttons > li > a:active,
+#font-type-buttons > li.selected > a {
+  border-color: #ff9400;
 }
 
 .segmented-button > li > a:active,
 .segmented-button > li.selected > a {
-  background: #ccc;
-}
-
-.step-control {
-  width: 100%;
-  padding: 0px;
-}
-
-.step-control > h1 {
-  font-size: 16px;
-  font-weight: normal;
-  color: black;
-  margin: 0px;
-  margin-top: 12px;
-  margin-bottom: 20px;
-  margin-left: 10px;
-  float: left;
+  font-weight: bold;
 }
 
-.step-control > .button {
-  float: right;
-  text-align: center;
-  width: 56px;
-  height: 43px;
-  background-size: 20px;
+#font-type-buttons > li > .sans-serif {
+  font-weight: lighter;
 }
 
-.step-control > .plus-button {
-  background-image: url('chrome://browser/skin/images/reader-plus-icon-mdpi.png');
-  border-left: 1px solid #ccc;
-  margin-right: 4px;
-}
-
-.step-control > .minus-button {
-  background-image: url('chrome://browser/skin/images/reader-minus-icon-mdpi.png');
-}
-
-.step-control > .disabled {
-  opacity: 0.25;
-  -moz-user-select: -moz-none;
+#font-type-buttons > li > div {
+  color: #666;
+  font-size: 12px;
 }
 
 .toggle-button.on {
   background-image: url('chrome://browser/skin/images/reader-toggle-on-icon-mdpi.png');
 }
 
 .toggle-button {
   background-image: url('chrome://browser/skin/images/reader-toggle-off-icon-mdpi.png');
--- a/netwerk/dns/effective_tld_names.dat
+++ b/netwerk/dns/effective_tld_names.dat
@@ -6966,16 +6966,21 @@ blogspot.se
 blogspot.sg
 blogspot.sk
 blogspot.td
 blogspot.tw
 codespot.com
 googleapis.com
 googlecode.com
 
+// Heroku : https://www.heroku.com/
+// Requested by Tom Maher <tmaher@heroku.com> 2013-05-02
+herokuapp.com
+herokussl.com
+
 // iki.fi
 // Requested by Hannu Aronsson <haa@iki.fi> 2009-11-05
 iki.fi
 
 // info.at : http://www.info.at/
 biz.at
 info.at
 
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -226,17 +226,18 @@ nsDNSRecord::ReportUnusable(uint16_t aPo
 
     MutexAutoLock lock(mHostRecord->addr_info_lock);
 
     // Check that we are using a real addr_info (as opposed to a single
     // constant address), and that the generation count is valid. Otherwise,
     // ignore the report.
 
     if (mHostRecord->addr_info &&
-        mIterGenCnt == mHostRecord->addr_info_gencnt) {
+        mIterGenCnt == mHostRecord->addr_info_gencnt &&
+        mIter) {
         mHostRecord->ReportUnusable(&mIter->mAddress);
     }
 
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
--- a/python/mozbuild/mozpack/packager/__init__.py
+++ b/python/mozbuild/mozpack/packager/__init__.py
@@ -3,16 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from Preprocessor import Preprocessor
 import re
 import os
 from mozpack.errors import errors
 from mozpack.chrome.manifest import (
     Manifest,
+    ManifestChrome,
     ManifestInterfaces,
     is_manifest,
     parse_manifest,
 )
 import mozpack.path
 from collections import deque
 
 
@@ -123,16 +124,18 @@ class SimplePackager(object):
     SimpleManifestSink to a formatter. Formatters expect some information to be
     given first that the simple manifest contents can't guarantee before the
     end of the input.
     '''
     def __init__(self, formatter):
         self.formatter = formatter
         # Queue for formatter.add_interfaces()/add_manifest() calls.
         self._queue = CallDeque()
+        # Queue for formatter.add_manifest() calls for ManifestChrome.
+        self._chrome_queue = CallDeque()
         # Queue for formatter.add() calls.
         self._file_queue = CallDeque()
         # All manifest paths imported.
         self._manifests = set()
         # All manifest paths included from some other manifest.
         self._included_manifests = set()
         self._closed = False
 
@@ -155,18 +158,23 @@ class SimplePackager(object):
         self._manifests.add(path)
         base = ''
         if hasattr(file, 'path'):
             # Find the directory the given path is relative to.
             b = mozpack.path.normsep(file.path)
             if b.endswith('/' + path) or b == path:
                 base = os.path.normpath(b[:-len(path)])
         for e in parse_manifest(base, path, file.open()):
-            if not isinstance(e, (Manifest, ManifestInterfaces)):
+            # ManifestResources need to be given after ManifestChrome, so just
+            # put all ManifestChrome in a separate queue to make them first.
+            if isinstance(e, ManifestChrome):
                 # e.move(e.base) just returns a clone of the entry.
+                self._chrome_queue.append(self.formatter.add_manifest,
+                                          e.move(e.base))
+            elif not isinstance(e, (Manifest, ManifestInterfaces)):
                 self._queue.append(self.formatter.add_manifest, e.move(e.base))
             if isinstance(e, Manifest):
                 if e.flags:
                     errors.fatal('Flags are not supported on ' +
                                  '"manifest" entries')
                 self._included_manifests.add(e.path)
 
     def get_bases(self):
@@ -180,16 +188,17 @@ class SimplePackager(object):
     def close(self):
         '''
         Push all instructions to the formatter.
         '''
         self._closed = True
         for base in self.get_bases():
             if base:
                 self.formatter.add_base(base)
+        self._chrome_queue.execute()
         self._queue.execute()
         self._file_queue.execute()
 
 
 class SimpleManifestSink(object):
     '''
     Parser sink for "simple" package manifests. Simple package manifests use
     the format described in the PackageManifestParser documentation, but don't
--- a/python/mozbuild/mozpack/packager/formats.py
+++ b/python/mozbuild/mozpack/packager/formats.py
@@ -125,17 +125,19 @@ class FlatFormatter(object):
     def contains(self, path):
         assert '*' not in path
         return self.copier.contains(path)
 
 
 class JarFormatter(FlatFormatter):
     '''
     Formatter for the jar package format. Assumes manifest entries related to
-    chrome are registered before the chrome data files are added.
+    chrome are registered before the chrome data files are added. Also assumes
+    manifest entries for resources are registered after chrome manifest
+    entries.
     '''
     def __init__(self, copier, compress=True, optimize=True):
         FlatFormatter.__init__(self, copier)
         self._chrome = set()
         self._frozen_chrome = False
         self._compress = compress
         self._optimize = optimize
 
--- a/python/mozbuild/mozpack/test/test_packager.py
+++ b/python/mozbuild/mozpack/test/test_packager.py
@@ -167,22 +167,24 @@ class TestSimplePackager(unittest.TestCa
         with errors.context('manifest', 7):
             packager.add('foo/qux.xpt', qux_xpt)
 
         self.assertEqual(formatter.log, [])
 
         with errors.context('dummy', 1):
             packager.close()
         self.maxDiff = None
+        # The formatter is expected to reorder the manifest entries so that
+        # chrome entries appear before the others.
         self.assertEqual(formatter.log, [
             (('dummy', 1), 'add_base', 'qux'),
+            ((os.path.join(curdir, 'foo', 'bar.manifest'), 2),
+             'add_manifest', ManifestContent('foo', 'bar', 'bar/')),
             ((os.path.join(curdir, 'foo', 'bar.manifest'), 1),
              'add_manifest', ManifestResource('foo', 'bar', 'bar/')),
-            ((os.path.join(curdir, 'foo', 'bar.manifest'), 2),
-             'add_manifest', ManifestContent('foo', 'bar', 'bar/')),
             (('bar/baz.manifest', 1),
              'add_manifest', ManifestResource('bar', 'baz', 'baz/')),
             (('qux/qux.manifest', 1),
              'add_manifest', ManifestResource('qux', 'qux', 'qux/')),
             (('manifest', 4), 'add_interfaces', 'foo/bar.xpt', bar_xpt),
             (('manifest', 7), 'add_interfaces', 'foo/qux.xpt', qux_xpt),
             (('manifest', 5), 'add', 'foo/bar/foo.html', foo_html),
             (('manifest', 5), 'add', 'foo/bar/bar.html', bar_html),
--- a/security/manager/ssl/src/nsCrypto.cpp
+++ b/security/manager/ssl/src/nsCrypto.cpp
@@ -1911,17 +1911,17 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMF
     return NS_ERROR_FAILURE;
   }
   jsString = JS_ValueToString(cx, argv[4]);
   NS_ENSURE_TRUE(jsString, NS_ERROR_OUT_OF_MEMORY);
   argv[4] = STRING_TO_JSVAL(jsString);
   JSAutoByteString jsCallback(cx, jsString);
   NS_ENSURE_TRUE(!!jsCallback, NS_ERROR_OUT_OF_MEMORY);
 
-  nrv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx),
+  nrv = xpc->WrapNative(cx, JS_GetGlobalForScopeChain(cx),
                         static_cast<nsIDOMCrypto *>(this),
                         NS_GET_IID(nsIDOMCrypto), getter_AddRefs(holder));
   NS_ENSURE_SUCCESS(nrv, nrv);
 
   nrv = holder->GetJSObject(script_obj.address());
   NS_ENSURE_SUCCESS(nrv, nrv);
 
   //Put up some UI warning that someone is trying to 
@@ -2171,25 +2171,20 @@ nsCryptoRunnable::~nsCryptoRunnable()
 }
 
 //Implementation that runs the callback passed to 
 //crypto.generateCRMFRequest as an event.
 NS_IMETHODIMP
 nsCryptoRunnable::Run()
 {
   nsNSSShutDownPreventionLock locker;
-  JSContext *cx = m_args->m_cx;
-
+  AutoPushJSContext cx(m_args->m_cx);
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, m_args->m_scope);
 
-  // make sure the right context is on the stack. must not return w/out popping
-  nsCxPusher pusher;
-  pusher.Push(cx);
-
   JSBool ok =
     JS_EvaluateScriptForPrincipals(cx, m_args->m_scope,
                                    nsJSPrincipals::get(m_args->m_principals),
                                    m_args->m_jsCallback, 
                                    strlen(m_args->m_jsCallback),
                                    nullptr, 0, nullptr);
   return ok ? NS_OK : NS_ERROR_FAILURE;
 }
--- a/services/healthreport/tests/xpcshell/test_healthreporter.js
+++ b/services/healthreport/tests/xpcshell/test_healthreporter.js
@@ -408,27 +408,31 @@ add_task(function test_constant_only_pro
 add_task(function test_json_payload_multiple_days() {
   let reporter = yield getReporter("json_payload_multiple_days");
 
   try {
     let provider = new DummyProvider();
     yield reporter._providerManager.registerProvider(provider);
 
     let now = new Date();
+
     let m = provider.getMeasurement("DummyMeasurement", 1);
     for (let i = 0; i < 200; i++) {
       let date = new Date(now.getTime() - i * MILLISECONDS_PER_DAY);
       yield m.incrementDailyCounter("daily-counter", date);
-      yield m.addDailyDiscreteNumeric("daily-discrete-numeric", i, date);
-      yield m.addDailyDiscreteNumeric("daily-discrete-numeric", i + 100, date);
-      yield m.addDailyDiscreteText("daily-discrete-text", "" + i, date);
-      yield m.addDailyDiscreteText("daily-discrete-text", "" + (i + 50), date);
-      yield m.setDailyLastNumeric("daily-last-numeric", date.getTime(), date);
     }
 
+    // This test could fail if we cross a UTC day boundary when running. So,
+    // we ensure this doesn't occur.
+    Object.defineProperty(reporter, "_now", {
+      value: function () {
+        return now;
+      },
+    });
+
     let payload = yield reporter.getJSONPayload();
     print(payload);
     let o = JSON.parse(payload);
 
     do_check_eq(Object.keys(o.data.days).length, 180);
     let today = reporter._formatDate(now);
     do_check_true(today in o.data.days);
   } finally {
--- a/testing/xpcshell/xpcshell_android.ini
+++ b/testing/xpcshell/xpcshell_android.ini
@@ -40,8 +40,9 @@
 [include:gfx/tests/unit/xpcshell.ini]
 [include:services/common/tests/unit/xpcshell.ini]
 [include:services/crypto/components/tests/unit/xpcshell.ini]
 [include:services/healthreport/tests/xpcshell/xpcshell.ini]
 [include:services/metrics/tests/xpcshell/xpcshell.ini]
 [include:services/sync/tests/unit/xpcshell.ini]
 [include:browser/components/privatebrowsing/test/unit/xpcshell.ini]
 [include:browser/modules/test/unit/xpcshell.ini]
+[include:toolkit/components/telemetry/tests/unit/xpcshell.ini]
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -4193,9 +4193,9 @@ var engineUpdateService = {
       // otherwise use the existing engine object.
       (testEngine || engine)._setIcon(engine._iconUpdateURL, true);
     }
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SearchService]);
 
-#include ../../../toolkit/content/debug.js
+#include ../../../toolkit/modules/debug.js
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -309,17 +309,17 @@ private:
   typedef AutoHashtable<AddonHistogramEntryType> AddonHistogramMapType;
   typedef nsBaseHashtableET<nsCStringHashKey, AddonHistogramMapType *> AddonEntryType;
   typedef AutoHashtable<AddonEntryType> AddonMapType;
   static bool AddonHistogramReflector(AddonHistogramEntryType *entry,
                                       JSContext *cx, JS::Handle<JSObject*> obj);
   static bool AddonReflector(AddonEntryType *entry, JSContext *cx, JS::Handle<JSObject*> obj);
   static bool CreateHistogramForAddon(const nsACString &name,
                                       AddonHistogramInfo &info);
-  void ReadLateWritesStacks();
+  void ReadLateWritesStacks(nsIFile* aProfileDir);
   AddonMapType mAddonMap;
 
   // This is used for speedy string->Telemetry::ID conversions
   typedef nsBaseHashtableET<nsCharPtrHashKey, Telemetry::ID> CharPtrEntryType;
   typedef AutoHashtable<CharPtrEntryType> HistogramMapType;
   HistogramMapType mHistogramMap;
   bool mCanRecord;
   static TelemetryImpl *sTelemetry;
@@ -738,60 +738,60 @@ GetFailedLockCount(nsIInputStream* inStr
   nsresult rv;
   rv = NS_ReadInputStreamToString(inStream, bufStr, aCount);
   NS_ENSURE_SUCCESS(rv, false);
   result = bufStr.ToInteger(&rv);
   return NS_SUCCEEDED(rv) && result > 0;
 }
 
 nsresult
-GetFailedProfileLockFile(nsIFile* *aFile, nsIFile* aProfileDir = nullptr)
+GetFailedProfileLockFile(nsIFile* *aFile, nsIFile* aProfileDir)
 {
-  nsresult rv;
-  if (aProfileDir) {
-    rv = aProfileDir->Clone(aFile);
-  } else {
-    rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, aFile);
-  }
+  NS_ENSURE_ARG_POINTER(aProfileDir);
+
+  nsresult rv = aProfileDir->Clone(aFile);
   NS_ENSURE_SUCCESS(rv, rv);
 
   (*aFile)->AppendNative(NS_LITERAL_CSTRING("Telemetry.FailedProfileLocks.txt"));
   return NS_OK;
 }
 
 class nsFetchTelemetryData : public nsRunnable
 {
 public:
   nsFetchTelemetryData(const char* aShutdownTimeFilename,
-                       nsIFile* aFailedProfileLockFile)
+                       nsIFile* aFailedProfileLockFile,
+                       nsIFile* aProfileDir)
     : mShutdownTimeFilename(aShutdownTimeFilename),
       mFailedProfileLockFile(aFailedProfileLockFile),
-      mTelemetry(TelemetryImpl::sTelemetry)
+      mTelemetry(TelemetryImpl::sTelemetry),
+      mProfileDir(aProfileDir)
   {
   }
 
 private:
   const char* mShutdownTimeFilename;
   nsCOMPtr<nsIFile> mFailedProfileLockFile;
   nsCOMPtr<TelemetryImpl> mTelemetry;
+  nsCOMPtr<nsIFile> mProfileDir;
 
 public:
   void MainThread() {
     mTelemetry->mCachedTelemetryData = true;
     for (unsigned int i = 0, n = mTelemetry->mCallbacks.Count(); i < n; ++i) {
       mTelemetry->mCallbacks[i]->Complete();
     }
     mTelemetry->mCallbacks.Clear();
   }
 
   NS_IMETHOD Run() {
     LoadFailedLockCount(mTelemetry->mFailedLockCount);
     mTelemetry->mLastShutdownTime = 
       ReadLastShutdownDuration(mShutdownTimeFilename);
-    mTelemetry->ReadLateWritesStacks();
+    mTelemetry->ReadLateWritesStacks(mProfileDir);
     nsCOMPtr<nsIRunnable> e =
       NS_NewRunnableMethod(this, &nsFetchTelemetryData::MainThread);
     NS_ENSURE_STATE(e);
     NS_DispatchToMainThread(e, NS_DISPATCH_NORMAL);
     return NS_OK;
   }
 
 private:
@@ -916,27 +916,39 @@ TelemetryImpl::AsyncFetchTelemetryData(n
   // We have to get the filename from the main thread.
   const char *shutdownTimeFilename = GetShutdownTimeFileName();
   if (!shutdownTimeFilename) {
     mCachedTelemetryData = true;
     aCallback->Complete();
     return NS_OK;
   }
 
+  nsCOMPtr<nsIFile> profileDir;
+  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+                                       getter_AddRefs(profileDir));
+  if (NS_FAILED(rv)) {
+    mCachedTelemetryData = true;
+    aCallback->Complete();
+    return NS_OK;
+  }
+
   nsCOMPtr<nsIFile> failedProfileLockFile;
-  nsresult rv = GetFailedProfileLockFile(getter_AddRefs(failedProfileLockFile));
+  rv = GetFailedProfileLockFile(getter_AddRefs(failedProfileLockFile),
+                                profileDir);
   if (NS_FAILED(rv)) {
     mCachedTelemetryData = true;
     aCallback->Complete();
     return NS_OK;
   }
 
   mCallbacks.AppendObject(aCallback);
+
   nsCOMPtr<nsIRunnable> event = new nsFetchTelemetryData(shutdownTimeFilename,
-                                                         failedProfileLockFile);
+                                                         failedProfileLockFile,
+                                                         profileDir);
 
   targetThread->Dispatch(event, NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
 TelemetryImpl::TelemetryImpl():
 mHistogramMap(Telemetry::HistogramCount),
 mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default),
@@ -1705,27 +1717,20 @@ ReadStack(const char *aFileName, Telemet
     };
     stack.AddFrame(frame);
   }
 
   aStack = stack;
 }
 
 void
-TelemetryImpl::ReadLateWritesStacks()
+TelemetryImpl::ReadLateWritesStacks(nsIFile* aProfileDir)
 {
-  nsCOMPtr<nsIFile> profileDir;
-  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                       getter_AddRefs(profileDir));
-  if (!profileDir || NS_FAILED(rv)) {
-    return;
-  }
-
   nsAutoCString nativePath;
-  rv = profileDir->GetNativePath(nativePath);
+  nsresult rv = aProfileDir->GetNativePath(nativePath);
   if (NS_FAILED(rv)) {
     return;
   }
 
   const char *name = nativePath.get();
   PRDir *dir = PR_OpenDir(name);
   if (!dir) {
     return;
--- a/toolkit/components/telemetry/TelemetryPing.js
+++ b/toolkit/components/telemetry/TelemetryPing.js
@@ -783,17 +783,17 @@ TelemetryPing.prototype = {
       // Prerequesite prefs aren't set
     }
     if (!enabled) {
       // Turn off local telemetry if telemetry is disabled.
       // This may change once about:telemetry is added.
       Telemetry.canRecord = false;
       return;
     }
-    Services.obs.addObserver(this, "profile-before-change", false);
+    Services.obs.addObserver(this, "profile-before-change2", false);
     Services.obs.addObserver(this, "sessionstore-windows-restored", false);
     Services.obs.addObserver(this, "quit-application-granted", false);
 #ifdef MOZ_WIDGET_ANDROID
     Services.obs.addObserver(this, "application-background", false);
 #endif
     Services.obs.addObserver(this, "xul-window-visible", false);
     this._hasWindowRestoredObserver = true;
     this._hasXulWindowVisibleObserver = true;
@@ -991,17 +991,17 @@ TelemetryPing.prototype = {
     if (this._hasWindowRestoredObserver) {
       Services.obs.removeObserver(this, "sessionstore-windows-restored");
       this._hasWindowRestoredObserver = false;
     }
     if (this._hasXulWindowVisibleObserver) {
       Services.obs.removeObserver(this, "xul-window-visible");
       this._hasXulWindowVisibleObserver = false;
     }
-    Services.obs.removeObserver(this, "profile-before-change");
+    Services.obs.removeObserver(this, "profile-before-change2");
     Services.obs.removeObserver(this, "quit-application-granted");
 #ifdef MOZ_WIDGET_ANDROID
     Services.obs.removeObserver(this, "application-background", false);
 #endif
   },
 
   getPayload: function getPayload() {
     // This function returns the current Telemetry payload to the caller.
@@ -1056,19 +1056,16 @@ TelemetryPing.prototype = {
    * This observer drives telemetry.
    */
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
     case "profile-after-change":
       this.setup();
       this.cacheProfileDirectory();
       break;
-    case "profile-before-change":
-      this.uninstall();
-      break;
     case "cycle-collector-begin":
       let now = new Date();
       if (!gLastMemoryPoll
           || (TELEMETRY_INTERVAL <= now - gLastMemoryPoll)) {
         gLastMemoryPoll = now;
         this.gatherMemory();
       }
       break;
@@ -1098,17 +1095,18 @@ TelemetryPing.prototype = {
         // The ping happens at the first idle of length IDLE_TIMEOUT_SECONDS.
         idleService.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
         this._isIdleObserver = true;
       }).bind(this), Ci.nsIThread.DISPATCH_NORMAL);
       break;
     case "idle":
       this.sendIdlePing(false, this._server);
       break;
-    case "quit-application-granted":
+    case "profile-before-change2":
+      this.uninstall();
       if (Telemetry.canSend) {
         this.savePendingPings();
       }
       break;
 
 #ifdef MOZ_WIDGET_ANDROID
     // On Android, we can get killed without warning once we are in the background,
     // but we may also submit data and/or come back into the foreground without getting
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js
@@ -0,0 +1,134 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ 
+*/
+/* A testcase to make sure reading late writes stacks works.  */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+
+// Constants from prio.h for nsIFileOutputStream.init
+const PR_WRONLY = 0x2;
+const PR_CREATE_FILE = 0x8;
+const PR_TRUNCATE = 0x20;
+const RW_OWNER = 0600;
+
+const STACK_SUFFIX1 = "stack1.txt";
+const STACK_SUFFIX2 = "stack2.txt";
+const STACK_BOGUS_SUFFIX = "bogus.txt";
+const LATE_WRITE_PREFIX = "Telemetry.LateWriteFinal-";
+
+// The names and IDs don't matter, but the format of the IDs does.
+const LOADED_MODULES = {
+  '4759A7E6993548C89CAF716A67EC242D00': 'libtest.so',
+  'F77AF15BB8D6419FA875954B4A3506CA00': 'libxul.so',
+  '1E2F7FB590424E8F93D60BB88D66B8C500': 'libc.so'
+};
+const N_MODULES = Object.keys(LOADED_MODULES).length;
+
+// Format of individual items is [index, offset-in-library].
+const STACK1 = [
+  [ 0, 0 ],
+  [ 1, 1 ],
+  [ 2, 2 ]
+];
+const STACK2 = [
+  [ 0, 0 ],
+  [ 1, 5 ],
+  [ 2, 10 ],
+];
+// XXX The only error checking is for a zero-sized stack.
+const STACK_BOGUS = [];
+
+function write_string_to_file(file, contents) {
+  let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
+                .createInstance(Ci.nsIFileOutputStream);
+  ostream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+	       RW_OWNER, ostream.DEFER_OPEN);
+  ostream.write(contents, contents.length);
+  ostream.QueryInterface(Ci.nsISafeOutputStream).finish();
+  ostream.close();
+}
+
+function construct_file(suffix) {
+  let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile);
+  let file = profileDirectory.clone();
+  file.append(LATE_WRITE_PREFIX + suffix);
+  return file;
+}
+
+function write_late_writes_file(stack, suffix)
+{
+  let file = construct_file(suffix);
+  let contents = N_MODULES + "\n";
+  for (let id in LOADED_MODULES) {
+    contents += id + " " + LOADED_MODULES[id] + "\n";
+  }
+
+  contents += stack.length + "\n";
+  for (let element of stack) {
+    contents += element[0] + " " + element[1].toString(16) + "\n";
+  }
+
+  write_string_to_file(file, contents);
+}
+
+function run_test() {
+  do_get_profile();
+
+  write_late_writes_file(STACK1, STACK_SUFFIX1);
+  write_late_writes_file(STACK2, STACK_SUFFIX2);
+  write_late_writes_file(STACK_BOGUS, STACK_BOGUS_SUFFIX);
+
+  let lateWrites = Telemetry.lateWrites;
+  do_check_true("memoryMap" in lateWrites);
+  do_check_eq(lateWrites.memoryMap.length, 0);
+  do_check_true("stacks" in lateWrites);
+  do_check_eq(lateWrites.stacks.length, 0);
+
+  do_test_pending();
+  Telemetry.asyncFetchTelemetryData(function () {
+    actual_test();
+  });
+}
+
+function actual_test() {
+  do_check_false(construct_file(STACK_SUFFIX1).exists());
+  do_check_false(construct_file(STACK_SUFFIX2).exists());
+  do_check_false(construct_file(STACK_BOGUS_SUFFIX).exists());
+
+  let lateWrites = Telemetry.lateWrites;
+
+  do_check_true("memoryMap" in lateWrites);
+  do_check_eq(lateWrites.memoryMap.length, N_MODULES);
+  for (let id in LOADED_MODULES) {
+    let matchingLibrary = lateWrites.memoryMap.filter(function(library, idx, array) {
+                                                        return library[1] == id;
+                                                      });
+    do_check_eq(matchingLibrary.length, 1);
+    let library = matchingLibrary[0]
+    let name = library[0];
+    do_check_eq(LOADED_MODULES[id], name);
+  }
+
+  do_check_true("stacks" in lateWrites);
+  do_check_eq(lateWrites.stacks.length, 2);
+  let uneval_STACKS = [uneval(STACK1), uneval(STACK2)];
+  let first_stack = lateWrites.stacks[0];
+  let second_stack = lateWrites.stacks[1];
+  function stackChecker(canonicalStack) {
+    let unevalCanonicalStack = uneval(canonicalStack);
+    return function(obj, idx, array) {
+      return unevalCanonicalStack == obj;
+    }
+  }
+  do_check_eq(uneval_STACKS.filter(stackChecker(first_stack)).length, 1);
+  do_check_eq(uneval_STACKS.filter(stackChecker(second_stack)).length, 1);
+
+  do_test_finished();
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLockCount.js
@@ -0,0 +1,60 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ 
+*/
+/* A testcase to make sure reading the failed profile lock count works.  */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+
+const LOCK_FILE_NAME = "Telemetry.FailedProfileLocks.txt";
+const N_FAILED_LOCKS = 10;
+
+// Constants from prio.h for nsIFileOutputStream.init
+const PR_WRONLY = 0x2;
+const PR_CREATE_FILE = 0x8;
+const PR_TRUNCATE = 0x20;
+const RW_OWNER = 0600;
+
+function write_string_to_file(file, contents) {
+  let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
+                .createInstance(Ci.nsIFileOutputStream);
+  ostream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+	       RW_OWNER, ostream.DEFER_OPEN);
+  ostream.write(contents, contents.length);
+  ostream.QueryInterface(Ci.nsISafeOutputStream).finish();
+  ostream.close();
+}
+
+function construct_file() {
+  let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile);
+  let file = profileDirectory.clone();
+  file.append(LOCK_FILE_NAME);
+  return file;
+}
+
+function run_test() {
+  do_get_profile();
+
+  do_check_eq(Telemetry.failedProfileLockCount, 0);
+
+  write_string_to_file(construct_file(), N_FAILED_LOCKS.toString());
+
+  // Make sure that we're not eagerly reading the count now that the
+  // file exists.
+  do_check_eq(Telemetry.failedProfileLockCount, 0);
+
+  do_test_pending();
+  Telemetry.asyncFetchTelemetryData(actual_test);
+}
+
+function actual_test() {
+  do_check_eq(Telemetry.failedProfileLockCount, N_FAILED_LOCKS);
+  do_check_false(construct_file().exists());
+  do_test_finished();
+}
\ No newline at end of file
--- a/toolkit/components/telemetry/tests/unit/xpcshell.ini
+++ b/toolkit/components/telemetry/tests/unit/xpcshell.ini
@@ -1,11 +1,13 @@
 [DEFAULT]
 head = 
 tail = 
 
 [test_nsITelemetry.js]
+[test_TelemetryLateWrites.js]
+[test_TelemetryLockCount.js]
 [test_TelemetryPing.js]
 # Bug 676989: test fails consistently on Android
 # fail-if = os == "android"
 [test_TelemetryPing_idle.js]
 [test_TelemetryStopwatch.js]
 [test_TelemetryPingBuildID.js]
--- a/toolkit/content/Makefile.in
+++ b/toolkit/content/Makefile.in
@@ -41,38 +41,9 @@ endif
 source_repo ?= $(call getSourceRepo)
 ifneq (,$(filter http%,$(source_repo)))
   DEFINES += -DSOURCE_REPO="$(source_repo)"
 endif
 
 BUILD_HOSTNAME = $(shell hostname -s || hostname)
 DEFINES += -DBUILD_HOSTNAME="$(BUILD_HOSTNAME)"
 
-ifdef MOZ_TOOLKIT_SEARCH
-DEFINES += -DMOZ_TOOLKIT_SEARCH
-endif
-
-EXTRA_JS_MODULES = \
-  debug.js \
-  DeferredTask.jsm \
-  Deprecated.jsm \
-  Dict.jsm \
-  Geometry.jsm \
-  InlineSpellChecker.jsm \
-  PageMenu.jsm \
-  PopupNotifications.jsm \
-  PropertyListUtils.jsm \
-  Task.jsm \
-  PrivateBrowsingUtils.jsm \
-  $(NULL)
-
-EXTRA_PP_JS_MODULES = \
-  Services.jsm \
-  WindowDraggingUtils.jsm \
-  Troubleshoot.jsm \
-  UpdateChannel.jsm \
-  $(NULL)
-
-ifneq (Android,$(OS_TARGET))
-EXTRA_PP_JS_MODULES += LightweightThemeConsumer.jsm
-endif
-
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/content/aboutSupport.xhtml
+++ b/toolkit/content/aboutSupport.xhtml
@@ -123,17 +123,17 @@
               &aboutSupport.appBasicsEnabledPlugins;
             </th>
 
             <td>
               <a href="about:plugins">about:plugins</a>
             </td>
           </tr>
 
-          <tr>
+          <tr class="no-copy">
             <th class="column">
               &aboutSupport.appBasicsBuildConfig;
             </th>
 
             <td>
               <a href="about:buildconfig">about:buildconfig</a>
             </td>
           </tr>
--- a/toolkit/content/license.html
+++ b/toolkit/content/license.html
@@ -62,16 +62,17 @@
       <li><a href="about:license#apple">Apple License</a></li>
       <li><a href="about:license#apple-mozilla">Apple/Mozilla NPRuntime License</a></li>
       <li><a href="about:license#apple-torch">Apple/Torch Mobile License</a></li>
       <li><a href="about:license#bspatch">bspatch License</a></li>
       <li><a href="about:license#cairo">Cairo Component Licenses</a></li>
       <li><a href="about:license#chromium">Chromium License</a></li>
       <li><a href="about:license#dtoa">dtoa License</a></li>
       <li><a href="about:license#hunspell-nl">Dutch Spellchecking Dictionary License</a></li>
+      <li><a href="about:license#easyexif">EasyEXIF License</a></li>
       <li><a href="about:license#edl">Eclipse Distribution License</a></li>
       <li><a href="about:license#hunspell-ee">Estonian Spellchecking Dictionary License</a></li>
       <li><a href="about:license#expat">Expat License</a></li>
       <li><a href="about:license#firebug">Firebug License</a></li>
       <li><a href="about:license#gfx-font-list">gfxFontList License</a></li>
       <li><a href="about:license#google-bsd">Google BSD License</a></li>
       <li><a href="about:license#gears">Google Gears License</a></li>
       <li><a href="about:license#gears-istumbler">Google Gears/iStumbler License</a></li>
@@ -1169,16 +1170,52 @@ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INC
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 </pre>
 
 
+
+    <hr>
+
+    <h1><a id="easyexif"></a>EasyEXIF License</h1>
+
+    <p>This license applies to certain files in the directory
+    <span class="path">media/easyexif/</span>.</p>
+
+<pre>
+Copyright (c) 2010 Mayank Lahiri
+mlahiri@gmail.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+-- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+-- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+
+
+
     <hr>
 
     <h1><a id="edl"></a>Eclipse Distribution License</h1>
 
     <p>This license applies to certain files in the directory
     <span class="path">browser/devtools/sourceeditor/orion/</span>.</p>
 
 <pre>
--- a/toolkit/content/tests/browser/Makefile.in
+++ b/toolkit/content/tests/browser/Makefile.in
@@ -10,21 +10,15 @@ VPATH          = @srcdir@
 relativesrcdir = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_FILES = \
   browser_keyevents_during_autoscrolling.js \
   browser_bug295977_autoscroll_overflow.js \
   browser_bug594509.js \
-  browser_Geometry.js \
-  browser_InlineSpellChecker.js \
   browser_save_resend_postdata.js \
   browser_browserDrop.js \
-  browser_Services.js \
-  browser_DeferredTask.js \
   browser_default_image_filename.js \
-  browser_Troubleshoot.js \
-  browser_Deprecated.js \
   browser_input_file_tooltips.js \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/content/tests/chrome/test_showcaret.xul
+++ b/toolkit/content/tests/chrome/test_showcaret.xul
@@ -28,32 +28,46 @@ function runTest()
   var sel1 = frames[0].getSelection();
   sel1.collapse(frames[0].document.body, 0);
 
   var sel2 = frames[1].getSelection();
   sel2.collapse(frames[1].document.body, 0);
 
   window.frames[0].focus();
   document.commandDispatcher.getControllerForCommand("cmd_moveBottom").doCommand("cmd_moveBottom");
-
-  ok(frames[0].scrollY > 0, "scrollY for non-showcaret");
   is(sel1.focusNode, frames[0].document.body, "focusNode for non-showcaret");
   is(sel1.focusOffset, 0, "focusOffset for non-showcaret");
 
   window.frames[1].focus();
   document.commandDispatcher.getControllerForCommand("cmd_moveBottom").doCommand("cmd_moveBottom");
 
   ok(frames[1].scrollY <
        frames[1].document.getElementById('s').getBoundingClientRect().top,
      "scrollY for showcaret");
   isnot(sel2.focusNode, frames[1].document.body, "focusNode for showcaret");
   ok(sel2.anchorOffset > 0, "focusOffset for showcaret");
 
   otherWindow = window.open("window_showcaret.xul", "_blank", "chrome,width=400,height=200");
   otherWindow.addEventListener("focus", otherWindowFocused, false);
+
+  var sel1 = frames[0].getSelection();
+  sel1.collapse(frames[0].document.body, 0);
+
+  var sel2 = frames[1].getSelection();
+  sel2.collapse(frames[1].document.body, 0);
+  window.frames[0].focus();
+  document.commandDispatcher.getControllerForCommand("cmd_moveBottom").doCommand("cmd_moveBottom");
+
+  /* We aren't sure exactly how long the cmd_moveBottom will take.
+   * Therefore, check for success every second. If we don't have success within 10 seconds, assume the scroll
+   * will never pass the test and fail it.
+   */
+
+  var timeoutUntilFail = window.setTimeout(scrollYTimeout, 10000);
+  var testScroll = self.setInterval(function(){continueTest()}, 10);
 }
 
 function otherWindowFocused()
 {
   otherWindow.removeEventListener("focus", otherWindowFocused, false);
 
   // enable caret browsing temporarily to test caret movement
   var prefs = Components.classes["@mozilla.org/preferences-service;1"].
@@ -68,16 +82,29 @@ function otherWindowFocused()
   is(otherWindow.document.activeElement, hbox, "hbox still focused in other window after down movement");
 
   prefs.setBoolPref("accessibility.browsewithcaret", false);
 
   otherWindow.close();
   SimpleTest.finish();
 }
 
+function continueTest() {
+  if (frames[0].scrollY > 0) {
+    return;
+  }
+  testScroll = window.clearInterval(testScroll);
+  window.clearTimeout(timeoutUntilFail);
+  return;
+}
+
+function scrollYTimeout() {
+  ok(frames[0].scrollY > 0, "scrollY for non-showcaret");
+}
+
 ]]>
 </script>
 
 <body xmlns="http://www.w3.org/1999/xhtml">
 <p id="display">
 </p>
 <div id="content" style="display: none">
 </div>
--- a/toolkit/content/tests/unit/xpcshell.ini
+++ b/toolkit/content/tests/unit/xpcshell.ini
@@ -1,8 +1,5 @@
 [DEFAULT]
 head = 
 tail = 
 
 [test_contentAreaUtils.js]
-[test_dict.js]
-[test_propertyListsUtils.js]
-[test_task.js]
rename from toolkit/mozapps/shared/CertUtils.jsm
rename to toolkit/modules/CertUtils.jsm
rename from toolkit/content/DeferredTask.jsm
rename to toolkit/modules/DeferredTask.jsm
rename from toolkit/content/Deprecated.jsm
rename to toolkit/modules/Deprecated.jsm
rename from toolkit/content/Dict.jsm
rename to toolkit/modules/Dict.jsm
rename from toolkit/mozapps/shared/FileUtils.jsm
rename to toolkit/modules/FileUtils.jsm
rename from toolkit/content/Geometry.jsm
rename to toolkit/modules/Geometry.jsm
rename from toolkit/content/InlineSpellChecker.jsm
rename to toolkit/modules/InlineSpellChecker.jsm
rename from toolkit/content/LightweightThemeConsumer.jsm
rename to toolkit/modules/LightweightThemeConsumer.jsm
--- a/toolkit/modules/Makefile.in
+++ b/toolkit/modules/Makefile.in
@@ -4,18 +4,46 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+ifdef MOZ_TOOLKIT_SEARCH
+DEFINES += -DMOZ_TOOLKIT_SEARCH
+endif
+
 EXTRA_JS_MODULES := \
+  debug.js \
+  DeferredTask.jsm \
+  Deprecated.jsm \
+  Dict.jsm \
+  FileUtils.jsm \
+  Geometry.jsm \
+  InlineSpellChecker.jsm \
   NewTabUtils.jsm \
+  PageMenu.jsm \
+  PopupNotifications.jsm \
   Preferences.jsm \
+  PrivateBrowsingUtils.jsm \
+  PropertyListUtils.jsm \
   RemoteWebProgress.jsm \
   Sqlite.jsm \
+  Task.jsm \
   TelemetryTimestamps.jsm \
   Timer.jsm \
   $(NULL)
 
+EXTRA_PP_JS_MODULES = \
+  CertUtils.jsm \
+  Services.jsm \
+  Troubleshoot.jsm \
+  UpdateChannel.jsm \
+  WindowDraggingUtils.jsm \
+  $(NULL)
+
+ifneq (Android,$(OS_TARGET))
+EXTRA_PP_JS_MODULES += LightweightThemeConsumer.jsm
+endif
+
 include $(topsrcdir)/config/rules.mk
rename from toolkit/content/PageMenu.jsm
rename to toolkit/modules/PageMenu.jsm
rename from toolkit/content/PopupNotifications.jsm
rename to toolkit/modules/PopupNotifications.jsm
rename from toolkit/content/PrivateBrowsingUtils.jsm
rename to toolkit/modules/PrivateBrowsingUtils.jsm
rename from toolkit/content/PropertyListUtils.jsm
rename to toolkit/modules/PropertyListUtils.jsm
rename from toolkit/content/Services.jsm
rename to toolkit/modules/Services.jsm
rename from toolkit/content/Task.jsm
rename to toolkit/modules/Task.jsm
rename from toolkit/content/Troubleshoot.jsm
rename to toolkit/modules/Troubleshoot.jsm
rename from toolkit/content/UpdateChannel.jsm
rename to toolkit/modules/UpdateChannel.jsm
rename from toolkit/content/WindowDraggingUtils.jsm
rename to toolkit/modules/WindowDraggingUtils.jsm
rename from toolkit/content/debug.js
rename to toolkit/modules/debug.js
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/browser/Makefile.in
@@ -0,0 +1,24 @@
+#
+# 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/.
+
+DEPTH          = @DEPTH@
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MOCHITEST_BROWSER_FILES = \
+  browser_DeferredTask.js \
+  browser_Deprecated.js \
+  browser_Geometry.js \
+  browser_InlineSpellChecker.js \
+  browser_Services.js \
+  browser_Troubleshoot.js \
+  
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
rename from toolkit/content/tests/browser/browser_DeferredTask.js
rename to toolkit/modules/tests/browser/browser_DeferredTask.js
rename from toolkit/content/tests/browser/browser_Deprecated.js
rename to toolkit/modules/tests/browser/browser_Deprecated.js
rename from toolkit/content/tests/browser/browser_Geometry.js
rename to toolkit/modules/tests/browser/browser_Geometry.js
rename from toolkit/content/tests/browser/browser_InlineSpellChecker.js
rename to toolkit/modules/tests/browser/browser_InlineSpellChecker.js
rename from toolkit/content/tests/browser/browser_Services.js
rename to toolkit/modules/tests/browser/browser_Services.js
rename from toolkit/content/tests/browser/browser_Troubleshoot.js
rename to toolkit/modules/tests/browser/browser_Troubleshoot.js
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/browser/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
rename from toolkit/mozapps/shared/test/chrome/Makefile.in
rename to toolkit/modules/tests/chrome/Makefile.in
rename from toolkit/mozapps/shared/test/chrome/moz.build
rename to toolkit/modules/tests/chrome/moz.build
rename from toolkit/mozapps/shared/test/chrome/test_bug544442_checkCert.xul
rename to toolkit/modules/tests/chrome/test_bug544442_checkCert.xul
--- a/toolkit/modules/tests/moz.build
+++ b/toolkit/modules/tests/moz.build
@@ -1,7 +1,11 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+DIRS += ['browser']
+
+MODULE = 'test_toolkit_general'
+
 XPCSHELL_TESTS_MANIFESTS += ['xpcshell/xpcshell.ini']
rename from toolkit/content/tests/unit/propertyLists/bug710259_propertyListBinary.plist
rename to toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListBinary.plist
rename from toolkit/content/tests/unit/propertyLists/bug710259_propertyListXML.plist
rename to toolkit/modules/tests/xpcshell/propertyLists/bug710259_propertyListXML.plist
rename from toolkit/mozapps/shared/test/unit/test_FileUtils.js
rename to toolkit/modules/tests/xpcshell/test_FileUtils.js
rename from toolkit/content/tests/unit/test_dict.js
rename to toolkit/modules/tests/xpcshell/test_dict.js
rename from toolkit/content/tests/unit/test_propertyListsUtils.js
rename to toolkit/modules/tests/xpcshell/test_propertyListsUtils.js
rename from toolkit/mozapps/shared/test/unit/test_readCertPrefs.js
rename to toolkit/modules/tests/xpcshell/test_readCertPrefs.js
rename from toolkit/content/tests/unit/test_task.js
rename to toolkit/modules/tests/xpcshell/test_task.js
--- a/toolkit/modules/tests/xpcshell/xpcshell.ini
+++ b/toolkit/modules/tests/xpcshell/xpcshell.ini
@@ -1,9 +1,14 @@
 [DEFAULT]
 head =
 tail =
 
+[test_dict.js]
+[test_FileUtils.js]
 [test_newtab-migrate-v1.js]
 [test_Preferences.js]
+[test_propertyListsUtils.js]
+[test_readCertPrefs.js]
 [test_sqlite.js]
+[test_task.js]
 [test_TelemetryTimestamps.js]
 [test_timer.js]
--- a/toolkit/moz.build
+++ b/toolkit/moz.build
@@ -12,17 +12,16 @@ PARALLEL_DIRS += [
     'identity',
     'locales',
     'modules',
     'mozapps/downloads',
     'mozapps/extensions',
     'mozapps/handling',
     'mozapps/preferences',
     'mozapps/plugins',
-    'mozapps/shared',
     'obsolete',
     'profile',
     'themes',
     'webapps',
 ]
 
 DIRS += ['mozapps/update']
 
--- a/toolkit/mozapps/installer/packager.py
+++ b/toolkit/mozapps/installer/packager.py
@@ -346,17 +346,18 @@ def main():
                 continue
             key = JarLog.canonicalize(os.path.join(args.destination, p))
             if key in log:
                 f.preload(log[key])
 
     # Fill startup cache
     if isinstance(formatter, OmniJarFormatter) and launcher.can_launch():
         if buildconfig.substs['LIBXUL_SDK']:
-            gre_path = buildconfig.substs['LIBXUL_DIST']
+            gre_path = mozpack.path.join(buildconfig.substs['LIBXUL_DIST'],
+                                         'bin')
         else:
             gre_path = None
         for base in sorted([[p for p in [mozpack.path.join('bin', b), b]
                             if os.path.exists(os.path.join(args.source, p))][0]
                            for b in sink.packager.get_bases()]):
             if not gre_path:
                 gre_path = base
             base_path = sink.normalize_path(base)
deleted file mode 100644
--- a/toolkit/mozapps/shared/Makefile.in
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-relativesrcdir = @relativesrcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-EXTRA_PP_JS_MODULES = \
-  CertUtils.jsm \
-  $(NULL)
-
-EXTRA_JS_MODULES = \
-  FileUtils.jsm \
-  $(NULL)
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/toolkit/mozapps/shared/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-TEST_DIRS += ['test/chrome']
-
-MODULE = 'toolkitShared'
-
-if CONFIG['ENABLE_TESTS']:
-    XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
deleted file mode 100644
--- a/toolkit/mozapps/shared/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-head = 
-tail = 
-
-[test_FileUtils.js]
-
-[test_readCertPrefs.js]
--- a/toolkit/themes/osx/mozapps/plugins/pluginProblem.css
+++ b/toolkit/themes/osx/mozapps/plugins/pluginProblem.css
@@ -158,17 +158,17 @@ html|a {
   top: 4px;
   right: 4px;
   border: none;
   background-color: transparent;
   background-image: url("chrome://global/skin/icons/close.png");
   background-repeat: no-repeat;
 }
 
-.closeIcon:-moz-locale-dir(rtl) {
+.mainBox[chromedir="rtl"] .closeIcon {
   right: auto;
   left: 4px;
 }
 
 .closeIcon:hover {
   background-position: -16px 0;
 }
 
--- a/toolkit/themes/windows/mozapps/plugins/pluginProblem.css
+++ b/toolkit/themes/windows/mozapps/plugins/pluginProblem.css
@@ -167,17 +167,17 @@ html|a {
   top: 4px;
   right: 4px;
   border: none;
   background-color: transparent;
   background-image: url("chrome://global/skin/icons/close.png");
   background-repeat: no-repeat;
 }
 
-.closeIcon:-moz-locale-dir(rtl) {
+.mainBox[chromedir="rtl"] .closeIcon {
   right: auto;
   left: 4px;
 }
 
 .closeIcon:hover {
   background-position: -16px 0;
 }
 
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2546,19 +2546,19 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDe
           else
             aResult->SizeTo(endcapSize, 0, 0, 0);
         }
       }
 
       if (nsLookAndFeel::GetInt(
             nsLookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
         if (isHorizontal) {
-          aResult->SizeTo(1, 2, 1, 1);
+          aResult->SizeTo(2, 1, 1, 1);
         } else {
-          aResult->SizeTo(2, 1, 1, 1);
+          aResult->SizeTo(1, 1, 1, 2);
         }
       }
 
       break;
     }
 
     case NS_THEME_STATUSBAR:
       aResult->SizeTo(1, 0, 0, 0);
--- a/xpfe/appshell/public/nsIWindowMediator.idl
+++ b/xpfe/appshell/public/nsIWindowMediator.idl
@@ -3,29 +3,29 @@
  * 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"
 #include "nsISimpleEnumerator.idl"
 
 %{C++
 #define NS_WINDOWMEDIATOR_CID \
-{ 0x808b2fa3, 0x8a02, 0x49ca, \
-  { 0x91, 0x04, 0x5f, 0x77, 0x29, 0x9e, 0x09, 0x0b } }
+{ 0x79a2b7cc, 0xf05b, 0x4605, \
+  { 0xbf, 0xa0, 0xfa, 0xc5, 0x4f, 0x27, 0xee, 0xc8 } }
 
 #define NS_WINDOWMEDIATOR_CONTRACTID \
   "@mozilla.org/appshell/window-mediator;1"
 %}
 
 interface nsIXULWindow;
 interface nsIWidget;
 interface nsIDOMWindow;
 interface nsIWindowMediatorListener;
 
-[scriptable, uuid(808b2fa3-8a02-49ca-9104-5f77299e090b)]
+[scriptable, uuid(30cda5a1-a6df-4f32-9a73-0e59a32928c5)]
 interface nsIWindowMediator: nsISupports
 {
   /** Return an enumerator which iterates over all windows of type aWindowType
     * from the oldest window to the youngest.
     * @param  aWindowType the returned enumerator will enumerate only
     *                     windows of this type. ("type" is the
     *                     |windowtype| attribute of the XML <window> element.)
     *                     If null, all windows will be enumerated.
@@ -69,16 +69,23 @@ interface nsIWindowMediator: nsISupports
     */
   nsIDOMWindow getMostRecentWindow(in wstring aWindowType);
 
   /**
    * Return the outer window with the given ID, if any.  Can return null.
    */
   nsIDOMWindow getOuterWindowWithId(in unsigned long long aOuterWindowID);
 
+  /**
+    * Return the outer window with the given current window ID, if any.
+    * Can return null if no inner window with the ID exists or if it's not
+    * a current inner anymore.
+    */
+  nsIDOMWindow getCurrentInnerWindowWithId(in unsigned long long aInnerWindowID);
+
   /** Add the window to the list of known windows. Listeners (see
     * addListener) will be notified through their onOpenWindow method.
     * @param aWindow the window to add
     */
   [noscript] void registerWindow(in nsIXULWindow aWindow);
 
   /** Remove the window from the list of known windows. Listeners (see
     * addListener) will be be notified through their onCloseWindow method.
--- a/xpfe/appshell/src/nsWindowMediator.cpp
+++ b/xpfe/appshell/src/nsWindowMediator.cpp
@@ -326,16 +326,38 @@ nsWindowMediator::GetOuterWindowWithId(u
                                        nsIDOMWindow** aWindow)
 {
   *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
   NS_IF_ADDREF(*aWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsWindowMediator::GetCurrentInnerWindowWithId(uint64_t aWindowID,
+                                              nsIDOMWindow** aWindow)
+{
+  nsCOMPtr<nsPIDOMWindow> inner = nsGlobalWindow::GetInnerWindowWithId(aWindowID);
+
+  // not found
+  if (!inner)
+    return NS_OK;
+
+  nsCOMPtr<nsPIDOMWindow> outer = inner->GetOuterWindow();
+  NS_ENSURE_TRUE(outer, NS_ERROR_UNEXPECTED);
+
+  // outer is already using another inner, so it's same as not found
+  if (outer->GetCurrentInnerWindow() != inner)
+    return NS_OK;
+
+  nsCOMPtr<nsIDOMWindow> ret = do_QueryInterface(outer);
+  ret.forget(aWindow);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsWindowMediator::UpdateWindowTimeStamp(nsIXULWindow* inWindow)
 {
   NS_ENSURE_STATE(mReady);
   MutexAutoLock lock(mListLock);
   nsWindowInfo *info = GetInfoFor(inWindow);
   if (info) {
     // increment the window's time stamp
     info->mTimeStamp = ++mTimeStamp;
--- a/xpfe/components/directory/nsDirectoryViewer.cpp
+++ b/xpfe/components/directory/nsDirectoryViewer.cpp
@@ -155,17 +155,17 @@ nsHTTPIndex::OnFTPControlLog(bool server
     NS_ENSURE_TRUE(scriptGlobal, NS_OK);
 
     nsIScriptContext *context = scriptGlobal->GetContext();
     NS_ENSURE_TRUE(context, NS_OK);
 
     AutoPushJSContext cx(context->GetNativeContext());
     NS_ENSURE_TRUE(cx, NS_OK);
 
-    JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
+    JS::Rooted<JSObject*> global(cx, JS_GetGlobalForScopeChain(cx));
     NS_ENSURE_TRUE(global, NS_OK);
 
     JS::Value params[2];
 
     nsString unicodeMsg;
     unicodeMsg.AssignWithConversion(msg);
     JSAutoRequest ar(cx);
     JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, (jschar*) unicodeMsg.get());
@@ -231,17 +231,17 @@ nsHTTPIndex::OnStartRequest(nsIRequest *
     // Now get the content viewer container's script object.
     nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_GetInterface(mRequestor));
     NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_FAILURE);
 
     nsIScriptContext *context = scriptGlobal->GetContext();
     NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
 
     AutoPushJSContext cx(context->GetNativeContext());
-    JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
+    JS::Rooted<JSObject*> global(cx, JS_GetGlobalForScopeChain(cx));
 
     // Using XPConnect, wrap the HTTP index object...
     static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID);
     nsCOMPtr<nsIXPConnect> xpc(do_GetService(kXPConnectCID, &rv));
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
     rv = xpc->WrapNative(cx,