Backout cb50e96dbee0 (Bug 677079) for Win PGO mochitests failures.
authorMarco Bonardo <mbonardo@mozilla.com>
Sat, 22 Oct 2011 11:03:26 +0200
changeset 79102 d252e090c6cfd751b2744ecc03da056ca738f2a4
parent 79101 01d0d7a3e4f7017d77f5500f88fe2884e8c1f502
child 79103 7ba4cea5382dda70acbc94ac91013958d8dfaad7
push id21359
push userbmo@edmorley.co.uk
push dateSat, 22 Oct 2011 12:59:01 +0000
treeherdermozilla-central@7ba4cea5382d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs677079
milestone10.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
Backout cb50e96dbee0 (Bug 677079) for Win PGO mochitests failures.
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsScriptLoader.cpp
content/html/content/src/nsHTMLAudioElement.cpp
content/xul/document/src/nsXULContentSink.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBEvents.cpp
dom/indexedDB/IDBKeyRange.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/workers/ChromeWorkerScope.cpp
dom/workers/EventTarget.cpp
dom/workers/Events.cpp
dom/workers/Exceptions.cpp
dom/workers/File.cpp
dom/workers/FileReaderSync.cpp
dom/workers/ListenerManager.cpp
dom/workers/Location.cpp
dom/workers/Navigator.cpp
dom/workers/Worker.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
js/ipc/ObjectWrapperChild.cpp
js/jetpack/Handle.h
js/jetpack/JetpackActorCommon.cpp
js/jetpack/JetpackChild.cpp
js/src/Makefile.in
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsclone.cpp
js/src/jsclone.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsgc.cpp
js/src/jsobjinlines.h
js/src/jsproxy.h
js/src/jswrapper.h
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCContext.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCString.cpp
js/xpconnect/src/XPCThreadContext.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
storage/src/mozStoragePrivateHelpers.cpp
toolkit/components/startup/nsAppStartup.cpp
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -33,17 +33,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContentChild.h"
 #include "ContentParent.h"
-#include "jsapi.h"
+#include "jscntxt.h"
 #include "nsFrameMessageManager.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -36,18 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * A class that handles loading and evaluation of <script> elements.
  */
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "nsScriptLoader.h"
 #include "nsIDOMCharacterData.h"
 #include "nsParserUtils.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Element.h"
 #include "nsGkAtoms.h"
@@ -493,17 +492,17 @@ nsScriptLoader::ProcessScriptElement(nsI
         if (rv != NS_ERROR_INVALID_ARG)
           return rv;
       } else {
         if (value.Length() == 1 && value[0] == '1')
           // This means that we need to set JSOPTION_XML in the JS options.
           // We re-use our knowledge of the implementation to reuse
           // JSVERSION_HAS_XML as a safe version flag.
           // If version has JSVERSION_UNKNOWN (-1), then this is still OK.
-          version = JS_VersionSetXML(JSVersion(version), true);
+          version |= js::VersionFlags::HAS_XML;
       }
     }
   } else {
     // no 'type=' element
     // "language" is a deprecated attribute of HTML, so we check it only for
     // HTML script elements.
     nsCOMPtr<nsIDOMHTMLScriptElement> htmlScriptElement =
       do_QueryInterface(aElement);
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -52,16 +52,17 @@
 #include "nsNetUtil.h"
 #include "nsXPCOMStrings.h"
 #include "prlock.h"
 #include "nsThreadUtils.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 #include "jstypedarray.h"
 #include "nsJSUtils.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -42,18 +42,17 @@
 /*
  * An implementation for a Gecko-style content sink that knows how
  * to build a content model (the "prototype" document) from XUL.
  *
  * For more information on XUL,
  * see http://developer.mozilla.org/en/docs/XUL
  */
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"  // for JSVERSION_HAS_XML
 #include "nsXULContentSink.h"
 #include "nsCOMPtr.h"
 #include "nsForwardReference.h"
 #include "nsIContentSink.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMXULDocument.h"
@@ -1056,40 +1055,40 @@ XULContentSinkImpl::OpenScript(const PRU
             }
           }
           // Some js specifics yet to be abstracted.
           if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
               // By default scripts in XUL documents have E4X turned on. We use
               // our implementation knowledge to reuse JSVERSION_HAS_XML as a
               // safe version flag. This is still OK if version is
               // JSVERSION_UNKNOWN (-1),
-              version = JS_VersionSetXML(JSVersion(version), true);
+              version |= js::VersionFlags::HAS_XML;
 
               nsAutoString value;
               rv = parser.GetParameter("e4x", value);
               if (NS_FAILED(rv)) {
                   if (rv != NS_ERROR_INVALID_ARG)
                       return rv;
               } else {
                   if (value.Length() == 1 && value[0] == '0')
-                    version = JS_VersionSetXML(JSVersion(version), false);
+                    version &= ~js::VersionFlags::HAS_XML;
               }
           }
       }
       else if (key.EqualsLiteral("language")) {
           // Language is deprecated, and the impl in nsScriptLoader ignores the
           // various version strings anyway.  So we make no attempt to support
           // languages other than JS for language=
           nsAutoString lang(aAttributes[1]);
           if (nsParserUtils::IsJavaScriptLanguage(lang, &version)) {
               langID = nsIProgrammingLanguage::JAVASCRIPT;
 
               // Even when JS version < 1.6 is specified, E4X is
               // turned on in XUL.
-              version = JS_VersionSetXML(JSVersion(version), true);
+              version |= js::VersionFlags::HAS_XML;
           }
       }
       aAttributes += 2;
   }
   // Not all script languages have a "sandbox" concept.  At time of
   // writing, Python is the only other language, and it does not.
   // For such languages, neither any inline script nor remote script are
   // safe to execute from untrusted sources.
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -38,16 +38,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 // JavaScript includes
 #include "jsapi.h"
 #include "jsprvtd.h"    // we are using private JS typedefs...
+#include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "WrapperFactory.h"
 #include "AccessCheck.h"
 
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
 
 #include "nscore.h"
@@ -5237,17 +5238,17 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
         // the window, so no need to wrap it again).
 
         return NS_SUCCESS_I_DID_SOMETHING;
       }
     }
   }
 
   if (id == sWrappedJSObject_id &&
-      xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
+      xpc::AccessCheck::isChrome(cx->compartment)) {
     obj = JS_ObjectToOuterObject(cx, obj);
     *vp = OBJECT_TO_JSVAL(obj);
     return NS_SUCCESS_I_DID_SOMETHING;
   }
 
   return NS_OK;
 }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6087,17 +6087,17 @@ PostMessageReadStructuredClone(JSContext
                                                     getter_AddRefs(wrapper)))) {
           return JSVAL_TO_OBJECT(val);
         }
       }
     }
   }
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
-    js::GetRuntimeStructuredCloneCallbacks(js::GetContextRuntime(cx));
+    cx->runtime->structuredCloneCallbacks;
 
   if (runtimeCallbacks) {
     return runtimeCallbacks->read(cx, reader, tag, data, nsnull);
   }
 
   return JS_FALSE;
 }
 
@@ -6127,17 +6127,17 @@ PostMessageWriteStructuredClone(JSContex
 
     if (scTag)
       return JS_WriteUint32Pair(writer, scTag, 0) &&
              JS_WriteBytes(writer, &supports, sizeof(supports)) &&
              scInfo->event->StoreISupports(supports);
   }
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
-    js::GetRuntimeStructuredCloneCallbacks(js::GetContextRuntime(cx));
+    cx->runtime->structuredCloneCallbacks;
 
   if (runtimeCallbacks) {
     return runtimeCallbacks->write(cx, writer, obj, nsnull);
   }
 
   return JS_FALSE;
 }
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -32,17 +32,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "jsapi.h"
+#include "jscntxt.h"
 #include "nsJSEnvironment.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsDOMCID.h"
 #include "nsIServiceManager.h"
@@ -219,17 +219,17 @@ public:
   }
 
 private:
   void resetRooter(JSContext *cx) {
     avr.changeArray(vals.Elements(), vals.Length());
   }
 
   nsAutoTArray<jsval, 16> vals;
-  JS::AutoArrayRooter avr;
+  js::AutoArrayRooter avr;
 };
 
 /****************************************************************
  ************************** AutoFree ****************************
  ****************************************************************/
 
 class AutoFree {
 public:
@@ -715,18 +715,18 @@ nsJSContext::DOMOperationCallback(JSCont
   // If we get here we're most likely executing an infinite loop in JS,
   // we'll tell the user about this and we'll give the user the option
   // of stopping the execution of the script.
   nsCOMPtr<nsIPrompt> prompt = GetPromptFromContext(ctx);
   NS_ENSURE_TRUE(prompt, JS_TRUE);
 
   // Check if we should offer the option to debug
   JSStackFrame* fp = ::JS_GetScriptedCaller(cx, NULL);
-  bool debugPossible = (fp != nsnull && js::GetContextDebugHooks(cx) &&
-                          js::GetContextDebugHooks(cx)->debuggerHandler != nsnull);
+  bool debugPossible = (fp != nsnull && cx->debugHooks &&
+                          cx->debugHooks->debuggerHandler != nsnull);
 #ifdef MOZ_JSDEBUGGER
   // Get the debugger service if necessary.
   if (debugPossible) {
     bool jsds_IsOn = false;
     const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
     nsCOMPtr<jsdIExecutionHook> jsdHook;
     nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
 
@@ -845,20 +845,20 @@ nsJSContext::DOMOperationCallback(JSCont
     }
 
     ctx->mOperationCallbackTime = PR_Now();
     return JS_TRUE;
   }
   else if ((buttonPressed == 2) && debugPossible) {
     // Debug the script
     jsval rval;
-    JSDebugHooks *hooks = js::GetContextDebugHooks(cx);
-    switch(hooks->debuggerHandler(cx, script, ::JS_GetFramePC(cx, fp),
-                                  &rval,
-                                  hooks->debuggerHandlerData)) {
+    switch(cx->debugHooks->debuggerHandler(cx, script, ::JS_GetFramePC(cx, fp),
+                                           &rval,
+                                           cx->debugHooks->
+                                           debuggerHandlerData)) {
       case JSTRAP_RETURN:
         JS_SetFrameReturnValue(cx, fp, rval);
         return JS_TRUE;
       case JSTRAP_ERROR:
         JS_ClearPendingException(cx);
         return JS_FALSE;
       case JSTRAP_THROW:
         JS_SetPendingException(cx, rval);
@@ -1147,17 +1147,17 @@ nsJSContext::DestroyJSContext()
   mContext = nsnull;
 }
 
 // QueryInterface implementation for nsJSContext
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSContext)
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSContext)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
-  NS_ASSERTION(!tmp->mContext || js::GetContextOutstandingRequests(tmp->mContext) == 0,
+  NS_ASSERTION(!tmp->mContext || tmp->mContext->outstandingRequests == 0,
                "Trying to unlink a context with outstanding requests.");
   tmp->mIsInitialized = false;
   tmp->mGCOnDestruction = false;
   tmp->DestroyJSContext();
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalObjectRef)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSContext)
   NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsJSContext, tmp->GetCCRefcnt())
@@ -1177,17 +1177,17 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSContext)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSContext)
 
 nsrefcnt
 nsJSContext::GetCCRefcnt()
 {
   nsrefcnt refcnt = mRefCnt.get();
   if (NS_LIKELY(mContext))
-    refcnt += js::GetContextOutstandingRequests(mContext);
+    refcnt += mContext->outstandingRequests;
   return refcnt;
 }
 
 nsresult
 nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
                                      void *aScopeObject,
                                      nsIPrincipal *aPrincipal,
                                      const char *aURL,
