| Index: runtime/third_party/binary_size/src/template/test-data-generator.html
|
| diff --git a/runtime/third_party/binary_size/src/template/test-data-generator.html b/runtime/third_party/binary_size/src/template/test-data-generator.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9c6790a8f9e636c652c4120a939129b26e2d19de
|
| --- /dev/null
|
| +++ b/runtime/third_party/binary_size/src/template/test-data-generator.html
|
| @@ -0,0 +1,157 @@
|
| +<!DOCTYPE html>
|
| +<!--
|
| + Copyright 2014 The Chromium Authors. All rights reserved.
|
| + Use of this source code is governed by a BSD-style license that can be
|
| + found in the LICENSE file.
|
| +-->
|
| +<html>
|
| +<head>
|
| +<script>
|
| +function rnd(max) {
|
| + return Math.round(Math.random()*max);
|
| +}
|
| +
|
| +function gen() {
|
| + var dirs1=['usr1', 'etc1', 'var1'];
|
| + var dirs2=['aaa2', 'bbb2', 'ccc2', 'ddd2', 'eee2', 'fff2', 'ggg2', 'hhh2',
|
| + 'frobozz2', 'kazaam2', 'shazam2'];
|
| + var dirs3=['iii3', 'jjj3', 'kkk3', 'lll3', 'mmm3', 'nnn3', 'ooo3', 'ppp3',
|
| + 'wonderllama3', 'excelsior3', 'src3'];
|
| + var filenames=['awesome.cc', 'rad.h', 'tubular.cxx', 'cool.cc', 'groovy.h',
|
| + 'excellent.c', 'gnarly.h', 'green.C', 'articulate.cc'];
|
| + //All possible types (we only see a subset in practice): 'ABbCDdGgiNpRrSsTtUuVvWw-?';
|
| + var nm_symbol_types = 'trd';
|
| + var minSize = 4;
|
| + var maxSize = 10000;
|
| + var numGen = 300000;
|
| + var text = 'var nm_data=[\n';
|
| + var vtablePercent = 5;
|
| + for (var x=0; x<numGen; x++) {
|
| + var path = '/' +
|
| + dirs1[rnd(dirs1.length - 1)] + '/' +
|
| + dirs2[rnd(dirs2.length - 1)] + '/' +
|
| + dirs3[rnd(dirs3.length - 1)] + '/' +
|
| + filenames[rnd(filenames.length - 1)];
|
| + var isVtable = Math.floor((Math.random()*100)+1) <= vtablePercent;
|
| + var size = rnd(maxSize);
|
| + var symbol_name;
|
| + var type;
|
| + if (!isVtable) {
|
| + symbol_name = 'sym' + x.toString(16);
|
| + type = nm_symbol_types.charAt(rnd(nm_symbol_types.length - 1));
|
| + } else {
|
| + symbol_name = 'vtable for ' + x.toString(16);
|
| + type = '@'
|
| + }
|
| + text = text + "{'n': '" + symbol_name +
|
| + "', 't': '" + type +
|
| + "', 's': " + size +
|
| + ", 'p': '" + path + "'},\n";
|
| + }
|
| + text += '];';
|
| +
|
| + eval(text);
|
| + var treeified = to_d3_tree(nm_data);
|
| + generateDownloadLink('tree_data=' + JSON.stringify(treeified));
|
| +}
|
| +
|
| +function generateDownloadLink(content) {
|
| + var blob = new Blob([content], {type: 'text/plain'});
|
| + var link = document.createElement('a');
|
| + link.download = 'generated-content.txt';
|
| + link.href = window.URL.createObjectURL(blob);
|
| + link.textContent = 'Download ready, click here.';
|
| + link.dataset.downloadurl = ['text/plain', link.download, link.href].join(':');
|
| + link.onclick = function(e) {
|
| + if ('disabled' in this.dataset) { return false; }
|
| + link.dataset.disabled = true;
|
| + setTimeout(function() { window.URL.revokeObjectURL(link.href); }, 1500);
|
| + };
|
| + document.getElementById('linkcontainer').innerHTML = '';
|
| + document.getElementById('linkcontainer').appendChild(link);
|
| +}
|
| +
|
| +/**
|
| + * This function takes in an array of nm records and converts them into a
|
| + * hierarchical data structure suitable for use in a d3-base treemap layout.
|
| + * Leaves are individual symbols. The parents of the leaves are logical
|
| + * groupings by common symbol-type (for BSS, read-only data, code, etc).
|
| + * Above this, each node represents part of a filesystem path relative
|
| + * to the parent node. The root node has the name '/', and represents
|
| + * a root (though not necessarily THE root) of a file system traversal.
|
| + * The root node also has a special property, 'maxDepth', to which is bound
|
| + * the deepest level of nesting that was found during conversion: for the
|
| + * record at path /a/b/c/d.foo, the maxDepth will be 6; the file 'd.foo'
|
| + * is at depth 4, the type-bucket is depth 5 and the symbols are depth 6.
|
| + */
|
| +function to_d3_tree(records) {
|
| + var result = {'n': '/', 'children': [], 'k': 'p'};
|
| + var maxDepth = 0;
|
| + //{'n': 'symbol1', 't': 'b', 's': 1000, 'p': '/usr/local/foo/foo.cc'},
|
| + for (index in records) {
|
| + var record = records[index];
|
| + var parts = record.p.split("/");
|
| + var node = result;
|
| + var depth = 0;
|
| + // Walk the tree and find the file that is named by the "location"
|
| + // field of the record. We create any intermediate nodes required.
|
| + // This is directly analogous to "mkdir -p".
|
| + while(parts.length > 0) {
|
| + var part = parts.shift();
|
| + if (part.length == 0) continue;
|
| + depth++;
|
| + node = _mk_child(node, part, record.s);
|
| + node.k = 'p'; // p for path
|
| + }
|
| + node.lastPathElement = true;
|
| +
|
| + // 'node' is now the file node. Find the symbol-type bucket.
|
| + node = _mk_child(node, record.t, record.s);
|
| + node.t = record.t;
|
| + node.k = 'b'; // b for bucket
|
| + depth++;
|
| + // 'node' is now the symbol-type bucket. Make the child entry.
|
| + node = _mk_child(node, record.n, record.s);
|
| + delete node.children;
|
| + node.value = record.s;
|
| + node.t = record.t;
|
| + node.k = 's'; // s for symbol
|
| + depth++;
|
| +
|
| + maxDepth = Math.max(maxDepth, depth);
|
| + }
|
| + result.maxDepth = maxDepth;
|
| + return result;
|
| +}
|
| +
|
| +/**
|
| + * Given a node and a name, return the child within node.children whose
|
| + * name matches the specified name. If necessary, a new child node is
|
| + * created and appended to node.children.
|
| + * If this method creates a new node, the 'name' attribute is set to the
|
| + * specified name and the 'children' attribute is an empty array, and
|
| + * total_size is the specified size. Otherwise, the existing node is
|
| + * returned and its total_size value is incremented by the specified size.
|
| + */
|
| +function _mk_child(node, name, size) {
|
| + var child = undefined;
|
| + for (child_index in node.children) {
|
| + if (node.children[child_index].n == name) {
|
| + child = node.children[child_index];
|
| + }
|
| + }
|
| + if (child === undefined) {
|
| + child = {'n': name, 'children': []};
|
| + node.children.push(child);
|
| + }
|
| + return child;
|
| +}
|
| +</script>
|
| +</head>
|
| +<body style='white-space: pre; font-family: monospace;'>
|
| +This script generates sample data for use in D3SymbolTreeMap, and can be used
|
| +for testing.
|
| +<input type=button onclick='gen();' value='Generate data'></input>
|
| +<div id='linkcontainer'></div>
|
| +</body>
|
| +</html>
|
|
|