gecko-dev/browser/components/extensions/ParseNMSymbols-worker.js
Doug Thayer ed9ed87b3e Bug 1362786 - (2) Run NMParser in worker r=kmag
Pulls out the NMParser work (parsing nm results and turning
them into an ArrayBuffer'd map of addresses to symbols) into
a worker.

For OSX we will still need to do some work to run c++filt in the
background, but this gets us most of the way there. Without a
Subprocess.jsm usable from a worker, we'll have to bounce data
back to the main thread in order to bounce it to the c++filt
worker.

MozReview-Commit-ID: LZi7J1qGpmh

--HG--
extra : rebase_source : 048329fb085542ecc4c8f8d872e6c4cf0b535376
2017-07-21 14:14:17 -07:00

86 lines
2.7 KiB
JavaScript

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* eslint-env worker */
"use strict";
importScripts("resource:///modules/ParseSymbols.jsm");
class WorkerNMParser {
constructor() {
this._decoder = new TextDecoder();
this._addrToSymMap = new Map();
this._approximateLength = 0;
}
consume(arrayBuffer) {
const data = this._decoder.decode(arrayBuffer, {stream: true});
const lineRegex = /.*\n?/g;
const buffer = this._currentLine + data;
let match;
while ((match = lineRegex.exec(buffer))) {
let [line] = match;
if (line[line.length - 1] === "\n") {
this._processLine(line);
} else {
this._currentLine = line;
break;
}
}
}
finish() {
this._processLine(this._currentLine);
return {syms: this._addrToSymMap, approximateLength: this._approximateLength};
}
_processLine(line) {
// Example lines:
// 00000000028c9888 t GrFragmentProcessor::MulOutputByInputUnpremulColor(sk_sp<GrFragmentProcessor>)::PremulFragmentProcessor::onCreateGLSLInstance() const::GLFP::~GLFP()
// 00000000028c9874 t GrFragmentProcessor::MulOutputByInputUnpremulColor(sk_sp<GrFragmentProcessor>)::PremulFragmentProcessor::onCreateGLSLInstance() const::GLFP::~GLFP()
// 00000000028c9874 t GrFragmentProcessor::MulOutputByInputUnpremulColor(sk_sp<GrFragmentProcessor>)::PremulFragmentProcessor::onCreateGLSLInstance() const::GLFP::~GLFP()
// 0000000003a33730 r mozilla::OggDemuxer::~OggDemuxer()::{lambda()#1}::operator()() const::__func__
// 0000000003a33930 r mozilla::VPXDecoder::Drain()::{lambda()#1}::operator()() const::__func__
//
// Some lines have the form
// <address> ' ' <letter> ' ' <symbol>
// and some have the form
// <address> ' ' <symbol>
// The letter has a meaning, but we ignore it.
const regex = /([^ ]+) (?:. )?(.*)/;
let match = regex.exec(line);
if (match) {
const [, address, symbol] = match;
this._addrToSymMap.set(parseInt(address, 16), symbol);
this._approximateLength += symbol.length;
}
}
}
let nmParser;
onmessage = async e => {
try {
if (!nmParser) {
nmParser = new WorkerNMParser();
}
if (e.data.finish) {
const {syms, approximateLength} = nmParser.finish();
let result;
if (e.data.isDarwin) {
result = ParseSymbols.convertSymsMapToDemanglerFormat(syms);
} else {
result = ParseSymbols.convertSymsMapToExpectedSymFormat(syms, approximateLength);
}
postMessage({result}, result.map(r => r.buffer));
close();
} else {
nmParser.consume(e.data.buffer);
}
} catch (error) {
postMessage({error: error.toString()});
}
};