@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 6.09 kB
JavaScript
import*as Common from"../../core/common/common.js";import*as Platform from"../../core/platform/platform.js";import{ProfileNode,ProfileTreeModel}from"./ProfileTreeModel.js";export class CPUProfileNode extends ProfileNode{id;self;positionTicks;deoptReason;constructor(e,t){super(e.callFrame||{functionName:e.functionName,scriptId:e.scriptId,url:e.url,lineNumber:e.lineNumber-1,columnNumber:e.columnNumber-1}),this.id=e.id,this.self=(e.hitCount||0)*t,this.positionTicks=e.positionTicks,this.deoptReason=e.deoptReason&&"no reason"!==e.deoptReason?e.deoptReason:null}}export class CPUProfileDataModel extends ProfileTreeModel{profileStartTime;profileEndTime;timestamps;samples;lines;totalHitCount;profileHead;#e;gcNode;programNode;idleNode;#t;#i;constructor(e){super();Boolean(e.head)?(this.profileStartTime=1e3*e.startTime,this.profileEndTime=1e3*e.endTime,this.timestamps=e.timestamps,this.compatibilityConversionHeadToNodes(e)):(this.profileStartTime=e.startTime/1e3,this.profileEndTime=e.endTime/1e3,this.timestamps=this.convertTimeDeltas(e)),this.samples=e.samples,this.lines=e.lines,this.totalHitCount=0,this.profileHead=this.translateProfileTree(e.nodes),this.initialize(this.profileHead),this.extractMetaNodes(),this.samples&&(this.sortSamples(),this.normalizeTimestamps(),this.fixMissingSamples())}compatibilityConversionHeadToNodes(e){if(!e.head||e.nodes)return;const t=[];!function e(i){return t.push(i),i.children=i.children.map(e),i.id}(e.head),e.nodes=t,delete e.head}convertTimeDeltas(e){if(!e.timeDeltas)return[];let t=e.startTime;const i=new Array(e.timeDeltas.length);for(let s=0;s<e.timeDeltas.length;++s)t+=e.timeDeltas[s],i[s]=t;return i}translateProfileTree(e){const t=new Map;for(let i=0;i<e.length;++i){const s=e[i];t.set(s.id,s)}!function(e,i){if("number"!=typeof e[0].hitCount){if(!i)throw new Error("Error: Neither hitCount nor samples are present in profile.");for(let t=0;t<e.length;++t)e[t].hitCount=0;for(let e=0;e<i.length;++e){const s=t.get(i[e]);s&&void 0!==s.hitCount&&s.hitCount++}}}(e,this.samples),function(e){if(!e[0].children){e[0].children=[];for(let i=1;i<e.length;++i){const s=e[i],o=t.get(s.parent);o.children?o.children.push(s.id):o.children=[s.id]}}}(e),this.totalHitCount=e.reduce(((e,t)=>e+(t.hitCount||0)),0);const i=(this.profileEndTime-this.profileStartTime)/this.totalHitCount,s=Boolean(Common.Settings.Settings.hasInstance()&&Common.Settings.Settings.instance().moduleSetting("showNativeFunctionsInJSProfile").get()),o=e[0],r=new Map([[o.id,o.id]]);this.#e=new Map;const n=new CPUProfileNode(o,i);if(this.#e.set(o.id,n),!o.children)throw new Error("Missing children for root");const l=o.children.map((()=>n)),a=o.children.map((e=>t.get(e)));for(;a.length;){let e=l.pop();const o=a.pop();if(!o||!e)continue;o.children||(o.children=[]);const n=new CPUProfileNode(o,i);s||!((h=o).callFrame?Boolean(h.callFrame.url)&&h.callFrame.url.startsWith("native "):Boolean(h.url)&&h.url.startsWith("native "))?(e.children.push(n),e=n):e.self+=n.self,r.set(o.id,e.id),l.push.apply(l,o.children.map((()=>e))),a.push.apply(a,o.children.map((e=>t.get(e)))),this.#e.set(o.id,n)}var h;return this.samples&&(this.samples=this.samples.map((e=>r.get(e)))),n}sortSamples(){if(!this.timestamps||!this.samples)return;const e=this.timestamps,t=this.samples,i=e.map(((e,t)=>t));i.sort(((t,i)=>e[t]-e[i])),this.timestamps=[],this.samples=[];for(let s=0;s<i.length;s++){const o=i[s];this.timestamps.push(e[o]),this.samples.push(t[o])}}normalizeTimestamps(){if(!this.samples)return;let e=this.timestamps;if(e){for(let t=0;t<e.length;++t)e[t]/=1e3;if(this.samples.length===e.length){const t=e.at(-1)||0,i=(t-e[0])/(e.length-1);this.timestamps.push(t+i)}this.profileStartTime=e.at(0)||this.profileStartTime,this.profileEndTime=e.at(-1)||this.profileEndTime}else{const t=this.profileStartTime,i=(this.profileEndTime-t)/this.samples.length;e=new Array(this.samples.length+1);for(let s=0;s<e.length;++s)e[s]=t+s*i;this.timestamps=e}}extractMetaNodes(){const e=this.profileHead.children;for(let t=0;t<e.length&&!(this.gcNode&&this.programNode&&this.idleNode);t++){const i=e[t];"(garbage collector)"===i.functionName?this.gcNode=i:"(program)"===i.functionName?this.programNode=i:"(idle)"===i.functionName&&(this.idleNode=i)}}fixMissingSamples(){const e=this.samples;if(!e)return;const t=e.length;if(!this.programNode||t<3)return;const i=this.#e,s=this.programNode.id,o=this.gcNode?this.gcNode.id:-1,r=this.idleNode?this.idleNode.id:-1;let n=e[0],l=e[1];for(let o=1;o<t-1;o++){const t=e[o+1],r=i.get(n),d=i.get(t);void 0!==n&&void 0!==t&&r&&d?(l!==s||h(n)||h(t)||a(r)!==a(d)||(e[o]=n),n=l,l=t):console.error(`Unexpectedly found undefined nodes: ${n} ${t}`)}function a(e){for(;e.parent&&e.parent.parent;)e=e.parent;return e}function h(e){return e===s||e===o||e===r}}forEachFrame(e,t,i,s){if(!this.profileHead||!this.samples)return;i=i||0,s=s||1/0;const o=this.samples,r=this.timestamps,n=this.#e,l=this.gcNode,a=o.length,h=Platform.ArrayUtilities.lowerBound(r,i,Platform.ArrayUtilities.DEFAULT_COMPARATOR);let d=0;const p=[];let m,c=this.profileHead.id,f=null;const u=this.maxDepth+3;this.#t||(this.#t=new Array(u));const g=this.#t;this.#i||(this.#i=new Array(u));const T=this.#i;let N,P;for(P=h;P<a&&(m=r[P],!(m>=s));P++){const i=o[P];if(i===c)continue;N=n.get(i);let s=n.get(c)||null;if(s)if(l&&N===l)f=s,e(f.depth+1,l,m),g[++d]=m,T[d]=0,c=i;else{if(l&&s===l&&f){const e=g[d],i=m-e;T[d-1]+=i,t(f.depth+1,l,e,i,i-T[d]),--d,s=f,c=s.id,f=null}for(;N&&N.depth>s.depth;)p.push(N),N=N.parent;for(;s&&s!==N;){const e=g[d],i=m-e;T[d-1]+=i,t(s.depth,s,e,i,i-T[d]),--d,N&&N.depth===s.depth&&(p.push(N),N=N.parent),s=s.parent}for(;p.length;){const t=p.pop();if(!t)break;N=t,e(t.depth,t,m),g[++d]=m,T[d]=0}c=i}}if(m=r[P]||this.profileEndTime,N&&f&&n.get(c)===l){const e=g[d],i=m-e;T[d-1]+=i,t(f.depth+1,N,e,i,i-T[d]),--d,c=f.id}for(let e=n.get(c);e&&e.parent;e=e.parent){const i=g[d],s=m-i;T[d-1]+=s,t(e.depth,e,i,s,s-T[d]),--d}}nodeByIndex(e){return this.samples&&this.#e.get(this.samples[e])||null}nodeById(e){return this.#e.get(e)||null}nodes(){return this.#e?[...this.#e.values()]:null}}