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 idunknown
push userunknown
push dateunknown
bugs677079
milestone10.0a1
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,