forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flutter_runner] Generate symbols for the Dart VM profiler (flutter#1…
…2048) Ported from the original implementation in the Topaz tree.
- Loading branch information
1 parent
954f198
commit bfa43e1
Showing
7 changed files
with
259 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
shell/platform/fuchsia/runtime/dart/profiler_symbols/BUILD.gn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Copyright 2013 The Flutter Authors. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license that can be | ||
# found in the LICENSE file. | ||
|
||
import("//third_party/dart/build/dart/dart_action.gni") | ||
import("$flutter_root/tools/fuchsia/clang.gni") | ||
|
||
template("generate_dart_profiler_symbols") { | ||
assert(defined(invoker.library_label), "Must define 'library_label'") | ||
assert(defined(invoker.library_path), "Must define 'library_path'") | ||
assert(defined(invoker.output), "Must define 'output'") | ||
|
||
prebuilt_dart_action(target_name) { | ||
deps = [ | ||
invoker.library_label, | ||
] | ||
inputs = [ | ||
invoker.library_path, | ||
] | ||
outputs = [ | ||
invoker.output, | ||
] | ||
|
||
script = "dart_profiler_symbols.dart" | ||
|
||
packages = rebase_path("//third_party/dart/.packages") | ||
|
||
args = [ | ||
"--nm", | ||
rebase_path("//fuchsia/toolchain/$host_os/bin/llvm-nm"), | ||
"--binary", | ||
rebase_path(invoker.library_path), | ||
"--output", | ||
rebase_path(invoker.output), | ||
] | ||
} | ||
} | ||
|
||
generate_dart_profiler_symbols("dart_jit_runner") { | ||
library_label = | ||
"$flutter_root/shell/platform/fuchsia/dart_runner:dart_jit_runner_bin" | ||
library_path = "${root_out_dir}/exe.unstripped/dart_jit_runner" | ||
output = "${target_gen_dir}/dart_jit_runner.dartprofilersymbols" | ||
} | ||
|
||
generate_dart_profiler_symbols("flutter_jit_runner") { | ||
library_label = "$flutter_root/shell/platform/fuchsia/flutter:jit" | ||
library_path = "${root_out_dir}/exe.unstripped/flutter_jit_runner" | ||
output = "${target_gen_dir}/flutter_jit_runner.dartprofilersymbols" | ||
} | ||
|
||
generate_dart_profiler_symbols("flutter_aot_runner") { | ||
library_label = "$flutter_root/shell/platform/fuchsia/flutter:aot" | ||
library_path = "${root_out_dir}/exe.unstripped/flutter_aot_runner" | ||
output = "${target_gen_dir}/flutter_aot_runner.dartprofilersymbols" | ||
} |
3 changes: 3 additions & 0 deletions
3
shell/platform/fuchsia/runtime/dart/profiler_symbols/analysis_options.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Copyright 2013 The Flutter Authors. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license that can be | ||
# found in the LICENSE file. |
143 changes: 143 additions & 0 deletions
143
shell/platform/fuchsia/runtime/dart/profiler_symbols/dart_profiler_symbols.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
// On Fuchsia, in lieu of the ELF dynamic symbol table consumed through dladdr, | ||
// the Dart VM profiler consumes symbols produced by this tool, which have the | ||
// format | ||
// | ||
// struct { | ||
// uint32_t num_entries; | ||
// struct { | ||
// uint32_t offset; | ||
// uint32_t size; | ||
// uint32_t string_table_offset; | ||
// } entries[num_entries]; | ||
// const char* string_table; | ||
// } | ||
// | ||
// Entries are sorted by offset. String table entries are NUL-terminated. | ||
// | ||
// See also //third_party/dart/runtime/vm/native_symbol_fuchsia.cc | ||
|
||
import "dart:convert"; | ||
import "dart:io"; | ||
import "dart:typed_data"; | ||
|
||
import "package:args/args.dart"; | ||
import "package:path/path.dart" as path; | ||
|
||
Future<void> main(List<String> args) async { | ||
final parser = new ArgParser(); | ||
parser.addOption("nm", help: "Path to `nm` tool"); | ||
parser.addOption("binary", | ||
help: "Path to the ELF file to extract symbols from"); | ||
parser.addOption("output", help: "Path to output symbol table"); | ||
final usage = """ | ||
Usage: dart_profiler_symbols.dart [options] | ||
Options: | ||
${parser.usage}; | ||
"""; | ||
|
||
String buildIdDir; | ||
String buildIdScript; | ||
String nm; | ||
String binary; | ||
String output; | ||
|
||
try { | ||
final options = parser.parse(args); | ||
nm = options["nm"]; | ||
if (nm == null) { | ||
throw "Must specify --nm"; | ||
} | ||
if (!FileSystemEntity.isFileSync(nm)) { | ||
throw "Cannot find $nm"; | ||
} | ||
binary = options["binary"]; | ||
if (binary == null) { | ||
throw "Must specify --binary"; | ||
} | ||
if (!FileSystemEntity.isFileSync(binary)) { | ||
throw "Cannot find $binary"; | ||
} | ||
output = options["output"]; | ||
if (output == null) { | ||
throw "Must specify --output"; | ||
} | ||
} catch (e) { | ||
print("ERROR: $e\n"); | ||
print(usage); | ||
exitCode = 1; | ||
return; | ||
} | ||
|
||
await run(buildIdDir, buildIdScript, nm, binary, output); | ||
} | ||
|
||
class Symbol { | ||
int offset; | ||
int size; | ||
String name; | ||
} | ||
|
||
Future<void> run(String buildIdDir, String buildIdScript, String nm, | ||
String binary, String output) async { | ||
final unstrippedFile = binary; | ||
final args = ["--demangle", "--numeric-sort", "--print-size", unstrippedFile]; | ||
final result = await Process.run(nm, args); | ||
if (result.exitCode != 0) { | ||
print(result.stdout); | ||
print(result.stderr); | ||
throw "Command failed: $nm $args"; | ||
} | ||
|
||
var symbols = new List(); | ||
|
||
var regex = new RegExp("([0-9A-Za-z]+) ([0-9A-Za-z]+) (t|T|w|W) (.*)"); | ||
for (final line in result.stdout.split("\n")) { | ||
var match = regex.firstMatch(line); | ||
if (match == null) { | ||
continue; // Ignore non-text symbols. | ||
} | ||
|
||
final symbol = new Symbol(); | ||
|
||
// Note that capture groups start at 1. | ||
symbol.offset = int.parse(match[1], radix: 16); | ||
symbol.size = int.parse(match[2], radix: 16); | ||
symbol.name = match[4].split("(")[0]; | ||
|
||
if (symbol.name.startsWith("\$")) { | ||
continue; // Ignore compiler/assembler temps. | ||
} | ||
|
||
symbols.add(symbol); | ||
} | ||
|
||
if (symbols.isEmpty) { | ||
throw "$unstrippedFile has no symbols"; | ||
} | ||
|
||
var nameTable = new BytesBuilder(); | ||
var binarySearchTable = new Uint32List(symbols.length * 3 + 1); | ||
var binarySearchTableIndex = 0; | ||
binarySearchTable[binarySearchTableIndex++] = symbols.length; | ||
// Symbols are sorted by offset because of --numeric-sort. | ||
for (var symbol in symbols) { | ||
var nameOffset = nameTable.length; | ||
nameTable.add(utf8.encode(symbol.name)); | ||
nameTable.addByte(0); | ||
binarySearchTable[binarySearchTableIndex++] = symbol.offset; | ||
binarySearchTable[binarySearchTableIndex++] = symbol.size; | ||
binarySearchTable[binarySearchTableIndex++] = nameOffset; | ||
} | ||
|
||
var file = new File(output); | ||
await file.parent.create(recursive: true); | ||
var sink = file.openWrite(); | ||
sink.add(binarySearchTable.buffer.asUint8List()); | ||
sink.add(nameTable.takeBytes()); | ||
await sink.close(); | ||
} |
8 changes: 8 additions & 0 deletions
8
shell/platform/fuchsia/runtime/dart/profiler_symbols/pubspec.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Copyright 2013 The Flutter Authors. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license that can be | ||
# found in the LICENSE file. | ||
|
||
name: profiler_symbols | ||
version: 0 | ||
description: Extracts a minimal symbols table for the Dart VM profiler | ||
author: Dart Team <[email protected]> |