Bug 1366932 - support extra JS context heap size pref for PAC; r=bagder
authorLiang-Heng Chen <xeonchen@gmail.com>
Wed, 24 May 2017 14:24:55 +0800
changeset 361763 208eb19a2a1ec6d9716eeb1c8f914376409daa05
parent 361730 d96110d766199d42524558fd83e6467906de4daf
child 361764 c2f8ea2153c8242dea1b82487e759eb0b9008f84
push id31942
push userryanvm@gmail.com
push dateThu, 01 Jun 2017 15:54:15 +0000
treeherdermozilla-central@cac2fd43de81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbagder
bugs1366932
milestone55.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 1366932 - support extra JS context heap size pref for PAC; r=bagder MozReview-Commit-ID: L7xzXZOnI0N
netwerk/base/ProxyAutoConfig.cpp
netwerk/base/ProxyAutoConfig.h
netwerk/base/nsPACMan.cpp
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -386,16 +386,17 @@ bool PACResolve(const nsCString &aHostNa
   return GetRunning()->ResolveAddress(aHostName, aNetAddr, aTimeout);
 }
 
 ProxyAutoConfig::ProxyAutoConfig()
   : mJSContext(nullptr)
   , mJSNeedsSetup(false)
   , mShutdown(false)
   , mIncludePath(false)
+  , mExtraHeapSize(0)
 {
   MOZ_COUNT_CTOR(ProxyAutoConfig);
 }
 
 bool
 ProxyAutoConfig::ResolveAddress(const nsCString &aHostName,
                                 NetAddr *aNetAddr,
                                 unsigned int aTimeout)
@@ -546,19 +547,19 @@ static const JSFunctionSpec PACGlobalFun
   JS_FS_END
 };
 
 // JSContextWrapper is a c++ object that manages the context for the JS engine
 // used on the PAC thread. It is initialized and destroyed on the PAC thread.
 class JSContextWrapper
 {
  public:
-  static JSContextWrapper *Create()
+  static JSContextWrapper *Create(uint32_t aExtraHeapSize)
   {
-    JSContext* cx = JS_NewContext(sContextHeapSize);
+    JSContext* cx = JS_NewContext(sContextHeapSize + aExtraHeapSize);
     if (NS_WARN_IF(!cx))
       return nullptr;
 
     JSContextWrapper *entry = new JSContextWrapper(cx);
     if (NS_FAILED(entry->Init())) {
       delete entry;
       return nullptr;
     }
@@ -593,17 +594,17 @@ class JSContextWrapper
   }
 
   bool IsOK()
   {
     return mOK;
   }
 
 private:
-  static const unsigned sContextHeapSize = 4 << 20; // 4 MB
+  static const uint32_t sContextHeapSize = 4 << 20; // 4 MB
 
   JSContext *mContext;
   JS::PersistentRooted<JSObject*> mGlobal;
   bool      mOK;
 
   static const JSClass sGlobalClass;
 
   explicit JSContextWrapper(JSContext* cx)
@@ -671,22 +672,24 @@ void
 ProxyAutoConfig::SetThreadLocalIndex(uint32_t index)
 {
   sRunningIndex = index;
 }
 
 nsresult
 ProxyAutoConfig::Init(const nsCString &aPACURI,
                       const nsCString &aPACScript,
-                      bool aIncludePath)
+                      bool aIncludePath,
+                      uint32_t aExtraHeapSize)
 {
   mPACURI = aPACURI;
   mPACScript = sPacUtils;
   mPACScript.Append(aPACScript);
   mIncludePath = aIncludePath;
+  mExtraHeapSize = aExtraHeapSize;
 
   if (!GetRunning())
     return SetupJS();
 
   mJSNeedsSetup = true;
   return NS_OK;
 }
 
@@ -699,17 +702,17 @@ ProxyAutoConfig::SetupJS()
   delete mJSContext;
   mJSContext = nullptr;
 
   if (mPACScript.IsEmpty())
     return NS_ERROR_FAILURE;
 
   NS_GetCurrentThread()->SetCanInvokeJS(true);
 
-  mJSContext = JSContextWrapper::Create();
+  mJSContext = JSContextWrapper::Create(mExtraHeapSize);
   if (!mJSContext)
     return NS_ERROR_FAILURE;
 
   JSContext* cx = mJSContext->Context();
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, mJSContext->Global());
   AutoPACErrorReporter aper(cx);
 
