• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {SpSystemTrace} from "../SpSystemTrace.js";
17import {query, queryAllHeapByEvent, queryHeapGroupByEvent, queryNativeHookProcess} from "../../database/SqlLite.js";
18import {TraceRow} from "../trace/base/TraceRow.js";
19import {info} from "../../../log/Log.js";
20import {procedurePool} from "../../database/Procedure.js";
21import {HeapStruct} from "../../bean/HeapStruct.js";
22import {NativeEvent, NativeEventHeap} from "../../bean/NativeHook.js";
23
24export class SpNativeMemoryChart {
25    static EVENT_HEAP: Array<NativeEventHeap> = [];
26    private trace: SpSystemTrace;
27
28    constructor(trace: SpSystemTrace) {
29        this.trace = trace;
30    }
31
32    initChart = async () => {
33        let time = new Date().getTime();
34        let nativeProcess = await queryNativeHookProcess();
35        info("NativeHook Process data size is: ", nativeProcess!.length)
36        if (nativeProcess.length == 0) {
37            return;
38        }
39        SpNativeMemoryChart.EVENT_HEAP = await queryHeapGroupByEvent();
40        let nativeRow = new TraceRow({
41            canvasNumber: 1,
42            alpha: false,
43            contextId: '2d',
44            isOffScreen: SpSystemTrace.isCanvasOffScreen
45        });
46        let process = "";
47        if (nativeProcess.length > 0) {
48            process = ` ${nativeProcess[0].pid}`
49        }
50        nativeRow.rowId = `native-memory`
51        nativeRow.index = 0;
52        nativeRow.rowType = TraceRow.ROW_TYPE_NATIVE_MEMORY
53        nativeRow.drawType = 0;
54        nativeRow.rowParentId = '';
55        nativeRow.folder = true;
56        nativeRow.name = `Native Memory` + process;
57        nativeRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
58        nativeRow.selectChangeHandler = this.trace.selectChangeHandler;
59        nativeRow.onDrawTypeChangeHandler = (type) => {
60            this.trace.rowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[row-type='heap']`).forEach(it => {
61                it.drawType = type;
62                it.isComplete = false;
63                it.draw();
64            })
65        };
66        nativeRow.supplier = () => new Promise<Array<any>>((resolve, reject) => resolve([]));
67        nativeRow.onThreadHandler = (useCache) => {
68            procedurePool.submitWithName(`process${nativeRow.index}`, `native-memory`, {
69                list: nativeRow.must ? nativeRow.dataList : undefined,
70                offscreen: !nativeRow.isTransferCanvas ? nativeRow.offscreen[0] : undefined,
71                xs: TraceRow.range?.xs,
72                dpr: nativeRow.dpr,
73                isHover: nativeRow.isHover,
74                flagMoveInfo: this.trace.hoverFlag,
75                flagSelectedInfo: this.trace.selectFlag,
76                hoverX: nativeRow.hoverX,
77                hoverY: nativeRow.hoverY,
78                canvasWidth: nativeRow.canvasWidth,
79                canvasHeight: nativeRow.canvasHeight,
80                isRangeSelect: nativeRow.rangeSelect,
81                rangeSelectObject: TraceRow.rangeSelectObject,
82                useCache: useCache,
83                lineColor: nativeRow.getLineColor(),
84                startNS: TraceRow.range?.startNS || 0,
85                endNS: TraceRow.range?.endNS || 0,
86                totalNS: TraceRow.range?.totalNS || 0,
87                slicesTime: TraceRow.range?.slicesTime,
88                range: TraceRow.range,
89                frame: nativeRow.frame
90            }, !nativeRow.isTransferCanvas ? nativeRow.offscreen[0] : undefined, (res: any) => {
91                nativeRow.must = false;
92            });
93            nativeRow.isTransferCanvas = true;
94        }
95
96        this.trace.rowsEL?.appendChild(nativeRow)
97        /**
98         * 添加heap信息
99         */
100        let native_memory = ["All Heap & Anonymous VM", "All Heap", "All Anonymous VM"];
101        for (let i = 0; i < native_memory.length; i++) {
102            let nm = native_memory[i];
103            let allHeapRow = new TraceRow<HeapStruct>({
104                canvasNumber: 1,
105                alpha: false,
106                contextId: '2d',
107                isOffScreen: true
108            });
109            allHeapRow.index = i;
110            allHeapRow.rowParentId = `native-memory`
111            allHeapRow.rowHidden = !nativeRow.expansion
112            allHeapRow.style.height = '40px'
113            allHeapRow.name = nm;
114            allHeapRow.rowId = nm;
115            allHeapRow.drawType = 0;
116            allHeapRow.folder = false;
117            allHeapRow.rowType = TraceRow.ROW_TYPE_HEAP;
118            allHeapRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
119            allHeapRow.selectChangeHandler = this.trace.selectChangeHandler;
120            allHeapRow.setAttribute('children', '')
121            allHeapRow.supplier = () => {
122                return this.getNativeMemoryDataByChartType(i, allHeapRow.drawType)
123            }
124            allHeapRow.onThreadHandler = (useCache) => {
125                procedurePool.submitWithName(`process${allHeapRow.index}`, `heap-${nm}`, {
126                    list: allHeapRow.must ? allHeapRow.dataList : undefined,
127                    offscreen: !allHeapRow.isTransferCanvas ? allHeapRow.offscreen[0] : undefined,
128                    xs: TraceRow.range?.xs,
129                    dpr: allHeapRow.dpr,
130                    isHover: allHeapRow.isHover,
131                    flagMoveInfo: this.trace.hoverFlag,
132                    flagSelectedInfo: this.trace.selectFlag,
133                    hoverX: allHeapRow.hoverX,
134                    hoverY: allHeapRow.hoverY,
135                    canvasWidth: allHeapRow.canvasWidth,
136                    canvasHeight: allHeapRow.canvasHeight,
137                    isRangeSelect: allHeapRow.rangeSelect,
138                    rangeSelectObject: TraceRow.rangeSelectObject,
139                    useCache: useCache,
140                    lineColor: allHeapRow.getLineColor(),
141                    startNS: TraceRow.range?.startNS || 0,
142                    endNS: TraceRow.range?.endNS || 0,
143                    totalNS: TraceRow.range?.totalNS || 0,
144                    slicesTime: TraceRow.range?.slicesTime,
145                    range: TraceRow.range,
146                    frame: allHeapRow.frame
147                }, !allHeapRow.isTransferCanvas ? allHeapRow.offscreen[0] : undefined, (res: any, hover: any) => {
148                    allHeapRow.must = false;
149                    if (allHeapRow.isHover) {
150                        HeapStruct.hoverHeapStruct = hover;
151                    }
152                });
153                allHeapRow.isTransferCanvas = true;
154            }
155            this.trace.rowsEL?.appendChild(allHeapRow)
156        }
157        let durTime = new Date().getTime() - time;
158        info('The time to load the Native Memory data is: ', durTime)
159    }
160
161    getNativeMemoryDataByChartType = async (nativeMemoryType: number, chartType: number): Promise<Array<HeapStruct>> => {
162        let args = new Map<string,any>();
163        args.set("nativeMemoryType",nativeMemoryType);
164        args.set("chartType",chartType);
165        args.set("totalNS",TraceRow.range?.totalNS!);
166        args.set("actionType","memory-chart");
167        let arr:Array<HeapStruct> = await new Promise<any>((resolve, reject) => {
168            procedurePool.submitWithName("logic1","native-memory-action",args,undefined,(res:any)=>{
169                resolve(res)
170            })
171        })
172        return arr;
173    }
174
175    initNativeMemory = async () => {
176        let time = new Date().getTime();
177        await new Promise<any>((resolve, reject) => {
178            procedurePool.submitWithName("logic1","native-memory-init",{},undefined,(res:any)=>{
179                resolve(res)
180            })
181        })
182        let durTime = new Date().getTime() - time;
183        info('The time to init the native memory data is: ', durTime)
184    }
185
186}