@@ -3368,27 +3368,26 @@ nsJSContext::GC()
 {
   PokeGC();
 }
 
 static JSBool
 DOMGCCallback(JSContext *cx, JSGCStatus status)
 {
   static PRTime start;
-  JSBool compartmental = JS_WasLastGCCompartmental(cx);
 
   if (sPostGCEventsToConsole && NS_IsMainThread()) {
     if (status == JSGC_BEGIN) {
       start = PR_Now();
     } else if (status == JSGC_END) {
       PRTime now = PR_Now();
       NS_NAMED_LITERAL_STRING(kFmt, "GC mode: %s, timestamp: %lld, duration: %llu ms.");
       nsString msg;
       msg.Adopt(nsTextFormatter::smprintf(kFmt.get(),
-                compartmental ? "compartment" : "full",
+                cx->runtime->gcTriggerCompartment ? "compartment" : "full",
                 now,
                 (now - start) / PR_USEC_PER_MSEC));
       nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
       if (cs) {
         cs->LogStringMessage(msg.get());
       }
     }
   }
@@ -3399,33 +3398,33 @@ DOMGCCallback(JSContext *cx, JSGCStatus 
       // If we were waiting for a GC to happen, kill the timer.
       nsJSContext::KillGCTimer();
 
       // If this is a compartment GC, restart it. We still want
       // a full GC to happen. Compartment GCs usually happen as a
       // result of last-ditch or MaybeGC. In both cases its
       // probably a time of heavy activity and we want to delay
       // the full GC, but we do want it to happen eventually.
-      if (compartmental) {
+      if (cx->runtime->gcTriggerCompartment) {
         nsJSContext::PokeGC();
 
         // We poked the GC, so we can kill any pending CC here.
         nsJSContext::KillCCTimer();
       }
     } else {
       // If this was a full GC, poke the CC to run soon.
-      if (!compartmental) {
+      if (!cx->runtime->gcTriggerCompartment) {
         sGCHasRun = true;
         nsJSContext::PokeCC();
       }
     }
 
     // If we didn't end up scheduling a GC, and there are unused
     // chunks waiting to expire, make sure we will GC again soon.
-    if (!sGCTimer && JS_GetGCParameter(JS_GetRuntime(cx), JSGC_UNUSED_CHUNKS) > 0) {
+    if (!sGCTimer && JS_GetGCParameter(cx->runtime, JSGC_UNUSED_CHUNKS) > 0) {
       nsJSContext::PokeGC();
     }
   }
 
   JSBool result = gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE;
 
   if (status == JSGC_BEGIN && !NS_IsMainThread())
     return JS_FALSE;
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -36,18 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBCursor.h"
 
 #include "nsIVariant.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "mozilla/storage.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsEventDispatcher.h"
 #include "nsJSUtils.h"
 #include "nsThreadUtils.h"
 
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -34,18 +34,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBDatabase.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/storage.h"
 #include "nsDOMClassInfo.h"
 #include "nsEventDispatcher.h"
 #include "nsJSUtils.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 
--- a/dom/indexedDB/IDBEvents.cpp
+++ b/dom/indexedDB/IDBEvents.cpp
@@ -37,18 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBEvents.h"
 
 #include "nsIIDBDatabaseException.h"
 #include "nsIPrivateDOMEvent.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMException.h"
 #include "nsJSON.h"
 #include "nsThreadUtils.h"
 
 #include "IDBRequest.h"
 #include "IDBTransaction.h"
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -36,18 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBKeyRange.h"
 
 #include "nsIXPConnect.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "nsDOMClassInfoID.h"
 #include "nsJSUtils.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
 
 #include "Key.h"
 
 USING_INDEXEDDB_NAMESPACE
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -37,18 +37,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBObjectStore.h"
 
 #include "nsIJSContextStack.h"
 #include "nsIVariant.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
+#include "jsclone.h"
 #include "mozilla/storage.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsEventDispatcher.h"
 #include "nsJSUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
@@ -444,25 +444,25 @@ StructuredCloneWriteDummyProp(JSContext*
                               JSStructuredCloneWriter* aWriter,
                               JSObject* aObj,
                               void* aClosure)
 {
   if (JS_GET_CLASS(aCx, aObj) == &gDummyPropClass) {
     PRUint64* closure = reinterpret_cast<PRUint64*>(aClosure);
 
     NS_ASSERTION(*closure == 0, "We should not have been here before!");
-    *closure = JS_GetSCOffset(aWriter);
+    *closure = js_GetSCOffset(aWriter);
 
     PRUint64 value = 0;
     return JS_WriteBytes(aWriter, &value, sizeof(value));
   }
 
   // try using the runtime callbacks
   const JSStructuredCloneCallbacks* runtimeCallbacks =
-    js::GetRuntimeStructuredCloneCallbacks(js::GetContextRuntime(aCx));
+    aCx->runtime->structuredCloneCallbacks;
   if (runtimeCallbacks) {
     return runtimeCallbacks->write(aCx, aWriter, aObj, nsnull);
   }
 
   return JS_FALSE;
 }
 
 } // anonymous namespace
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -33,18 +33,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
 
-#include "jsapi.h"
-#include "jsfriendapi.h"
+// FIXME(bug 332648): Give me a real API please!
+#include "jscntxt.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsJSNPRuntime.h"
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsDOMJSUtils.h"
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -45,16 +45,17 @@
 /* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
 #include "mozilla/Util.h"
 
 #include "prtypes.h"
 #include "prmem.h"
 #include "prenv.h"
 #include "prclist.h"
 
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "nsPluginHost.h"
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsNPAPIPluginStreamListener.h"
 #include "nsIServiceManager.h"
 #include "nsThreadUtils.h"
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ChromeWorkerScope.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 
 #include "nsXPCOM.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsStringGlue.h"
 
 #include "WorkerPrivate.h"
 
 #define CTYPES_STR "ctypes"
--- a/dom/workers/EventTarget.cpp
+++ b/dom/workers/EventTarget.cpp
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "EventTarget.h"
 
 #include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 
 USING_WORKERS_NAMESPACE
 
 using mozilla::dom::workers::events::EventTarget;
 
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "Events.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 #include "WorkerPrivate.h"
 
 #define PROPERTY_FLAGS \
--- a/dom/workers/Exceptions.cpp
+++ b/dom/workers/Exceptions.cpp
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "Exceptions.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 #include "jsprf.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 
 #define PROPERTY_FLAGS \
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "File.h"
 
 #include "nsIDOMFile.h"
 
 #include "jsapi.h"
 #include "jsatom.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsJSUtils.h"
 #include "nsStringGlue.h"
 #include "xpcprivate.h"
 #include "XPCQuickStubs.h"
 
 #include "Exceptions.h"
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "FileReaderSync.h"
 
 #include "nsIDOMFile.h"
 
 #include "jsapi.h"
 #include "jsatom.h"
+#include "jscntxt.h"
 #include "jstypedarray.h"
 #include "nsJSUtils.h"
 #include "xpcprivate.h"
 
 #include "Exceptions.h"
 #include "File.h"
 #include "FileReaderSyncPrivate.h"
 #include "WorkerInlines.h"
--- a/dom/workers/ListenerManager.cpp
+++ b/dom/workers/ListenerManager.cpp
@@ -36,22 +36,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "ListenerManager.h"
 
 #include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
+#include "js/Vector.h"
 
 #include "Events.h"
 
-#include "nsTArray.h"
-
 using namespace mozilla;
 using dom::workers::events::ListenerManager;
 
 namespace {
 
 struct Listener;
 
 struct ListenerCollection : PRCList
@@ -363,39 +362,41 @@ ListenerManager::DispatchEvent(JSContext
   ListenerCollection* collection =
     GetCollectionForType(&mCollectionHead,
                          INTERNED_STRING_TO_JSID(aCx, eventType));
   if (!collection) {
     *aPreventDefaultCalled = false;
     return true;
   }
 
-  InfallibleTArray<jsval> listeners;
+  js::ContextAllocPolicy ap(aCx);
+  js::Vector<jsval, 10, js::ContextAllocPolicy> listeners(ap);
 
   for (PRCList* elem = PR_NEXT_LINK(&collection->mListenerHead);
        elem != &collection->mListenerHead;
        elem = PR_NEXT_LINK(elem)) {
     Listener* listener = static_cast<Listener*>(elem);
 
     // Listeners that don't want untrusted events will be skipped if this is an
     // untrusted event.
-    if (eventIsTrusted || listener->mWantsUntrusted) {
-      listeners.AppendElement(listener->mListenerVal);
+    if ((eventIsTrusted || listener->mWantsUntrusted) &&
+        !listeners.append(listener->mListenerVal)) {
+      return false;
     }
   }
 
-  if (listeners.IsEmpty()) {
+  if (listeners.empty()) {
     return true;
   }
 
   if (!events::SetEventTarget(aCx, aEvent, aTarget)) {
     return false;
   }
 
-  for (size_t index = 0; index < listeners.Length(); index++) {
+  for (size_t index = 0; index < listeners.length(); index++) {
     // If anything fails in here we want to report the exception and continue on
     // to the next listener rather than bailing out. If something fails and
     // does not set an exception then we bail out entirely as we've either run
     // out of memory or the operation callback has indicated that we should
     // stop running.
 
     jsval listenerVal = listeners[index];
 
--- a/dom/workers/Location.cpp
+++ b/dom/workers/Location.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Location.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
 
 USING_WORKERS_NAMESPACE
--- a/dom/workers/Navigator.cpp
+++ b/dom/workers/Navigator.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Navigator.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "RuntimeService.h"
 
 #define PROPERTY_FLAGS \
   JSPROP_ENUMERATE | JSPROP_SHARED
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Worker.h"
 
 #include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jscntxt.h"
 
 #include "EventTarget.h"
 #include "RuntimeService.h"
 #include "WorkerPrivate.h"
 
 #include "WorkerInlines.h"
 
 #define PROPERTY_FLAGS \
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -51,17 +51,17 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsITextToSubURI.h"
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIXPConnect.h"
 
-#include "jsapi.h"
+#include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsprf.h"
 #include "nsAlgorithm.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsDOMJSUtils.h"
 #include "nsGUIEvent.h"
 #include "nsJSEnvironment.h"
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "WorkerScope.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 
 #include "nsTraceRefcnt.h"
 #include "xpcprivate.h"
 
 #include "ChromeWorkerScope.h"
 #include "Events.h"
 #include "EventTarget.h"
 #include "Exceptions.h"
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "XMLHttpRequest.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "WorkerPrivate.h"
 #include "XMLHttpRequestPrivate.h"
 
 #include "WorkerInlines.h"
 
 #define PROPERTY_FLAGS \
--- a/js/ipc/ObjectWrapperChild.cpp
+++ b/js/ipc/ObjectWrapperChild.cpp
@@ -34,16 +34,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
+#include "jscntxt.h"
 
 #include "mozilla/jsipc/ContextWrapperChild.h"
 #include "mozilla/jsipc/ObjectWrapperChild.h"
 #include "mozilla/jsipc/CPOWTypes.h"
 
 #include "jsapi.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
@@ -449,25 +450,25 @@ ObjectWrapperChild::AnswerNewEnumerateIn
     if (!state)
         return false;
     AutoObjectRooter tvr(cx, state);
 
     for (JSObject* proto = mObj;
          proto;
          proto = JS_GetPrototype(cx, proto))
     {
-        JS::AutoIdArray ids(cx, JS_Enumerate(cx, proto));
+        AutoIdArray ids(cx, JS_Enumerate(cx, proto));
         for (uint i = 0; i < ids.length(); ++i)
             JS_DefinePropertyById(cx, state, ids[i], JSVAL_VOID,
                                   NULL, NULL, JSPROP_ENUMERATE | JSPROP_SHARED);
     }
 
     InfallibleTArray<nsString>* strIds;
     {
-        JS::AutoIdArray ids(cx, JS_Enumerate(cx, state));
+        AutoIdArray ids(cx, JS_Enumerate(cx, state));
         if (!ids)
             return false;
         strIds = new InfallibleTArray<nsString>(ids.length());
         for (uint i = 0; i < ids.length(); ++i)
             if (!jsid_to_nsString(cx, ids[i], strIds->AppendElement())) {
                 delete strIds;
                 return false;
             }
@@ -595,17 +596,17 @@ ObjectWrapperChild::AnswerCall(PObjectWr
     if (!JSObject_from_PObjectWrapperChild(cx, receiver, &obj))
         return false;
 
     AutoJSArgs args;
     PRUint32 argc = argv.Length();
     jsval *jsargs = args.AppendElements(argc);
     if (!jsargs)
         return false;
-    JS::AutoArrayRooter tvr(cx, argc, jsargs);
+    AutoArrayRooter tvr(cx, argc, jsargs);
 
     for (PRUint32 i = 0; i < argc; ++i)
         if (!jsval_from_JSVariant(cx, argv.ElementAt(i), jsargs + i))
             return false;
 
     jsval rv;
     *status = JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(mObj),
                                    argv.Length(), jsargs, &rv);
@@ -621,17 +622,17 @@ ObjectWrapperChild::AnswerConstruct(cons
     AutoContextPusher acp(cx);
     AutoCheckOperation aco(this, status);
 
     AutoJSArgs args;
     PRUint32 argc = argv.Length();
     jsval* jsargs = args.AppendElements(argc);
     if (!jsargs)
         return false;
-    JS::AutoArrayRooter tvr(cx, argc, jsargs);
+    AutoArrayRooter tvr(cx, argc, jsargs);
 
     for (PRUint32 i = 0; i < argc; ++i)
         if (!jsval_from_JSVariant(cx, argv.ElementAt(i), jsargs + i))
             return false;
 
     JSObject* obj = JS_New(cx, mObj, argc, jsargs);
 
     *status = !!obj;
--- a/js/jetpack/Handle.h
+++ b/js/jetpack/Handle.h
@@ -41,16 +41,17 @@
 #ifndef mozilla_jetpack_HandleParent_h
 #define mozilla_jetpack_HandleParent_h
 
 #include "mozilla/jetpack/PHandleParent.h"
 #include "mozilla/jetpack/PHandleChild.h"
 
 #include "jsapi.h"
 #include "jsclass.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/unused.h"
 
 namespace mozilla {
 namespace jetpack {
 
 /**
@@ -120,17 +121,17 @@ public:
   }
 
   JSObject* ToJSObject(JSContext* cx) {
     if (!mObj && !mCx) {
       JSClass* clasp = const_cast<JSClass*>(&sHandle_JSClass);
       JSObject* obj = JS_NewObject(cx, clasp, NULL, NULL);
       if (!obj)
         return NULL;
-      JS::AutoObjectRooter root(cx, obj);
+      js::AutoObjectRooter root(cx, obj);
 
       JSPropertySpec* ps = const_cast<JSPropertySpec*>(sHandle_Properties);
       JSFunctionSpec* fs = const_cast<JSFunctionSpec*>(sHandle_Functions);
 
       if (JS_SetPrivate(cx, obj, (void*)this) &&
           JS_DefineProperties(cx, obj, ps) &&
           JS_DefineFunctions(cx, obj, fs)) {
         mObj = obj;
@@ -154,26 +155,26 @@ private:
 
   void TearDown() {
     if (mCx) {
       JSAutoRequest ar(mCx);
 
       if (mObj) {
         JS_SetPrivate(mCx, mObj, NULL);
 
-        JS::AutoObjectRooter obj(mCx, mObj);
+        js::AutoObjectRooter obj(mCx, mObj);
         mObj = NULL;
 
         // If we can't enter the compartment, we won't run onInvalidate().
         JSAutoEnterCompartment ac;
         if (ac.enter(mCx, obj.object())) {
           JSBool hasOnInvalidate;
           if (JS_HasProperty(mCx, obj.object(), "onInvalidate",
                              &hasOnInvalidate) && hasOnInvalidate) {
-            JS::AutoValueRooter r(mCx);
+            js::AutoValueRooter r(mCx);
             JSBool ok = JS_CallFunctionName(mCx, obj.object(), "onInvalidate", 0,
                                             NULL, r.jsval_addr());
             if (!ok)
               JS_ReportPendingException(mCx);
           }
         }
 
         // By not nulling out mContext, we prevent ToJSObject from
--- a/js/jetpack/JetpackActorCommon.cpp
+++ b/js/jetpack/JetpackActorCommon.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "js/HashTable.h"
 
 #include "mozilla/jetpack/JetpackActorCommon.h"
 #include "mozilla/jetpack/PJetpack.h"
 #include "mozilla/jetpack/PHandleParent.h"
 #include "mozilla/jetpack/PHandleChild.h"
 #include "mozilla/jetpack/Handle.h"
 
@@ -336,26 +337,26 @@ JetpackActorCommon::jsval_from_CompVaria
   }
 
   JSObject* obj = NULL;
 
   switch (from.type()) {
   case CompVariant::TArrayOfKeyValue: {
     if (!(obj = JS_NewObject(cx, NULL, NULL, NULL)))
       return false;
-    JS::AutoObjectRooter root(cx, obj);
+    js::AutoObjectRooter root(cx, obj);
 
     OpaqueSeenType::IdType ignored;
     if (!seen->add(obj, &ignored))
       return false;
 
     const nsTArray<KeyValue>& kvs = from.get_ArrayOfKeyValue();
     for (PRUint32 i = 0; i < kvs.Length(); ++i) {
       const KeyValue& kv = kvs.ElementAt(i);
-      JS::AutoValueRooter toSet(cx);
+      js::AutoValueRooter toSet(cx);
       if (!jsval_from_Variant(cx, kv.value(), toSet.jsval_addr(), seen) ||
           !JS_SetUCProperty(cx, obj,
                             kv.key().get(),
                             kv.key().Length(),
                             toSet.jsval_addr()))
         return false;
     }
 
@@ -365,17 +366,17 @@ JetpackActorCommon::jsval_from_CompVaria
   case CompVariant::TArrayOfVariant: {
     const nsTArray<Variant>& vs = from.get_ArrayOfVariant();
     nsAutoTArray<jsval, 8> jsvals;
     jsval* elems = jsvals.AppendElements(vs.Length());
     if (!elems)
       return false;
     for (PRUint32 i = 0; i < vs.Length(); ++i)
       elems[i] = JSVAL_VOID;
-    JS::AutoArrayRooter root(cx, vs.Length(), elems);
+    js::AutoArrayRooter root(cx, vs.Length(), elems);
 
     OpaqueSeenType::IdType ignored;
     if (!seen->add(obj, &ignored))
       return false;
 
     for (PRUint32 i = 0; i < vs.Length(); ++i)
       if (!jsval_from_Variant(cx, vs.ElementAt(i), elems + i, seen))
         return false;
@@ -440,31 +441,31 @@ JetpackActorCommon::RecvMessage(JSContex
   
   nsAutoTArray<jsval, 4> args;
   PRUint32 argc = data.Length() + 1;
   jsval* argv = args.AppendElements(argc);
   if (!argv)
     return false;
   for (PRUint32 i = 0; i < argc; ++i)
     argv[i] = JSVAL_VOID;
-  JS::AutoArrayRooter argvRooter(cx, argc, argv);
+  js::AutoArrayRooter argvRooter(cx, argc, argv);
 
   JSString* msgNameStr =
     JS_NewUCStringCopyN(cx,
                         messageName.get(),
                         messageName.Length());
   if (!msgNameStr)
     return false;
   argv[0] = STRING_TO_JSVAL(msgNameStr);
 
   for (PRUint32 i = 0; i < data.Length(); ++i)
     if (!jsval_from_Variant(cx, data.ElementAt(i), argv + i + 1))
       return false;
 
-  JS::AutoValueRooter rval(cx);
+  js::AutoValueRooter rval(cx);
   for (PRUint32 i = 0; i < snapshot.Length(); ++i) {
     Variant* vp = results ? results->AppendElement() : NULL;
     rval.set(JSVAL_VOID);
     if (!JS_CallFunctionValue(cx, implGlobal, snapshot[i], argc, argv,
                               rval.jsval_addr())) {
       (void) JS_ReportPendingException(cx);
       if (vp)
         *vp = void_t();
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -31,16 +31,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
+#include "jscntxt.h"
 #include "jswrapper.h"
 #include "nsXULAppAPI.h"
 #include "nsNativeCharsetUtils.h"
 
 #include "mozilla/jetpack/JetpackChild.h"
 #include "mozilla/jetpack/Handle.h"
 #include "mozilla/IntentionalCrash.h"
 
@@ -305,17 +306,17 @@ JetpackChild::CallMessage(JSContext* cx,
   nsAutoTArray<jsval, 4> jsvals;
   jsval* rvals = jsvals.AppendElements(results.Length());
   if (!rvals) {
     JS_ReportOutOfMemory(cx);
     return JS_FALSE;
   }
   for (PRUint32 i = 0; i < results.Length(); ++i)
     rvals[i] = JSVAL_VOID;
-  JS::AutoArrayRooter root(cx, results.Length(), rvals);
+  js::AutoArrayRooter root(cx, results.Length(), rvals);
 
   for (PRUint32 i = 0; i < results.Length(); ++i)
     if (!jsval_from_Variant(cx, results.ElementAt(i), rvals + i)) {
       JS_ReportError(cx, "Invalid result from handler %d", i);
       return JS_FALSE;
     }
 
   JSObject* arrObj = JS_NewArrayObject(cx, results.Length(), rvals);
@@ -506,34 +507,34 @@ JetpackChild::EvalInSandbox(JSContext* c
   if (!str)
     return JS_FALSE;
 
   size_t length;
   const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
   if (!chars)
       return JS_FALSE;
 
-  JS::AutoValueRooter ignored(cx);
+  js::AutoValueRooter ignored(cx);
   return JS_EvaluateUCScript(cx, obj, chars, length, "", 1, ignored.jsval_addr());
 }
 
 bool JetpackChild::sReportingError;
 
 /* static */ void
 JetpackChild::ReportError(JSContext* cx, const char* message,
                           JSErrorReport* report)
 {
   if (sReportingError) {
     NS_WARNING("Recursive error reported.");
     return;
   }
 
   sReportingError = true;
 
-  JS::AutoObjectRooter obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
+  js::AutoObjectRooter obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
 
   if (report && report->filename) {
     jsval filename = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, report->filename));
     JS_SetProperty(cx, obj.object(), "fileName", &filename);
   }
 
   if (report) {
     jsval lineno = INT_TO_JSVAL(report->lineno);
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -186,38 +186,45 @@ INSTALLED_HEADERS = \
 		$(CURDIR)/jsautokw.h \
 		js.msg \
 		jsalloc.h \
 		jsapi.h \
 		jsatom.h \
 		jsclass.h \
 		jsclist.h \
 		jsclone.h \
+		jscntxt.h \
 		jscompat.h \
+		jscrashreport.h \
+		jsdate.h \
 		jsdbgapi.h \
 		jsdhash.h \
 		jsfriendapi.h \
 		jsgc.h \
 		jscell.h \
 		jsgcchunk.h \
 		jsgcstats.h \
 		jshash.h \
 		jsinttypes.h \
 		jslock.h \
 		json.h \
 		jsopcode.tbl \
 		jsopcode.h \
 		jsotypes.h \
 		jsproxy.h \
 		jsprf.h \
+		jspropertycache.h \
+		jspropertytree.h \
 		jsproto.tbl \
 		jsprvtd.h \
 		jspubtd.h \
+		jsreflect.h \
 		jsstdint.h \
 		jsstr.h \
+		jstracer.h \
 		jstypedarray.h \
 		jstypes.h \
 		jsutil.h \
 		jsversion.h \
 		jswrapper.h \
 		jsxdrapi.h \
 		jsval.h \
 		prmjtime.h \
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -112,17 +112,17 @@ using namespace js::frontend;
         if (tokenStream.getToken((__flags)) != tt) {                                        \
             reportErrorNumber(NULL, JSREPORT_ERROR, errno);                                 \
             return NULL;                                                                    \
         }                                                                                   \
     JS_END_MACRO
 #define MUST_MATCH_TOKEN(tt, errno) MUST_MATCH_TOKEN_WITH_FLAGS(tt, errno, 0)
 
 Parser::Parser(JSContext *cx, JSPrincipals *prin, StackFrame *cfp, bool foldConstants)
-  : js::AutoGCRooter(cx),
+  : AutoGCRooter(cx, PARSER),
     context(cx),
     tokenStream(cx),
     principals(NULL),
     callerFrame(cfp),
     callerVarObj(cfp ? &cfp->varObj() : NULL),
     allocator(cx),
     functionCount(0),
     traceListHead(NULL),
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -115,16 +115,17 @@ struct Parser : private AutoGCRooter
     AutoKeepAtoms       keepAtoms;
 
     /* Perform constant-folding; must be true when interfacing with the emitter. */
     bool                foldConstants;
 
     Parser(JSContext *cx, JSPrincipals *prin = NULL, StackFrame *cfp = NULL, bool fold = true);
     ~Parser();
 
+    friend void AutoGCRooter::trace(JSTracer *trc);
     friend struct TreeContext;
     friend struct BytecodeCompiler;
 
     /*
      * Initialize a parser. Parameters are passed on to init tokenStream. The
      * compiler owns the arena pool "tops-of-stack" space above the current
      * JSContext.tempLifoAlloc mark. This means you cannot allocate from
      * tempLifoAlloc and save the pointer beyond the next Parser destructor
@@ -169,17 +170,17 @@ struct Parser : private AutoGCRooter
      * siblings, their kids, etc.
      */
     bool analyzeFunctions(TreeContext *tc);
     void cleanFunctionList(FunctionBox **funbox);
     bool markFunArgs(FunctionBox *funbox);
     void markExtensibleScopeDescendants(FunctionBox *funbox, bool hasExtensibleParent);
     void setFunctionKinds(FunctionBox *funbox, uint32 *tcflags);
 
-    virtual void trace(JSTracer *trc);
+    void trace(JSTracer *trc);
 
     /*
      * Report a parse (compile) error.
      */
     inline bool reportErrorNumber(ParseNode *pn, uintN flags, uintN errorNumber, ...);
 
   private:
     void *allocParseNode(size_t size) {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -630,17 +630,16 @@ JS_IsBuiltinFunctionConstructor(JSFuncti
  * Has a new runtime ever been created?  This flag is used to detect unsafe
  * changes to js_CStringsAreUTF8 after a runtime has been created, and to
  * control things that should happen only once across all runtimes.
  */
 static JSBool js_NewRuntimeWasCalled = JS_FALSE;
 
 JSRuntime::JSRuntime()
   : atomsCompartment(NULL),
-    structuredCloneCallbacks(NULL),
 #ifdef JS_THREADSAFE
     atomsCompartmentIsLocked(false),
 #endif
     state(),
     cxCallback(NULL),
     compartmentCallback(NULL),
     activityCallback(NULL),
     activityCallbackArg(NULL),
@@ -699,16 +698,17 @@ JSRuntime::JSRuntime()
     rtLock(NULL),
 # ifdef DEBUG
     rtLockOwner(0),
 # endif
     stateChange(NULL),
 #endif
     debuggerMutations(0),
     securityCallbacks(NULL),
+    structuredCloneCallbacks(NULL),
     telemetryCallback(NULL),
     propertyRemovals(0),
     scriptFilenameTable(NULL),
 #ifdef JS_THREADSAFE
     scriptFilenameTableLock(NULL),
 #endif
     thousandsSeparator(0),
     decimalSeparator(0),
@@ -5885,22 +5885,16 @@ JS_ReportOutOfMemory(JSContext *cx)
 
 JS_PUBLIC_API(void)
 JS_ReportAllocationOverflow(JSContext *cx)
 {
     js_ReportAllocationOverflow(cx);
 }
 
 JS_PUBLIC_API(JSErrorReporter)
-JS_GetErrorReporter(JSContext *cx)
-{
-    return cx->errorReporter;
-}
-
-JS_PUBLIC_API(JSErrorReporter)
 JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
 {
     JSErrorReporter older;
 
     older = cx->errorReporter;
     cx->errorReporter = er;
     return older;
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4641,18 +4641,16 @@ struct JSErrorReport {
  * JS_ExecuteScript returns failure, and signal or propagate the exception, as
  * appropriate.
  */
 #define JSREPORT_IS_WARNING(flags)      (((flags) & JSREPORT_WARNING) != 0)
 #define JSREPORT_IS_EXCEPTION(flags)    (((flags) & JSREPORT_EXCEPTION) != 0)
 #define JSREPORT_IS_STRICT(flags)       (((flags) & JSREPORT_STRICT) != 0)
 #define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) &                      \
                                               JSREPORT_STRICT_MODE_ERROR) != 0)
-extern JS_PUBLIC_API(JSErrorReporter)
-JS_GetErrorReporter(JSContext *cx);
 
 extern JS_PUBLIC_API(JSErrorReporter)
 JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
 
 /************************************************************************/
 
 /*
  * Dates.
@@ -4886,229 +4884,9 @@ extern JS_PUBLIC_API(void)
 JS_SetGCZeal(JSContext *cx, uint8 zeal, uint32 frequency, JSBool compartment);
 
 extern JS_PUBLIC_API(void)
 JS_ScheduleGC(JSContext *cx, uint32 count, JSBool compartment);
 #endif
 
 JS_END_EXTERN_C
 
-/************************************************************************/
-
-#ifdef __cplusplus
-
-namespace JS {
-
-class AutoGCRooter;
-
-namespace shadow {
-
-struct Context {
-    JS::AutoGCRooter *autoGCRooters;
-};
-
-} /* namespace shadow */
-
-class AutoGCRooter {
-  public:
-    AutoGCRooter(JSContext *cx)
-      : down(reinterpret_cast<shadow::Context *>(cx)->autoGCRooters), context(cx)
-    {
-        JS_ASSERT(this != reinterpret_cast<shadow::Context *>(cx)->autoGCRooters);
-        reinterpret_cast<shadow::Context *>(cx)->autoGCRooters = this;
-    }
-
-    virtual ~AutoGCRooter() {
-        JS_ASSERT(this == reinterpret_cast<shadow::Context *>(context)->autoGCRooters);
-        reinterpret_cast<shadow::Context *>(context)->autoGCRooters = down;
-    }
-
-    /* Implemented in jsgc.cpp. */
-    void traceAll(JSTracer *trc);
-
-  protected:
-    virtual void trace(JSTracer *trc) = 0;
-
-    AutoGCRooter * const down;
-    JSContext * const context;
-
-  private:
-    /* No copy or assignment semantics. */
-    AutoGCRooter(AutoGCRooter &ida);
-    void operator=(AutoGCRooter &ida);
-};
-
-class AutoValueRooter : private AutoGCRooter
-{
-  public:
-    explicit AutoValueRooter(JSContext *cx
-                             JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), val(js::NullValue())
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    AutoValueRooter(JSContext *cx, const Value &v
-                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), val(v)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    /*
-     * If you are looking for Object* overloads, use AutoObjectRooter instead;
-     * rooting Object*s as a js::Value requires discerning whether or not it is
-     * a function object. Also, AutoObjectRooter is smaller.
-     */
-
-    void set(Value v) {
-        val = v;
-    }
-
-    const Value &value() const {
-        return val;
-    }
-
-    Value *addr() {
-        return &val;
-    }
-
-    const jsval &jsval_value() const {
-        return val;
-    }
-
-    jsval *jsval_addr() {
-        return &val;
-    }
-
-  private:
-    virtual JS_PUBLIC_API(void) trace(JSTracer *trc);
-
-    Value val;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoObjectRooter : private AutoGCRooter {
-  public:
-    AutoObjectRooter(JSContext *cx, JSObject *obj = NULL
-                     JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), obj(obj)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    void setObject(JSObject *obj) {
-        this->obj = obj;
-    }
-
-    JSObject * object() const {
-        return obj;
-    }
-
-    JSObject ** addr() {
-        return &obj;
-    }
-
-  private:
-    virtual JS_PUBLIC_API(void) trace(JSTracer *trc);
-
-    JSObject *obj;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoArrayRooter : private AutoGCRooter {
-  public:
-    AutoArrayRooter(JSContext *cx, size_t len, Value *vec
-                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), array(vec), length(len)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    void changeLength(size_t newLength) {
-        length = newLength;
-    }
-
-    void changeArray(Value *newArray, size_t newLength) {
-        changeLength(newLength);
-        array = newArray;
-    }
-
-    Value *array;
-    size_t length;
-
-  private:
-    virtual JS_PUBLIC_API(void) trace(JSTracer *trc);
-
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoIdRooter : private AutoGCRooter
-{
-  public:
-    explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0)
-                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), id_(id)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    jsid id() {
-        return id_;
-    }
-
-    jsid * addr() {
-        return &id_;
-    }
-
-  private:
-    virtual JS_PUBLIC_API(void) trace(JSTracer *trc);
-
-    jsid id_;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoIdArray : private AutoGCRooter {
-  public:
-    AutoIdArray(JSContext *cx, JSIdArray *ida
-                JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), idArray(ida)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-    ~AutoIdArray() {
-        if (idArray)
-            JS_DestroyIdArray(context, idArray);
-    }
-    bool operator!() {
-        return idArray == NULL;
-    }
-    jsid operator[](size_t i) const {
-        JS_ASSERT(idArray);
-        JS_ASSERT(i < size_t(idArray->length));
-        return idArray->vector[i];
-    }
-    size_t length() const {
-         return idArray->length;
-    }
-
-    JSIdArray *steal() {
-        JSIdArray *copy = idArray;
-        idArray = NULL;
-        return copy;
-    }
-
-  private:
-    virtual JS_PUBLIC_API(void) trace(JSTracer *trc);
-
-    JSIdArray * idArray;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-    /* No copy or assignment semantics. */
-    AutoIdArray(AutoIdArray &ida);
-    void operator=(AutoIdArray &ida);
-};
-
-} /* namespace JS */
-
-#endif
-
 #endif /* jsapi_h___ */
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -41,18 +41,18 @@
 #include "jstypedarray.h"
 
 #include "jstypedarrayinlines.h"
 
 #include "vm/RegExpObject-inl.h"
 
 using namespace js;
 
-JS_FRIEND_API(JSUint64)
-JS_GetSCOffset(JSStructuredCloneWriter* writer)
+JS_FRIEND_API(uint64_t)
+js_GetSCOffset(JSStructuredCloneWriter* writer)
 {
     JS_ASSERT(writer);
     return writer->output().count() * sizeof(uint64_t);
 }
 
 namespace js {
 
 bool
--- a/js/src/jsclone.h
+++ b/js/src/jsclone.h
@@ -41,16 +41,19 @@
 
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsstdint.h"
 
 #include "js/HashTable.h"
 #include "js/Vector.h"
 
+JS_FRIEND_API(uint64_t)
+js_GetSCOffset(JSStructuredCloneWriter* writer);
+
 namespace js {
 
 bool
 WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp,
                      const JSStructuredCloneCallbacks *cb, void *cbClosure);
 
 bool
 ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *vp,
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1328,49 +1328,49 @@ DSTOffsetCache::purge()
  * doesn't return a bogus offset.
  */
 DSTOffsetCache::DSTOffsetCache()
 {
     purge();
 }
 
 JSContext::JSContext(JSRuntime *rt)
-  : autoGCRooters(NULL),
-    data(NULL),
-    data2(NULL),
-#ifdef JS_THREADSAFE
-    thread_(NULL),
-#endif
-    compartment(NULL),
-    globalObject(NULL),
-    runtime(rt),
-#if JS_STACK_GROWTH_DIRECTION > 0
-    stackLimit((jsuword)-1),
-#else
-    stackLimit(0),
-#endif
-#ifdef JS_THREADSAFE
-    outstandingRequests(0),
-#endif
-    debugHooks(&rt->globalDebugHooks),
-    defaultVersion(JSVERSION_DEFAULT),
+  : defaultVersion(JSVERSION_DEFAULT),
     hasVersionOverride(false),
     throwing(false),
     exception(UndefinedValue()),
     runOptions(0),
     reportGranularity(JS_DEFAULT_JITREPORT_GRANULARITY),
     localeCallbacks(NULL),
     resolvingList(NULL),
     generatingError(false),
+#if JS_STACK_GROWTH_DIRECTION > 0
+    stackLimit((jsuword)-1),
+#else
+    stackLimit(0),
+#endif
+    runtime(rt),
+    compartment(NULL),
+#ifdef JS_THREADSAFE
+    thread_(NULL),
+#endif
     stack(thisDuringConstruction()),  /* depends on cx->thread_ */
     parseMapPool_(NULL),
+    globalObject(NULL),
     argumentFormatMap(NULL),
     lastMessage(NULL),
     errorReporter(NULL),
     operationCallback(NULL),
+    data(NULL),
+    data2(NULL),
+#ifdef JS_THREADSAFE
+    outstandingRequests(0),
+#endif
+    autoGCRooters(NULL),
+    debugHooks(&rt->globalDebugHooks),
     securityCallbacks(NULL),
     resolveFlags(0),
     rngSeed(0),
     iterValue(MagicValue(JS_NO_ITER_VALUE)),
 #ifdef JS_TRACER
     traceJitEnabled(false),
 #endif
 #ifdef JS_METHODJIT
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -40,17 +40,16 @@
 
 #ifndef jscntxt_h___
 #define jscntxt_h___
 /*
  * JS execution context.
  */
 #include <string.h>
 
-#include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jsprvtd.h"
 #include "jsatom.h"
 #include "jsclist.h"
 #include "jsdhash.h"
 #include "jsgc.h"
 #include "jsgcchunk.h"
 #include "jspropertycache.h"
@@ -258,26 +257,22 @@ struct ThreadData {
  * that can be accessed without a global lock.
  */
 struct JSThread {
     typedef js::HashMap<void *,
                         JSThread *,
                         js::DefaultHasher<void *>,
                         js::SystemAllocPolicy> Map;
 
+    /* Linked list of all contexts in use on this thread. */
+    JSCList             contextList;
+
     /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */
     void                *id;
 
-    void staticAsserts() {
-        JS_STATIC_ASSERT(offsetof(JSThread, id) == offsetof(js::shadow::Thread, id));
-    }
-
-    /* Linked list of all contexts in use on this thread. */
-    JSCList             contextList;
-
     /* Number of JS_SuspendRequest calls withot JS_ResumeRequest. */
     unsigned            suspendCount;
 
 # ifdef DEBUG
     unsigned            checkRequestDepth;
 # endif
 
     /* Factored out of JSThread for !JS_THREADSAFE embedding in JSRuntime. */
@@ -348,43 +343,25 @@ typedef void
 
 namespace js {
 
 typedef js::Vector<JSCompartment *, 0, js::SystemAllocPolicy> CompartmentVector;
 
 }
 
 struct JSRuntime {
-    /* Literal table maintained by jsatom.cpp functions. */
-    JSAtomState         atomState;
-
     /* Default compartment. */
     JSCompartment       *atomsCompartment;
+#ifdef JS_THREADSAFE
+    bool                atomsCompartmentIsLocked;
+#endif
 
     /* List of compartments (protected by the GC lock). */
     js::CompartmentVector compartments;
 
-    /* Structured data callbacks are runtime-wide. */
-    const JSStructuredCloneCallbacks *structuredCloneCallbacks;
-
-    void staticAsserts() {
-        JS_STATIC_ASSERT(offsetof(JSRuntime, atomState) ==
-                         offsetof(js::shadow::Runtime, atomState));
-        JS_STATIC_ASSERT(offsetof(JSRuntime, atomsCompartment) ==
-                         offsetof(js::shadow::Runtime, atomsCompartment));
-        JS_STATIC_ASSERT(offsetof(JSRuntime, compartments) ==
-                         offsetof(js::shadow::Runtime, compartments));
-        JS_STATIC_ASSERT(offsetof(JSRuntime, structuredCloneCallbacks) ==
-                         offsetof(js::shadow::Runtime, structuredCloneCallbacks));
-    }
-
-#ifdef JS_THREADSAFE
-    bool                atomsCompartmentIsLocked;
-#endif
-
     /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
     JSRuntimeState      state;
 
     /* Context create/destroy callback. */
     JSContextCallback   cxCallback;
 
     /* Compartment create/destroy callback. */
     JSCompartmentCallback compartmentCallback;
@@ -461,19 +438,16 @@ struct JSRuntime {
 
     /* Pre-allocated space for the GC mark stacks. Pointer type ensures alignment. */
     void                *gcMarkStackObjs[js::OBJECT_MARK_STACK_SIZE / sizeof(void *)];
     void                *gcMarkStackRopes[js::ROPES_MARK_STACK_SIZE / sizeof(void *)];
     void                *gcMarkStackTypes[js::TYPE_MARK_STACK_SIZE / sizeof(void *)];
     void                *gcMarkStackXMLs[js::XML_MARK_STACK_SIZE / sizeof(void *)];
     void                *gcMarkStackLarges[js::LARGE_MARK_STACK_SIZE / sizeof(void *)];
 
-    /* Was the most recent GC compartmental or full? */
-    bool                wasCompartmentGC;
-
     /*
      * Compartment that triggered GC. If more than one Compatment need GC,
      * gcTriggerCompartment is reset to NULL and a global GC is performed.
      */
     JSCompartment       *gcTriggerCompartment;
 
     /* Compartment that is currently involved in per-compartment GC */
     JSCompartment       *gcCurrentCompartment;
@@ -622,16 +596,19 @@ struct JSRuntime {
     uint32              debuggerMutations;
 
     /*
      * Security callbacks set on the runtime are used by each context unless
      * an override is set on the context.
      */
     JSSecurityCallbacks *securityCallbacks;
 
+    /* Structured data callbacks are runtime-wide. */
+    const JSStructuredCloneCallbacks *structuredCloneCallbacks;
+
     /* Call this to accumulate telemetry data. */
     JSAccumulateTelemetryDataCallback telemetryCallback;
 
     /*
      * The propertyRemovals counter is incremented for every JSObject::clear,
      * and for each JSObject::remove method call that frees a slot in the given
      * object. See js_NativeGet and js_NativeSet in jsobj.cpp.
      */
@@ -683,16 +660,19 @@ struct JSRuntime {
      *
      * If this counter overflows into SHAPE_OVERFLOW_BIT (in jsinterp.h), the
      * cache is disabled, to avoid aliasing two different types. It stays
      * disabled until a triggered GC at some later moment compresses live
      * types, minimizing rt->shapeGen in the process.
      */
     volatile uint32     shapeGen;
 
+    /* Literal table maintained by jsatom.c functions. */
+    JSAtomState         atomState;
+
     /* Tables of strings that are pre-allocated in the atomsCompartment. */
     js::StaticStrings   staticStrings;
 
     JSWrapObjectCallback wrapObjectCallback;
     JSPreWrapCallback    preWrapObjectCallback;
 
     /*
      * To ensure that cx->malloc does not cause a GC, we set this flag during
@@ -821,16 +801,17 @@ struct JSArgumentFormatMap {
     JSArgumentFormatMap *next;
 };
 #endif
 
 extern const JSDebugHooks js_NullDebugHooks;  /* defined in jsdbgapi.cpp */
 
 namespace js {
 
+class AutoGCRooter;
 struct AutoResolving;
 
 static inline bool
 OptionsHasXML(uint32 options)
 {
     return !!(options & JSOPTION_XML);
 }
 
@@ -929,81 +910,16 @@ typedef HashSet<JSObject *,
 } /* namespace js */
 
 struct JSContext
 {
     explicit JSContext(JSRuntime *rt);
     JSContext *thisDuringConstruction() { return this; }
     ~JSContext();
 
-    /* Stack of thread-stack-allocated GC roots. */
-    js::AutoGCRooter   *autoGCRooters;
-
-    /* Client opaque pointers. */
-    void                *data;
-    void                *data2;
-
-#ifdef JS_THREADSAFE
-  private:
-    JSThread            *thread_;
-  public:
-    JSThread *thread() const { return thread_; }
-
-    void setThread(JSThread *thread);
-    static const size_t threadOffset() { return offsetof(JSContext, thread_); }
-#endif
-
-    /* GC heap compartment. */
-    JSCompartment       *compartment;
-
-    /* Top-level object and pointer to top stack frame's scope chain. */
-    JSObject            *globalObject;
-
-    /* Data shared by threads in an address space. */
-    JSRuntime *const    runtime;
-
-    /* Limit pointer for checking native stack consumption during recursion. */
-    jsuword             stackLimit;
-
-#ifdef JS_THREADSAFE
-    unsigned            outstandingRequests;/* number of JS_BeginRequest calls
-                                               without the corresponding
-                                               JS_EndRequest. */
-#endif
-
-    /* Debug hooks associated with the current context. */
-    const JSDebugHooks  *debugHooks;
-
-    void staticAsserts() {
-        JS_STATIC_ASSERT(offsetof(JSContext, autoGCRooters) ==
-                         offsetof(JS::shadow::Context, autoGCRooters));
-        JS_STATIC_ASSERT(offsetof(JSContext, data) ==
-                         offsetof(js::shadow::Context, data));
-        JS_STATIC_ASSERT(offsetof(JSContext, data2) ==
-                         offsetof(js::shadow::Context, data2));
-#ifdef JS_THREADSAFE
-        JS_STATIC_ASSERT(offsetof(JSContext, thread_) ==
-                         offsetof(js::shadow::Context, thread_));
-#endif
-        JS_STATIC_ASSERT(offsetof(JSContext, compartment) ==
-                         offsetof(js::shadow::Context, compartment));
-        JS_STATIC_ASSERT(offsetof(JSContext, runtime) ==
-                         offsetof(js::shadow::Context, runtime));
-        JS_STATIC_ASSERT(offsetof(JSContext, stackLimit) ==
-                         offsetof(js::shadow::Context, stackLimit));
-#ifdef JS_THREADSAFE
-        JS_STATIC_ASSERT(offsetof(JSContext, outstandingRequests) ==
-                         offsetof(js::shadow::Context, outstandingRequests));
-#endif
-        JS_STATIC_ASSERT(offsetof(JSContext, globalObject) ==
-                         offsetof(js::shadow::Context, globalObject));
-        JS_STATIC_ASSERT(offsetof(JSContext, debugHooks) ==
-                         offsetof(js::shadow::Context, debugHooks));
-    }
-
     /* JSRuntime contextList linkage. */
     JSCList             link;
 
   private:
     /* See JSContext::findVersion. */
     JSVersion           defaultVersion;      /* script compilation version */
     JSVersion           versionOverride;     /* supercedes defaultVersion when valid */
     bool                hasVersionOverride;
@@ -1024,18 +940,37 @@ struct JSContext
     js::AutoResolving   *resolvingList;
 
     /*
      * True if generating an error, to prevent runaway recursion.
      * NB: generatingError packs with throwing below.
      */
     JSPackedBool        generatingError;
 
+    /* Limit pointer for checking native stack consumption during recursion. */
+    jsuword             stackLimit;
+
+    /* Data shared by threads in an address space. */
+    JSRuntime *const    runtime;
+
+    /* GC heap compartment. */
+    JSCompartment       *compartment;
+
     inline void setCompartment(JSCompartment *compartment);
 
+#ifdef JS_THREADSAFE
+  private:
+    JSThread            *thread_;
+  public:
+    JSThread *thread() const { return thread_; }
+
+    void setThread(JSThread *thread);
+    static const size_t threadOffset() { return offsetof(JSContext, thread_); }
+#endif
+
     /* Current execution stack. */
     js::ContextStack    stack;
 
     /* ContextStack convenience functions */
     inline bool hasfp() const;
     inline js::StackFrame* fp() const;
     inline js::StackFrame* maybefp() const;
     inline js::FrameRegs& regs() const;
@@ -1047,32 +982,39 @@ struct JSContext
     /* Wrap cx->exception for the current compartment. */
     void wrapPendingException();
 
   private:
     /* Lazily initialized pool of maps used during parse/emit. */
     js::ParseMapPool    *parseMapPool_;
 
   public:
+    /* Top-level object and pointer to top stack frame's scope chain. */
+    JSObject            *globalObject;
+
     /* State for object and array toSource conversion. */
     JSSharpObjectMap    sharpObjectMap;
     js::BusyArraysSet   busyArrays;
 
     /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
     JSArgumentFormatMap *argumentFormatMap;
 
     /* Last message string and log file for debugging. */
     char                *lastMessage;
 
     /* Per-context optional error reporter. */
     JSErrorReporter     errorReporter;
 
     /* Branch callback. */
     JSOperationCallback operationCallback;
 
+    /* Client opaque pointers. */
+    void                *data;
+    void                *data2;
+
     inline js::RegExpStatics *regExpStatics();
 
   public:
     js::ParseMapPool &parseMapPool() {
         JS_ASSERT(parseMapPool_);
         return *parseMapPool_;
     }
 
@@ -1149,19 +1091,28 @@ struct JSContext
     bool hasStrictOption() const { return hasRunOption(JSOPTION_STRICT); }
     bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); }
     bool hasAtLineOption() const { return hasRunOption(JSOPTION_ATLINE); }
 
     js::LifoAlloc &tempLifoAlloc() { return JS_THREAD_DATA(this)->tempLifoAlloc; }
     inline js::LifoAlloc &typeLifoAlloc();
 
 #ifdef JS_THREADSAFE
+    unsigned            outstandingRequests;/* number of JS_BeginRequest calls
+                                               without the corresponding
+                                               JS_EndRequest. */
     JSCList             threadLinks;        /* JSThread contextList linkage */
 #endif
 
+    /* Stack of thread-stack-allocated GC roots. */
+    js::AutoGCRooter   *autoGCRooters;
+
+    /* Debug hooks associated with the current context. */
+    const JSDebugHooks  *debugHooks;
+
     /* Security callbacks that override any defined on the runtime. */
     JSSecurityCallbacks *securityCallbacks;
 
     /* Stored here to avoid passing it around as a parameter. */
     uintN               resolveFlags;
 
     /* Random number generator state, used by jsmath.cpp. */
     int64               rngSeed;
@@ -1407,85 +1358,338 @@ struct AutoResolving {
     JSContext           *const context;
     JSObject            *const object;
     jsid                const id;
     Kind                const kind;
     AutoResolving       *const link;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+class AutoGCRooter {
+  public:
+    AutoGCRooter(JSContext *cx, ptrdiff_t tag)
+      : down(cx->autoGCRooters), tag(tag), context(cx)
+    {
+        JS_ASSERT(this != cx->autoGCRooters);
+        CHECK_REQUEST(cx);
+        cx->autoGCRooters = this;
+    }
+
+    ~AutoGCRooter() {
+        JS_ASSERT(this == context->autoGCRooters);
+        CHECK_REQUEST(context);
+        context->autoGCRooters = down;
+    }
+
+    /* Implemented in jsgc.cpp. */
+    inline void trace(JSTracer *trc);
+
+#ifdef __GNUC__
+# pragma GCC visibility push(default)
+#endif
+    friend JS_FRIEND_API(void) MarkContext(JSTracer *trc, JSContext *acx);
+    friend void MarkRuntime(JSTracer *trc);
+#ifdef __GNUC__
+# pragma GCC visibility pop
+#endif
+
+  protected:
+    AutoGCRooter * const down;
+
+    /*
+     * Discriminates actual subclass of this being used.  If non-negative, the
+     * subclass roots an array of values of the length stored in this field.
+     * If negative, meaning is indicated by the corresponding value in the enum
+     * below.  Any other negative value indicates some deeper problem such as
+     * memory corruption.
+     */
+    ptrdiff_t tag;
+
+    JSContext * const context;
+
+    enum {
+        JSVAL =        -1, /* js::AutoValueRooter */
+        VALARRAY =     -2, /* js::AutoValueArrayRooter */
+        PARSER =       -3, /* js::Parser */
+        SHAPEVECTOR =  -4, /* js::AutoShapeVector */
+        ENUMERATOR =   -5, /* js::AutoEnumStateRooter */
+        IDARRAY =      -6, /* js::AutoIdArray */
+        DESCRIPTORS =  -7, /* js::AutoPropDescArrayRooter */
+        NAMESPACES =   -8, /* js::AutoNamespaceArray */
+        XML =          -9, /* js::AutoXMLRooter */
+        OBJECT =      -10, /* js::AutoObjectRooter */
+        ID =          -11, /* js::AutoIdRooter */
+        VALVECTOR =   -12, /* js::AutoValueVector */
+        DESCRIPTOR =  -13, /* js::AutoPropertyDescriptorRooter */
+        STRING =      -14, /* js::AutoStringRooter */
+        IDVECTOR =    -15, /* js::AutoIdVector */
+        OBJVECTOR =   -16  /* js::AutoObjectVector */
+    };
+
+    private:
+    /* No copy or assignment semantics. */
+    AutoGCRooter(AutoGCRooter &ida);
+    void operator=(AutoGCRooter &ida);
+};
+
+/* FIXME(bug 332648): Move this into a public header. */
+class AutoValueRooter : private AutoGCRooter
+{
+  public:
+    explicit AutoValueRooter(JSContext *cx
+                             JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, JSVAL), val(js::NullValue())
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    AutoValueRooter(JSContext *cx, const Value &v
+                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, JSVAL), val(v)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    /*
+     * If you are looking for Object* overloads, use AutoObjectRooter instead;
+     * rooting Object*s as a js::Value requires discerning whether or not it is
+     * a function object. Also, AutoObjectRooter is smaller.
+     */
+
+    void set(Value v) {
+        JS_ASSERT(tag == JSVAL);
+        val = v;
+    }
+
+    const Value &value() const {
+        JS_ASSERT(tag == JSVAL);
+        return val;
+    }
+
+    Value *addr() {
+        JS_ASSERT(tag == JSVAL);
+        return &val;
+    }
+
+    const jsval &jsval_value() const {
+        JS_ASSERT(tag == JSVAL);
+        return val;
+    }
+
+    jsval *jsval_addr() {
+        JS_ASSERT(tag == JSVAL);
+        return &val;
+    }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+    friend void MarkRuntime(JSTracer *trc);
+
+  private:
+    Value val;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoObjectRooter : private AutoGCRooter {
+  public:
+    AutoObjectRooter(JSContext *cx, JSObject *obj = NULL
+                     JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, OBJECT), obj(obj)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    void setObject(JSObject *obj) {
+        this->obj = obj;
+    }
+
+    JSObject * object() const {
+        return obj;
+    }
+
+    JSObject ** addr() {
+        return &obj;
+    }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+    friend void MarkRuntime(JSTracer *trc);
+
+  private:
+    JSObject *obj;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
 class AutoStringRooter : private AutoGCRooter {
   public:
     AutoStringRooter(JSContext *cx, JSString *str = NULL
                      JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), str(str)
+      : AutoGCRooter(cx, STRING), str(str)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     void setString(JSString *str) {
         this->str = str;
     }
 
     JSString * string() const {
         return str;
     }
 
     JSString ** addr() {
         return &str;
     }
 
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
   private:
-    virtual void trace(JSTracer *trc);
-
     JSString *str;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+class AutoArrayRooter : private AutoGCRooter {
+  public:
+    AutoArrayRooter(JSContext *cx, size_t len, Value *vec
+                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, len), array(vec)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+        JS_ASSERT(tag >= 0);
+    }
+
+    void changeLength(size_t newLength) {
+        tag = ptrdiff_t(newLength);
+        JS_ASSERT(tag >= 0);
+    }
+
+    void changeArray(Value *newArray, size_t newLength) {
+        changeLength(newLength);
+        array = newArray;
+    }
+
+    Value *array;
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
+  private:
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoIdRooter : private AutoGCRooter
+{
+  public:
+    explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0)
+                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, ID), id_(id)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    jsid id() {
+        return id_;
+    }
+
+    jsid * addr() {
+        return &id_;
+    }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+    friend void MarkRuntime(JSTracer *trc);
+
+  private:
+    jsid id_;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoIdArray : private AutoGCRooter {
+  public:
+    AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, IDARRAY), idArray(ida)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+    ~AutoIdArray() {
+        if (idArray)
+            JS_DestroyIdArray(context, idArray);
+    }
+    bool operator!() {
+        return idArray == NULL;
+    }
+    jsid operator[](size_t i) const {
+        JS_ASSERT(idArray);
+        JS_ASSERT(i < size_t(idArray->length));
+        return idArray->vector[i];
+    }
+    size_t length() const {
+         return idArray->length;
+    }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
+    JSIdArray *steal() {
+        JSIdArray *copy = idArray;
+        idArray = NULL;
+        return copy;
+    }
+
+  protected:
+    inline void trace(JSTracer *trc);
+
+  private:
+    JSIdArray * idArray;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+    /* No copy or assignment semantics. */
+    AutoIdArray(AutoIdArray &ida);
+    void operator=(AutoIdArray &ida);
+};
+
 /* The auto-root for enumeration object and its state. */
 class AutoEnumStateRooter : private AutoGCRooter
 {
   public:
     AutoEnumStateRooter(JSContext *cx, JSObject *obj
                         JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), obj(obj), stateValue()
+      : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue()
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         JS_ASSERT(obj);
     }
 
     ~AutoEnumStateRooter();
 
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
     const Value &state() const { return stateValue; }
     Value *addr() { return &stateValue; }
 
   protected:
+    void trace(JSTracer *trc);
+
     JSObject * const obj;
 
   private:
-    virtual void trace(JSTracer *trc);
-
     Value stateValue;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 #ifdef JS_HAS_XML_SUPPORT
 class AutoXMLRooter : private AutoGCRooter {
   public:
     AutoXMLRooter(JSContext *cx, JSXML *xml
                   JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx), xml(xml)
+      : AutoGCRooter(cx, XML), xml(xml)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         JS_ASSERT(xml);
     }
 
+    friend void AutoGCRooter::trace(JSTracer *trc);
+    friend void MarkRuntime(JSTracer *trc);
+
   private:
-    virtual void trace(JSTracer *trc);
-
     JSXML * const xml;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 #endif /* JS_HAS_XML_SUPPORT */
 
 class AutoLockGC {
   public:
     explicit AutoLockGC(JSRuntime *rt = NULL
@@ -1764,16 +1968,31 @@ js_ContextIterator(JSRuntime *rt, JSBool
 /*
  * Iterate through contexts with active requests. The caller must be holding
  * rt->gcLock in case of a thread-safe build, or otherwise guarantee that the
  * context list is not alternated asynchroniously.
  */
 extern JS_FRIEND_API(JSContext *)
 js_NextActiveContext(JSRuntime *, JSContext *);
 
+/*
+ * Report an exception, which is currently realized as a printf-style format
+ * string and its arguments.
+ */
+typedef enum JSErrNum {
+#define MSG_DEF(name, number, count, exception, format) \
+    name = number,
+#include "js.msg"
+#undef MSG_DEF
+    JSErr_Limit
+} JSErrNum;
+
+extern JS_FRIEND_API(const JSErrorFormatString *)
+js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
+
 #ifdef va_start
 extern JSBool
 js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
 
 extern JSBool
 js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
                        void *userRef, const uintN errorNumber,
                        JSBool charArgs, va_list ap);
@@ -1783,19 +2002,33 @@ js_ExpandErrorArguments(JSContext *cx, J
                         void *userRef, const uintN errorNumber,
                         char **message, JSErrorReport *reportp,
                         bool charArgs, va_list ap);
 #endif
 
 extern void
 js_ReportOutOfMemory(JSContext *cx);
 
+/* JS_CHECK_RECURSION is used outside JS, so JS_FRIEND_API. */
+JS_FRIEND_API(void)
+js_ReportOverRecursed(JSContext *maybecx);
+
 extern JS_FRIEND_API(void)
 js_ReportAllocationOverflow(JSContext *cx);
 
+#define JS_CHECK_RECURSION(cx, onerror)                                       \
+    JS_BEGIN_MACRO                                                            \
+        int stackDummy_;                                                      \
+                                                                              \
+        if (!JS_CHECK_STACK_SIZE(cx->stackLimit, &stackDummy_)) {             \
+            js_ReportOverRecursed(cx);                                        \
+            onerror;                                                          \
+        }                                                                     \
+    JS_END_MACRO
+
 /*
  * Report an exception using a previously composed JSErrorReport.
  * XXXbe remove from "friend" API
  */
 extern JS_FRIEND_API(void)
 js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
 
 extern void
@@ -1887,16 +2120,19 @@ js_GetCurrentBytecodePC(JSContext* cx);
 extern JSScript *
 js_GetCurrentScript(JSContext* cx);
 
 extern bool
 js_CurrentPCIsInImacro(JSContext *cx);
 
 namespace js {
 
+extern JS_FORCES_STACK JS_FRIEND_API(void)
+LeaveTrace(JSContext *cx);
+
 extern bool
 CanLeaveTrace(JSContext *cx);
 
 #ifdef JS_METHODJIT
 namespace mjit {
     void ExpandInlineFrames(JSCompartment *compartment);
 }
 #endif
@@ -1944,16 +2180,41 @@ ClearValueRange(Value *vec, uintN len, b
             vec[i].setMagic(JS_ARRAY_HOLE);
     } else {
         for (uintN i = 0; i < len; i++)
             vec[i].setUndefined();
     }
 }
 
 static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(Value *vec, size_t len)
+{
+    PodZero(vec, len);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(Value *beg, Value *end)
+{
+    PodZero(beg, end - beg);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(jsid *beg, jsid *end)
+{
+    for (jsid *id = beg; id != end; ++id)
+        *id = INT_TO_JSID(0);
+}
+
+static JS_ALWAYS_INLINE void
+MakeRangeGCSafe(jsid *vec, size_t len)
+{
+    MakeRangeGCSafe(vec, vec + len);
+}
+
+static JS_ALWAYS_INLINE void
 MakeRangeGCSafe(const Shape **beg, const Shape **end)
 {
     PodZero(beg, end - beg);
 }
 
 static JS_ALWAYS_INLINE void
 MakeRangeGCSafe(const Shape **vec, size_t len)
 {
@@ -1981,52 +2242,157 @@ SetValueRangeToNull(Value *beg, Value *e
 }
 
 static JS_ALWAYS_INLINE void
 SetValueRangeToNull(Value *vec, size_t len)
 {
     SetValueRangeToNull(vec, vec + len);
 }
 
+template<class T>
+class AutoVectorRooter : protected AutoGCRooter
+{
+  public:
+    explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
+                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
+        : AutoGCRooter(cx, tag), vector(cx)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    size_t length() const { return vector.length(); }
+
+    bool append(const T &v) { return vector.append(v); }
+
+    /* For use when space has already been reserved. */
+    void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
+
+    void popBack() { vector.popBack(); }
+    T popCopy() { return vector.popCopy(); }
+
+    bool growBy(size_t inc) {
+        size_t oldLength = vector.length();
+        if (!vector.growByUninitialized(inc))
+            return false;
+        MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
+        return true;
+    }
+
+    bool resize(size_t newLength) {
+        size_t oldLength = vector.length();
+        if (newLength <= oldLength) {
+            vector.shrinkBy(oldLength - newLength);
+            return true;
+        }
+        if (!vector.growByUninitialized(newLength - oldLength))
+            return false;
+        MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
+        return true;
+    }
+
+    void clear() { vector.clear(); }
+
+    bool reserve(size_t newLength) {
+        return vector.reserve(newLength);
+    }
+
+    T &operator[](size_t i) { return vector[i]; }
+    const T &operator[](size_t i) const { return vector[i]; }
+
+    const T *begin() const { return vector.begin(); }
+    T *begin() { return vector.begin(); }
+
+    const T *end() const { return vector.end(); }
+    T *end() { return vector.end(); }
+
+    const T &back() const { return vector.back(); }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
+  private:
+    typedef Vector<T, 8> VectorImpl;
+    VectorImpl vector;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoValueVector : public AutoVectorRooter<Value>
+{
+  public:
+    explicit AutoValueVector(JSContext *cx
+                             JS_GUARD_OBJECT_NOTIFIER_PARAM)
+        : AutoVectorRooter<Value>(cx, VALVECTOR)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    const jsval *jsval_begin() const { return begin(); }
+    jsval *jsval_begin() { return begin(); }
+
+    const jsval *jsval_end() const { return end(); }
+    jsval *jsval_end() { return end(); }
+
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoObjectVector : public AutoVectorRooter<JSObject *>
+{
+  public:
+    explicit AutoObjectVector(JSContext *cx
+                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
+        : AutoVectorRooter<JSObject *>(cx, OBJVECTOR)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class AutoIdVector : public AutoVectorRooter<jsid>
+{
+  public:
+    explicit AutoIdVector(JSContext *cx
+                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
+        : AutoVectorRooter<jsid>(cx, IDVECTOR)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
 class AutoShapeVector : public AutoVectorRooter<const Shape *>
 {
   public:
     explicit AutoShapeVector(JSContext *cx
                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoVectorRooter<const Shape *>(cx)
+        : AutoVectorRooter<const Shape *>(cx, SHAPEVECTOR)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-  protected:
-    virtual void trace(JSTracer *trc);
 };
 
 class AutoValueArray : public AutoGCRooter
 {
     js::Value *start_;
     unsigned length_;
 
   public:
     AutoValueArray(JSContext *cx, js::Value *start, unsigned length
                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoGCRooter(cx), start_(start), length_(length)
+        : AutoGCRooter(cx, VALARRAY), start_(start), length_(length)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     Value *start() const { return start_; }
     unsigned length() const { return length_; }
 
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-  protected:
-    virtual void trace(JSTracer *trc);
 };
 
 JSIdArray *
 NewIdArray(JSContext *cx, jsint length);
 
 /*
  * Allocation policy that uses JSRuntime::malloc_ and friends, so that
  * memory pressure is properly accounted for. This is suitable for
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=4 sw=4 et tw=78:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
@@ -97,30 +97,29 @@ GetGlobalForScopeChain(JSContext *cx)
 inline GSNCache *
 GetGSNCache(JSContext *cx)
 {
     return &JS_THREAD_DATA(cx)->gsnCache;
 }
 
 class AutoNamespaceArray : protected AutoGCRooter {
   public:
-    AutoNamespaceArray(JSContext *cx) : AutoGCRooter(cx) {
+    AutoNamespaceArray(JSContext *cx) : AutoGCRooter(cx, NAMESPACES) {
         array.init();
     }
 
     ~AutoNamespaceArray() {
         array.finish(context);
     }
 
     uint32 length() const { return array.length; }
 
-  protected:
-    virtual void trace(JSTracer *trc);
+  public:
+    friend void AutoGCRooter::trace(JSTracer *trc);
 
-  public:
     JSXMLArray array;
 };
 
 #ifdef DEBUG
 class CompartmentChecker
 {
   private:
     JSContext *context;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -314,61 +314,8 @@ js::DumpHeapComplete(JSContext *cx, FILE
         fprintf(fp, "%p %s\n", dci.node, dtrc.buffer);
         JS_TraceChildren(&dtrc, dci.node, dci.kind);
     }
 
     dtrc.visited.finish();
 }
 
 #endif
-
-JS_FRIEND_API(JSBool)
-JS_DateIsValid(JSContext *cx, JSObject* obj)
-{
-    return js_DateIsValid(cx, obj);
-}
-
-JS_FRIEND_API(jsdouble)
-JS_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
-{
-    return js_DateGetMsecSinceEpoch(cx, obj);
-}
-
-JS_FRIEND_API(JSBool)
-JS_WasLastGCCompartmental(JSContext *cx)
-{
-    return cx->runtime->wasCompartmentGC;
-}
-
-JS_FRIEND_API(JSVersion)
-JS_VersionSetXML(JSVersion version, JSBool enable)
-{
-    js::VersionSetXML(&version, enable);
-    return version;
-}
-
-JS_FRIEND_API(JSBool)
-JS_IsContextRunningJS(JSContext *cx)
-{
-    return !cx->stack.empty();
-}
-
-#ifdef JS_THREADSAFE
-AutoSkipConservativeScan::AutoSkipConservativeScan(JSContext *cx
-                                                   JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
-  : context(cx)
-{
-    JS_GUARD_OBJECT_NOTIFIER_INIT;
-
-    js::ThreadData &threadData = context->thread()->data;
-    JS_ASSERT(threadData.requestDepth >= 1);
-    JS_ASSERT(!threadData.conservativeGC.requestThreshold);
-    if(threadData.requestDepth == 1)
-        threadData.conservativeGC.requestThreshold = 1;
-}
-
-AutoSkipConservativeScan::~AutoSkipConservativeScan()
-{
-    js::ThreadData &threadData = context->thread()->data;
-    if(threadData.requestDepth == 1)
-        threadData.conservativeGC.requestThreshold = 0;
-}
-#endif
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -39,21 +39,16 @@
 
 #ifndef jsfriendapi_h___
 #define jsfriendapi_h___
 
 #include "jsclass.h"
 #include "jspubtd.h"
 #include "jsprvtd.h"
 
-#ifdef __cplusplus
-#include "jsatom.h"
-#include "js/Vector.h"
-#endif
-
 JS_BEGIN_EXTERN_C
 
 extern JS_FRIEND_API(void)
 JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
 
 extern JS_FRIEND_API(JSString *)
 JS_GetAnonymousString(JSRuntime *rt);
 
@@ -132,19 +127,16 @@ extern JS_FRIEND_API(JSObject *)
 JS_ObjectToOuterObject(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(JSObject *)
 JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent);
 
 extern JS_FRIEND_API(JSBool)
 js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
 
-JS_FRIEND_API(void)
-js_ReportOverRecursed(JSContext *maybecx);
-
 #ifdef __cplusplus
 
 extern JS_FRIEND_API(bool)
 JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj);
 
 extern JS_FRIEND_API(JSBool)
 JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
 
@@ -200,18 +192,16 @@ JS_FRIEND_API(JSBool) obj_defineSetter(J
  * Check whether it is OK to assign an undeclared property with name
  * propname of the global object in the current script on cx.  Reports
  * an error if one needs to be reported (in particular in all cases
  * when it returns false).
  */
 extern JS_FRIEND_API(bool)
 CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
 
-typedef js::Vector<JSCompartment *, 0, js::SystemAllocPolicy> CompartmentVector;
-
 /*
  * Shadow declarations of JS internal structures, for access by inline access
  * functions below. Do not use these structures in any other way. When adding
  * new fields for access by inline methods, make sure to add static asserts to
  * the original header file to ensure that offsets are consistent.
  */
 namespace shadow {
 
@@ -236,44 +226,16 @@ struct Object {
     js::Value &slotRef(size_t slot) const {
         size_t nfixed = flags >> FIXED_SLOTS_SHIFT;
         if (slot < nfixed)
             return ((Value *)((jsuword) this + sizeof(shadow::Object)))[slot];
         return slots[slot - nfixed];
     }
 };
 
-struct Context {
-    JS::AutoGCRooter *autoGCRooters;
-    void *data;
-    void *data2;
-#ifdef JS_THREADSAFE
-    JSThread *thread_;
-#endif
-    JSCompartment *compartment;
-    JSObject *globalObject;
-    JSRuntime *runtime;
-    jsuword stackLimit;
-#ifdef JS_THREADSAFE
-    unsigned outstandingRequests;
-#endif
-    JSDebugHooks *debugHooks;
-};
-
-struct Thread {
-    void *id;
-};
-
-struct Runtime {
-    JSAtomState atomState;
-    JSCompartment *atomsCompartment;
-    js::CompartmentVector compartments;
-    JSStructuredCloneCallbacks *structuredCloneCallbacks;
-};
-
 } /* namespace shadow */
 
 extern JS_FRIEND_DATA(js::Class) AnyNameClass;
 extern JS_FRIEND_DATA(js::Class) AttributeNameClass;
 extern JS_FRIEND_DATA(js::Class) CallClass;
 extern JS_FRIEND_DATA(js::Class) DeclEnvClass;
 extern JS_FRIEND_DATA(js::Class) FunctionClass;
 extern JS_FRIEND_DATA(js::Class) FunctionProxyClass;
@@ -394,317 +356,12 @@ StringIsArrayIndex(JSLinearString *str, 
 #define JSITER_FOREACH    0x2   /* return [key, value] pair rather than key */
 #define JSITER_KEYVALUE   0x4   /* destructuring for-in wants [key, value] */
 #define JSITER_OWNONLY    0x8   /* iterate over obj's own properties only */
 #define JSITER_HIDDEN     0x10  /* also enumerate non-enumerable properties */
 
 /* When defining functions, JSFunctionSpec::call points to a JSNativeTraceInfo. */
 #define JSFUN_TRCINFO     0x2000
 
-static inline void *
-GetContextPrivate(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->data;
-}
-
-static inline void *
-GetContextPrivate2(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->data2;
-}
-
-static inline void
-SetContextPrivate2(JSContext *cx, void *data)
-{
-    reinterpret_cast<js::shadow::Context *>(cx)->data2 = data;
-}
-
-#ifdef JS_THREADSAFE
-static inline JSThread *
-GetContextThread(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->thread_;
-}
-
-static inline void *
-GetContextThreadId(JSContext *cx)
-{
-    JSThread *th = GetContextThread(cx);
-    return reinterpret_cast<js::shadow::Thread *>(th)->id;
-}
-#endif
-
-static inline JSCompartment *
-GetContextCompartment(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->compartment;
-}
-
-static inline JSObject *
-GetContextGlobalObject(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->globalObject;
-}
-
-static inline void
-SetContextGlobalObject(JSContext *cx, JSObject *obj)
-{
-    reinterpret_cast<js::shadow::Context *>(cx)->globalObject = obj;
-}
-
-static inline JSRuntime *
-GetContextRuntime(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->runtime;
-}
-
-static inline jsuword
-GetContextStackLimit(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->stackLimit;
-}
-
-#ifdef JS_THREADSAFE
-static inline unsigned
-GetContextOutstandingRequests(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->outstandingRequests;
-}
-#endif
-
-static inline JSDebugHooks *
-GetContextDebugHooks(JSContext *cx)
-{
-    return reinterpret_cast<js::shadow::Context *>(cx)->debugHooks;
-}
-
-static inline JSString *
-GetEmptyAtom(JSContext *cx)
-{
-    JSRuntime *rt = js::GetContextRuntime(cx);
-    return (JSString *)reinterpret_cast<js::shadow::Runtime *>(rt)->atomState.emptyAtom;
-}
-
-static inline CompartmentVector &
-GetRuntimeCompartments(JSRuntime *rt)
-{
-    return reinterpret_cast<js::shadow::Runtime *>(rt)->compartments;
-}
-
-static inline JSStructuredCloneCallbacks *
-GetRuntimeStructuredCloneCallbacks(JSRuntime *rt)
-{
-    return reinterpret_cast<js::shadow::Runtime *>(rt)->structuredCloneCallbacks;
-}
-
-#define JS_CHECK_RECURSION(cx, onerror)                                       \
-    JS_BEGIN_MACRO                                                            \
-        int stackDummy_;                                                      \
-                                                                              \
-        if (!JS_CHECK_STACK_SIZE(js::GetContextStackLimit(cx), &stackDummy_)) { \
-            js_ReportOverRecursed(cx);                                        \
-            onerror;                                                          \
-        }                                                                     \
-    JS_END_MACRO
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(Value *vec, size_t len)
-{
-    JS_ASSERT(vec <= vec + len);
-    PodZero(vec, len);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(Value *beg, Value *end)
-{
-    JS_ASSERT(beg <= end);
-    PodZero(beg, end - beg);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(jsid *beg, jsid *end)
-{
-    JS_ASSERT(beg <= end);
-    for (jsid *id = beg; id < end; ++id)
-        *id = INT_TO_JSID(0);
-}
-
-static JS_ALWAYS_INLINE void
-MakeRangeGCSafe(jsid *vec, size_t len)
-{
-    MakeRangeGCSafe(vec, vec + len);
-}
-
-template<class T>
-class AutoVectorRooter : protected AutoGCRooter
-{
-  public:
-    explicit AutoVectorRooter(JSContext *cx
-                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoGCRooter(cx), vector(cx)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    size_t length() const { return vector.length(); }
-
-    bool append(const T &v) { return vector.append(v); }
-
-    /* For use when space has already been reserved. */
-    void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
-
-    void popBack() { vector.popBack(); }
-    T popCopy() { return vector.popCopy(); }
-
-    bool growBy(size_t inc) {
-        size_t oldLength = vector.length();
-        if (!vector.growByUninitialized(inc))
-            return false;
-        MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
-        return true;
-    }
-
-    bool resize(size_t newLength) {
-        size_t oldLength = vector.length();
-        if (newLength <= oldLength) {
-            vector.shrinkBy(oldLength - newLength);
-            return true;
-        }
-        if (!vector.growByUninitialized(newLength - oldLength))
-            return false;
-        MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
-        return true;
-    }
-
-    void clear() { vector.clear(); }
-
-    bool reserve(size_t newLength) {
-        return vector.reserve(newLength);
-    }
-
-    T &operator[](size_t i) { return vector[i]; }
-    const T &operator[](size_t i) const { return vector[i]; }
-
-    const T *begin() const { return vector.begin(); }
-    T *begin() { return vector.begin(); }
-
-    const T *end() const { return vector.end(); }
-    T *end() { return vector.end(); }
-
-    const T &back() const { return vector.back(); }
-
-  protected:
-    typedef Vector<T, 8> VectorImpl;
-    VectorImpl vector;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoValueVector : public AutoVectorRooter<Value>
-{
-  public:
-    explicit AutoValueVector(JSContext *cx
-                             JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoVectorRooter<Value>(cx)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    const jsval *jsval_begin() const { return begin(); }
-    jsval *jsval_begin() { return begin(); }
-
-    const jsval *jsval_end() const { return end(); }
-    jsval *jsval_end() { return end(); }
-
-  protected:
-    virtual JS_FRIEND_API(void) trace(JSTracer *trc);
-
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoObjectVector : public AutoVectorRooter<JSObject *>
-{
-  public:
-    explicit AutoObjectVector(JSContext *cx
-                              JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoVectorRooter<JSObject *>(cx)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-  protected:
-    virtual JS_FRIEND_API(void) trace(JSTracer *trc);
-
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-class AutoIdVector : public AutoVectorRooter<jsid>
-{
-  public:
-    explicit AutoIdVector(JSContext *cx
-                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : AutoVectorRooter<jsid>(cx)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-  protected:
-    virtual JS_FRIEND_API(void) trace(JSTracer *trc);
-
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-#ifdef JS_THREADSAFE
-class JS_FRIEND_API(AutoSkipConservativeScan)
-{
-  public:
-    AutoSkipConservativeScan(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM);
-    ~AutoSkipConservativeScan();
-
-  private:
-    JSContext *context;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-#endif
-
-extern JS_FORCES_STACK JS_FRIEND_API(void)
-LeaveTrace(JSContext *cx);
-
 } /* namespace js */
 #endif
 
-/*
- * Report an exception, which is currently realized as a printf-style format
- * string and its arguments.
- */
-typedef enum JSErrNum {
-#define MSG_DEF(name, number, count, exception, format) \
-    name = number,
-#include "js.msg"
-#undef MSG_DEF
-    JSErr_Limit
-} JSErrNum;
-
-extern JS_FRIEND_API(const JSErrorFormatString *)
-js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
-
-/*
- * Detect whether the internal date value is NaN.  (Because failure is
- * out-of-band for js_DateGet*)
- */
-extern JS_FRIEND_API(JSBool)
-JS_DateIsValid(JSContext *cx, JSObject* obj);
-
-extern JS_FRIEND_API(jsdouble)
-JS_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj);
-
-extern JS_FRIEND_API(JSBool)
-JS_WasLastGCCompartmental(JSContext *cx);
-
-extern JS_FRIEND_API(JSUint64)
-JS_GetSCOffset(JSStructuredCloneWriter* writer);
-
-extern JS_FRIEND_API(JSVersion)
-JS_VersionSetXML(JSVersion version, JSBool enable);
-
-extern JS_FRIEND_API(JSBool)
-JS_IsContextRunningJS(JSContext *cx);
-
 #endif /* jsfriendapi_h___ */
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1786,148 +1786,149 @@ js_TraceStackFrame(JSTracer *trc, StackF
     MarkScript(trc, fp->script(), "script");
     fp->script()->compartment()->active = true;
     MarkValue(trc, fp->returnValue(), "rval");
 }
 
 void
 AutoIdArray::trace(JSTracer *trc)
 {
+    JS_ASSERT(tag == IDARRAY);
     gc::MarkIdRange(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray");
 }
 
 void
 AutoEnumStateRooter::trace(JSTracer *trc)
 {
     gc::MarkObject(trc, *obj, "js::AutoEnumStateRooter.obj");
 }
 
-void
-AutoValueRooter::trace(JSTracer *trc)
-{
-    MarkValue(trc, val, "js::AutoValueRooter.val");
-}
-
-void
-AutoPropDescArrayRooter::trace(JSTracer *trc)
-{
-    for (size_t i = 0, len = descriptors.length(); i < len; i++) {
-        PropDesc &desc = descriptors[i];
-        MarkValue(trc, desc.pd, "PropDesc::pd");
-        MarkValue(trc, desc.value, "PropDesc::value");
-        MarkValue(trc, desc.get, "PropDesc::get");
-        MarkValue(trc, desc.set, "PropDesc::set");
-    }
-}
-
-void
-AutoPropertyDescriptorRooter::trace(JSTracer *trc)
-{
-    if (obj)
-        MarkObject(trc, *obj, "Descriptor::obj");
-    MarkValue(trc, value, "Descriptor::value");
-    if ((attrs & JSPROP_GETTER) && getter)
-        MarkObject(trc, *CastAsObject(getter), "Descriptor::get");
-    if (attrs & JSPROP_SETTER && setter)
-        MarkObject(trc, *CastAsObject(setter), "Descriptor::set");
-}
-
-void
-AutoNamespaceArray::trace(JSTracer *trc)
-{
-    MarkObjectRange(trc, array.length, reinterpret_cast<JSObject **>(array.vector),
-                    "JSXMLArray.vector");
-    array.cursors->trace(trc);
-}
-
-void
-AutoXMLRooter::trace(JSTracer *trc)
-{
-    js_TraceXML(trc, xml);
-}
-
-void
-AutoObjectRooter::trace(JSTracer *trc)
+inline void
+AutoGCRooter::trace(JSTracer *trc)
 {
-    if (obj)
-        MarkObject(trc, *obj, "js::AutoObjectRooter.obj");
-}
-
-void
-AutoIdRooter::trace(JSTracer *trc)
-{
-    MarkId(trc, id_, "js::AutoIdRooter.val");
-}
-
-void
-AutoValueVector::trace(JSTracer *trc)
-{
-    MarkValueRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
-}
-
-void
-AutoStringRooter::trace(JSTracer *trc)
-{
-    if (str)
-        MarkString(trc, str, "js::AutoStringRooter.str");
-}
-
-void
-AutoIdVector::trace(JSTracer *trc)
-{
-    MarkIdRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
-}
-
-void
-AutoShapeVector::trace(JSTracer *trc)
-{
-    MarkShapeRange(trc, vector.length(), vector.begin(), "js::AutoShapeVector.vector");
-}
-
-void
-AutoObjectVector::trace(JSTracer *trc)
-{
-    MarkObjectRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
-}
-
-void
-AutoValueArray::trace(JSTracer *trc)
-{
-    MarkValueRange(trc, length(), start(), "js::AutoValueArray");
-}
-
-void
-AutoArrayRooter::trace(JSTracer *trc)
-{
-    MarkValueRange(trc, length, array, "js::AutoArrayRooter.array");
-}
-
-void
-AutoGCRooter::traceAll(JSTracer *trc)
-{
-    trace(trc);
-    if (down)
-        down->traceAll(trc);
+    switch (tag) {
+      case JSVAL:
+        MarkValue(trc, static_cast<AutoValueRooter *>(this)->val, "js::AutoValueRooter.val");
+        return;
+
+      case PARSER:
+        static_cast<Parser *>(this)->trace(trc);
+        return;
+
+      case ENUMERATOR:
+        static_cast<AutoEnumStateRooter *>(this)->trace(trc);
+        return;
+
+      case IDARRAY: {
+        JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
+        MarkIdRange(trc, ida->length, ida->vector, "js::AutoIdArray.idArray");
+        return;
+      }
+
+      case DESCRIPTORS: {
+        PropDescArray &descriptors =
+            static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
+        for (size_t i = 0, len = descriptors.length(); i < len; i++) {
+            PropDesc &desc = descriptors[i];
+            MarkValue(trc, desc.pd, "PropDesc::pd");
+            MarkValue(trc, desc.value, "PropDesc::value");
+            MarkValue(trc, desc.get, "PropDesc::get");
+            MarkValue(trc, desc.set, "PropDesc::set");
+        }
+        return;
+      }
+
+      case DESCRIPTOR : {
+        PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this);
+        if (desc.obj)
+            MarkObject(trc, *desc.obj, "Descriptor::obj");
+        MarkValue(trc, desc.value, "Descriptor::value");
+        if ((desc.attrs & JSPROP_GETTER) && desc.getter)
+            MarkObject(trc, *CastAsObject(desc.getter), "Descriptor::get");
+        if (desc.attrs & JSPROP_SETTER && desc.setter)
+            MarkObject(trc, *CastAsObject(desc.setter), "Descriptor::set");
+        return;
+      }
+
+      case NAMESPACES: {
+        JSXMLArray &array = static_cast<AutoNamespaceArray *>(this)->array;
+        MarkObjectRange(trc, array.length, reinterpret_cast<JSObject **>(array.vector),
+                        "JSXMLArray.vector");
+        array.cursors->trace(trc);
+        return;
+      }
+
+      case XML:
+        js_TraceXML(trc, static_cast<AutoXMLRooter *>(this)->xml);
+        return;
+
+      case OBJECT:
+        if (JSObject *obj = static_cast<AutoObjectRooter *>(this)->obj)
+            MarkObject(trc, *obj, "js::AutoObjectRooter.obj");
+        return;
+
+      case ID:
+        MarkId(trc, static_cast<AutoIdRooter *>(this)->id_, "js::AutoIdRooter.val");
+        return;
+
+      case VALVECTOR: {
+        AutoValueVector::VectorImpl &vector = static_cast<AutoValueVector *>(this)->vector;
+        MarkValueRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
+        return;
+      }
+
+      case STRING:
+        if (JSString *str = static_cast<AutoStringRooter *>(this)->str)
+            MarkString(trc, str, "js::AutoStringRooter.str");
+        return;
+
+      case IDVECTOR: {
+        AutoIdVector::VectorImpl &vector = static_cast<AutoIdVector *>(this)->vector;
+        MarkIdRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
+        return;
+      }
+
+      case SHAPEVECTOR: {
+        AutoShapeVector::VectorImpl &vector = static_cast<js::AutoShapeVector *>(this)->vector;
+        MarkShapeRange(trc, vector.length(), vector.begin(), "js::AutoShapeVector.vector");
+        return;
+      }
+
+      case OBJVECTOR: {
+        AutoObjectVector::VectorImpl &vector = static_cast<AutoObjectVector *>(this)->vector;
+        MarkObjectRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
+        return;
+      }
+
+      case VALARRAY: {
+        AutoValueArray *array = static_cast<AutoValueArray *>(this);
+        MarkValueRange(trc, array->length(), array->start(), "js::AutoValueArray");
+        return;
+      }
+    }
+
+    JS_ASSERT(tag >= 0);
+    MarkValueRange(trc, tag, static_cast<AutoArrayRooter *>(this)->array, "js::AutoArrayRooter.array");
 }
 
 namespace js {
 
 JS_FRIEND_API(void)
 MarkContext(JSTracer *trc, JSContext *acx)
 {
     /* Stack frames and slots are traced by StackSpace::mark. */
 
     /* Mark other roots-by-definition in acx. */
     if (acx->globalObject && !acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL))
         MarkObject(trc, *acx->globalObject, "global object");
     if (acx->isExceptionPending())
         MarkValue(trc, acx->getPendingException(), "exception");
 
-    if (acx->autoGCRooters)
-        acx->autoGCRooters->traceAll(trc);
+    for (js::AutoGCRooter *gcr = acx->autoGCRooters; gcr; gcr = gcr->down)
+        gcr->trace(trc);
 
     if (acx->sharpObjectMap.depth > 0)
         js_TraceSharpMap(trc, &acx->sharpObjectMap);
 
     MarkValue(trc, acx->iterValue, "iterValue");
 }
 
 JS_REQUIRES_STACK void
@@ -2772,17 +2773,16 @@ GCCycle(JSContext *cx, JSCompartment *co
     /*
      * We should not be depending on cx->compartment in the GC, so set it to
      * NULL to look for violations.
      */
     SwitchToCompartment sc(cx, (JSCompartment *)NULL);
 
     JS_ASSERT(!rt->gcCurrentCompartment);
     rt->gcCurrentCompartment = comp;
-    rt->wasCompartmentGC = !!comp;
 
     rt->gcMarkAndSweep = true;
 
 #ifdef JS_THREADSAFE
     /*
      * As we about to purge caches and clear the mark bits we must wait for
      * any background finalization to finish. We must also wait for the
      * background allocation to finish so we can avoid taking the GC lock
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sw=4 et tw=99:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
@@ -1319,59 +1319,58 @@ js_UnwrapWithObject(JSContext *cx, JSObj
 }
 
 namespace js {
 
 class AutoPropDescArrayRooter : private AutoGCRooter
 {
   public:
     AutoPropDescArrayRooter(JSContext *cx)
-      : AutoGCRooter(cx), descriptors(cx)
+      : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx)
     { }
 
     PropDesc *append() {
         if (!descriptors.append(PropDesc()))
             return NULL;
         return &descriptors.back();
     }
 
     PropDesc& operator[](size_t i) {
         JS_ASSERT(i < descriptors.length());
         return descriptors[i];
     }
 
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
   private:
-    virtual void trace(JSTracer *trc);
-
     PropDescArray descriptors;
 };
 
 class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescriptor
 {
   public:
-    AutoPropertyDescriptorRooter(JSContext *cx) : AutoGCRooter(cx) {
+    AutoPropertyDescriptorRooter(JSContext *cx) : AutoGCRooter(cx, DESCRIPTOR) {
         obj = NULL;
         attrs = 0;
         getter = (PropertyOp) NULL;
         setter = (StrictPropertyOp) NULL;
         value.setUndefined();
     }
 
     AutoPropertyDescriptorRooter(JSContext *cx, PropertyDescriptor *desc)
-      : AutoGCRooter(cx)
+      : AutoGCRooter(cx, DESCRIPTOR)
     {
         obj = desc->obj;
         attrs = desc->attrs;
         getter = desc->getter;
         setter = desc->setter;
         value = desc->value;
     }
 
-  private:
-    virtual void trace(JSTracer *trc);
+    friend void AutoGCRooter::trace(JSTracer *trc);
 };
 
 static inline bool
 InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, js::types::TypeObject *type,
                    gc::AllocKind kind)
 {
     JS_ASSERT(clasp->isNative());
 
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -38,16 +38,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsproxy_h___
 #define jsproxy_h___
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsfriendapi.h"
 
 namespace js {
 
 /* Base class for all C++ proxy handlers. */
 class JS_FRIEND_API(ProxyHandler) {
     void *mFamily;
   public:
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -42,18 +42,16 @@
 #ifndef jswrapper_h___
 #define jswrapper_h___
 
 #include "jsapi.h"
 #include "jsproxy.h"
 
 namespace js {
 
-class DummyFrameGuard;
-
 /* No-op wrapper handler base class. */
 class JS_FRIEND_API(Wrapper) : public ProxyHandler
 {
     uintN mFlags;
   public:
     uintN flags() const { return mFlags; }
 
     explicit Wrapper(uintN flags);
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -54,16 +54,17 @@
 #include "nsDependentString.h"
 #include "nsAutoPtr.h"
 #include "nsNetUtil.h"
 #include "nsIProtocolHandler.h"
 #include "nsIFileURL.h"
 #include "nsScriptLoader.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 
 using namespace mozilla::scache;
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -45,16 +45,17 @@
 
 /* XPConnect JavaScript interactive shell. */
 
 #include <stdio.h>
 
 #include "mozilla/Util.h"
 
 #include "jsapi.h"
+#include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 #include "jsprf.h"
 #include "nsXULAppAPI.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsStringAPI.h"
 #include "nsIXPConnect.h"
@@ -539,19 +540,22 @@ DumpXPC(JSContext *cx, uintN argc, jsval
         xpc->DebugDump((int16)depth);
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
 GC(JSContext *cx, uintN argc, jsval *vp)
 {
+    JSRuntime *rt;
+
+    rt = cx->runtime;
     JS_GC(cx);
 #ifdef JS_GCMETER
-    js_DumpGCStats(JS_GetRuntime(cx), stdout);
+    js_DumpGCStats(rt, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 #ifdef JS_GC_ZEAL
 static JSBool
 GCZeal(JSContext *cx, uintN argc, jsval *vp)
@@ -996,19 +1000,19 @@ JSErrorFormatString jsShell_ErrorFormatS
 #include "jsshell.msg"
 #undef MSG_DEF
 };
 
 static const JSErrorFormatString *
 my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
 {
     if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
-        return &jsShell_ErrorFormatString[errorNumber];
-    JS_NOT_REACHED("invalid error number");
-    return NULL;
+            return &jsShell_ErrorFormatString[errorNumber];
+        else
+            return NULL;
 }
 
 static void
 ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
             JSBool forceTTY)
 {
     JSScript *script;
     jsval result;
--- a/js/xpconnect/src/XPCContext.cpp
+++ b/js/xpconnect/src/XPCContext.cpp
@@ -54,25 +54,25 @@ XPCContext::XPCContext(XPCJSRuntime* aRu
         mException(nsnull),
         mCallingLangType(LANG_UNKNOWN),
         mSecurityManagerFlags(0)
 {
     MOZ_COUNT_CTOR(XPCContext);
 
     PR_INIT_CLIST(&mScopes);
 
-    NS_ASSERTION(!js::GetContextPrivate2(mJSContext), "Must be null");
-    js::SetContextPrivate2(mJSContext, this);
+    NS_ASSERTION(!mJSContext->data2, "Must be null");
+    mJSContext->data2 = this;
 }
 
 XPCContext::~XPCContext()
 {
     MOZ_COUNT_DTOR(XPCContext);
-    NS_ASSERTION(js::GetContextPrivate2(mJSContext) == this, "Must match this");
-    js::SetContextPrivate2(mJSContext, nsnull);
+    NS_ASSERTION(mJSContext->data2 == this, "Must match this");
+    mJSContext->data2 = nsnull;
     NS_IF_RELEASE(mException);
     NS_IF_RELEASE(mSecurityManager);
 
     // Iterate over our scopes and tell them that we have been destroyed
     for (PRCList *scopeptr = PR_NEXT_LINK(&mScopes);
          scopeptr != &mScopes;
          scopeptr = PR_NEXT_LINK(scopeptr)) {
         XPCWrappedNativeScope *scope = (XPCWrappedNativeScope *)scopeptr;
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -248,17 +248,17 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
     NS_PRECONDITION(s, "bad param");
     NS_PRECONDITION(d, "bad param");
 
    JSContext* cx = lccx.GetJSContext();
 
     // Allow wrong compartment or unset ScopeForNewObject when the caller knows
     // the value is primitive (viz., XPCNativeMember::GetConstantValue).
     NS_ABORT_IF_FALSE(type.IsArithmetic() ||
-                      js::GetContextCompartment(cx) == js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()),
+                      cx->compartment == js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()),
                       "bad scope for new JSObjects");
 
     if (pErr)
         *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
 
     switch (type.TagPart()) {
     case nsXPTType::T_I8    : *d = INT_TO_JSVAL((int32)*((int8*)s));                 break;
     case nsXPTType::T_I16   : *d = INT_TO_JSVAL((int32)*((int16*)s));                break;
@@ -1056,18 +1056,17 @@ XPCConvert::NativeInterface2JSObject(XPC
     // We used to have code here that unwrapped and simply exposed the
     // underlying JSObject. That caused anomolies when JSComponents were
     // accessed from other JS code - they didn't act like other xpconnect
     // wrapped components. So, instead, we create "double wrapped" objects
     // (that means an XPCWrappedNative around an nsXPCWrappedJS). This isn't
     // optimal -- we could detect this and roll the functionality into a
     // single wrapper, but the current solution is good enough for now.
     JSContext* cx = lccx.GetJSContext();
-    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) ==
-                      js::GetContextCompartment(cx),
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     JSObject *jsscope = lccx.GetScopeForNewJSObjects();
     XPCWrappedNativeScope* xpcscope =
         XPCWrappedNativeScope::FindInJSObjectScope(cx, jsscope);
     if (!xpcscope)
         return JS_FALSE;
 
@@ -1103,17 +1102,17 @@ XPCConvert::NativeInterface2JSObject(XPC
                 return CreateHolderIfNeeded(ccx, flat, d, dest);
             }
         }
 
         if (!dest) {
             if (!flat) {
                 tryConstructSlimWrapper = true;
             } else if (IS_SLIM_WRAPPER_OBJECT(flat)) {
-                if (js::GetObjectCompartment(flat) == js::GetContextCompartment(cx)) {
+                if (js::GetObjectCompartment(flat) == cx->compartment) {
                     *d = OBJECT_TO_JSVAL(flat);
                     return JS_TRUE;
                 }
             }
         }
     } else {
         flat = nsnull;
     }
@@ -1253,33 +1252,33 @@ XPCConvert::NativeInterface2JSObject(XPC
 
                 // Cache the location wrapper to ensure that we maintain
                 // the identity of window/document.location.
                 wrapper->SetWrapper(locationWrapper);
             }
 
             flat = locationWrapper;
         } else if (wrapper->NeedsSOW() &&
-                   !xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
+                   !xpc::AccessCheck::isChrome(cx->compartment)) {
             JSObject *sowWrapper = wrapper->GetWrapper();
             if (!sowWrapper) {
                 sowWrapper = xpc::WrapperFactory::WrapSOWObject(cx, flat);
                 if (!sowWrapper)
                     return JS_FALSE;
 
                 // Cache the sow wrapper to ensure that we maintain
                 // the identity of this node.
                 wrapper->SetWrapper(sowWrapper);
             }
 
             flat = sowWrapper;
         } else {
             flat = JS_ObjectToOuterObject(cx, flat);
             NS_ASSERTION(flat, "bad outer object hook!");
-            NS_ASSERTION(js::GetObjectCompartment(flat) == js::GetContextCompartment(cx),
+            NS_ASSERTION(js::GetObjectCompartment(flat) == cx->compartment,
                          "bad compartment");
         }
     }
 
     *d = OBJECT_TO_JSVAL(flat);
 
     if (dest) {
         // The strongWrapper still holds the original flat object.
@@ -1700,18 +1699,17 @@ XPCConvert::NativeArray2JS(XPCLazyCallCo
     NS_PRECONDITION(s, "bad param");
     NS_PRECONDITION(d, "bad param");
 
     XPCCallContext& ccx = lccx.GetXPCCallContext();
     if (!ccx.IsValid())
         return JS_FALSE;
 
     JSContext* cx = ccx.GetJSContext();
-    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) ==
-                      js::GetContextCompartment(cx),
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     // XXX add support for putting chars in a string rather than an array
 
     // XXX add support to indicate *which* array element was not convertable
 
     JSObject *array = JS_NewArrayObject(cx, count, nsnull);
 
--- a/js/xpconnect/src/XPCInlines.h
+++ b/js/xpconnect/src/XPCInlines.h
@@ -159,18 +159,17 @@ XPCCallContext::GetScopeForNewJSObjects(
     CHECK_STATE(HAVE_SCOPE);
     return mScopeForNewJSObjects;
 }
 
 inline void
 XPCCallContext::SetScopeForNewJSObjects(JSObject *scope)
 {
     NS_ABORT_IF_FALSE(mState == HAVE_CONTEXT, "wrong call context state");
-    NS_ABORT_IF_FALSE(js::GetObjectCompartment(scope) == js::GetContextCompartment(mJSContext),
-                      "wrong compartment");
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(scope) == mJSContext->compartment, "wrong compartment");
     mScopeForNewJSObjects = scope;
     mState = HAVE_SCOPE;
 }
 
 inline JSObject*
 XPCCallContext::GetFlattenedJSObject() const
 {
     CHECK_STATE(HAVE_OBJECT);
--- a/js/xpconnect/src/XPCString.cpp
+++ b/js/xpconnect/src/XPCString.cpp
@@ -82,18 +82,20 @@ XPCStringConvert::ReadableToJSVal(JSCont
                                   const nsAString &readable,
                                   nsStringBuffer** sharedBuffer)
 {
     JSString *str;
     *sharedBuffer = nsnull;
 
     PRUint32 length = readable.Length();
 
-    if (length == 0)
-        return STRING_TO_JSVAL(js::GetEmptyAtom(cx));
+    JSAtom *atom;
+    if (length == 0 && (atom = cx->runtime->atomState.emptyAtom)) {
+        return STRING_TO_JSVAL(atom);
+    }
 
     nsStringBuffer *buf = nsStringBuffer::FromString(readable);
     if (buf) {
         // yay, we can share the string's buffer!
 
         if (sDOMStringFinalizerIndex == -1) {
             sDOMStringFinalizerIndex =
                     JS_AddExternalStringFinalizer(DOMStringFinalizer);
--- a/js/xpconnect/src/XPCThreadContext.cpp
+++ b/js/xpconnect/src/XPCThreadContext.cpp
@@ -130,17 +130,17 @@ GetPrincipalFromCx(JSContext *cx)
     }
     return nsnull;
 }
 
 /* void push (in JSContext cx); */
 NS_IMETHODIMP
 XPCJSContextStack::Push(JSContext * cx)
 {
-    JS_ASSERT_IF(cx, js::GetContextThread(cx));
+    JS_ASSERT_IF(cx, JS_GetContextThread(cx));
     if (mStack.Length() > 0) {
         XPCJSContextInfo & e = mStack[mStack.Length() - 1];
         if (e.cx) {
             if (e.cx == cx) {
                 nsIScriptSecurityManager* ssm = XPCWrapper::GetSecurityManager();
                 if (ssm) {
                     if (nsIPrincipal* globalObjectPrincipal = GetPrincipalFromCx(cx)) {
                         nsIPrincipal* subjectPrincipal = ssm->GetCxSubjectPrincipal(cx);
@@ -434,17 +434,17 @@ XPCPerThreadData::GetDataImpl(JSContext 
         if (PR_FAILURE == PR_SetThreadPrivate(gTLSIndex, data)) {
             NS_ERROR("PR_SetThreadPrivate failed!");
             delete data;
             return nsnull;
         }
     }
 
     if (cx && !sMainJSThread && NS_IsMainThread()) {
-        sMainJSThread = js::GetContextThread(cx);
+        sMainJSThread = cx->thread();
 
         sMainThreadData = data;
 
         sMainThreadData->mThread = PR_GetCurrentThread();
     }
 
     return data;
 }
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -462,18 +462,17 @@ XPCVariant::VariantDataToJS(XPCLazyCallC
     nsAutoString astring;
     nsCAutoString cString;
     nsUTF8String utf8String;
     PRUint32 size;
     xpctvar.flags = 0;
     JSBool success;
 
     JSContext* cx = lccx.GetJSContext();
-    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) ==
-                      js::GetContextCompartment(cx),
+    NS_ABORT_IF_FALSE(js::GetObjectCompartment(lccx.GetScopeForNewJSObjects()) == cx->compartment,
                       "bad scope for new JSObjects");
 
     switch (type) {
         case nsIDataType::VTYPE_INT8:
         case nsIDataType::VTYPE_INT16:
         case nsIDataType::VTYPE_INT32:
         case nsIDataType::VTYPE_INT64:
         case nsIDataType::VTYPE_UINT8:
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -57,17 +57,17 @@ static uint32 zero_methods_descriptor;
 bool AutoScriptEvaluate::StartEvaluating(JSObject *scope, JSErrorReporter errorReporter)
 {
     NS_PRECONDITION(!mEvaluated, "AutoScriptEvaluate::Evaluate should only be called once");
 
     if (!mJSContext)
         return true;
 
     mEvaluated = true;
-    if (!JS_GetErrorReporter(mJSContext)) {
+    if (!mJSContext->errorReporter) {
         JS_SetErrorReporter(mJSContext, errorReporter);
         mErrorReporterSet = true;
     }
     mContextHasThread = JS_GetContextThread(mJSContext);
     if (mContextHasThread)
         JS_BeginRequest(mJSContext);
 
     if (!mEnterCompartment.enter(mJSContext, scope))
@@ -548,17 +548,17 @@ GetContextFromObject(JSObject *obj)
     if (!ac.enter(ccx, obj))
         return nsnull;
     XPCWrappedNativeScope* scope =
         XPCWrappedNativeScope::FindInJSObjectScope(ccx, obj);
     XPCContext *xpcc = scope->GetContext();
 
     if (xpcc) {
         JSContext *cx = xpcc->GetJSContext();
-        if (js::GetContextThreadId(cx) == js_CurrentThreadId())
+        if (cx->thread()->id == js_CurrentThreadId())
             return cx;
     }
 
     return nsnull;
 }
 
 class SameOriginCheckedComponent : public nsISecurityCheckedComponent
 {
@@ -1065,17 +1065,17 @@ nsXPCWrappedJSClass::CheckForException(X
                     !strcmp(aPropertyName, "getInterface")) {
                     reportable = false;
                 }
             }
 
             // Try to use the error reporter set on the context to handle this
             // error if it came from a JS exception.
             if (reportable && is_js_exception &&
-               JS_GetErrorReporter(cx) != xpcWrappedJSErrorReporter) {
+                cx->errorReporter != xpcWrappedJSErrorReporter) {
                 reportable = !JS_ReportPendingException(cx);
             }
 
             if (reportable) {
 #ifdef DEBUG
                 static const char line[] =
                     "************************************************************\n";
                 static const char preamble[] =
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -3666,17 +3666,17 @@ ConstructSlimWrapper(XPCCallContext &ccx
     JSObject* plannedParent = parent;
     rv = classInfoHelper->PreCreate(identityObj, ccx, parent, &parent);
     if (rv != NS_SUCCESS_ALLOW_SLIM_WRAPPERS) {
         SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused");
 
         return JS_FALSE;
     }
 
-    if (js::GetContextCompartment(ccx.GetJSContext()) != js::GetObjectCompartment(parent)) {
+    if (ccx.GetJSContext()->compartment != js::GetObjectCompartment(parent)) {
         SLIM_LOG_NOT_CREATED(ccx, identityObj, "wrong compartment");
 
         return JS_FALSE;
     }
 
     JSAutoEnterCompartment ac;
     if (!ac.enter(ccx, parent)) {
         SLIM_LOG_NOT_CREATED(ccx, identityObj, "unable to enter compartment");
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -396,18 +396,24 @@ nsXPConnect::Collect()
 
     JSContext *cx = ccx.GetJSContext();
 
     // We want to scan the current thread for GC roots only if it was in a
     // request prior to the Collect call to avoid false positives during the
     // cycle collection. So to compensate for JS_BeginRequest in
     // XPCCallContext::Init we disable the conservative scanner if that call
     // has started the request on this thread.
-    js::AutoSkipConservativeScan ascs(cx);
+    js::ThreadData &threadData = cx->thread()->data;
+    JS_ASSERT(threadData.requestDepth >= 1);
+    JS_ASSERT(!threadData.conservativeGC.requestThreshold);
+    if (threadData.requestDepth == 1)
+        threadData.conservativeGC.requestThreshold = 1;
     JS_GC(cx);
+    if (threadData.requestDepth == 1)
+        threadData.conservativeGC.requestThreshold = 0;
 }
 
 NS_IMETHODIMP
 nsXPConnect::GarbageCollect()
 {
     Collect();
     return NS_OK;
 }
@@ -599,17 +605,17 @@ xpc_GCThingIsGrayCCThing(void *thing)
  * black in step 2 above. This must be done on everything reachable from the
  * object being returned. The following code takes care of the recursive
  * re-coloring.
  */
 static void
 UnmarkGrayChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
 {
     int stackDummy;
-    if (!JS_CHECK_STACK_SIZE(js::GetContextStackLimit(trc->context), &stackDummy)) {
+    if (!JS_CHECK_STACK_SIZE(trc->context->stackLimit, &stackDummy)) {
         /*
          * If we run out of stack, we take a more drastic measure: require that
          * we GC again before the next CC.
          */
         nsXPConnect* xpc = nsXPConnect::GetXPConnect();
         xpc->EnsureGCBeforeCC();
         return;
     }
@@ -866,17 +872,17 @@ nsXPConnect::Traverse(void *p, nsCycleCo
     }
 
     return NS_OK;
 }
 
 unsigned
 nsXPConnect::GetOutstandingRequests(JSContext* cx)
 {
-    unsigned n = js::GetContextOutstandingRequests(cx);
+    unsigned n = cx->outstandingRequests;
     XPCCallContext* context = mCycleCollectionContext;
     // Ignore the contribution from the XPCCallContext we created for cycle
     // collection.
     if (context && cx == context->GetJSContext()) {
         JS_ASSERT(n);
         --n;
     }
     return n;
@@ -887,37 +893,39 @@ class JSContextParticipant : public nsCy
 public:
     NS_IMETHOD Root(void *n)
     {
         return NS_OK;
     }
     NS_IMETHOD Unlink(void *n)
     {
         JSContext *cx = static_cast<JSContext*>(n);
-        NS_ASSERTION(js::GetContextGlobalObject(cx), "global object NULL before unlinking");
-        js::SetContextGlobalObject(cx, nsnull);
+        NS_ASSERTION(cx->globalObject, "global object NULL before unlinking");
+        cx->globalObject = nsnull;
         return NS_OK;
     }
     NS_IMETHOD Unroot(void *n)
     {
         return NS_OK;
     }
     NS_IMETHODIMP Traverse(void *n, nsCycleCollectionTraversalCallback &cb)
     {
         JSContext *cx = static_cast<JSContext*>(n);
 
         // Add outstandingRequests to the count, if there are outstanding
         // requests the context needs to be kept alive and adding unknown
         // edges will ensure that any cycles this context is in won't be
         // collected.
         unsigned refCount = nsXPConnect::GetXPConnect()->GetOutstandingRequests(cx) + 1;
-        cb.DescribeRefCountedNode(refCount, 0, "JSContext");
+        NS_IMPL_CYCLE_COLLECTION_DESCRIBE(JSContext, refCount)
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[global object]");
-        if (JSObject *global = js::GetContextGlobalObject(cx))
-            cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, global);
+        if (cx->globalObject) {
+            cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT,
+                               cx->globalObject);
+        }
 
         return NS_OK;
     }
 };
 
 static JSContextParticipant JSContext_cycleCollectorGlobal;
 
 // static
@@ -2515,17 +2523,17 @@ nsXPConnect::CheckForDebugMode(JSRuntime
     {
         struct AutoDestroyContext {
             JSContext *cx;
             AutoDestroyContext(JSContext *cx) : cx(cx) {}
             ~AutoDestroyContext() { JS_DestroyContext(cx); }
         } adc(cx);
         JSAutoRequest ar(cx);
 
-        js::CompartmentVector &vector = js::GetRuntimeCompartments(rt);
+        js::CompartmentVector &vector = rt->compartments;
         for (JSCompartment **p = vector.begin(); p != vector.end(); ++p) {
             JSCompartment *comp = *p;
             if (!JS_GetCompartmentPrincipals(comp)) {
                 /* Ignore special compartments (atoms, JSD compartments) */
                 continue;
             }
 
             /* ParticipatesInCycleCollection means "on the main thread" */
@@ -2585,17 +2593,17 @@ nsXPConnect::Push(JSContext * cx)
          const nsTArray<XPCJSContextInfo>* stack = data->GetJSContextStack()->GetStack();
          if (!gDesiredDebugMode) {
              /* Turn off debug mode immediately, even if JS code is currently running */
              CheckForDebugMode(mRuntime->GetJSRuntime());
          } else {
              bool runningJS = false;
              for (PRUint32 i = 0; i < stack->Length(); ++i) {
                  JSContext *cx = (*stack)[i].cx;
-                 if (cx && JS_IsContextRunningJS(cx)) {
+                 if (cx && !cx->stack.empty()) {
                      runningJS = true;
                      break;
                  }
              }
              if (!runningJS)
                  CheckForDebugMode(mRuntime->GetJSRuntime());
          }
      }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -50,16 +50,17 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <math.h>
 #include "xpcpublic.h"
 #include "jsapi.h"
 #include "jsdhash.h"
 #include "jsprf.h"
 #include "prprf.h"
+#include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 #include "jsgc.h"
 #include "jswrapper.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
@@ -849,18 +850,18 @@ private:
 
 // no virtuals
 class XPCContext
 {
     friend class XPCJSRuntime;
 public:
     static XPCContext* GetXPCContext(JSContext* aJSContext)
         {
-            NS_ASSERTION(js::GetContextPrivate2(aJSContext), "should already have XPCContext");
-            return static_cast<XPCContext *>(js::GetContextPrivate2(aJSContext));
+            NS_ASSERTION(aJSContext->data2, "should already have XPCContext");
+            return static_cast<XPCContext *>(aJSContext->data2);
         }
 
     XPCJSRuntime* GetRuntime() const {return mRuntime;}
     JSContext* GetJSContext() const {return mJSContext;}
 
     enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
 
     LangType GetCallingLangType() const
@@ -3633,19 +3634,19 @@ class XPCPerThreadData
 {
     typedef mozilla::Mutex Mutex;
 
 public:
     // Get the instance of this object for the current thread
     static inline XPCPerThreadData* GetData(JSContext *cx)
     {
         if (cx) {
-            NS_ASSERTION(js::GetContextThread(cx), "Uh, JS context w/o a thread?");
-
-            if(js::GetContextThread(cx) == sMainJSThread)
+            NS_ASSERTION(cx->thread(), "Uh, JS context w/o a thread?");
+
+            if (cx->thread() == sMainJSThread)
                 return sMainThreadData;
         } else if (sMainThreadData && sMainThreadData->mThread == PR_GetCurrentThread()) {
             return sMainThreadData;
         }
 
         return GetDataImpl(cx);
     }
 
@@ -3738,17 +3739,17 @@ public:
     void      ClearWrappedNativeThreadsafetyReportDepth()
         {mWrappedNativeThreadsafetyReportDepth = 0;}
 #endif
 
     static void ShutDown()
         {sMainJSThread = nsnull; sMainThreadData = nsnull;}
 
     static bool IsMainThread(JSContext *cx)
-        { return js::GetContextThread(cx) == sMainJSThread; }
+        { return cx->thread() == sMainJSThread; }
 
 private:
     XPCPerThreadData();
     static XPCPerThreadData* GetDataImpl(JSContext *cx);
 
 private:
     XPCJSContextStack*   mJSContextStack;
     XPCPerThreadData*    mNextThread;
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -47,17 +47,16 @@
 #include "nsContentUtils.h"
 
 #include "XPCWrapper.h"
 #include "XrayWrapper.h"
 #include "FilteringWrapper.h"
 #include "WrapperFactory.h"
 
 #include "jsfriendapi.h"
-#include "jsstr.h"
 
 using namespace mozilla;
 using namespace js;
 
 namespace xpc {
 
 nsIPrincipal *
 GetCompartmentPrincipal(JSCompartment *compartment)
@@ -193,17 +192,17 @@ IsFrameId(JSContext *cx, JSObject *obj, 
     nsCOMPtr<nsIDOMWindowCollection> col;
     domwin->GetFrames(getter_AddRefs(col));
     if (!col) {
         return false;
     }
 
     if (JSID_IS_INT(id)) {
         col->Item(JSID_TO_INT(id), getter_AddRefs(domwin));
-    } else if (JSID_IS_STRING(id)) {
+    } else if (JSID_IS_ATOM(id)) {
         nsAutoString str(JS_GetInternedStringChars(JSID_TO_STRING(id)));
         col->NamedItem(str, getter_AddRefs(domwin));
     } else {
         return false;
     }
 
     return domwin != nsnull;
 }
@@ -300,17 +299,17 @@ AccessCheck::isCrossOriginAccessPermitte
     const char *name;
     js::Class *clasp = js::GetObjectClass(obj);
     NS_ASSERTION(Jsvalify(clasp) != &XrayUtils::HolderClass, "shouldn't have a holder here");
     if (clasp->ext.innerObject)
         name = "Window";
     else
         name = clasp->name;
 
-    if (JSID_IS_STRING(id)) {
+    if (JSID_IS_ATOM(id)) {
         if (IsPermitted(name, JSID_TO_FLAT_STRING(id), act == Wrapper::SET))
             return true;
     }
 
     if (IsWindow(name) && IsFrameId(cx, obj, id))
         return true;
 
     // We only reach this point for cross origin location objects (see
@@ -493,17 +492,17 @@ ExposedPropertiesOnly::check(JSContext *
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, wrappedObject) ||
         !JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found))
         return false;
 
     // Always permit access to "length" and indexed properties of arrays.
     if (JS_IsArrayObject(cx, wrappedObject) &&
         ((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) ||
-         (JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) {
+         (JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) {
         perm = PermitPropertyAccess;
         return true; // Allow
     }
 
     // If no __exposedProps__ existed, deny access.
     if (!found) {
         // For now, only do this on functions.
         if (!JS_ObjectIsFunction(cx, wrappedObject)) {
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -265,17 +265,17 @@ WrapperFactory::Rewrap(JSContext *cx, JS
 {
     NS_ASSERTION(!IsWrapper(obj) ||
                  GetProxyHandler(obj) == &WaiveXrayWrapperWrapper ||
                  js::GetObjectClass(obj)->ext.innerObject,
                  "wrapped object passed to rewrap");
     NS_ASSERTION(JS_GET_CLASS(cx, obj) != &XrayUtils::HolderClass, "trying to wrap a holder");
 
     JSCompartment *origin = js::GetObjectCompartment(obj);
-    JSCompartment *target = js::GetContextCompartment(cx);
+    JSCompartment *target = cx->compartment;
     JSObject *xrayHolder = nsnull;
 
     Wrapper *wrapper;
     CompartmentPrivate *targetdata =
         static_cast<CompartmentPrivate *>(JS_GetCompartmentPrivate(cx, target));
     if (AccessCheck::isChrome(target)) {
         if (AccessCheck::isChrome(origin)) {
             wrapper = &CrossCompartmentWrapper::singleton;
@@ -434,17 +434,17 @@ WrapperFactory::WrapLocationObject(JSCon
 bool
 WrapperFactory::WaiveXrayAndWrap(JSContext *cx, jsval *vp)
 {
     if (JSVAL_IS_PRIMITIVE(*vp))
         return JS_WrapValue(cx, vp);
 
     JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(*vp));
     obj = GetCurrentOuter(cx, obj);
-    if (js::GetObjectCompartment(obj) == js::GetContextCompartment(cx)) {
+    if (js::GetObjectCompartment(obj) == cx->compartment) {
         *vp = OBJECT_TO_JSVAL(obj);
         return true;
     }
 
     obj = WaiveXray(cx, obj);
     if (!obj)
         return false;
 
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -38,16 +38,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "XrayWrapper.h"
 #include "AccessCheck.h"
 #include "FilteringWrapper.h"
 #include "CrossOriginWrapper.h"
 #include "WrapperFactory.h"
 
+#include "jscntxt.h"
+
 #include "nsINode.h"
 #include "nsIDocument.h"
 
 #include "XPCWrapper.h"
 #include "xpcprivate.h"
 
 namespace xpc {
 
@@ -254,17 +256,17 @@ ResolveNativeProperty(JSContext *cx, JSO
     JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder);
     XPCWrappedNative *wn = GetWrappedNative(wnObject);
 
     // This will do verification and the method lookup for us.
     XPCCallContext ccx(JS_CALLER, cx, wnObject, nsnull, id);
 
     // There are no native numeric properties, so we can shortcut here. We will not
     // find the property.
-    if (!JSID_IS_STRING(id)) {
+    if (!JSID_IS_ATOM(id)) {
         /* Not found */
         return true;
     }
 
     XPCNativeInterface *iface;
     XPCNativeMember *member;
     if (ccx.GetWrapper() != wn ||
         !wn->IsValid()  ||
--- a/storage/src/mozStoragePrivateHelpers.cpp
+++ b/storage/src/mozStoragePrivateHelpers.cpp
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "sqlite3.h"
 
 #include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jsdate.h"
 
 #include "nsPrintfCString.h"
 #include "nsString.h"
 #include "nsError.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/CondVar.h"
 #include "nsThreadUtils.h"
 #include "nsJSUtils.h"
@@ -167,20 +167,20 @@ convertJSValToVariant(
     return new IntegerVariant((aValue == JSVAL_TRUE) ? 1 : 0);
 
   if (JSVAL_IS_NULL(aValue))
     return new NullVariant();
 
   if (JSVAL_IS_OBJECT(aValue)) {
     JSObject *obj = JSVAL_TO_OBJECT(aValue);
     // We only support Date instances, all others fail.
-    if (!::JS_DateIsValid(aCtx, obj))
+    if (!::js_DateIsValid(aCtx, obj))
       return nsnull;
 
-    double msecd = ::JS_DateGetMsecSinceEpoch(aCtx, obj);
+    double msecd = ::js_DateGetMsecSinceEpoch(aCtx, obj);
     msecd *= 1000.0;
     PRInt64 msec;
     LL_D2L(msec, msecd);
 
     return new IntegerVariant(msec);
   }
 
   return nsnull;
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -68,16 +68,17 @@
 #include "nsCRT.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShellCID.h"
 #include "mozilla/Services.h"
 #include "mozilla/FunctionTimer.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
+#include "jsdate.h"
 #include "prenv.h"
 
 #if defined(XP_WIN)
 #include <windows.h>
 // windows.h can go to hell 
 #undef GetStartupInfo
 #elif defined(XP_UNIX)
 #include <unistd.h>
@@ -702,17 +703,17 @@ CalculateProcessCreationTimestamp()
 }
 #endif
  
 static void
 MaybeDefineProperty(JSContext *cx, JSObject *obj, const char *name, PRTime timestamp)
 {
   if (!timestamp)
     return;
-  JSObject *date = JS_NewDateObjectMsec(cx, timestamp / PR_USEC_PER_MSEC);
+  JSObject *date = js_NewDateObjectMsec(cx, timestamp/PR_USEC_PER_MSEC);
   JS_DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(date), NULL, NULL, JSPROP_ENUMERATE);     
 }
 
 enum {
   INVALID_PROCESS_CREATION = 0,
   INVALID_MAIN,
   INVALID_FIRST_PAINT,
   INVALID_SESSION_RESTORED,