Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 "use strict";
6 module.metadata = {
7 "stability": "deprecated"
8 };
10 const { Cc, Ci, Cu, components } = require("chrome");
11 const { when: unload } = require("../system/unload")
13 var trackedObjects = {};
14 const Compacter = {
15 notify: function() {
16 var newTrackedObjects = {};
18 for (let name in trackedObjects) {
19 let oldBin = trackedObjects[name];
20 let newBin = [];
21 let strongRefs = [];
23 for (let i = 0, l = oldBin.length; i < l; i++) {
24 let strongRef = oldBin[i].weakref.get();
26 if (strongRef && strongRefs.indexOf(strongRef) == -1) {
27 strongRefs.push(strongRef);
28 newBin.push(oldBin[i]);
29 }
30 }
32 if (newBin.length)
33 newTrackedObjects[name] = newBin;
34 }
36 trackedObjects = newTrackedObjects;
37 }
38 };
40 var timer = Cc["@mozilla.org/timer;1"]
41 .createInstance(Ci.nsITimer);
42 timer.initWithCallback(Compacter,
43 5000,
44 Ci.nsITimer.TYPE_REPEATING_SLACK);
46 function track(object, bin, stackFrameNumber) {
47 var frame = components.stack.caller;
48 var weakref = Cu.getWeakReference(object);
50 if (!bin && 'constructor' in object)
51 bin = object.constructor.name;
52 if (bin == "Object")
53 bin = frame.name;
54 if (!bin)
55 bin = "generic";
56 if (!(bin in trackedObjects))
57 trackedObjects[bin] = [];
59 if (stackFrameNumber > 0)
60 for (var i = 0; i < stackFrameNumber; i++)
61 frame = frame.caller;
63 trackedObjects[bin].push({weakref: weakref,
64 created: new Date(),
65 filename: frame.filename,
66 lineNo: frame.lineNumber,
67 bin: bin});
68 }
69 exports.track = track;
71 var getBins = exports.getBins = function getBins() {
72 var names = [];
73 for (let name in trackedObjects)
74 names.push(name);
75 return names;
76 };
78 function getObjects(bin) {
79 var results = [];
81 function getLiveObjectsInBin(bin) {
82 for (let i = 0, l = bin.length; i < l; i++) {
83 let object = bin[i].weakref.get();
85 if (object) {
86 results.push(bin[i]);
87 }
88 }
89 }
91 if (bin) {
92 if (bin in trackedObjects)
93 getLiveObjectsInBin(trackedObjects[bin]);
94 }
95 else {
96 for (let name in trackedObjects)
97 getLiveObjectsInBin(trackedObjects[name]);
98 }
100 return results;
101 }
102 exports.getObjects = getObjects;
104 function gc() {
105 // Components.utils.forceGC() doesn't currently perform
106 // cycle collection, which means that e.g. DOM elements
107 // won't be collected by it. Fortunately, there are
108 // other ways...
109 var test_utils = Cc["@mozilla.org/appshell/appShellService;1"]
110 .getService(Ci.nsIAppShellService)
111 .hiddenDOMWindow
112 .QueryInterface(Ci.nsIInterfaceRequestor)
113 .getInterface(Ci.nsIDOMWindowUtils);
114 test_utils.garbageCollect();
115 // Clean metadata for dead objects
116 Compacter.notify();
117 // Not sure why, but sometimes it appears that we don't get
118 // them all with just one CC, so let's do it again.
119 test_utils.garbageCollect();
120 };
121 exports.gc = gc;
123 unload(_ => {
124 trackedObjects = {};
125 if (timer) {
126 timer.cancel();
127 timer = null;
128 }
129 });