Added SDK
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Apple 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:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
|
||||
*/
|
||||
|
||||
WI.ProfileNode = class ProfileNode
|
||||
{
|
||||
constructor(id, type, functionName, sourceCodeLocation, callInfo, childNodes)
|
||||
{
|
||||
childNodes = childNodes || [];
|
||||
|
||||
console.assert(id);
|
||||
console.assert(callInfo && !isEmptyObject(callInfo));
|
||||
console.assert(childNodes instanceof Array);
|
||||
console.assert(childNodes.every((node) => node instanceof WI.ProfileNode));
|
||||
|
||||
this._id = id;
|
||||
this._type = type || WI.ProfileNode.Type.Function;
|
||||
this._functionName = functionName || null;
|
||||
this._sourceCodeLocation = sourceCodeLocation || null;
|
||||
this._callInfo = callInfo;
|
||||
this._childNodes = childNodes;
|
||||
this._parentNode = null;
|
||||
this._previousSibling = null;
|
||||
this._nextSibling = null;
|
||||
this._computedTotalTimes = false;
|
||||
|
||||
this._startTime = this._callInfo.startTime;
|
||||
this._endTime = this._callInfo.endTime;
|
||||
this._totalTime = this._callInfo.totalTime;
|
||||
this._callCount = this._callInfo.callCount;
|
||||
|
||||
for (var i = 0; i < this._childNodes.length; ++i)
|
||||
this._childNodes[i].establishRelationships(this, this._childNodes[i - 1], this._childNodes[i + 1]);
|
||||
}
|
||||
|
||||
// Public
|
||||
|
||||
get id() { return this._id; }
|
||||
get type() { return this._type; }
|
||||
get functionName() { return this._functionName; }
|
||||
get sourceCodeLocation() { return this._sourceCodeLocation; }
|
||||
get callInfo() { return this._callInfo; }
|
||||
get previousSibling() { return this._previousSibling; }
|
||||
get nextSibling() { return this._nextSibling; }
|
||||
get parentNode() { return this._parentNode; }
|
||||
get childNodes() { return this._childNodes; }
|
||||
get startTime() { return this._startTime; }
|
||||
get endTime() { return this._endTime; }
|
||||
|
||||
get selfTime()
|
||||
{
|
||||
this._computeTotalTimesIfNeeded();
|
||||
return this._selfTime;
|
||||
}
|
||||
|
||||
get totalTime()
|
||||
{
|
||||
this._computeTotalTimesIfNeeded();
|
||||
return this._totalTime;
|
||||
}
|
||||
|
||||
computeCallInfoForTimeRange(rangeStartTime, rangeEndTime)
|
||||
{
|
||||
console.assert(typeof rangeStartTime === "number");
|
||||
console.assert(typeof rangeEndTime === "number");
|
||||
|
||||
// With aggregate call info we can't accurately partition self/total/average time
|
||||
// in partial ranges because we don't know exactly when each call started. So we
|
||||
// always return the entire range.
|
||||
if (this._selfTime === undefined) {
|
||||
var childNodesTotalTime = 0;
|
||||
for (var childNode of this._childNodes)
|
||||
childNodesTotalTime += childNode.totalTime;
|
||||
this._selfTime = this._totalTime - childNodesTotalTime;
|
||||
// selfTime can negative or very close to zero due to floating point error.
|
||||
// Since we show at most four decimal places, treat anything less as zero.
|
||||
if (this._selfTime < 0.0001)
|
||||
this._selfTime = 0.0;
|
||||
}
|
||||
|
||||
return {
|
||||
callCount: this._callCount,
|
||||
startTime: this._startTime,
|
||||
endTime: this._endTime,
|
||||
selfTime: this._selfTime,
|
||||
totalTime: this._totalTime,
|
||||
averageTime: this._selfTime / this._callCount,
|
||||
};
|
||||
}
|
||||
|
||||
traverseNextProfileNode(stayWithin)
|
||||
{
|
||||
var profileNode = this._childNodes[0];
|
||||
if (profileNode)
|
||||
return profileNode;
|
||||
|
||||
if (this === stayWithin)
|
||||
return null;
|
||||
|
||||
profileNode = this._nextSibling;
|
||||
if (profileNode)
|
||||
return profileNode;
|
||||
|
||||
profileNode = this;
|
||||
while (profileNode && !profileNode.nextSibling && profileNode.parentNode !== stayWithin)
|
||||
profileNode = profileNode.parentNode;
|
||||
|
||||
if (!profileNode)
|
||||
return null;
|
||||
|
||||
return profileNode.nextSibling;
|
||||
}
|
||||
|
||||
saveIdentityToCookie(cookie)
|
||||
{
|
||||
cookie[WI.ProfileNode.TypeCookieKey] = this._type || null;
|
||||
cookie[WI.ProfileNode.FunctionNameCookieKey] = this._functionName || null;
|
||||
cookie[WI.ProfileNode.SourceCodeURLCookieKey] = this._sourceCodeLocation ? this._sourceCodeLocation.sourceCode.url ? this._sourceCodeLocation.sourceCode.url.hash : null : null;
|
||||
cookie[WI.ProfileNode.SourceCodeLocationLineCookieKey] = this._sourceCodeLocation ? this._sourceCodeLocation.lineNumber : null;
|
||||
cookie[WI.ProfileNode.SourceCodeLocationColumnCookieKey] = this._sourceCodeLocation ? this._sourceCodeLocation.columnNumber : null;
|
||||
}
|
||||
|
||||
// Protected
|
||||
|
||||
establishRelationships(parentNode, previousSibling, nextSibling)
|
||||
{
|
||||
this._parentNode = parentNode || null;
|
||||
this._previousSibling = previousSibling || null;
|
||||
this._nextSibling = nextSibling || null;
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
_computeTotalTimesIfNeeded()
|
||||
{
|
||||
if (this._computedTotalTimes)
|
||||
return;
|
||||
|
||||
this._computedTotalTimes = true;
|
||||
|
||||
var info = this.computeCallInfoForTimeRange(0, Infinity);
|
||||
this._startTime = info.startTime;
|
||||
this._endTime = info.endTime;
|
||||
this._selfTime = info.selfTime;
|
||||
this._totalTime = info.totalTime;
|
||||
}
|
||||
};
|
||||
|
||||
WI.ProfileNode.Type = {
|
||||
Function: "profile-node-type-function",
|
||||
Program: "profile-node-type-program"
|
||||
};
|
||||
|
||||
WI.ProfileNode.TypeIdentifier = "profile-node";
|
||||
WI.ProfileNode.TypeCookieKey = "profile-node-type";
|
||||
WI.ProfileNode.FunctionNameCookieKey = "profile-node-function-name";
|
||||
WI.ProfileNode.SourceCodeURLCookieKey = "profile-node-source-code-url";
|
||||
WI.ProfileNode.SourceCodeLocationLineCookieKey = "profile-node-source-code-location-line";
|
||||
WI.ProfileNode.SourceCodeLocationColumnCookieKey = "profile-node-source-code-location-column";
|
||||
Reference in New Issue
Block a user