• 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
16importScripts('trace_converter_builtin.js');
17self.onerror = function (error: any) {};
18
19let convertModule: any = null;
20
21function initConvertWASM() {
22  return new Promise((resolve, reject) => {
23    // @ts-ignore
24    let wasm = trace_converter_builtin_wasm;
25    convertModule = wasm({
26      locateFile: (s: any) => {
27        return s;
28      },
29      print: (line: any) => {},
30      printErr: (line: any) => {},
31      onAbort: () => {
32        reject('on abort');
33      },
34      onRuntimeInitialized: () => {
35        resolve('ok');
36      },
37    });
38  });
39}
40
41const ARRAY_BUF_SIZE = 2 * 1024 * 1024;
42self.onmessage = async (e: MessageEvent) => {
43  if (e.data.action === 'getConvertData') {
44    await initConvertWASM();
45    let fileData = e.data.buffer;
46    const stepSize = 4 * 1024 * 1024;
47    let totalSize = fileData.byteLength;
48    let traceInsPtr = convertModule._GetTraceConverterIns(); // 获取TraceConverter 实例
49    convertModule._SetDebugFlag(false, traceInsPtr); // 设置是否为debug模式
50    let uint8Array = new Uint8Array(fileData.slice(0, 8)); // 获取前8个字节,用来判断文件是htrace还是raw trace
51    let enc = new TextDecoder();
52    let headerStr = enc.decode(uint8Array);
53    let currentPosition = 1024;
54    let dataHeader = convertModule._malloc(1100);
55    let traceAllData = new Uint8Array(e.data.buffer);
56    if (headerStr.indexOf('OHOSPROF') === 0) {
57      handleHTrace(fileData, dataHeader, traceInsPtr);
58    } else {
59      handleRowTrace(e, fileData, dataHeader, traceInsPtr, currentPosition, traceAllData, totalSize);
60    }
61    let dataPtr = convertModule._malloc(stepSize);
62    let arrayBufferPtr = convertModule._malloc(ARRAY_BUF_SIZE);
63    convertModule._free(dataHeader);
64    let bodyDataStr: string[] = [];
65    let callback = (heapPtr: number, size: number) => {
66      let out = convertModule.HEAPU8.slice(heapPtr, heapPtr + size);
67      let dec = new TextDecoder();
68      let str = dec.decode(out);
69      bodyDataStr.push(str);
70    };
71    let bodyFn = convertModule.addFunction(callback, 'vii');
72    convertModule._SetCallback(bodyFn, traceInsPtr);
73    convertData(currentPosition, traceAllData, arrayBufferPtr, dataPtr, traceInsPtr, headerStr, stepSize, totalSize);
74    convertModule._GetRemainingData(traceInsPtr);
75    let headerData: string[] = [];
76    let headerCallback = (heapPtr: number, size: number) => {
77      let out = convertModule.HEAPU8.slice(heapPtr, heapPtr + size);
78      let dec = new TextDecoder();
79      let str = dec.decode(out);
80      headerData.push(str);
81    };
82    let headerFn = convertModule.addFunction(headerCallback, 'vii');
83    convertModule._SetCallback(headerFn, traceInsPtr);
84    convertModule._GetFinalHeader(traceInsPtr);
85    let allDataStr = headerData.concat(bodyDataStr);
86    convertModule._ReleaseTraceConverterIns(traceInsPtr); // 释放TraceConverter 实例
87    convertModule._free(arrayBufferPtr); //释放分片内存
88    convertModule._free(dataPtr);
89    postMessage(e, allDataStr);
90  }
91};
92function handleHTrace(fileData: Array<any>, dataHeader: any, traceInsPtr: any) {
93  let uint8Array = new Uint8Array(fileData.slice(0, 1024));
94  convertModule.HEAPU8.set(uint8Array, dataHeader);
95  convertModule._SendFileHeader(dataHeader, 1024, traceInsPtr);
96}
97function handleRowTrace(
98  e: MessageEvent,
99  fileData: Array<any>,
100  dataHeader: any,
101  traceInsPtr: any,
102  currentPosition: number,
103  traceAllData: Uint8Array,
104  totalSize: number
105): void {
106  let uint8Array = new Uint8Array(fileData.slice(0, 12));
107  convertModule.HEAPU8.set(uint8Array, dataHeader);
108  convertModule._SendRawFileHeader(dataHeader, 12, traceInsPtr);
109  currentPosition = 12;
110  let allRowTraceData = new Uint8Array(e.data.buffer);
111  let commonDataOffsetList: Array<{
112    startOffset: number;
113    endOffset: number;
114  }> = [];
115  let commonTotalLength = 0;
116  setCommonDataOffsetList(e, allRowTraceData, commonTotalLength, commonDataOffsetList);
117  let commonTotalOffset = 0;
118  let commonTotalData = new Uint8Array(commonTotalLength);
119  commonDataOffsetList.forEach((item) => {
120    commonTotalData.set(allRowTraceData.slice(item.startOffset, item.endOffset), commonTotalOffset);
121    commonTotalOffset += item.endOffset - item.startOffset;
122  });
123  traceAllData = new Uint8Array(allRowTraceData.length + commonTotalData.length);
124  traceAllData.set(allRowTraceData.slice(0, currentPosition), 0);
125  traceAllData.set(commonTotalData, currentPosition);
126  traceAllData.set(allRowTraceData.slice(currentPosition), commonTotalData.length + currentPosition);
127  totalSize += commonTotalData.length;
128}
129function setCommonDataOffsetList(
130  e: MessageEvent,
131  allRowTraceData: Uint8Array,
132  commonTotalLength: number,
133  commonDataOffsetList: Array<any>
134): void {
135  let commonOffset = 12;
136  let tlvTypeLength = 4;
137  while (commonOffset < allRowTraceData.length) {
138    let commonDataOffset = {
139      startOffset: commonOffset,
140      endOffset: commonOffset,
141    };
142    let dataTypeData = e.data.buffer.slice(commonOffset, commonOffset + tlvTypeLength);
143    commonOffset += tlvTypeLength;
144    let dataType = Array.from(new Uint32Array(dataTypeData));
145    let currentLData = e.data.buffer.slice(commonOffset, commonOffset + tlvTypeLength);
146    commonOffset += tlvTypeLength;
147    let currentVLength = Array.from(new Uint32Array(currentLData));
148    commonOffset += currentVLength[0];
149    commonDataOffset.endOffset = commonOffset;
150    if (dataType[0] === 2 || dataType[0] === 3) {
151      commonTotalLength += commonDataOffset.endOffset - commonDataOffset.startOffset;
152      commonDataOffsetList.push(commonDataOffset);
153    }
154  }
155}
156function convertData(
157  currentPosition: number,
158  traceAllData: Uint8Array,
159  arrayBufferPtr: any,
160  dataPtr: any,
161  traceInsPtr: any,
162  headerStr: string,
163  stepSize: number,
164  totalSize: number
165): void {
166  while (currentPosition < totalSize) {
167    let endPosition = Math.min(currentPosition + stepSize, totalSize);
168    let currentChunk = new Uint8Array(traceAllData.slice(currentPosition, endPosition));
169    convertModule.HEAPU8.set(currentChunk, dataPtr);
170    let leftLen = currentChunk.length;
171    let processedLen = 0;
172    let blockSize = 0;
173    let blockPtr = dataPtr;
174    while (leftLen > 0) {
175      if (leftLen > ARRAY_BUF_SIZE) {
176        blockSize = ARRAY_BUF_SIZE;
177      } else {
178        blockSize = leftLen;
179      }
180      let subArrayBuffer = convertModule.HEAPU8.subarray(blockPtr, blockPtr + blockSize);
181      convertModule.HEAPU8.set(subArrayBuffer, arrayBufferPtr);
182      // 调用分片转换接口
183      if (headerStr.indexOf('OHOSPROF') === 0) {
184        // htrace
185        convertModule._ConvertBlockData(arrayBufferPtr, subArrayBuffer.length, traceInsPtr);
186      } else {
187        // raw trace
188        convertModule._ConvertRawBlockData(arrayBufferPtr, subArrayBuffer.length, traceInsPtr);
189      }
190      processedLen = processedLen + blockSize;
191      blockPtr = dataPtr + processedLen;
192      leftLen = currentChunk.length - processedLen;
193    }
194    currentPosition = endPosition;
195  }
196}
197function postMessage(e: MessageEvent, allDataStr: Array<string>): void {
198  self.postMessage(
199    {
200      id: e.data.id,
201      action: 'convert',
202      status: true,
203      results: new Blob(allDataStr, { type: 'text/plain' }),
204      buffer: e.data.buffer,
205    },
206    // @ts-ignore
207    [e.data.buffer!]
208  );
209}
210