author | Bobby Holley <bobbyholley@gmail.com> |
Wed, 23 Oct 2013 14:02:42 +0200 | |
changeset 165664 | a00ba6f64d80a50c9e5a0abf88a3a8a2b59b5f6b |
parent 165663 | 9687708309c56eb4e7a82404cc9fbb4e5d65c3e1 |
child 165665 | d64bea16611b69c3533ec238577c5139a02b3f1e |
push id | 3066 |
push user | akeybl@mozilla.com |
push date | Mon, 09 Dec 2013 19:58:46 +0000 |
treeherder | mozilla-beta@a31a0dce83aa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mrbkap, nfroyd |
bugs | 928476 |
milestone | 27.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
|
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1654,24 +1654,29 @@ ReparentWrapper(JSContext* aCx, JS::Hand JS::Rooted<JSObject*> aObj(aCx, aObjArg); const DOMClass* domClass = GetDOMClass(aObj); JS::Rooted<JSObject*> oldParent(aCx, JS_GetParent(aObj)); JS::Rooted<JSObject*> newParent(aCx, domClass->mGetParent(aCx, aObj)); JSAutoCompartment oldAc(aCx, oldParent); - if (js::GetObjectCompartment(oldParent) == - js::GetObjectCompartment(newParent)) { + JSCompartment* oldCompartment = js::GetObjectCompartment(oldParent); + JSCompartment* newCompartment = js::GetObjectCompartment(newParent); + if (oldCompartment == newCompartment) { if (!JS_SetParent(aCx, aObj, newParent)) { MOZ_CRASH(); } return NS_OK; } + // Telemetry. + xpc::RecordDonatedNode(oldCompartment); + xpc::RecordAdoptedNode(newCompartment); + nsISupports* native = UnwrapDOMObjectToISupports(aObj); if (!native) { return NS_OK; } // Before proceeding, eagerly create any same-compartment security wrappers // that the object might have. This forces us to take the 'WithWrapper' path // while transplanting that handles this stuff correctly.
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -256,19 +256,42 @@ public: public: bool mContinuation; bool mActive; }; namespace xpc { +static uint32_t kLivingAdopters = 0; + +void +RecordAdoptedNode(JSCompartment *c) +{ + CompartmentPrivate *priv = EnsureCompartmentPrivate(c); + if (!priv->adoptedNode) { + priv->adoptedNode = true; + ++kLivingAdopters; + } +} + +void +RecordDonatedNode(JSCompartment *c) +{ + EnsureCompartmentPrivate(c)->donatedNode = true; +} + CompartmentPrivate::~CompartmentPrivate() { MOZ_COUNT_DTOR(xpc::CompartmentPrivate); + + Telemetry::Accumulate(Telemetry::COMPARTMENT_ADOPTED_NODE, adoptedNode); + Telemetry::Accumulate(Telemetry::COMPARTMENT_DONATED_NODE, donatedNode); + if (adoptedNode) + --kLivingAdopters; } bool CompartmentPrivate::TryParseLocationURI() { // Already tried parsing the location before if (locationWasParsed) return false; locationWasParsed = true; @@ -648,16 +671,23 @@ XPCJSRuntime::GCSliceCallback(JSRuntime if (self->mPrevGCSliceCallback) (*self->mPrevGCSliceCallback)(rt, progress, desc); } void XPCJSRuntime::CustomGCCallback(JSGCStatus status) { + // Record kLivingAdopters once per GC to approximate time sampling during + // periods of activity. + if (status == JSGC_BEGIN) { + Telemetry::Accumulate(Telemetry::COMPARTMENT_LIVING_ADOPTERS, + kLivingAdopters); + } + nsTArray<xpcGCCallback> callbacks(extraGCCallbacks); for (uint32_t i = 0; i < callbacks.Length(); ++i) callbacks[i](status); } /* static */ void XPCJSRuntime::FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartmentGC) {
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3739,32 +3739,38 @@ GetRTIdByIndex(JSContext *cx, unsigned i namespace xpc { class CompartmentPrivate { public: CompartmentPrivate() : wantXrays(false) , universalXPConnectEnabled(false) + , adoptedNode(false) + , donatedNode(false) , scope(nullptr) , locationWasParsed(false) { MOZ_COUNT_CTOR(xpc::CompartmentPrivate); } ~CompartmentPrivate(); bool wantXrays; // This is only ever set during mochitest runs when enablePrivilege is called. // It's intended as a temporary stopgap measure until we can finish ripping out // enablePrivilege. Once set, this value is never unset (i.e., it doesn't follow // the old scoping rules of enablePrivilege). Using it is inherently unsafe. bool universalXPConnectEnabled; + // for telemetry. See bug 928476. + bool adoptedNode; + bool donatedNode; + // Our XPCWrappedNativeScope. This is non-null if and only if this is an // XPConnect compartment. XPCWrappedNativeScope *scope; const nsACString& GetLocation() { if (location.IsEmpty() && locationURI) { if (NS_FAILED(locationURI->GetSpec(location))) location = NS_LITERAL_CSTRING("<unknown location>");
--- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -354,16 +354,22 @@ SystemErrorReporter(JSContext *cx, const // to fail to compile. NS_EXPORT_(void) SystemErrorReporterExternal(JSContext *cx, const char *message, JSErrorReport *rep); NS_EXPORT_(void) SimulateActivityCallback(bool aActive); +void +RecordAdoptedNode(JSCompartment *c); + +void +RecordDonatedNode(JSCompartment *c); + } // namespace xpc namespace mozilla { namespace dom { typedef JSObject* (*DefineInterface)(JSContext *cx, JS::Handle<JSObject*> global, JS::Handle<jsid> id, bool defineOnGlobal);
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -23,16 +23,29 @@ "extended_statistics_ok": true, "description": "time spent updating accessibility (ms)" }, "BACKGROUNDFILESAVER_THREAD_COUNT": { "kind": "enumerated", "n_values": 21, "description": "Maximum number of concurrent threads reached during a given download session" }, + "COMPARTMENT_DONATED_NODE": { + "kind": "boolean", + "description": "When a compartment is destroyed, we record whether one of its nodes was ever adopted into another compartment" + }, + "COMPARTMENT_ADOPTED_NODE": { + "kind": "boolean", + "description": "When a compartment is destroyed, we record whether it had ever adopted a node from another compartment" + }, + "COMPARTMENT_LIVING_ADOPTERS": { + "kind": "enumerated", + "n_values": 10, + "description": "The number of living compartments for which COMPARTMENT_ADOPTED_NODE is true" + }, "CYCLE_COLLECTOR": { "kind": "exponential", "high": "10000", "n_buckets": 50, "description": "Time spent on one cycle collection (ms)" }, "CYCLE_COLLECTOR_WORKER": { "kind": "exponential",