Skip to content

Commit

Permalink
add support for "wasm-function" symbol maps
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 18, 2018
1 parent 8fcc0f8 commit e1e07f2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 39 deletions.
6 changes: 3 additions & 3 deletions application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {SortMethod, SortField, SortDirection} from './profile-table-view'
import {triangle} from './utils'
import {Color} from './color'
import {RowAtlas} from './row-atlas'
import {importAsmJsSymbolMap} from './asm-js'
import {importEmscriptenSymbolMap} from './emscripten'
import {SandwichView} from './sandwich-view'
import {saveToFile} from './file-format'

Expand Down Expand Up @@ -384,9 +384,9 @@ export class Application extends ReloadableComponent<{}, ApplicationState> {
// a symbol map. If that's the case, we want to parse it, and apply the symbol
// mapping to the already loaded profile. This can be use to take an opaque
// profile and make it readable.
const map = importAsmJsSymbolMap(reader.result)
const map = importEmscriptenSymbolMap(reader.result)
if (map) {
console.log('Importing as asm.js symbol map')
console.log('Importing as emscripten symbol map')
let profile = this.state.profile
profile.remapNames(name => map.get(name) || name)
return profile
Expand Down
26 changes: 0 additions & 26 deletions asm-js.ts

This file was deleted.

33 changes: 23 additions & 10 deletions asm-js.test.ts → emscripten.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {importAsmJsSymbolMap} from './asm-js'
import {importEmscriptenSymbolMap} from './emscripten'

test('importAsmJSSymbolMap', () => {
test('importEmscriptenSymbolMap', () => {
// Valid symbol map
expect(
importAsmJsSymbolMap(
importEmscriptenSymbolMap(
[
/* prettier: ignore */
'a:A',
Expand All @@ -15,7 +15,7 @@ test('importAsmJSSymbolMap', () => {

// Valid symbol map with trailing newline
expect(
importAsmJsSymbolMap(
importEmscriptenSymbolMap(
[
/* prettier: ignore */
'a:A',
Expand All @@ -27,14 +27,27 @@ test('importAsmJSSymbolMap', () => {
).toEqual(new Map([['a', 'A'], ['b', 'B'], ['c', 'C']]))

// Valid symbol map with non-alpha characters

expect(importAsmJsSymbolMap('u6:__ZN8tinyxml210XMLCommentD0Ev\n')).toEqual(
expect(importEmscriptenSymbolMap('u6:__ZN8tinyxml210XMLCommentD0Ev\n')).toEqual(
new Map([['u6', '__ZN8tinyxml210XMLCommentD0Ev']]),
)

// WebAssembly symbol map
expect(
importEmscriptenSymbolMap(
[
/* prettier: ignore */
'0:A',
'1:B',
'2:C',
].join('\n'),
),
).toEqual(
new Map([['wasm-function[0]', 'A'], ['wasm-function[1]', 'B'], ['wasm-function[2]', 'C']]),
)

// Invalid symbol map
expect(
importAsmJsSymbolMap(
importEmscriptenSymbolMap(
[
/* prettier: ignore */
'a:A',
Expand All @@ -47,7 +60,7 @@ test('importAsmJSSymbolMap', () => {

// Collapsed stack format should not be imported as an asm.js symbol map
expect(
importAsmJsSymbolMap(
importEmscriptenSymbolMap(
[
/* prettier: ignore */
'a;b 1',
Expand All @@ -58,6 +71,6 @@ test('importAsmJSSymbolMap', () => {
).toEqual(null)

// Unrelated files
expect(importAsmJsSymbolMap('')).toEqual(null)
expect(importAsmJsSymbolMap('\n')).toEqual(null)
expect(importEmscriptenSymbolMap('')).toEqual(null)
expect(importEmscriptenSymbolMap('\n')).toEqual(null)
})
39 changes: 39 additions & 0 deletions emscripten.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
type EmscriptenSymbolMap = Map<string, string>

// This imports symbol maps generated by emscripten using the "--emit-symbol-map" flag.
// It allows you to visualize a profile captured in a release build as long as you also
// have the associated symbol map. To do this, first drop the profile into speedscope
// and then drop the symbol map. After the second drop, the symbols will be remapped to
// their original names.
export function importEmscriptenSymbolMap(contents: string): EmscriptenSymbolMap | null {
const lines = contents.split('\n')
if (!lines.length) return null

// Remove a trailing blank line if there is one
if (lines[lines.length - 1] === '') lines.pop()
if (!lines.length) return null

const map: EmscriptenSymbolMap = new Map()
const intRegex = /^(\d+):([\$\w]+)$/
const idRegex = /^([\$\w]+):([\$\w]+)$/

for (const line of lines) {
// Match lines like "103:__ZN8tinyxml210XMLCommentD0Ev"
const intMatch = intRegex.exec(line)
if (intMatch) {
map.set(`wasm-function[${intMatch[1]}]`, intMatch[2])
continue
}

// Match lines like "u6:__ZN8tinyxml210XMLCommentD0Ev"
const idMatch = idRegex.exec(line)
if (idMatch) {
map.set(idMatch[1], idMatch[2])
continue
}

return null
}

return map
}

0 comments on commit e1e07f2

Please sign in to comment.