bug 1074567 - measure time spent processing in sync CPOW calls per compartment r=bholley,billm
authorBrad Lassey <blassey@mozilla.com>
Wed, 19 Nov 2014 18:54:34 -0500
changeset 216554 dc5206885f8727c30b3b99c268cfbed0b936951f
parent 216553 ef7bfca8a59f7cf2d6d259b058b0ad20c9b58ea9
child 216555 1b946e43e5dc3854d6436ed98e42a6f3a3a80641
push idunknown
push userunknown
push dateunknown
reviewersbholley, billm
bugs1074567
milestone36.0a1
bug 1074567 - measure time spent processing in sync CPOW calls per compartment r=bholley,billm * * * try: -b do -p linux64-b2g-haz -u none
js/ipc/CPOWTimer.cpp
js/ipc/CPOWTimer.h
js/ipc/WrapperOwner.cpp
js/ipc/moz.build
js/xpconnect/src/xpcprivate.h
new file mode 100644
--- /dev/null
+++ b/js/ipc/CPOWTimer.cpp
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=80:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jsfriendapi.h"
+#include "xpcprivate.h"
+#include "CPOWTimer.h"
+
+CPOWTimer::~CPOWTimer() {
+    /* This is a best effort to find the compartment responsible for this CPOW call */
+    xpc::CompartmentPrivate* compartment = xpc::CompartmentPrivate::Get(js::GetObjectCompartment(mozilla::dom::GetIncumbentGlobal()
+                                                                                                 ->GetGlobalJSObject()));
+    PRIntervalTime time = PR_IntervalNow() - startInterval;
+    compartment->CPOWTime += time;
+}
new file mode 100644
--- /dev/null
+++ b/js/ipc/CPOWTimer.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=80:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CPOWTIMER_H
+#define CPOWTIMER_H
+
+#include "prinrval.h"
+
+class JSObject;
+
+class MOZ_STACK_CLASS CPOWTimer {
+  public:
+    CPOWTimer(): startInterval(PR_IntervalNow()) {}
+    ~CPOWTimer();
+
+  private:
+    PRIntervalTime startInterval;
+};
+
+#endif
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -6,16 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WrapperOwner.h"
 #include "JavaScriptLogging.h"
 #include "mozilla/unused.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "jsfriendapi.h"
 #include "xpcprivate.h"
+#include "CPOWTimer.h"
 #include "WrapperFactory.h"
 
 #include "nsIRemoteTagService.h"
 
 using namespace js;
 using namespace JS;
 using namespace mozilla;
 using namespace mozilla::jsipc;
@@ -129,17 +130,20 @@ const char CPOWProxyHandler::family = 0;
 const CPOWProxyHandler CPOWProxyHandler::singleton;
 
 #define FORWARD(call, args)                                             \
     WrapperOwner *owner = OwnerOf(proxy);                               \
     if (!owner->active()) {                                             \
         JS_ReportError(cx, "cannot use a CPOW whose process is gone");  \
         return false;                                                   \
     }                                                                   \
-    return owner->call args;
+    {                                                                   \
+        CPOWTimer timer;                                                \
+        return owner->call args;                                        \
+    }
 
 bool
 CPOWProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                         MutableHandle<JSPropertyDescriptor> desc) const
 {
     FORWARD(getPropertyDescriptor, (cx, proxy, id, desc));
 }
 
--- a/js/ipc/moz.build
+++ b/js/ipc/moz.build
@@ -1,15 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 UNIFIED_SOURCES += [
+    'CPOWTimer.cpp',
     'JavaScriptChild.cpp',
     'JavaScriptParent.cpp',
     'JavaScriptShared.cpp',
     'WrapperAnswer.cpp',
     'WrapperOwner.cpp',
 ]
 
 IPDL_SOURCES += [
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3624,16 +3624,17 @@ public:
     };
 
     explicit CompartmentPrivate(JSCompartment *c)
         : wantXrays(false)
         , writeToGlobalPrototype(false)
         , skipWriteToGlobalPrototype(false)
         , universalXPConnectEnabled(false)
         , forcePermissiveCOWs(false)
+        , CPOWTime(0)
         , skipCOWCallableChecks(false)
         , scriptability(c)
         , scope(nullptr)
     {
         MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
         mozilla::PodArrayZero(wrapperDenialWarnings);
     }
 
@@ -3677,16 +3678,19 @@ public:
     // This is only ever set during mochitest runs when enablePrivilege is called.
     // It allows the SpecialPowers scope to waive the normal chrome security
     // wrappers and expose properties directly to content. This lets us avoid a
     // bunch of overhead and complexity in our SpecialPowers automation glue.
     //
     // Using it in production is inherently unsafe.
     bool forcePermissiveCOWs;
 
+    // A running count of how much time we've spent processing CPOWs.
+    PRIntervalTime               CPOWTime;
+
     // Disables the XPConnect security checks that deny access to callables and
     // accessor descriptors on COWs. Do not use this unless you are bholley.
     bool skipCOWCallableChecks;
 
     // Whether we've emitted a warning about a property that was filtered out
     // by a security wrapper. See XrayWrapper.cpp.
     bool wrapperDenialWarnings[WrapperDenialTypeCount];