--- a/netwerk/base/ProxyAutoConfig.h
+++ b/netwerk/base/ProxyAutoConfig.h
@@ -26,17 +26,18 @@ union NetAddr;
 
 class ProxyAutoConfig  {
 public:
   ProxyAutoConfig();
   ~ProxyAutoConfig();
 
   nsresult Init(const nsCString &aPACURI,
                 const nsCString &aPACScript,
-                bool aIncludePath);
+                bool aIncludePath,
+                uint32_t aExtraHeapSize);
   void     SetThreadLocalIndex(uint32_t index);
   void     Shutdown();
   void     GC();
   bool     MyIPAddress(const JS::CallArgs &aArgs);
   bool     ResolveAddress(const nsCString &aHostName,
                           NetAddr *aNetAddr, unsigned int aTimeout);
 
   /**
@@ -89,16 +90,17 @@ private:
                           const JS::CallArgs &aArgs, bool* aResult);
 
   JSContextWrapper *mJSContext;
   bool              mJSNeedsSetup;
   bool              mShutdown;
   nsCString         mPACScript;
   nsCString         mPACURI;
   bool              mIncludePath;
+  uint32_t          mExtraHeapSize;
   nsCString         mRunningHost;
   nsCOMPtr<nsITimer> mTimer;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif  // ProxyAutoConfig_h__
--- a/netwerk/base/nsPACMan.cpp
+++ b/netwerk/base/nsPACMan.cpp
@@ -45,16 +45,42 @@ HttpRequestSucceeded(nsIStreamLoader *lo
   if (httpChannel) {
     // failsafe
     Unused << httpChannel->GetRequestSucceeded(&result);
   }
 
   return result;
 }
 
+// Read preference setting of extra JavaScript context heap size.
+// PrefService tends to be run on main thread, where ProxyAutoConfig runs on
+// ProxyResolution thread, so it's read here and passed to ProxyAutoConfig.
+static uint32_t
+GetExtraJSContextHeapSize()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  static int32_t extraSize = -1;
+
+  if (extraSize < 0) {
+    nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+    int32_t value;
+
+    if (prefs && NS_SUCCEEDED(prefs->GetIntPref(
+        "network.proxy.autoconfig_extra_jscontext_heap_size", &value))) {
+      LOG(("autoconfig_extra_jscontext_heap_size: %d\n", value));
+
+      extraSize = value;
+    }
+  }
+
+  return extraSize < 0 ? 0 : extraSize;
+}
+
+
 //-----------------------------------------------------------------------------
 
 // The ExecuteCallback runnable is triggered by
 // nsPACManCallback::OnQueryComplete on the Main thread when its completion is
 // discovered on the pac thread
 
 class ExecuteCallback final : public Runnable
 {
@@ -175,46 +201,52 @@ class ExecutePACThreadAction final : pub
 {
 public:
   // by default we just process the queue
   explicit ExecutePACThreadAction(nsPACMan *aPACMan)
     : mPACMan(aPACMan)
     , mCancel(false)
     , mCancelStatus(NS_OK)
     , mSetupPAC(false)
+    , mExtraHeapSize(0)
   { }
 
   void CancelQueue (nsresult status)
   {
     mCancel = true;
     mCancelStatus = status;
   }
 
-  void SetupPAC (const char *text, uint32_t datalen, nsCString &pacURI)
+  void SetupPAC (const char *text,
+                 uint32_t datalen,
+                 nsCString &pacURI,
+                 uint32_t extraHeapSize)
   {
     mSetupPAC = true;
     mSetupPACData.Assign(text, datalen);
     mSetupPACURI = pacURI;
+    mExtraHeapSize = extraHeapSize;
   }
 
   NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
     if (mCancel) {
       mPACMan->CancelPendingQ(mCancelStatus);
       mCancel = false;
       return NS_OK;
     }
 
     if (mSetupPAC) {
       mSetupPAC = false;
 
       mPACMan->mPAC.Init(mSetupPACURI,
                          mSetupPACData,
-                         mPACMan->mIncludePath);
+                         mPACMan->mIncludePath,
+                         mExtraHeapSize);
 
       RefPtr<PACLoadComplete> runnable = new PACLoadComplete(mPACMan);
       NS_DispatchToMainThread(runnable);
       return NS_OK;
     }
 
     mPACMan->ProcessPendingQ();
     return NS_OK;
@@ -222,16 +254,17 @@ public:
 
 private:
   RefPtr<nsPACMan> mPACMan;
 
   bool      mCancel;
   nsresult  mCancelStatus;
 
   bool                 mSetupPAC;
+  uint32_t             mExtraHeapSize;
   nsCString            mSetupPACData;
   nsCString            mSetupPACURI;
 };
 
 //-----------------------------------------------------------------------------
 
 PendingPACQuery::PendingPACQuery(nsPACMan *pacMan, nsIURI *uri,
                                  nsPACManCallback *callback,
@@ -666,17 +699,17 @@ nsPACMan::OnStreamComplete(nsIStreamLoad
 
     // we have succeeded in loading the pac file using a bunch of interfaces that
     // are main thread only, unfortunately we have to initialize the instance of
     // the PAC evaluator (NS_PROXYAUTOCONFIG_CONTRACTID) on the pac thread, because
     // that is where it will be used.
 
     RefPtr<ExecutePACThreadAction> pending =
       new ExecutePACThreadAction(this);
-    pending->SetupPAC(text, dataLen, pacURI);
+    pending->SetupPAC(text, dataLen, pacURI, GetExtraJSContextHeapSize());
     if (mPACThread)
       mPACThread->Dispatch(pending, nsIEventTarget::DISPATCH_NORMAL);
 
     LOG(("OnStreamComplete: process the PAC contents\n"));
 
     // Even if the PAC file could not be parsed, we did succeed in loading the
     // data for it.
     mLoadFailureCount = 0;