UNPKG

occaecatidicta

Version:
497 lines (422 loc) 15.2 kB
/* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyrightdd * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ WebInspector.HeapSnapshotRealWorker = function() { this._worker = new Worker("HeapSnapshotWorker.js"); this._worker.addEventListener("message", this._messageReceived.bind(this), false); } WebInspector.HeapSnapshotRealWorker.prototype = { _messageReceived: function(event) { this.dispatchEventToListeners("message", event.data); }, postMessage: function(message) { this._worker.postMessage(message); }, terminate: function() { this._worker.terminate(); } }; WebInspector.HeapSnapshotRealWorker.prototype.__proto__ = WebInspector.Object.prototype; WebInspector.HeapSnapshotFakeWorker = function() { this._dispatcher = new WebInspector.HeapSnapshotWorkerDispatcher(window, this._postMessageFromWorker.bind(this)); } WebInspector.HeapSnapshotFakeWorker.prototype = { postMessage: function(message) { function dispatch() { if (this._dispatcher) this._dispatcher.dispatchMessage({data: message}); } setTimeout(dispatch.bind(this), 0); }, terminate: function() { this._dispatcher = null; }, _postMessageFromWorker: function(message) { function send() { this.dispatchEventToListeners("message", message); } setTimeout(send.bind(this), 0); } }; WebInspector.HeapSnapshotFakeWorker.prototype.__proto__ = WebInspector.Object.prototype; WebInspector.HeapSnapshotWorker = function() { this._nextObjectId = 1; this._nextCallId = 1; this._callbacks = []; this._previousCallbacks = []; // There is no support for workers in Chromium DRT. this._worker = typeof InspectorTest === "undefined" ? new WebInspector.HeapSnapshotRealWorker() : new WebInspector.HeapSnapshotFakeWorker(); this._worker.addEventListener("message", this._messageReceived.bind(this), false); } WebInspector.HeapSnapshotWorker.prototype = { createObject: function(constructorName) { var proxyConstructorFunction = this._findFunction(constructorName + "Proxy"); var objectId = this._nextObjectId++; var proxy = new proxyConstructorFunction(this, objectId); this._postMessage({callId: this._nextCallId++, disposition: "create", objectId: objectId, methodName: constructorName}); return proxy; }, dispose: function() { this._worker.terminate(); if (this._interval) clearInterval(this._interval); }, disposeObject: function(objectId) { this._postMessage({callId: this._nextCallId++, disposition: "dispose", objectId: objectId}); }, callGetter: function(callback, objectId, getterName) { var callId = this._nextCallId++; this._callbacks[callId] = callback; this._postMessage({callId: callId, disposition: "getter", objectId: objectId, methodName: getterName}); }, callFactoryMethod: function(callback, objectId, methodName, proxyConstructorName) { var callId = this._nextCallId++; var methodArguments = Array.prototype.slice.call(arguments, 4); var newObjectId = this._nextObjectId++; var proxyConstructorFunction = this._findFunction(proxyConstructorName); if (callback) { function wrapCallback(remoteResult) { callback(remoteResult ? new proxyConstructorFunction(this, newObjectId) : null); } this._callbacks[callId] = wrapCallback.bind(this); this._postMessage({callId: callId, disposition: "factory", objectId: objectId, methodName: methodName, methodArguments: methodArguments, newObjectId: newObjectId}); return null; } else { this._postMessage({callId: callId, disposition: "factory", objectId: objectId, methodName: methodName, methodArguments: methodArguments, newObjectId: newObjectId}); return new proxyConstructorFunction(this, newObjectId); } }, callMethod: function(callback, objectId, methodName) { var callId = this._nextCallId++; var methodArguments = Array.prototype.slice.call(arguments, 3); if (callback) this._callbacks[callId] = callback; this._postMessage({callId: callId, disposition: "method", objectId: objectId, methodName: methodName, methodArguments: methodArguments}); }, startCheckingForLongRunningCalls: function() { this._checkLongRunningCalls(); this._interval = setInterval(this._checkLongRunningCalls.bind(this), 300); }, _checkLongRunningCalls: function() { for (var callId in this._previousCallbacks) if (!(callId in this._callbacks)) delete this._previousCallbacks[callId]; var hasLongRunningCalls = false; for (callId in this._previousCallbacks) { hasLongRunningCalls = true; break; } this.dispatchEventToListeners("wait", hasLongRunningCalls); for (callId in this._callbacks) this._previousCallbacks[callId] = true; }, _findFunction: function(name) { var path = name.split("."); var result = window; for (var i = 0; i < path.length; ++i) result = result[path[i]]; return result; }, _messageReceived: function(event) { var data = event.data; if (event.data.error) { if (event.data.errorMethodName) WebInspector.log(WebInspector.UIString("An error happened when a call for method '%s' was requested", event.data.errorMethodName)); WebInspector.log(event.data.errorCallStack); delete this._callbacks[data.callId]; return; } if (!this._callbacks[data.callId]) return; var callback = this._callbacks[data.callId]; delete this._callbacks[data.callId]; callback(data.result); }, _postMessage: function(message) { this._worker.postMessage(message); } }; WebInspector.HeapSnapshotWorker.prototype.__proto__ = WebInspector.Object.prototype; WebInspector.HeapSnapshotProxyObject = function(worker, objectId) { this._worker = worker; this._objectId = objectId; } WebInspector.HeapSnapshotProxyObject.prototype = { _callWorker: function(workerMethodName, args) { args.splice(1, 0, this._objectId); return this._worker[workerMethodName].apply(this._worker, args); }, dispose: function() { this._worker.disposeObject(this._objectId); }, disposeWorker: function() { this._worker.dispose(); }, callFactoryMethod: function(callback, methodName, proxyConstructorName) { return this._callWorker("callFactoryMethod", Array.prototype.slice.call(arguments, 0)); }, callGetter: function(callback, getterName) { return this._callWorker("callGetter", Array.prototype.slice.call(arguments, 0)); }, callMethod: function(callback, methodName) { return this._callWorker("callMethod", Array.prototype.slice.call(arguments, 0)); }, get worker() { return this._worker; } }; WebInspector.HeapSnapshotLoaderProxy = function(worker, objectId) { WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId); this._loading = false; this._loaded = false; } WebInspector.HeapSnapshotLoaderProxy.prototype = { finishLoading: function(callback) { if (!this._loading) return false; var loadCallbacks = this._onLoadCallbacks; loadCallbacks.splice(0, 0, callback); delete this._onLoadCallbacks; this._loading = false; this._loaded = true; var self = this; function updateStaticData(snapshotProxy) { this.dispose(); snapshotProxy.updateStaticData(this._callLoadCallbacks.bind(this, loadCallbacks)); } this.callFactoryMethod(updateStaticData.bind(this), "finishLoading", "WebInspector.HeapSnapshotProxy"); return true; }, _callLoadCallbacks: function(loadCallbacks, snapshotProxy) { for (var i = 0; i < loadCallbacks.length; ++i) loadCallbacks[i](snapshotProxy); }, get loaded() { return this._loaded; }, startLoading: function(callback) { if (!this._loading) { this._onLoadCallbacks = [callback]; this._loading = true; return true; } else { this._onLoadCallbacks.push(callback); return false; } }, pushJSONChunk: function(chunk) { if (!this._loading) return; this.callMethod(null, "pushJSONChunk", chunk); } }; WebInspector.HeapSnapshotLoaderProxy.prototype.__proto__ = WebInspector.HeapSnapshotProxyObject.prototype; WebInspector.HeapSnapshotProxy = function(worker, objectId) { WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId); } WebInspector.HeapSnapshotProxy.prototype = { aggregates: function(sortedIndexes, key, filter, callback) { this.callMethod(callback, "aggregates", sortedIndexes, key, filter); }, createDiff: function(className) { return this.callFactoryMethod(null, "createDiff", "WebInspector.HeapSnapshotsDiffProxy", className); }, createEdgesProvider: function(nodeIndex, filter) { return this.callFactoryMethod(null, "createEdgesProvider", "WebInspector.HeapSnapshotProviderProxy", nodeIndex, filter); }, createRetainingEdgesProvider: function(nodeIndex, filter) { return this.callFactoryMethod(null, "createRetainingEdgesProvider", "WebInspector.HeapSnapshotProviderProxy", nodeIndex, filter); }, createNodesProvider: function(filter) { return this.callFactoryMethod(null, "createNodesProvider", "WebInspector.HeapSnapshotProviderProxy", filter); }, createNodesProviderForClass: function(className, aggregatesKey) { return this.callFactoryMethod(null, "createNodesProviderForClass", "WebInspector.HeapSnapshotProviderProxy", className, aggregatesKey); }, createNodesProviderForDominator: function(nodeIndex, filter) { return this.callFactoryMethod(null, "createNodesProviderForDominator", "WebInspector.HeapSnapshotProviderProxy", nodeIndex, filter); }, dispose: function() { this.disposeWorker(); }, finishLoading: function() { return false; }, get loaded() { return !!this._objectId; }, get maxNodeId() { return this._staticData.maxNodeId; }, get nodeCount() { return this._staticData.nodeCount; }, nodeFieldValuesByIndex: function(fieldName, indexes, callback) { this.callMethod(callback, "nodeFieldValuesByIndex", fieldName, indexes); }, get nodeFlags() { return this._staticData.nodeFlags; }, pushBaseIds: function(snapshotId, className, nodeIds) { this.callMethod(null, "pushBaseIds", snapshotId, className, nodeIds); }, get rootNodeIndex() { return this._staticData.rootNodeIndex; }, updateStaticData: function(callback) { function dataReceived(staticData) { this._staticData = staticData; callback(this); } this.callMethod(dataReceived.bind(this), "updateStaticData"); }, startLoading: function(callback) { setTimeout(callback.bind(null, this), 0); return false; }, get totalSize() { return this._staticData.totalSize; }, get uid() { return this._staticData.uid; } }; WebInspector.HeapSnapshotProxy.prototype.__proto__ = WebInspector.HeapSnapshotProxyObject.prototype; WebInspector.HeapSnapshotProviderProxy = function(worker, objectId) { WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId); } WebInspector.HeapSnapshotProviderProxy.prototype = { isEmpty: function(callback) { this.callGetter(callback, "isEmpty"); }, serializeNextItems: function(count, callback) { this.callMethod(callback, "serializeNextItems", count); }, sortAndRewind: function(comparator, callback) { this.callMethod(callback, "sortAndRewind", comparator); } }; WebInspector.HeapSnapshotProviderProxy.prototype.__proto__ = WebInspector.HeapSnapshotProxyObject.prototype; WebInspector.HeapSnapshotPathFinderProxy = function(worker, objectId) { WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId); } WebInspector.HeapSnapshotPathFinderProxy.prototype = { findNext: function(callback) { this.callMethod(callback, "findNext"); }, updateRoots: function(filter) { this.callMethod(null, "updateRoots", filter); } }; WebInspector.HeapSnapshotPathFinderProxy.prototype.__proto__ = WebInspector.HeapSnapshotProxyObject.prototype; WebInspector.HeapSnapshotsDiffProxy = function(worker, objectId) { WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId); } WebInspector.HeapSnapshotsDiffProxy.prototype = { calculate: function(callback) { this.callMethod(callback, "calculate"); }, pushBaseIds: function(baseIds) { this.callMethod(null, "pushBaseIds", baseIds); }, pushBaseSelfSizes: function(baseSelfSizes) { this.callMethod(null, "pushBaseSelfSizes", baseSelfSizes); } }; WebInspector.HeapSnapshotsDiffProxy.prototype.__proto__ = WebInspector.HeapSnapshotProxyObject.prototype;