Bug 744034 - Link the script context to the outer window earlier to ensure that we always have TI for content. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Thu, 12 Apr 2012 11:21:12 -0700
changeset 94869 0ef3e84e6ce9c555bf8406b78a1f2bcd135c8d6f
parent 94868 ae32cca25ce0e844716b7ea7df812659008fa07e
child 94870 8f783fc30dd34ae5b286f80c119724613735ab20
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs744034
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 744034 - Link the script context to the outer window earlier to ensure that we always have TI for content. r=mrbkap
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
js/xpconnect/src/nsXPConnect.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1600,16 +1600,20 @@ nsGlobalWindow::SetScriptContext(nsIScri
   NS_ASSERTION(IsOuterWindow(), "Uh, SetScriptContext() called on inner window!");
 
   NS_ASSERTION(!aScriptContext || !mContext, "Bad call to SetContext()!");
 
   if (aScriptContext) {
     // should probably assert the context is clean???
     aScriptContext->WillInitializeContext();
 
+    // We need point the context to the global window before initializing it
+    // so that it can make various decisions properly.
+    aScriptContext->SetGlobalObject(this);
+
     nsresult rv = aScriptContext->InitContext();
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (IsFrame()) {
       // This window is a [i]frame, don't bother GC'ing when the
       // frame's context is destroyed since a GC will happen when the
       // frameset or host document is destroyed anyway.
 
@@ -1869,18 +1873,16 @@ WindowStateHolder::~WindowStateHolder()
   }
 }
 
 NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
 
 nsresult
 nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
 {
-  mContext->SetGlobalObject(this);
-
   JSContext* cx = mContext->GetNativeContext();
 
   if (IsChromeWindow()) {
     // Always enable E4X for XUL and other chrome content -- there is no
     // need to preserve the <!-- script hiding hack from JS-in-HTML daze
     // (introduced in 1995 for graceful script degradation in Netscape 1,
     // Mosaic, and other pre-JS browsers).
     JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_XML);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -940,17 +940,21 @@ nsJSContext::JSOptionChangedCallback(con
   sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
 
   bool strict = Preferences::GetBool(js_strict_option_str);
   if (strict)
     newDefaultJSOptions |= JSOPTION_STRICT;
   else
     newDefaultJSOptions &= ~JSOPTION_STRICT;
 
-  nsIScriptGlobalObject *global = context->GetGlobalObject();
+  // The vanilla GetGlobalObject returns null if a global isn't set up on
+  // the context yet. We can sometimes be call midway through context init,
+  // So ask for the member directly instead.
+  nsIScriptGlobalObject *global = context->GetGlobalObjectRef();
+
   // XXX should we check for sysprin instead of a chrome window, to make
   // XXX components be covered by the chrome pref instead of the content one?
   nsCOMPtr<nsIDOMWindow> contentWindow(do_QueryInterface(global));
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
 
   bool useMethodJIT = Preferences::GetBool(chromeWindow || !contentWindow ?
                                                js_methodjit_chrome_str :
                                                js_methodjit_content_str);
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -130,16 +130,18 @@ public:
                                    const nsAString& aBody,
                                    const char* aURL,
                                    PRUint32 aLineNo,
                                    PRUint32 aVersion,
                                    bool aShared,
                                    JSObject** aFunctionObject);
 
   virtual nsIScriptGlobalObject *GetGlobalObject();
+  inline nsIScriptGlobalObject *GetGlobalObjectRef() { return mGlobalObjectRef; };
+
   virtual JSContext* GetNativeContext();
   virtual JSObject* GetNativeGlobal();
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aGlobal,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
                                       JSObject** aNativeGlobal,
                                       nsISupports **aHolder);
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1194,16 +1194,28 @@ TraceXPCGlobal(JSTracer *trc, JSObject *
 }
 
 nsresult
 xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
                        nsIPrincipal *principal, nsISupports *ptr,
                        bool wantXrays, JSObject **global,
                        JSCompartment **compartment)
 {
+    // Make sure that Type Inference is enabled for everything non-chrome.
+    // Sandboxes and compilation scopes are exceptions. See bug 744034.
+    mozilla::DebugOnly<bool> isSystem;
+    mozilla::DebugOnly<nsIScriptSecurityManager*> ssm;
+    MOZ_ASSERT_IF(strcmp(clasp->name, "Sandbox") &&
+                  strcmp(clasp->name, "nsXBLPrototypeScript compilation scope") &&
+                  strcmp(clasp->name, "nsXULPrototypeScript compilation scope") &&
+                  (ssm = XPCWrapper::GetSecurityManager()) &&
+                  NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &isSystem.value)) &&
+                  !isSystem.value,
+                  JS_GetOptions(cx) & JSOPTION_TYPE_INFERENCE);
+
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "using a principal off the main thread?");
     NS_ABORT_IF_FALSE(principal, "bad key");
 
     XPCCompartmentMap& map = nsXPConnect::GetRuntimeInstance()->GetCompartmentMap();
     xpc::PtrAndPrincipalHashKey key(ptr, principal);
     if (!map.Get(&key, compartment)) {
         xpc::PtrAndPrincipalHashKey *priv_key =
             new xpc::PtrAndPrincipalHashKey(ptr, principal);