aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2016-08-08 18:44:38 +0100
committerBen Murdoch <benm@google.com>2016-08-08 18:53:09 +0100
commitbcf72ee8e3b26f1d0726869c7ddb3921c68b09a8 (patch)
treef29dbc902638cd0978d68e11ca4210b4d42ad94b /tools
parentc760da5ef600c88c80b92873880fa8d221642e06 (diff)
downloadv8-bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8.tar.gz
Merge V8 5.2.361.47
https://chromium.googlesource.com/v8/v8/+/5.2.361.47 Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
Diffstat (limited to 'tools')
-rw-r--r--tools/blink_tests/TestExpectationsIgnition4
-rw-r--r--tools/callstats.html1481
-rwxr-xr-xtools/callstats.py556
-rw-r--r--tools/check-static-initializers.gyp4
-rw-r--r--tools/codemap.js8
-rw-r--r--tools/dump-cpp.py74
-rw-r--r--tools/dumpcpp.js100
-rwxr-xr-xtools/eval_gc_nvp.py29
-rwxr-xr-xtools/eval_gc_time.sh9
-rw-r--r--tools/gcmole/gcmole.lua2
-rw-r--r--tools/gcmole/run-gcmole.isolate1
-rw-r--r--tools/gcmole/run_gcmole.gyp4
-rw-r--r--tools/gen-postmortem-metadata.py2
-rw-r--r--tools/gyp/v8.gyp2281
-rw-r--r--tools/ic-explorer.html608
-rwxr-xr-xtools/ignition/bytecode_dispatches_report.py258
-rw-r--r--tools/ignition/bytecode_dispatches_report_test.py54
-rwxr-xr-xtools/ignition/linux_perf_bytecode_annotate.py174
-rw-r--r--tools/ignition/linux_perf_bytecode_annotate_test.py85
-rwxr-xr-xtools/ignition/linux_perf_report.py222
-rw-r--r--tools/ignition/linux_perf_report_test.py147
-rw-r--r--tools/jsfunfuzz/jsfunfuzz.gyp4
-rwxr-xr-xtools/mingw-generate-makefiles.sh10
-rw-r--r--tools/parser-shell.gyp10
-rwxr-xr-xtools/perf-to-html.py4
-rwxr-xr-xtools/release/auto_roll.py4
-rwxr-xr-xtools/release/create_release.py22
-rw-r--r--tools/release/test_scripts.py4
-rw-r--r--tools/run-deopt-fuzzer.gyp4
-rwxr-xr-xtools/run-deopt-fuzzer.py1
-rwxr-xr-xtools/run-perf.sh3
-rwxr-xr-xtools/run-tests.py36
-rw-r--r--tools/run-valgrind.gyp4
-rwxr-xr-xtools/run_perf.py220
-rw-r--r--tools/testrunner/local/execution.py5
-rw-r--r--tools/testrunner/local/progress.py21
-rw-r--r--tools/testrunner/local/statusfile.py8
-rw-r--r--tools/testrunner/local/testsuite.py25
-rw-r--r--tools/testrunner/network/network_execution.py1
-rw-r--r--tools/tickprocessor.js11
-rwxr-xr-xtools/try_perf.py1
-rwxr-xr-xtools/verify_source_deps.py2
-rw-r--r--tools/whitespace.txt2
43 files changed, 3812 insertions, 2693 deletions
diff --git a/tools/blink_tests/TestExpectationsIgnition b/tools/blink_tests/TestExpectationsIgnition
new file mode 100644
index 00000000..f2c912d2
--- /dev/null
+++ b/tools/blink_tests/TestExpectationsIgnition
@@ -0,0 +1,4 @@
+# Failures due to eager compilation, crbug/608287.
+[ Linux ] inspector/sources/debugger-frameworks/frameworks-jquery.html [ Failure ]
+[ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Failure ]
+[ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html [ Failure ]
diff --git a/tools/callstats.html b/tools/callstats.html
new file mode 100644
index 00000000..da85494f
--- /dev/null
+++ b/tools/callstats.html
@@ -0,0 +1,1481 @@
+<html>
+<!--
+Copyright 2016 the V8 project authors. All rights reserved. Use of this source
+code is governed by a BSD-style license that can be found in the LICENSE file.
+-->
+
+<head>
+ <meta charset="UTF-8">
+ <style>
+ body {
+ font-family: arial;
+ }
+
+ table {
+ display: table;
+ border-spacing: 0px;
+ }
+
+ tr {
+ border-spacing: 0px;
+ padding: 10px;
+ }
+
+ td,
+ th {
+ padding: 3px 10px 3px 5px;
+ }
+
+ .inline {
+ display: inline-block;
+ vertical-align: top;
+ }
+
+ h2,
+ h3 {
+ margin-bottom: 0px;
+ }
+
+ .hidden {
+ display: none;
+ }
+
+ .view {
+ display: table;
+ }
+
+ .column {
+ display: table-cell;
+ border-right: 1px black dotted;
+ min-width: 200px;
+ }
+
+ .column .header {
+ padding: 0 10px 0 10px
+ }
+
+ #column {
+ display: none;
+ }
+
+ .list {
+ width: 100%;
+ }
+
+ select {
+ width: 100%
+ }
+
+ .list tbody {
+ cursor: pointer;
+ }
+
+ .list tr:nth-child(even) {
+ background-color: #EFEFEF;
+ }
+
+ .list tr:nth-child(even).selected {
+ background-color: #DDD;
+ }
+
+ .list tr.child {
+ display: none;
+ }
+
+ .list tr.child.visible {
+ display: table-row;
+ }
+
+ .list .child .name {
+ padding-left: 20px;
+ }
+
+ .list .parent td {
+ border-top: 1px solid #AAA;
+ }
+
+ .list .total {
+ font-weight: bold
+ }
+
+ .list tr.parent {
+ background-color: #FFF;
+ }
+
+ .list tr.parent.selected {
+ background-color: #DDD;
+ }
+
+ tr.selected {
+ background-color: #DDD;
+ }
+
+ .list .position {
+ text-align: right;
+ display: none;
+ }
+
+ .list div.toggle {
+ cursor: pointer;
+ }
+
+ #column_0 .position {
+ display: table-cell;
+ }
+
+ #column_0 .name {
+ display: table-cell;
+ }
+
+ .list .name {
+ display: none;
+ white-space: nowrap;
+ }
+
+ .value {
+ text-align: right;
+ }
+
+ .selectedVersion {
+ font-weight: bold;
+ }
+
+ #baseline {
+ width: auto;
+ }
+
+ .compareSelector {
+ padding-bottom: 20px;
+ }
+
+ .pageDetailTable tbody {
+ cursor: pointer
+ }
+
+ .pageDetailTable tfoot td {
+ border-top: 1px grey solid;
+ }
+
+ #popover {
+ position: absolute;
+ transform: translateY(-50%) translateX(40px);
+ box-shadow: -2px 10px 44px -10px #000;
+ border-radius: 5px;
+ z-index: 1;
+ background-color: #FFF;
+ display: none;
+ white-space: nowrap;
+ }
+
+ #popover table {
+ position: relative;
+ z-index: 1;
+ text-align: right;
+ margin: 10px;
+ }
+ #popover td {
+ padding: 3px 0px 3px 5px;
+ white-space: nowrap;
+ }
+
+ .popoverArrow {
+ background-color: #FFF;
+ position: absolute;
+ width: 30px;
+ height: 30px;
+ transform: translateY(-50%)rotate(45deg);
+ top: 50%;
+ left: -10px;
+ z-index: 0;
+ }
+
+ #popover .name {
+ padding: 5px;
+ font-weight: bold;
+ text-align: center;
+ }
+
+ #popover table .compare {
+ display: none
+ }
+
+ #popover table.compare .compare {
+ display: table-cell;
+ }
+
+ #popover .compare .time,
+ #popover .compare .version {
+ padding-left: 10px;
+ }
+ </style>
+ <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
+ <script type="text/javascript">
+ "use strict"
+ google.charts.load('current', {packages: ['corechart']});
+
+ // Did anybody say monkeypatching?
+ if (!NodeList.prototype.forEach) {
+ NodeList.prototype.forEach = function(func) {
+ for (var i = 0; i < this.length; i++) {
+ func(this[i]);
+ }
+ }
+ }
+
+ var versions;
+ var selectedPage;
+ var baselineVersion;
+ var selectedEntry;
+
+ function initialize() {
+ var original = $("column");
+ var view = document.createElement('div');
+ view.id = 'view';
+ var i = 0;
+ versions.forEach((version) => {
+ if (!version.enabled) return;
+ // add column
+ var column = original.cloneNode(true);
+ column.id = "column_" + i;
+ // Fill in all versions
+ var select = column.querySelector(".version");
+ select.id = "selectVersion_" + i;
+ // add all select options
+ versions.forEach((version) => {
+ if (!version.enabled) return;
+ var option = document.createElement("option");
+ option.textContent = version.name;
+ option.version = version;
+ select.appendChild(option);
+ });
+ // Fill in all page versions
+ select = column.querySelector(".pageVersion");
+ select.id = "select_" + i;
+ // add all pages
+ versions.forEach((version) => {
+ if (!version.enabled) return;
+ var optgroup = document.createElement("optgroup");
+ optgroup.label = version.name;
+ optgroup.version = version;
+ version.pages.forEach((page) => {
+ var option = document.createElement("option");
+ option.textContent = page.name;
+ option.page = page;
+ optgroup.appendChild(option);
+ });
+ select.appendChild(optgroup);
+ });
+ view.appendChild(column);
+ i++;
+ });
+ var oldView = $('view');
+ oldView.parentNode.replaceChild(view, oldView);
+
+ var select = $('baseline');
+ removeAllChildren(select);
+ select.appendChild(document.createElement('option'));
+ versions.forEach((version) => {
+ var option = document.createElement("option");
+ option.textContent = version.name;
+ option.version = version;
+ select.appendChild(option);
+ });
+
+ var versionSelectorList = $('results').querySelector('.versionSelector ul');
+ removeAllChildren(versionSelectorList);
+ versions.forEach((version) => {
+ var li = document.createElement('li');
+ var checkbox = document.createElement('input');
+ checkbox.type = 'checkbox';
+ checkbox.checked = version.enabled;
+ checkbox.version = version;
+ checkbox.addEventListener('click', handleToggleVersionEnable);
+ li.appendChild(checkbox);
+ li.appendChild(document.createTextNode(version.name));
+ versionSelectorList.appendChild(li);
+ });
+ $('results').querySelectorAll('#results > .hidden').forEach((node) => {
+ toggleCssClass(node, 'hidden', false);
+ });
+ }
+
+ function showPage(firstPage) {
+ var changeSelectedEntry = selectedEntry !== undefined
+ && selectedEntry.page === selectedPage;
+ selectedPage = firstPage;
+ selectedPage.sort();
+ showPageInColumn(firstPage, 0);
+ // Show the other versions of this page in the following columns.
+ var pageVersions = versions.pageVersions(firstPage.name);
+ var index = 1;
+ pageVersions.forEach((page) => {
+ if (page !== firstPage) {
+ showPageInColumn(page, index);
+ index++;
+ }
+ });
+ if (changeSelectedEntry) {
+ showEntryDetail(selectedPage.getEntry(selectedEntry));
+ } else {
+ showImpactList(selectedPage);
+ }
+ }
+
+ function showPageInColumn(page, columnIndex) {
+ page.sort();
+ var showDiff = (baselineVersion === undefined && columnIndex !== 0) ||
+ (baselineVersion !== undefined && page.version !== baselineVersion);
+ var diffStatus = (td, a, b) => {};
+ if (showDiff) {
+ if (baselineVersion !== undefined) {
+ diffStatus = (td, a, b) => {
+ if (a == 0) return;
+ td.style.color = a < 0 ? '#FF0000' : '#00BB00';
+ };
+ } else {
+ diffStatus = (td, a, b) => {
+ if (a == b) return;
+ var color;
+ var ratio = a / b;
+ if (ratio > 1) {
+ ratio = Math.min(Math.round((ratio - 1) * 255 * 10), 200);
+ color = '#' + ratio.toString(16) + "0000";
+ } else {
+ ratio = Math.min(Math.round((1 - ratio) * 255 * 10), 200);
+ color = '#00' + ratio.toString(16) + "00";
+ }
+ td.style.color = color;
+ }
+ }
+ }
+
+ var column = $('column_' + columnIndex);
+ var select = $('select_' + columnIndex);
+ // Find the matching option
+ selectOption(select, (i, option) => {
+ return option.page == page
+ });
+ var table = column.querySelector("table");
+ var oldTbody = table.querySelector('tbody');
+ var tbody = document.createElement('tbody');
+ var referencePage = selectedPage;
+ page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => {
+ // Filter out entries that do not exist in the first column for the default
+ // view.
+ if (baselineVersion === undefined && referenceEntry &&
+ referenceEntry.time == 0) {
+ return;
+ }
+ var tr = document.createElement('tr');
+ tbody.appendChild(tr);
+ tr.entry = entry;
+ tr.parentEntry = parentEntry;
+ tr.className = parentEntry === undefined ? 'parent' : 'child';
+ // Don't show entries that do not exist on the current page or if we
+ // compare against the current page
+ if (entry !== undefined && page.version !== baselineVersion) {
+ // If we show a diff, use the baselineVersion as the referenceEntry
+ if (baselineVersion !== undefined) {
+ var baselineEntry = baselineVersion.getEntry(entry);
+ if (baselineEntry !== undefined) referenceEntry = baselineEntry
+ }
+ if (!parentEntry) {
+ var node = td(tr, '<div class="toggle">►</div>', 'position');
+ node.firstChild.addEventListener('click', handleToggleGroup);
+ } else {
+ td(tr, entry.position == 0 ? '' : entry.position, 'position');
+ }
+ td(tr, entry.name, 'name ' + entry.cssClass());
+ diffStatus(
+ td(tr, ms(entry.time), 'value time'),
+ entry.time, referenceEntry.time);
+ diffStatus(
+ td(tr, percent(entry.timePercent), 'value time'),
+ entry.time, referenceEntry.time);
+ diffStatus(
+ td(tr, count(entry.count), 'value count'),
+ entry.count, referenceEntry.count);
+ } else if (baselineVersion !== undefined && referenceEntry
+ && page.version !== baselineVersion) {
+ // Show comparison of entry that does not exist on the current page.
+ tr.entry = referenceEntry;
+ td(tr, '-', 'position');
+ td(tr, referenceEntry.name, 'name');
+ diffStatus(
+ td(tr, ms(referenceEntry.time), 'value time'),
+ referenceEntry.time, 0);
+ diffStatus(
+ td(tr, percent(referenceEntry.timePercent), 'value time'),
+ referenceEntry.timePercent, 0);
+ diffStatus(
+ td(tr, count(referenceEntry.count), 'value count'),
+ referenceEntry.count, 0);
+ } else {
+ // Display empty entry / baseline entry
+ var showBaselineEntry = entry !== undefined;
+ if (showBaselineEntry) {
+ if (!parentEntry) {
+ var node = td(tr, '<div class="toggle">►</div>', 'position');
+ node.firstChild.addEventListener('click', handleToggleGroup);
+ } else {
+ td(tr, entry.position == 0 ? '' : entry.position, 'position');
+ }
+ td(tr, entry.name, 'name');
+ td(tr, ms(entry.time, false), 'value time');
+ td(tr, percent(entry.timePercent, false), 'value time');
+ td(tr, count(entry.count, false), 'value count');
+ } else {
+ td(tr, '-', 'position');
+ td(tr, '-', 'name');
+ td(tr, '-', 'value time');
+ td(tr, '-', 'value time');
+ td(tr, '-', 'value count');
+ }
+ }
+ });
+ table.replaceChild(tbody, oldTbody);
+ var versionSelect = column.querySelector('select.version');
+ selectOption(versionSelect, (index, option) => {
+ return option.version == page.version
+ });
+ }
+
+ function selectEntry(entry, updateSelectedPage) {
+ if (updateSelectedPage) {
+ entry = selectedPage.version.getEntry(entry);
+ }
+ var rowIndex;
+ var needsPageSwitch = updateSelectedPage && entry.page != selectedPage;
+ // If clicked in the detail row change the first column to that page.
+ if (needsPageSwitch) showPage(entry.page);
+ var childNodes = $('column_0').querySelector('.list tbody').childNodes;
+ for (var i = 0; i < childNodes.length; i++) {
+ if (childNodes[i].entry.name == entry.name) {
+ rowIndex = i;
+ break;
+ }
+ }
+ var firstEntry = childNodes[rowIndex].entry;
+ if (rowIndex) {
+ if (firstEntry.parent) showGroup(firstEntry.parent);
+ }
+ // Deselect all
+ $('view').querySelectorAll('.list tbody tr').forEach((tr) => {
+ toggleCssClass(tr, 'selected', false);
+ });
+ // Select the entry row
+ $('view').querySelectorAll("tbody").forEach((body) => {
+ var row = body.childNodes[rowIndex];
+ if (!row) return;
+ toggleCssClass(row, 'selected', row.entry && row.entry.name ==
+ firstEntry.name);
+ });
+ if (updateSelectedPage) {
+ entry = selectedEntry.page.version.getEntry(entry);
+ }
+ selectedEntry = entry;
+ showEntryDetail(entry);
+ }
+
+ function showEntryDetail(entry) {
+ var table, tbody, entries;
+ table = $('detailView').querySelector('.versionDetailTable');
+ tbody = document.createElement('tbody');
+ if (entry !== undefined) {
+ $('detailView').querySelector('.versionDetail h3 span').innerHTML =
+ entry.name;
+ entries = versions.pageVersions(entry.page.name).map(
+ (page) => {
+ return page.get(entry.name)
+ });
+ entries.sort((a, b) => {
+ return a.time - b.time
+ });
+ entries.forEach((pageEntry) => {
+ if (pageEntry === undefined) return;
+ var tr = document.createElement('tr');
+ if (pageEntry == entry) tr.className += 'selected';
+ tr.entry = pageEntry;
+ td(tr, pageEntry.page.version.name, 'version');
+ td(tr, pageEntry.position, 'value position');
+ td(tr, ms(pageEntry.time), 'value time');
+ td(tr, percent(pageEntry.timePercent), 'value time');
+ td(tr, count(pageEntry.count), 'value count');
+ tbody.appendChild(tr);
+ });
+ }
+ table.replaceChild(tbody, table.querySelector('tbody'));
+
+ table = $('detailView').querySelector('.pageDetailTable');
+ tbody = document.createElement('tbody');
+ if (entry !== undefined) {
+ var version = entry.page.version;
+ $('detailView').querySelector('.pageDetail h3 span').innerHTML =
+ version.name;
+ entries = version.pages.map(
+ (page) => {
+ return page.get(entry.name)
+ });
+ entries.sort((a, b) => {
+ var cmp = b.timePercent - a.timePercent;
+ if (cmp.toFixed(1) == 0) return b.time - a.time;
+ return cmp
+ });
+ entries.forEach((pageEntry) => {
+ if (pageEntry === undefined) return;
+ var tr = document.createElement('tr');
+ if (pageEntry === entry) tr.className += 'selected';
+ tr.entry = pageEntry;
+ td(tr, pageEntry.page.name, 'name');
+ td(tr, pageEntry.position, 'value position');
+ td(tr, ms(pageEntry.time), 'value time');
+ td(tr, percent(pageEntry.timePercent), 'value time');
+ td(tr, count(pageEntry.count), 'value count');
+ tbody.appendChild(tr);
+ });
+ // show the total for all pages
+ var tds = table.querySelectorAll('tfoot td');
+ tds[2].innerHTML = ms(entry.getTimeImpact());
+ // Only show the percentage total if we are in diff mode:
+ tds[3].innerHTML = percent(entry.getTimePercentImpact());
+ tds[4].innerHTML = count(entry.getCountImpact());
+ }
+ table.replaceChild(tbody, table.querySelector('tbody'));
+ showImpactList(entry.page);
+ showPageGraphs(entry.page);
+ }
+
+ function showImpactList(page) {
+ var impactView = $('detailView').querySelector('.impactView');
+ impactView.querySelector('h3 span').innerHTML = page.version.name;
+
+ var table = impactView.querySelector('table');
+ var tbody = document.createElement('tbody');
+ var version = page.version;
+ var entries = version.allEntries();
+ if (selectedEntry !== undefined && selectedEntry.isGroup) {
+ impactView.querySelector('h3 span').innerHTML += " " + selectedEntry.name;
+ entries = entries.filter((entry) => {
+ return entry.name == selectedEntry.name ||
+ (entry.parent && entry.parent.name == selectedEntry.name)
+ });
+ }
+ var isCompareView = baselineVersion !== undefined;
+ entries = entries.filter((entry) => {
+ if (isCompareView) {
+ var impact = entry.getTimeImpact();
+ return impact < -1 || 1 < impact
+ }
+ return entry.getTimePercentImpact() > 0.1;
+ });
+ entries.sort((a, b) => {
+ var cmp = b.getTimePercentImpact() - a.getTimePercentImpact();
+ if (isCompareView || cmp.toFixed(1) == 0) {
+ return b.getTimeImpact() - a.getTimeImpact();
+ }
+ return cmp
+ });
+ entries.forEach((entry) => {
+ var tr = document.createElement('tr');
+ tr.entry = entry;
+ td(tr, entry.name, 'name');
+ td(tr, ms(entry.getTimeImpact()), 'value time');
+ var percentImpact = entry.getTimePercentImpact();
+ td(tr, percentImpact > 1000 ? '-' : percent(percentImpact), 'value time');
+ var topPages = entry.getPagesByPercentImpact().slice(0, 3)
+ .map((each) => {
+ return each.name + ' (' + percent(each.getEntry(entry).timePercent) +
+ ')'
+ });
+ td(tr, topPages.join(', '), 'name');
+ tbody.appendChild(tr);
+ });
+ table.replaceChild(tbody, table.querySelector('tbody'));
+ }
+
+ var selectedGroup;
+ function showPageGraphs(page) {
+ var groups = page.groups.filter(each => each.name != page.total.name);
+ if (selectedGroup == undefined) {
+ selectedGroup = groups[0];
+ } else {
+ groups = groups.filter(each => each.name != selectedGroup.name);
+ groups.unshift(selectedGroup);
+ }
+ var dataTable = new google.visualization.DataTable();
+ dataTable.addColumn('string', 'Name');
+ groups.forEach(group => {
+ var column = dataTable.addColumn('number', group.name);
+ dataTable.setColumnProperty(column, 'group', group);
+ });
+ // Calculate the average row
+ var row = ['Average'];
+ groups.forEach((group) => {
+ row.push(group.getTimeImpact());
+ });
+ dataTable.addRow(row);
+ // Sort the pages by the selected group.
+ var pages = page.version.pages.slice();
+ pages.sort((a, b) => {
+ return b.getEntry(selectedGroup).timePercent - a.getEntry(selectedGroup).timePercent;
+ });
+ // Calculate the entries for the pages
+ pages.forEach((page) => {
+ row = [page.name];
+ groups.forEach((group) => {
+ row.push(page.getEntry(group).time);
+ });
+ dataTable.addRow(row);
+ });
+
+ var height = 1000/27*page.version.pages.length;
+ var options = {
+ title: 'Page Comparison for Version ' + page.version.name,
+ isStacked: 'percent',
+ height: height ,
+ hAxis: {
+ title: '% Time',
+ minValue: 0,
+ },
+ vAxis: {
+ }
+ };
+ var chart = new google.visualization.BarChart($('pageGraphs'));
+ chart.draw(dataTable, options);
+ google.visualization.events.addListener(chart, 'select', selectHandler);
+ function selectHandler() {
+ var column = chart.getSelection()[0].column;
+ if (column === undefined) return;
+ selectedGroup = dataTable.getColumnProperty(column, 'group');
+ showPageGraphs(selectedEntry.page);
+ }
+ }
+
+ function showGroup(entry) {
+ toggleGroup(entry, true);
+ }
+
+ function toggleGroup(group, show) {
+ $('view').querySelectorAll(".child").forEach((tr) => {
+ var entry = tr.parentEntry;
+ if (!entry) return;
+ if (entry.name !== group.name) return;
+ toggleCssClass(tr, 'visible', show);
+ });
+ }
+
+ function showPopover(entry) {
+ var popover = $('popover');
+ popover.querySelector('td.name').innerHTML = entry.name;
+ popover.querySelector('td.page').innerHTML = entry.page.name;
+ setPopoverDetail(popover, entry, '');
+ popover.querySelector('table').className = "";
+ if (baselineVersion !== undefined) {
+ entry = baselineVersion.getEntry(entry);
+ setPopoverDetail(popover, entry, '.compare');
+ popover.querySelector('table').className = "compare";
+ }
+ }
+
+ function setPopoverDetail(popover, entry, prefix) {
+ var node = (name) => popover.querySelector(prefix + name);
+ if (entry == undefined) {
+ node('.version').innerHTML = baselineVersion.name;
+ node('.time').innerHTML = '-';
+ node('.timeVariance').innerHTML = '-';
+ node('.percent').innerHTML = '-';
+ node('.percentVariance').innerHTML = '-';
+ node('.count').innerHTML = '-';
+ node('.countVariance').innerHTML = '-';
+ node('.timeImpact').innerHTML = '-';
+ node('.timePercentImpact').innerHTML = '-';
+ } else {
+ node('.version').innerHTML = entry.page.version.name;
+ node('.time').innerHTML = ms(entry._time, false);
+ node('.timeVariance').innerHTML
+ = percent(entry.timeVariancePercent, false);
+ node('.percent').innerHTML = percent(entry.timePercent, false);
+ node('.percentVariance').innerHTML
+ = percent(entry.timePercentVariancePercent, false);
+ node('.count').innerHTML = count(entry._count, false);
+ node('.countVariance').innerHTML
+ = percent(entry.timeVariancePercent, false);
+ node('.timeImpact').innerHTML
+ = ms(entry.getTimeImpact(false), false);
+ node('.timePercentImpact').innerHTML
+ = percent(entry.getTimeImpactVariancePercent(false), false);
+ }
+ }
+
+ // ===========================================================================
+ // Helpers
+ function $(id) {
+ return document.getElementById(id)
+ }
+
+ function removeAllChildren(node) {
+ while (node.firstChild) {
+ node.removeChild(node.firstChild);
+ }
+ }
+
+ function selectOption(select, match) {
+ var options = select.options;
+ for (var i = 0; i < options.length; i++) {
+ if (match(i, options[i])) {
+ select.selectedIndex = i;
+ return;
+ }
+ }
+ }
+
+ function td(tr, content, className) {
+ var td = document.createElement("td");
+ td.innerHTML = content;
+ td.className = className
+ tr.appendChild(td);
+ return td
+ }
+
+ function nodeIndex(node) {
+ var children = node.parentNode.childNodes,
+ i = 0;
+ for (; i < children.length; i++) {
+ if (children[i] == node) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ function toggleCssClass(node, cssClass, toggleState) {
+ var index = -1;
+ var classes;
+ if (node.className != undefined) {
+ classes = node.className.split(' ');
+ index = classes.indexOf(cssClass);
+ }
+ if (index == -1) {
+ if (toggleState === false) return;
+ node.className += ' ' + cssClass;
+ return;
+ }
+ if (toggleState === true) return;
+ classes.splice(index, 1);
+ node.className = classes.join(' ');
+ }
+
+ function diffSign(value, digits, unit, showDiff) {
+ if (showDiff === false || baselineVersion == undefined) {
+ return value.toFixed(digits) + unit;
+ }
+ return (value >= 0 ? '+' : '') + value.toFixed(digits) + unit + 'Δ';
+ }
+
+ function ms(value, showDiff) {
+ return diffSign(value, 1, 'ms', showDiff);
+ }
+
+ function count(value, showDiff) {
+ return diffSign(value, 0, '#', showDiff);
+ }
+
+ function percent(value, showDiff) {
+ return diffSign(value, 1, '%', showDiff);
+ }
+
+ // =========================================================================
+ // EventHandlers
+ function handleBodyLoad() {
+ $('uploadInput').focus();
+ }
+
+ function handleLoadFile() {
+ var files = document.getElementById("uploadInput").files;
+ var file = files[0];
+ var reader = new FileReader();
+
+ reader.onload = function(evt) {
+ versions = Versions.fromJSON(JSON.parse(this.result));
+ initialize()
+ showPage(versions.versions[0].pages[0]);
+ }
+ reader.readAsText(file);
+ }
+
+ function handleToggleGroup(event) {
+ var group = event.target.parentNode.parentNode.entry;
+ toggleGroup(selectedPage.get(group.name));
+ }
+
+ function handleSelectPage(select, event) {
+ var option = select.options[select.selectedIndex];
+ if (select.id == "select_0") {
+ showPage(option.page);
+ } else {
+ var columnIndex = select.id.split('_')[1];
+ showPageInColumn(option.page, columnIndex);
+ }
+ }
+
+ function handleSelectVersion(select, event) {
+ var option = select.options[select.selectedIndex];
+ var version = option.version;
+ if (select.id == "selectVersion_0") {
+ var page = version.get(selectedPage.name);
+ showPage(page);
+ } else {
+ var columnIndex = select.id.split('_')[1];
+ var pageSelect = $('select_' + columnIndex);
+ var page = pageSelect.options[select.selectedIndex].page;
+ page = version.get(page.name);
+ showPageInColumn(page, columnIndex);
+ }
+ }
+
+ function handleSelectDetailRow(table, event) {
+ if (event.target.tagName != 'TD') return;
+ var tr = event.target.parentNode;
+ if (tr.tagName != 'TR') return;
+ if (tr.entry === undefined) return;
+ selectEntry(tr.entry, true);
+ }
+
+ function handleSelectRow(table, event, fromDetail) {
+ if (event.target.tagName != 'TD') return;
+ var tr = event.target.parentNode;
+ if (tr.tagName != 'TR') return;
+ if (tr.entry === undefined) return;
+ selectEntry(tr.entry, false);
+ }
+
+ function handleSelectBaseline(select, event) {
+ var option = select.options[select.selectedIndex];
+ baselineVersion = option.version
+ showPage(selectedPage);
+ if (selectedEntry === undefined) return;
+ selectEntry(selectedEntry, true);
+ }
+
+ function handleUpdatePopover(event) {
+ var popover = $('popover');
+ popover.style.left = event.pageX + 'px';
+ popover.style.top = event.pageY + 'px';
+ popover.style.display = event.shiftKey ? 'block' : 'none';
+ var target = event.target;
+ while (target.entry === undefined) {
+ target = target.parentNode;
+ if (!target) return;
+ }
+ showPopover(target.entry);
+ }
+
+ function handleToggleVersionEnable(event) {
+ var version = this.version;
+ if (version === undefined) return;
+ version.enabled = this.checked;
+ initialize();
+ var page = selectedPage;
+ if (page === undefined || !page.version.enabled) {
+ page = versions.getEnabledPage(page.name);
+ }
+ showPage(page);
+ }
+
+ // ===========================================================================
+
+ class Versions {
+ constructor() {
+ this.versions = [];
+ }
+ add(version) {
+ this.versions.push(version)
+ }
+ pageVersions(name) {
+ var result = [];
+ this.versions.forEach((version) => {
+ if (!version.enabled) return;
+ var page = version.get(name);
+ if (page !== undefined) result.push(page);
+ });
+ return result;
+ }
+ get length() {
+ return this.versions.length
+ }
+ get(index) {
+ return this.versions[index]
+ };
+ forEach(f) {
+ this.versions.forEach(f);
+ }
+ sort() {
+ this.versions.sort((a, b) => {
+ if (a.name > b.name) return 1;
+ if (a.name < b.name) return -1;
+ return 0
+ })
+ }
+ getEnabledPage(name) {
+ for (var i = 0; i < this.versions.length; i++) {
+ var version = this.versions[i];
+ if (!version.enabled) continue;
+ var page = version.get(name);
+ if (page !== undefined) return page;
+ }
+ }
+ }
+ Versions.fromJSON = function(json) {
+ var versions = new Versions();
+ for (var version in json) {
+ versions.add(Version.fromJSON(version, json[version]));
+ }
+ versions.sort();
+ return versions;
+ }
+
+ class Version {
+ constructor(name) {
+ this.name = name;
+ this.enabled = true;
+ this.pages = [];
+ }
+ add(page) {
+ this.pages.push(page);
+ }
+ indexOf(name) {
+ for (var i = 0; i < this.pages.length; i++) {
+ if (this.pages[i].name == name) return i;
+ }
+ return -1;
+ }
+ get(name) {
+ var index = this.indexOf(name);
+ if (0 <= index) return this.pages[index];
+ return undefined
+ }
+ get length() {
+ return this.versions.length
+ }
+ getEntry(entry) {
+ if (entry === undefined) return undefined;
+ var page = this.get(entry.page.name);
+ if (page === undefined) return undefined;
+ return page.get(entry.name);
+ }
+ forEachEntry(fun) {
+ this.pages.forEach((page) => {
+ page.forEach(fun);
+ });
+ }
+ allEntries() {
+ var map = new Map();
+ this.forEachEntry((group, entry) => {
+ if (!map.has(entry.name)) map.set(entry.name, entry);
+ });
+ return Array.from(map.values());
+ }
+ getTotalValue(name, property) {
+ if (name === undefined) name = this.pages[0].total.name;
+ var sum = 0;
+ this.pages.forEach((page) => {
+ var entry = page.get(name);
+ if (entry !== undefined) sum += entry[property];
+ });
+ return sum;
+ }
+ getTotalTime(name, showDiff) {
+ return this.getTotalValue(name, showDiff === false ? '_time' : 'time');
+ }
+ getTotalTimePercent(name, showDiff) {
+ if (baselineVersion === undefined) {
+ // Return the overall average percent of the given entry name.
+ return this.getTotalValue(name, 'time') /
+ this.getTotalTime('Group-Total') * 100;
+ }
+ // Otherwise return the difference to the sum of the baseline version.
+ var baselineValue = baselineVersion.getTotalTime(name, false);
+ return this.getTotalValue(name, '_time') / baselineValue * 100;
+ }
+ getTotalTimeVariance(name, showDiff) {
+ // Calculate the overall error for a given entry name
+ var sum = 0;
+ this.pages.forEach((page) => {
+ var entry = page.get(name);
+ if (entry === undefined) return;
+ sum += entry.timeVariance * entry.timeVariance;
+ });
+ return Math.sqrt(sum);
+ }
+ getTotalTimeVariancePercent(name, showDiff) {
+ return this.getTotalTimeVariance(name, showDiff) /
+ this.getTotalTime(name, showDiff) * 100;
+ }
+ getTotalCount(name, showDiff) {
+ return this.getTotalValue(name, showDiff === false ? '_count' : 'count');
+ }
+ getPagesByPercentImpact(name) {
+ var sortedPages =
+ this.pages.filter((each) => {
+ return each.get(name) !== undefined
+ });
+ sortedPages.sort((a, b) => {
+ return b.get(name).timePercent - a.get(name).timePercent;
+ });
+ return sortedPages;
+ }
+ sort() {
+ this.pages.sort((a, b) => {
+ if (a.name > b.name) return 1;
+ if (a.name < b.name) return -1;
+ return 0
+ })
+ }
+ }
+ Version.fromJSON = function(name, data) {
+ var version = new Version(name);
+ for (var page in data) {
+ version.add(Page.fromJSON(version, page, data[page]));
+ }
+ version.sort();
+ return version;
+ }
+
+
+ class Page {
+ constructor(version, name) {
+ this.name = name;
+ this.total = new GroupedEntry('Total', /.*Total.*/);
+ this.unclassified = new UnclassifiedEntry(this)
+ this.groups = [
+ this.total,
+ new GroupedEntry('IC', /.*IC.*/),
+ new GroupedEntry('Optimize',
+ /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/),
+ new GroupedEntry('Compile', /.*Compile.*|Parse.*/),
+ new GroupedEntry('Callback', /.*Callback$/),
+ new GroupedEntry('API', /.*API.*/),
+ new GroupedEntry('GC', /GC|AllocateInTargetSpace/),
+ new GroupedEntry('JavaScript', /JS_Execution/),
+ this.unclassified
+ ];
+ this.entryDict = new Map();
+ this.groups.forEach((entry) => {
+ entry.page = this;
+ this.entryDict.set(entry.name, entry);
+ });
+ this.version = version;
+ }
+ add(entry) {
+ entry.page = this;
+ this.entryDict.set(entry.name, entry);
+ var added = false;
+ this.groups.forEach((group) => {
+ if (!added) added = group.add(entry);
+ });
+ if (added) return;
+ this.unclassified.push(entry);
+ }
+ get(name) {
+ return this.entryDict.get(name)
+ }
+ getEntry(entry) {
+ if (entry === undefined) return undefined;
+ return this.get(entry.name);
+ }
+ get length() {
+ return this.versions.length
+ }
+ forEachSorted(referencePage, func) {
+ // Iterate over all the entries in the order they appear on the reference page.
+ referencePage.forEach((parent, referenceEntry) => {
+ var entry;
+ if (parent) parent = this.entryDict.get(parent.name);
+ if (referenceEntry) entry = this.entryDict.get(referenceEntry.name);
+ func(parent, entry, referenceEntry);
+ });
+ }
+ forEach(fun) {
+ this.forEachGroup((group) => {
+ fun(undefined, group);
+ group.forEach((entry) => {
+ fun(group, entry)
+ });
+ });
+ }
+ forEachGroup(fun) {
+ this.groups.forEach(fun)
+ }
+ sort() {
+ this.groups.sort((a, b) => {
+ return b.time - a.time;
+ });
+ this.groups.forEach((group) => {
+ group.sort()
+ });
+ }
+ }
+ Page.fromJSON = function(version, name, data) {
+ if (name.indexOf('www.') == 0) {
+ name = name.substring(4);
+ }
+ var page = new Page(version, name);
+ for (var i = 0; i < data.length; i++) {
+ page.add(Entry.fromJSON(i, data[data.length - i - 1]));
+ }
+ page.sort();
+ return page
+ }
+
+
+ class Entry {
+ constructor(position, name, time, timeVariance, timeVariancePercent,
+ count,
+ countVariance, countVariancePercent) {
+ this.position = position;
+ this.name = name;
+ this._time = time;
+ this._timeVariance = timeVariance;
+ this._timeVariancePercent = timeVariancePercent;
+ this._count = count;
+ this.countVariance = countVariance;
+ this.countVariancePercent = countVariancePercent;
+ this.page = undefined;
+ this.parent = undefined;
+ }
+ getCompareWithBaseline(value, property) {
+ if (baselineVersion == undefined) return value;
+ var baselineEntry = baselineVersion.getEntry(this);
+ if (!baselineEntry) return value;
+ if (baselineVersion === this.page.version) return value;
+ return value - baselineEntry[property];
+ }
+ cssClass() {
+ return ''
+ }
+ get time() {
+ return this.getCompareWithBaseline(this._time, '_time');
+ }
+ get count() {
+ return this.getCompareWithBaseline(this._count, '_count');
+ }
+ get timePercent() {
+ var value = this._time / this.page.total._time * 100;
+ if (baselineVersion == undefined) return value;
+ var baselineEntry = baselineVersion.getEntry(this);
+ if (!baselineEntry) return value;
+ if (baselineVersion === this.page.version) return value;
+ return (this._time - baselineEntry._time) / this.page.total._time *
+ 100;
+ }
+ get timePercentVariancePercent() {
+ // Get the absolute values for the percentages
+ return this.timeVariance / this.page.total._time * 100;
+ }
+ getTimeImpact(showDiff) {
+ return this.page.version.getTotalTime(this.name, showDiff);
+ }
+ getTimeImpactVariancePercent(showDiff) {
+ return this.page.version.getTotalTimeVariancePercent(this.name, showDiff);
+ }
+ getTimePercentImpact(showDiff) {
+ return this.page.version.getTotalTimePercent(this.name, showDiff);
+ }
+ getCountImpact(showDiff) {
+ return this.page.version.getTotalCount(this.name, showDiff);
+ }
+ getPagesByPercentImpact() {
+ return this.page.version.getPagesByPercentImpact(this.name);
+ }
+ get isGroup() {
+ return false
+ }
+ get timeVariance() {
+ return this._timeVariance
+ }
+ get timeVariancePercent() {
+ return this._timeVariancePercent
+ }
+ }
+ Entry.fromJSON = function(position, data) {
+ return new Entry(position, ...data);
+ }
+
+
+ class GroupedEntry extends Entry {
+ constructor(name, regexp) {
+ super(0, 'Group-' + name, 0, 0, 0, 0, 0, 0);
+ this.regexp = regexp;
+ this.entries = [];
+ }
+ add(entry) {
+ if (!entry.name.match(this.regexp)) return false;
+ this._time += entry.time;
+ this._count += entry.count;
+ // TODO: sum up variance
+ this.entries.push(entry);
+ entry.parent = this;
+ return true;
+ }
+ forEach(fun) {
+ if (baselineVersion === undefined) {
+ this.entries.forEach(fun);
+ return;
+ }
+ // If we have a baslineVersion to compare against show also all entries from the
+ // other group.
+ var tmpEntries = baselineVersion.getEntry(this)
+ .entries.filter((entry) => {
+ return this.page.get(entry.name) == undefined
+ });
+
+ // The compared entries are sorted by absolute impact.
+ tmpEntries = tmpEntries.map((entry) => {
+ var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0);
+ tmpEntry.page = this.page;
+ return tmpEntry;
+ });
+ tmpEntries = tmpEntries.concat(this.entries);
+ tmpEntries.sort((a, b) => {
+ return a.time - b.time
+ });
+ tmpEntries.forEach(fun);
+ }
+ sort() {
+ this.entries.sort((a, b) => {
+ return b.time - a.time;
+ });
+ }
+ cssClass() {
+ if (this.page.total == this) return 'total';
+ return '';
+ }
+ get isGroup() {
+ return true
+ }
+ getVarianceForProperty(property) {
+ var sum = 0;
+ this.entries.forEach((entry) => {
+ sum += entry[property + 'Variance'] * entry[property +
+ 'Variance'];
+ });
+ return Math.sqrt(sum);
+ }
+ get timeVariancePercent() {
+ if (this._time == 0) return 0;
+ return this.getVarianceForProperty('time') / this._time * 100
+ }
+ get timeVariance() {
+ return this.getVarianceForProperty('time')
+ }
+ }
+
+ class UnclassifiedEntry extends GroupedEntry {
+ constructor(page) {
+ super('Runtime');
+ this.page = page;
+ this._time = undefined;
+ this._count = undefined;
+ }
+ add(entry) {
+ this.entries.push(entry);
+ entry.parent = this;
+ return true;
+ }
+ forEachPageGroup(fun) {
+ this.page.forEachGroup((group) => {
+ if (group == this) return;
+ if (group == this.page.total) return;
+ fun(group);
+ });
+ }
+ get time() {
+ if (this._time === undefined) {
+ this._time = this.page.total._time;
+ this.forEachPageGroup((group) => {
+ this._time -= group._time;
+ });
+ }
+ return this.getCompareWithBaseline(this._time, '_time');
+ }
+ get count() {
+ if (this._count === undefined) {
+ this._count = this.page.total._count;
+ this.forEachPageGroup((group) => {
+ this._count -= group._count;
+ });
+ }
+ return this.getCompareWithBaseline(this._count, '_count');
+ }
+ }
+ </script>
+</head>
+
+<body onmousemove="handleUpdatePopover(event)" onload="handleBodyLoad()">
+ <h1>Runtime Stats Komparator</h1>
+
+ <div id="results">
+ <div class="inline">
+ <h2>Data</h2>
+ <form name="fileForm">
+ <p>
+ <input id="uploadInput" type="file" name="files" onchange="handleLoadFile();" accept=".json">
+ </p>
+ </form>
+ </div>
+
+ <div class="inline hidden">
+ <h2>Result</h2>
+ <div class="compareSelector inline">
+ Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseline(this, event)"></select><br/>
+ <span style="color: #060">Green</span> the selected version above performs
+ better on this measurement.
+ </div>
+ <div class="versionSelector inline">
+ Select Versions:
+ <ul></ul>
+ </div>
+ </div>
+ <div id="view">
+ </div>
+
+ <div id="detailView" class="hidden">
+ <h2></h2>
+ <div class="versionDetail inline">
+ <h3>Version Comparison for <span></span></h3>
+ <table class="versionDetailTable" onclick="handleSelectDetailRow(this, event);">
+ <thead>
+ <tr>
+ <th class="version">Version&nbsp;</th>
+ <th class="position">Pos.&nbsp;</th>
+ <th class="value time">Time▴&nbsp;</th>
+ <th class="value time">Percent&nbsp;</th>
+ <th class="value count">Count&nbsp;</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ <div class="pageDetail inline">
+ <h3>Page Comparison for <span></span></h3>
+ <table class="pageDetailTable" onclick="handleSelectDetailRow(this, event);">
+ <thead>
+ <tr>
+ <th class="page">Page&nbsp;</th>
+ <th class="position">Pos.&nbsp;</th>
+ <th class="value time">Time&nbsp;</th>
+ <th class="value time">Percent▾&nbsp;</th>
+ <th class="value count">Count&nbsp;</th>
+ </tr>
+ </thead>
+ <tfoot>
+ <tr>
+ <td class="page">Total:</td>
+ <td class="position"></td>
+ <td class="value time"></td>
+ <td class="value time"></td>
+ <td class="value count"></td>
+ </tr>
+ </tfoot>
+ <tbody></tbody>
+ </table>
+ </div>
+ <div class="impactView inline">
+ <h3>Impact list for <span></span></h3>
+ <table class="pageDetailTable" onclick="handleSelectDetailRow(this, event);">
+ <thead>
+ <tr>
+ <th class="page">Name&nbsp;</th>
+ <th class="value time">Time&nbsp;</th>
+ <th class="value time">Percent▾&nbsp;</th>
+ <th class="">Top Pages</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ </div>
+ <div id="pageGraphs" class="hidden">
+ </div>
+
+ <div id="column" class="column">
+ <div class="header">
+ <select class="version" onchange="handleSelectVersion(this, event);"></select>
+ <select class="pageVersion" onchange="handleSelectPage(this, event);"></select>
+ </div>
+ <table class="list" onclick="handleSelectRow(this, event);">
+ <thead>
+ <tr>
+ <th class="position">Pos.&nbsp;</th>
+ <th class="name">Name&nbsp;</th>
+ <th class="value time">Time&nbsp;</th>
+ <th class="value time">Percent&nbsp;</th>
+ <th class="value count">Count&nbsp;</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ </div>
+
+ <div class="inline">
+ <h2>Usage</h2>
+ <ol>
+ <li>Install scipy, e.g. <code>sudo aptitude install python-scipy</code>
+ <li>Build chrome with the <a href="https://codereview.chromium.org/1923893002">extended runtime callstats</a>.</li>
+ <li>Run <code>callstats.py</code> with a web-page-replay archive:
+ <pre>$V8_DIR/tools/callstats.py run \
+ --replay-bin=$CHROME_SRC/third_party/webpagereplay/replay.py \
+ --replay-wpr=$INPUT_DIR/top25.wpr \
+ --js-flags="" \
+ --with-chrome=$CHROME_SRC/out/Release/chrome \
+ --sites-file=$INPUT_DIR/top25.json</pre>
+ </li>
+ <li>Move results file to a subdirectory: <code>mkdir $VERSION_DIR; mv *.txt $VERSION_DIR</code></li>
+ <li>Repeat from step 1 with a different configuration (e.g. <code>--js-flags="--nolazy"</code>).</li>
+ <li>Create the final results file: <code>./callstats.py json $VERSION_DIR1 $VERSION_DIR2 > result.json</code></li>
+ <li>Use <code>results.json</code> on this site.</code>
+ </ol>
+ </div>
+
+ <div id="popover">
+ <div class="popoverArrow"></div>
+ <table>
+ <tr>
+ <td class="name" colspan="6"></td>
+ </tr>
+ <tr>
+ <td>Page:</td>
+ <td class="page name" colspan="6"></td>
+ </tr>
+ <tr>
+ <td>Version:</td>
+ <td class="version name" colspan="3"></td>
+ <td class="compare version name" colspan="3"></td>
+ </tr>
+ <tr>
+ <td>Time:</td>
+ <td class="time"></td><td>±</td><td class="timeVariance"></td>
+ <td class="compare time"></td><td class="compare"> ± </td><td class="compare timeVariance"></td>
+ </tr>
+ <tr>
+ <td>Percent:</td>
+ <td class="percent"></td><td>±</td><td class="percentVariance"></td>
+ <td class="compare percent"></td><td class="compare"> ± </td><td class="compare percentVariance"></td>
+ </tr>
+ <tr>
+ <td>Count:</td>
+ <td class="count"></td><td>±</td><td class="countVariance"></td>
+ <td class="compare count"></td><td class="compare"> ± </td><td class="compare countVariance"></td>
+ </tr>
+ <tr>
+ <td>Overall Impact:</td>
+ <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td>
+ <td class="compare timeImpact"></td><td class="compare"> ± </td><td class="compare timePercentImpact"></td>
+ </tr>
+ </table>
+ </div>
+
+</body>
+
+</html>
diff --git a/tools/callstats.py b/tools/callstats.py
new file mode 100755
index 00000000..90446184
--- /dev/null
+++ b/tools/callstats.py
@@ -0,0 +1,556 @@
+#!/usr/bin/env python
+# Copyright 2016 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+'''
+Usage: runtime-call-stats.py [-h] <command> ...
+
+Optional arguments:
+ -h, --help show this help message and exit
+
+Commands:
+ run run chrome with --runtime-call-stats and generate logs
+ stats process logs and print statistics
+ json process logs from several versions and generate JSON
+ help help information
+
+For each command, you can try ./runtime-call-stats.py help command.
+'''
+
+import argparse
+import json
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+
+import numpy
+import scipy
+import scipy.stats
+from math import sqrt
+
+
+# Run benchmarks.
+
+def print_command(cmd_args):
+ def fix_for_printing(arg):
+ m = re.match(r'^--([^=]+)=(.*)$', arg)
+ if m and (' ' in m.group(2) or m.group(2).startswith('-')):
+ arg = "--{}='{}'".format(m.group(1), m.group(2))
+ elif ' ' in arg:
+ arg = "'{}'".format(arg)
+ return arg
+ print " ".join(map(fix_for_printing, cmd_args))
+
+
+def start_replay_server(args, sites):
+ with tempfile.NamedTemporaryFile(prefix='callstats-inject-', suffix='.js',
+ mode='wt', delete=False) as f:
+ injection = f.name
+ generate_injection(f, sites, args.refresh)
+ cmd_args = [
+ args.replay_bin,
+ "--port=4080",
+ "--ssl_port=4443",
+ "--no-dns_forwarding",
+ "--use_closest_match",
+ "--no-diff_unknown_requests",
+ "--inject_scripts=deterministic.js,{}".format(injection),
+ args.replay_wpr,
+ ]
+ print "=" * 80
+ print_command(cmd_args)
+ with open(os.devnull, 'w') as null:
+ server = subprocess.Popen(cmd_args, stdout=null, stderr=null)
+ print "RUNNING REPLAY SERVER: %s with PID=%s" % (args.replay_bin, server.pid)
+ print "=" * 80
+ return {'process': server, 'injection': injection}
+
+
+def stop_replay_server(server):
+ print("SHUTTING DOWN REPLAY SERVER %s" % server['process'].pid)
+ server['process'].terminate()
+ os.remove(server['injection'])
+
+
+def generate_injection(f, sites, refreshes=0):
+ print >> f, """\
+(function() {
+ let s = window.sessionStorage.getItem("refreshCounter");
+ let refreshTotal = """, refreshes, """;
+ let refreshCounter = s ? parseInt(s) : refreshTotal;
+ let refreshId = refreshTotal - refreshCounter;
+ if (refreshCounter > 0) {
+ window.sessionStorage.setItem("refreshCounter", refreshCounter-1);
+ }
+
+ function match(url, item) {
+ if ('regexp' in item) return url.match(item.regexp) !== null;
+ let url_wanted = item.url;
+ // Allow automatic redirections from http to https.
+ if (url_wanted.startsWith("http://") && url.startsWith("https://")) {
+ url_wanted = "https://" + url_wanted.substr(7);
+ }
+ return url.startsWith(url_wanted);
+ };
+
+ function onLoad(e) {
+ let url = e.target.URL;
+ for (let item of sites) {
+ if (!match(url, item)) continue;
+ let timeout = 'timeline' in item ? 2500 * item.timeline
+ : 'timeout' in item ? 1000 * (item.timeout - 3)
+ : 10000;
+ console.log("Setting time out of " + timeout + " for: " + url);
+ window.setTimeout(function() {
+ console.log("Time is out for: " + url);
+ let msg = "STATS: (" + refreshId + ") " + url;
+ %GetAndResetRuntimeCallStats(1, msg);
+ if (refreshCounter > 0) {
+ console.log("Refresh counter is " + refreshCounter + ", refreshing: " + url);
+ window.location.reload();
+ }
+ }, timeout);
+ return;
+ }
+ console.log("Ignoring: " + url);
+ };
+
+ let sites =
+ """, json.dumps(sites), """;
+
+ console.log("Event listenner added for: " + window.location.href);
+ window.addEventListener("load", onLoad);
+})();"""
+
+
+def run_site(site, domain, args, timeout=None):
+ print "="*80
+ print "RUNNING DOMAIN %s" % domain
+ print "="*80
+ result_template = "{domain}#{count}.txt" if args.repeat else "{domain}.txt"
+ count = 0
+ if timeout is None: timeout = args.timeout
+ if args.replay_wpr:
+ timeout *= 1 + args.refresh
+ timeout += 1
+ while count == 0 or args.repeat is not None and count < args.repeat:
+ count += 1
+ result = result_template.format(domain=domain, count=count)
+ retries = 0
+ while args.retries is None or retries < args.retries:
+ retries += 1
+ try:
+ if args.user_data_dir:
+ user_data_dir = args.user_data_dir
+ else:
+ user_data_dir = tempfile.mkdtemp(prefix="chr_")
+ js_flags = "--runtime-call-stats"
+ if args.replay_wpr: js_flags += " --allow-natives-syntax"
+ if args.js_flags: js_flags += " " + args.js_flags
+ chrome_flags = [
+ "--no-default-browser-check",
+ "--disable-translate",
+ "--js-flags={}".format(js_flags),
+ "--no-first-run",
+ "--user-data-dir={}".format(user_data_dir),
+ ]
+ if args.replay_wpr:
+ chrome_flags += [
+ "--host-resolver-rules=MAP *:80 localhost:4080, " \
+ "MAP *:443 localhost:4443, " \
+ "EXCLUDE localhost",
+ "--ignore-certificate-errors",
+ "--disable-seccomp-sandbox",
+ "--disable-web-security",
+ "--reduce-security-for-testing",
+ "--allow-insecure-localhost",
+ ]
+ else:
+ chrome_flags += [
+ "--single-process",
+ ]
+ if args.chrome_flags:
+ chrome_flags += args.chrome_flags.split()
+ cmd_args = [
+ "timeout", str(timeout),
+ args.with_chrome
+ ] + chrome_flags + [ site ]
+ print "- " * 40
+ print_command(cmd_args)
+ print "- " * 40
+ with open(result, "wt") as f:
+ status = subprocess.call(cmd_args, stdout=f)
+ # 124 means timeout killed chrome, 0 means the user was bored first!
+ # If none of these two happened, then chrome apparently crashed, so
+ # it must be called again.
+ if status != 124 and status != 0:
+ print("CHROME CRASHED, REPEATING RUN");
+ continue
+ # If the stats file is empty, chrome must be called again.
+ if os.path.isfile(result) and os.path.getsize(result) > 0:
+ if args.print_url:
+ with open(result, "at") as f:
+ print >> f
+ print >> f, "URL: {}".format(site)
+ break
+ if retries <= 6: timeout += 2 ** (retries-1)
+ print("EMPTY RESULT, REPEATING RUN");
+ finally:
+ if not args.user_data_dir:
+ shutil.rmtree(user_data_dir)
+
+
+def read_sites_file(args):
+ try:
+ sites = []
+ try:
+ with open(args.sites_file, "rt") as f:
+ for item in json.load(f):
+ if 'timeout' not in item:
+ # This is more-or-less arbitrary.
+ item['timeout'] = int(2.5 * item['timeline'] + 3)
+ if item['timeout'] > args.timeout: item['timeout'] = args.timeout
+ sites.append(item)
+ except ValueError:
+ with open(args.sites_file, "rt") as f:
+ for line in f:
+ line = line.strip()
+ if not line or line.startswith('#'): continue
+ sites.append({'url': line, 'timeout': args.timeout})
+ return sites
+ except IOError as e:
+ args.error("Cannot read from {}. {}.".format(args.sites_file, e.strerror))
+ sys.exit(1)
+
+
+def do_run(args):
+ # Determine the websites to benchmark.
+ if args.sites_file:
+ sites = read_sites_file(args)
+ else:
+ sites = [{'url': site, 'timeout': args.timeout} for site in args.sites]
+ # Disambiguate domains, if needed.
+ L = []
+ domains = {}
+ for item in sites:
+ site = item['url']
+ m = re.match(r'^(https?://)?([^/]+)(/.*)?$', site)
+ if not m:
+ args.error("Invalid URL {}.".format(site))
+ continue
+ domain = m.group(2)
+ entry = [site, domain, None, item['timeout']]
+ if domain not in domains:
+ domains[domain] = entry
+ else:
+ if not isinstance(domains[domain], int):
+ domains[domain][2] = 1
+ domains[domain] = 1
+ domains[domain] += 1
+ entry[2] = domains[domain]
+ L.append(entry)
+ replay_server = start_replay_server(args, sites) if args.replay_wpr else None
+ try:
+ # Run them.
+ for site, domain, count, timeout in L:
+ if count is not None: domain = "{}%{}".format(domain, count)
+ print site, domain, timeout
+ run_site(site, domain, args, timeout)
+ finally:
+ if replay_server:
+ stop_replay_server(replay_server)
+
+
+# Calculate statistics.
+
+def statistics(data):
+ N = len(data)
+ average = numpy.average(data)
+ median = numpy.median(data)
+ low = numpy.min(data)
+ high= numpy.max(data)
+ if N > 1:
+ # evaluate sample variance by setting delta degrees of freedom (ddof) to
+ # 1. The degree used in calculations is N - ddof
+ stddev = numpy.std(data, ddof=1)
+ # Get the endpoints of the range that contains 95% of the distribution
+ t_bounds = scipy.stats.t.interval(0.95, N-1)
+ #assert abs(t_bounds[0] + t_bounds[1]) < 1e-6
+ # sum mean to the confidence interval
+ ci = {
+ 'abs': t_bounds[1] * stddev / sqrt(N),
+ 'low': average + t_bounds[0] * stddev / sqrt(N),
+ 'high': average + t_bounds[1] * stddev / sqrt(N)
+ }
+ else:
+ stddev = 0
+ ci = { 'abs': 0, 'low': average, 'high': average }
+ if abs(stddev) > 0.0001 and abs(average) > 0.0001:
+ ci['perc'] = t_bounds[1] * stddev / sqrt(N) / average * 100
+ else:
+ ci['perc'] = 0
+ return { 'samples': N, 'average': average, 'median': median,
+ 'stddev': stddev, 'min': low, 'max': high, 'ci': ci }
+
+
+def read_stats(path, S):
+ with open(path, "rt") as f:
+ # Process the whole file and sum repeating entries.
+ D = { 'Sum': {'time': 0, 'count': 0} }
+ for line in f:
+ line = line.strip()
+ # Discard headers and footers.
+ if not line: continue
+ if line.startswith("Runtime Function"): continue
+ if line.startswith("===="): continue
+ if line.startswith("----"): continue
+ if line.startswith("URL:"): continue
+ if line.startswith("STATS:"): continue
+ # We have a regular line.
+ fields = line.split()
+ key = fields[0]
+ time = float(fields[1].replace("ms", ""))
+ count = int(fields[3])
+ if key not in D: D[key] = { 'time': 0, 'count': 0 }
+ D[key]['time'] += time
+ D[key]['count'] += count
+ # We calculate the sum, if it's not the "total" line.
+ if key != "Total":
+ D['Sum']['time'] += time
+ D['Sum']['count'] += count
+ # Append the sums as single entries to S.
+ for key in D:
+ if key not in S: S[key] = { 'time_list': [], 'count_list': [] }
+ S[key]['time_list'].append(D[key]['time'])
+ S[key]['count_list'].append(D[key]['count'])
+
+
+def print_stats(S, args):
+ # Sort by ascending/descending time average, then by ascending/descending
+ # count average, then by ascending name.
+ def sort_asc_func(item):
+ return (item[1]['time_stat']['average'],
+ item[1]['count_stat']['average'],
+ item[0])
+ def sort_desc_func(item):
+ return (-item[1]['time_stat']['average'],
+ -item[1]['count_stat']['average'],
+ item[0])
+ # Sorting order is in the commend-line arguments.
+ sort_func = sort_asc_func if args.sort == "asc" else sort_desc_func
+ # Possibly limit how many elements to print.
+ L = [item for item in sorted(S.items(), key=sort_func)
+ if item[0] not in ["Total", "Sum"]]
+ N = len(L)
+ if args.limit == 0:
+ low, high = 0, N
+ elif args.sort == "desc":
+ low, high = 0, args.limit
+ else:
+ low, high = N-args.limit, N
+ # How to print entries.
+ def print_entry(key, value):
+ def stats(s, units=""):
+ conf = "{:0.1f}({:0.2f}%)".format(s['ci']['abs'], s['ci']['perc'])
+ return "{:8.1f}{} +/- {:15s}".format(s['average'], units, conf)
+ print "{:>50s} {} {}".format(
+ key,
+ stats(value['time_stat'], units="ms"),
+ stats(value['count_stat'])
+ )
+ # Print and calculate partial sums, if necessary.
+ for i in range(low, high):
+ print_entry(*L[i])
+ if args.totals and args.limit != 0:
+ if i == low:
+ partial = { 'time_list': [0] * len(L[i][1]['time_list']),
+ 'count_list': [0] * len(L[i][1]['count_list']) }
+ assert len(partial['time_list']) == len(L[i][1]['time_list'])
+ assert len(partial['count_list']) == len(L[i][1]['count_list'])
+ for j, v in enumerate(L[i][1]['time_list']):
+ partial['time_list'][j] += v
+ for j, v in enumerate(L[i][1]['count_list']):
+ partial['count_list'][j] += v
+ # Print totals, if necessary.
+ if args.totals:
+ print '-' * 80
+ if args.limit != 0:
+ partial['time_stat'] = statistics(partial['time_list'])
+ partial['count_stat'] = statistics(partial['count_list'])
+ print_entry("Partial", partial)
+ print_entry("Sum", S["Sum"])
+ print_entry("Total", S["Total"])
+
+
+def do_stats(args):
+ T = {}
+ for path in args.logfiles:
+ filename = os.path.basename(path)
+ m = re.match(r'^([^#]+)(#.*)?$', filename)
+ domain = m.group(1)
+ if domain not in T: T[domain] = {}
+ read_stats(path, T[domain])
+ for i, domain in enumerate(sorted(T)):
+ if len(T) > 1:
+ if i > 0: print
+ print "{}:".format(domain)
+ print '=' * 80
+ S = T[domain]
+ for key in S:
+ S[key]['time_stat'] = statistics(S[key]['time_list'])
+ S[key]['count_stat'] = statistics(S[key]['count_list'])
+ print_stats(S, args)
+
+
+# Generate JSON file.
+
+def do_json(args):
+ J = {}
+ for path in args.logdirs:
+ if os.path.isdir(path):
+ for root, dirs, files in os.walk(path):
+ version = os.path.basename(root)
+ if version not in J: J[version] = {}
+ for filename in files:
+ if filename.endswith(".txt"):
+ m = re.match(r'^([^#]+)(#.*)?\.txt$', filename)
+ domain = m.group(1)
+ if domain not in J[version]: J[version][domain] = {}
+ read_stats(os.path.join(root, filename), J[version][domain])
+ for version, T in J.items():
+ for domain, S in T.items():
+ A = []
+ for name, value in S.items():
+ # We don't want the calculated sum in the JSON file.
+ if name == "Sum": continue
+ entry = [name]
+ for x in ['time_list', 'count_list']:
+ s = statistics(S[name][x])
+ entry.append(round(s['average'], 1))
+ entry.append(round(s['ci']['abs'], 1))
+ entry.append(round(s['ci']['perc'], 2))
+ A.append(entry)
+ T[domain] = A
+ print json.dumps(J, separators=(',', ':'))
+
+
+# Help.
+
+def do_help(parser, subparsers, args):
+ if args.help_cmd:
+ if args.help_cmd in subparsers:
+ subparsers[args.help_cmd].print_help()
+ else:
+ args.error("Unknown command '{}'".format(args.help_cmd))
+ else:
+ parser.print_help()
+
+
+# Main program, parse command line and execute.
+
+def coexist(*l):
+ given = sum(1 for x in l if x)
+ return given == 0 or given == len(l)
+
+def main():
+ parser = argparse.ArgumentParser()
+ subparser_adder = parser.add_subparsers(title="commands", dest="command",
+ metavar="<command>")
+ subparsers = {}
+ # Command: run.
+ subparsers["run"] = subparser_adder.add_parser(
+ "run", help="run --help")
+ subparsers["run"].set_defaults(
+ func=do_run, error=subparsers["run"].error)
+ subparsers["run"].add_argument(
+ "--chrome-flags", type=str, default="",
+ help="specify additional chrome flags")
+ subparsers["run"].add_argument(
+ "--js-flags", type=str, default="",
+ help="specify additional V8 flags")
+ subparsers["run"].add_argument(
+ "--no-url", dest="print_url", action="store_false", default=True,
+ help="do not include url in statistics file")
+ subparsers["run"].add_argument(
+ "-n", "--repeat", type=int, metavar="<num>",
+ help="specify iterations for each website (default: once)")
+ subparsers["run"].add_argument(
+ "-k", "--refresh", type=int, metavar="<num>", default=0,
+ help="specify refreshes for each iteration (default: 0)")
+ subparsers["run"].add_argument(
+ "--replay-wpr", type=str, metavar="<path>",
+ help="use the specified web page replay (.wpr) archive")
+ subparsers["run"].add_argument(
+ "--replay-bin", type=str, metavar="<path>",
+ help="specify the replay.py script typically located in " \
+ "$CHROMIUM/src/third_party/webpagereplay/replay.py")
+ subparsers["run"].add_argument(
+ "-r", "--retries", type=int, metavar="<num>",
+ help="specify retries if website is down (default: forever)")
+ subparsers["run"].add_argument(
+ "-f", "--sites-file", type=str, metavar="<path>",
+ help="specify file containing benchmark websites")
+ subparsers["run"].add_argument(
+ "-t", "--timeout", type=int, metavar="<seconds>", default=60,
+ help="specify seconds before chrome is killed")
+ subparsers["run"].add_argument(
+ "-u", "--user-data-dir", type=str, metavar="<path>",
+ help="specify user data dir (default is temporary)")
+ subparsers["run"].add_argument(
+ "-c", "--with-chrome", type=str, metavar="<path>",
+ default="/usr/bin/google-chrome",
+ help="specify chrome executable to use")
+ subparsers["run"].add_argument(
+ "sites", type=str, metavar="<URL>", nargs="*",
+ help="specify benchmark website")
+ # Command: stats.
+ subparsers["stats"] = subparser_adder.add_parser(
+ "stats", help="stats --help")
+ subparsers["stats"].set_defaults(
+ func=do_stats, error=subparsers["stats"].error)
+ subparsers["stats"].add_argument(
+ "-l", "--limit", type=int, metavar="<num>", default=0,
+ help="limit how many items to print (default: none)")
+ subparsers["stats"].add_argument(
+ "-s", "--sort", choices=["asc", "desc"], default="asc",
+ help="specify sorting order (default: ascending)")
+ subparsers["stats"].add_argument(
+ "-n", "--no-total", dest="totals", action="store_false", default=True,
+ help="do not print totals")
+ subparsers["stats"].add_argument(
+ "logfiles", type=str, metavar="<logfile>", nargs="*",
+ help="specify log files to parse")
+ # Command: json.
+ subparsers["json"] = subparser_adder.add_parser(
+ "json", help="json --help")
+ subparsers["json"].set_defaults(
+ func=do_json, error=subparsers["json"].error)
+ subparsers["json"].add_argument(
+ "logdirs", type=str, metavar="<logdir>", nargs="*",
+ help="specify directories with log files to parse")
+ # Command: help.
+ subparsers["help"] = subparser_adder.add_parser(
+ "help", help="help information")
+ subparsers["help"].set_defaults(
+ func=lambda args: do_help(parser, subparsers, args),
+ error=subparsers["help"].error)
+ subparsers["help"].add_argument(
+ "help_cmd", type=str, metavar="<command>", nargs="?",
+ help="command for which to display help")
+ # Execute the command.
+ args = parser.parse_args()
+ setattr(args, 'script_path', os.path.dirname(sys.argv[0]))
+ if args.command == "run" and coexist(args.sites_file, args.sites):
+ args.error("use either option --sites-file or site URLs")
+ sys.exit(1)
+ elif args.command == "run" and not coexist(args.replay_wpr, args.replay_bin):
+ args.error("options --replay-wpr and --replay-bin must be used together")
+ sys.exit(1)
+ else:
+ args.func(args)
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/tools/check-static-initializers.gyp b/tools/check-static-initializers.gyp
index 547a6c87..cfeacfc8 100644
--- a/tools/check-static-initializers.gyp
+++ b/tools/check-static-initializers.gyp
@@ -13,8 +13,8 @@
'../src/d8.gyp:d8_run',
],
'includes': [
- '../build/features.gypi',
- '../build/isolate.gypi',
+ '../gypfiles/features.gypi',
+ '../gypfiles/isolate.gypi',
],
'sources': [
'check-static-initializers.isolate',
diff --git a/tools/codemap.js b/tools/codemap.js
index fa6c36b5..30cdc21d 100644
--- a/tools/codemap.js
+++ b/tools/codemap.js
@@ -246,6 +246,14 @@ CodeMap.prototype.getAllStaticEntries = function() {
/**
+ * Returns an array of pairs of all static code entries and their addresses.
+ */
+CodeMap.prototype.getAllStaticEntriesWithAddresses = function() {
+ return this.statics_.exportKeysAndValues();
+};
+
+
+/**
* Returns an array of all libraries entries.
*/
CodeMap.prototype.getAllLibrariesEntries = function() {
diff --git a/tools/dump-cpp.py b/tools/dump-cpp.py
new file mode 100644
index 00000000..b7bb32e9
--- /dev/null
+++ b/tools/dump-cpp.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# Copyright 2016 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script executes dumpcpp.js, collects all dumped C++ symbols,
+# and merges them back into v8 log.
+
+import os
+import platform
+import re
+import subprocess
+import sys
+
+def is_file_executable(fPath):
+ return os.path.isfile(fPath) and os.access(fPath, os.X_OK)
+
+if __name__ == '__main__':
+ JS_FILES = ['splaytree.js', 'codemap.js', 'csvparser.js', 'consarray.js',
+ 'profile.js', 'logreader.js', 'tickprocessor.js', 'SourceMap.js',
+ 'dumpcpp.js']
+ tools_path = os.path.dirname(os.path.realpath(__file__))
+ on_windows = platform.system() == 'Windows'
+ JS_FILES = [os.path.join(tools_path, f) for f in JS_FILES]
+
+ args = []
+ log_file = 'v8.log'
+ debug = False
+ for arg in sys.argv[1:]:
+ if arg == '--debug':
+ debug = True
+ continue
+ args.append(arg)
+ if not arg.startswith('-'):
+ log_file = arg
+
+ if on_windows:
+ args.append('--windows')
+
+ with open(log_file, 'r') as f:
+ lines = f.readlines()
+
+ d8_line = re.search(',\"(.*d8)', ''.join(lines))
+ if d8_line:
+ d8_exec = d8_line.group(1)
+ if not is_file_executable(d8_exec):
+ print 'd8 binary path found in {} is not executable.'.format(log_file)
+ sys.exit(-1)
+ else:
+ print 'No d8 binary path found in {}.'.format(log_file)
+ sys.exit(-1)
+
+ args = [d8_exec] + JS_FILES + ['--'] + args
+
+ with open(log_file) as f:
+ sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=f)
+ out, err = sp.communicate()
+ if debug:
+ print err
+ if sp.returncode != 0:
+ print out
+ exit(-1)
+
+ if on_windows and out:
+ out = re.sub('\r+\n', '\n', out)
+
+ is_written = not bool(out)
+ with open(log_file, 'w') as f:
+ for line in lines:
+ if not is_written and line.startswith('tick'):
+ f.write(out)
+ is_written = True
+ f.write(line)
diff --git a/tools/dumpcpp.js b/tools/dumpcpp.js
new file mode 100644
index 00000000..28885e0c
--- /dev/null
+++ b/tools/dumpcpp.js
@@ -0,0 +1,100 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Dump C++ symbols of shared library if possible
+
+function processArguments(args) {
+ var processor = new ArgumentsProcessor(args);
+ if (processor.parse()) {
+ return processor.result();
+ } else {
+ processor.printUsageAndExit();
+ }
+}
+
+function initSourceMapSupport() {
+ // Pull dev tools source maps into our name space.
+ SourceMap = WebInspector.SourceMap;
+
+ // Overwrite the load function to load scripts synchronously.
+ SourceMap.load = function(sourceMapURL) {
+ var content = readFile(sourceMapURL);
+ var sourceMapObject = (JSON.parse(content));
+ return new SourceMap(sourceMapURL, sourceMapObject);
+ };
+}
+
+var entriesProviders = {
+ 'unix': UnixCppEntriesProvider,
+ 'windows': WindowsCppEntriesProvider,
+ 'mac': MacCppEntriesProvider
+};
+
+var params = processArguments(arguments);
+var sourceMap = null;
+if (params.sourceMap) {
+ initSourceMapSupport();
+ sourceMap = SourceMap.load(params.sourceMap);
+}
+
+function CppProcessor(cppEntriesProvider, timedRange, pairwiseTimedRange) {
+ LogReader.call(this, {
+ 'shared-library': { parsers: [null, parseInt, parseInt],
+ processor: this.processSharedLibrary }
+ }, timedRange, pairwiseTimedRange);
+
+ this.cppEntriesProvider_ = cppEntriesProvider;
+ this.codeMap_ = new CodeMap();
+ this.lastLogFileName_ = null;
+}
+inherits(CppProcessor, LogReader);
+
+/**
+ * @override
+ */
+CppProcessor.prototype.printError = function(str) {
+ print(str);
+};
+
+CppProcessor.prototype.processLogFile = function(fileName) {
+ this.lastLogFileName_ = fileName;
+ var line;
+ while (line = readline()) {
+ this.processLogLine(line);
+ }
+};
+
+CppProcessor.prototype.processLogFileInTest = function(fileName) {
+ // Hack file name to avoid dealing with platform specifics.
+ this.lastLogFileName_ = 'v8.log';
+ var contents = readFile(fileName);
+ this.processLogChunk(contents);
+};
+
+CppProcessor.prototype.processSharedLibrary = function(
+ name, startAddr, endAddr) {
+ var self = this;
+ var libFuncs = this.cppEntriesProvider_.parseVmSymbols(
+ name, startAddr, endAddr, function(fName, fStart, fEnd) {
+ var entry = new CodeMap.CodeEntry(fEnd - fStart, fName, 'CPP');
+ self.codeMap_.addStaticCode(fStart, entry);
+ });
+};
+
+CppProcessor.prototype.dumpCppSymbols = function() {
+ var staticEntries = this.codeMap_.getAllStaticEntriesWithAddresses();
+ var total = staticEntries.length;
+ for (var i = 0; i < total; ++i) {
+ var entry = staticEntries[i];
+ var printValues = ['cpp', '0x' + entry[0].toString(16), entry[1].size,
+ '"' + entry[1].name + '"'];
+ print(printValues.join(','));
+ }
+};
+
+var cppProcessor = new CppProcessor(
+ new (entriesProviders[params.platform])(params.nm, params.targetRootFS),
+ params.timedRange, params.pairwiseTimedRange);
+cppProcessor.processLogFile(params.logFileName);
+cppProcessor.dumpCppSymbols();
diff --git a/tools/eval_gc_nvp.py b/tools/eval_gc_nvp.py
index fcb6d8b9..25afe8e4 100755
--- a/tools/eval_gc_nvp.py
+++ b/tools/eval_gc_nvp.py
@@ -10,7 +10,7 @@
from argparse import ArgumentParser
from copy import deepcopy
from gc_nvp_common import split_nvp
-from math import log
+from math import ceil,log
from sys import stdin
@@ -74,11 +74,12 @@ class Histogram:
class Category:
- def __init__(self, key, histogram, csv):
+ def __init__(self, key, histogram, csv, percentiles):
self.key = key
self.values = []
self.histogram = histogram
self.csv = csv
+ self.percentiles = percentiles
def process_entry(self, entry):
if self.key in entry:
@@ -100,6 +101,16 @@ class Category:
def empty(self):
return len(self.values) == 0
+ def _compute_percentiles(self):
+ ret = []
+ if len(self.values) == 0:
+ return ret
+ sorted_values = sorted(self.values)
+ for percentile in self.percentiles:
+ index = int(ceil((len(self.values) - 1) * percentile / 100))
+ ret.append(" {0}%: {1}".format(percentile, sorted_values[index]))
+ return ret
+
def __str__(self):
if self.csv:
ret = [self.key]
@@ -118,6 +129,8 @@ class Category:
ret.append(" avg: {0}".format(self.avg()))
if self.histogram:
ret.append(str(self.histogram))
+ if self.percentiles:
+ ret.append("\n".join(self._compute_percentiles()))
return "\n".join(ret)
def __repr__(self):
@@ -160,6 +173,9 @@ def main():
help="rank keys by metric (default: no)")
parser.add_argument('--csv', dest='csv',
action='store_true', help='provide output as csv')
+ parser.add_argument('--percentiles', dest='percentiles',
+ type=str, default="",
+ help='comma separated list of percentiles')
args = parser.parse_args()
histogram = None
@@ -171,7 +187,14 @@ def main():
bucket_trait = LinearBucket(args.linear_histogram_granularity)
histogram = Histogram(bucket_trait, not args.histogram_omit_empty)
- categories = [ Category(key, deepcopy(histogram), args.csv)
+ percentiles = []
+ for percentile in args.percentiles.split(','):
+ try:
+ percentiles.append(float(percentile))
+ except ValueError:
+ pass
+
+ categories = [ Category(key, deepcopy(histogram), args.csv, percentiles)
for key in args.keys ]
while True:
diff --git a/tools/eval_gc_time.sh b/tools/eval_gc_time.sh
index ceb4db54..140165da 100755
--- a/tools/eval_gc_time.sh
+++ b/tools/eval_gc_time.sh
@@ -17,6 +17,7 @@ print_usage_and_die() {
echo " -c|--csv provide csv output"
echo " -f|--file FILE profile input in a file"
echo " (default: stdin)"
+ echo " -p|--percentiles comma separated percentiles"
exit 1
}
@@ -25,6 +26,7 @@ RANK_MODE=max
TOP_LEVEL=no
CSV=""
LOGFILE=/dev/stdin
+PERCENTILES=""
while [[ $# -ge 1 ]]
do
@@ -60,6 +62,10 @@ do
LOGFILE=$2
shift
;;
+ -p|--percentiles)
+ PERCENTILES="--percentiles=$2"
+ shift
+ ;;
*)
break
;;
@@ -98,7 +104,6 @@ INTERESTING_OLD_GEN_KEYS="\
evacuate.clean_up \
evacuate.copy \
evacuate.update_pointers \
- evacuate.update_pointers.between_evacuated \
evacuate.update_pointers.to_evacuated \
evacuate.update_pointers.to_new \
evacuate.update_pointers.weak \
@@ -145,6 +150,7 @@ case $OP in
--no-histogram \
--rank $RANK_MODE \
$CSV \
+ $PERCENTILES \
${INTERESTING_NEW_GEN_KEYS}
;;
old-gen-rank)
@@ -153,6 +159,7 @@ case $OP in
--no-histogram \
--rank $RANK_MODE \
$CSV \
+ $PERCENTILES \
${INTERESTING_OLD_GEN_KEYS}
;;
*)
diff --git a/tools/gcmole/gcmole.lua b/tools/gcmole/gcmole.lua
index 82ea4e02..f16ad8fd 100644
--- a/tools/gcmole/gcmole.lua
+++ b/tools/gcmole/gcmole.lua
@@ -185,7 +185,7 @@ end
local function ParseGYPFile()
local gyp = ""
- local gyp_files = { "tools/gyp/v8.gyp", "test/cctest/cctest.gyp" }
+ local gyp_files = { "src/v8.gyp", "test/cctest/cctest.gyp" }
for i = 1, #gyp_files do
local f = assert(io.open(gyp_files[i]), "failed to open GYP file")
local t = f:read('*a')
diff --git a/tools/gcmole/run-gcmole.isolate b/tools/gcmole/run-gcmole.isolate
index df6e9a26..39990dee 100644
--- a/tools/gcmole/run-gcmole.isolate
+++ b/tools/gcmole/run-gcmole.isolate
@@ -12,7 +12,6 @@
'parallel.py',
'run-gcmole.py',
# The following contains all relevant source and gyp files.
- '../gyp/v8.gyp',
'../../base/',
'../../include/',
'../../src/',
diff --git a/tools/gcmole/run_gcmole.gyp b/tools/gcmole/run_gcmole.gyp
index 9d13f760..7d206bf4 100644
--- a/tools/gcmole/run_gcmole.gyp
+++ b/tools/gcmole/run_gcmole.gyp
@@ -10,8 +10,8 @@
'target_name': 'run_gcmole_run',
'type': 'none',
'includes': [
- '../../build/features.gypi',
- '../../build/isolate.gypi',
+ '../../gypfiles/features.gypi',
+ '../../gypfiles/isolate.gypi',
],
'sources': [
'run-gcmole.isolate',
diff --git a/tools/gen-postmortem-metadata.py b/tools/gen-postmortem-metadata.py
index a0afc06a..55f915d3 100644
--- a/tools/gen-postmortem-metadata.py
+++ b/tools/gen-postmortem-metadata.py
@@ -92,6 +92,8 @@ consts_misc = [
'value': 'DescriptorArray::kFirstIndex' },
{ 'name': 'prop_type_field',
'value': 'DATA' },
+ { 'name': 'prop_type_const_field',
+ 'value': 'DATA_CONSTANT' },
{ 'name': 'prop_type_mask',
'value': 'PropertyDetails::TypeField::kMask' },
{ 'name': 'prop_index_mask',
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
deleted file mode 100644
index b09fd1f2..00000000
--- a/tools/gyp/v8.gyp
+++ /dev/null
@@ -1,2281 +0,0 @@
-# Copyright 2012 the V8 project authors. All rights reserved.
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-{
- 'variables': {
- 'icu_use_data_file_flag%': 0,
- 'v8_code': 1,
- 'v8_random_seed%': 314159265,
- 'v8_vector_stores%': 0,
- 'embed_script%': "",
- 'warmup_script%': "",
- 'v8_extra_library_files%': [],
- 'v8_experimental_extra_library_files%': [],
- 'mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
- },
- 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
- 'targets': [
- {
- 'target_name': 'v8',
- 'dependencies_traverse': 1,
- 'dependencies': ['v8_maybe_snapshot'],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ['component=="shared_library"', {
- 'type': '<(component)',
- 'sources': [
- # Note: on non-Windows we still build this file so that gyp
- # has some sources to link into the component.
- '../../src/v8dll-main.cc',
- ],
- 'include_dirs': [
- '../..',
- ],
- 'defines': [
- 'V8_SHARED',
- 'BUILDING_V8_SHARED',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'V8_SHARED',
- 'USING_V8_SHARED',
- ],
- },
- 'target_conditions': [
- ['OS=="android" and _toolset=="target"', {
- 'libraries': [
- '-llog',
- ],
- 'include_dirs': [
- 'src/common/android/include',
- ],
- }],
- ],
- 'conditions': [
- ['OS=="mac"', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': ['-dynamiclib', '-all_load']
- },
- }],
- ['soname_version!=""', {
- 'product_extension': 'so.<(soname_version)',
- }],
- ],
- },
- {
- 'type': 'none',
- }],
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '../../include',
- ],
- },
- },
- {
- # This rule delegates to either v8_snapshot, v8_nosnapshot, or
- # v8_external_snapshot, depending on the current variables.
- # The intention is to make the 'calling' rules a bit simpler.
- 'target_name': 'v8_maybe_snapshot',
- 'type': 'none',
- 'conditions': [
- ['v8_use_snapshot!="true"', {
- # The dependency on v8_base should come from a transitive
- # dependency however the Android toolchain requires libv8_base.a
- # to appear before libv8_snapshot.a so it's listed explicitly.
- 'dependencies': ['v8_base', 'v8_nosnapshot'],
- }],
- ['v8_use_snapshot=="true" and v8_use_external_startup_data==0', {
- # The dependency on v8_base should come from a transitive
- # dependency however the Android toolchain requires libv8_base.a
- # to appear before libv8_snapshot.a so it's listed explicitly.
- 'dependencies': ['v8_base', 'v8_snapshot'],
- }],
- ['v8_use_snapshot=="true" and v8_use_external_startup_data==1 and want_separate_host_toolset==0', {
- 'dependencies': ['v8_base', 'v8_external_snapshot'],
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob.bin'],
- 'conditions': [
- ['v8_separate_ignition_snapshot==1', {
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition.bin'],
- }],
- ]
- }],
- ['v8_use_snapshot=="true" and v8_use_external_startup_data==1 and want_separate_host_toolset==1', {
- 'dependencies': ['v8_base', 'v8_external_snapshot'],
- 'target_conditions': [
- ['_toolset=="host"', {
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob_host.bin'],
- }, {
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob.bin'],
- }],
- ],
- 'conditions': [
- ['v8_separate_ignition_snapshot==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition_host.bin'],
- }, {
- 'inputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition.bin'],
- }],
- ],
- }],
- ],
- }],
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ]
- },
- {
- 'target_name': 'v8_snapshot',
- 'type': 'static_library',
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- 'dependencies': [
- 'mksnapshot#host',
- 'js2c#host',
- ],
- }, {
- 'toolsets': ['target'],
- 'dependencies': [
- 'mksnapshot',
- 'js2c',
- ],
- }],
- ['component=="shared_library"', {
- 'defines': [
- 'V8_SHARED',
- 'BUILDING_V8_SHARED',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'V8_SHARED',
- 'USING_V8_SHARED',
- ],
- },
- }],
- ],
- 'dependencies': [
- 'v8_base',
- ],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
- '<(INTERMEDIATE_DIR)/snapshot.cc',
- ],
- 'actions': [
- {
- 'action_name': 'run_mksnapshot',
- 'inputs': [
- '<(mksnapshot_exec)',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/snapshot.cc',
- ],
- 'variables': {
- 'mksnapshot_flags': [],
- 'conditions': [
- ['v8_random_seed!=0', {
- 'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'],
- }],
- ['v8_vector_stores!=0', {
- 'mksnapshot_flags': ['--vector-stores'],
- }],
- ],
- },
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags)',
- '--startup_src', '<@(INTERMEDIATE_DIR)/snapshot.cc',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- },
- ],
- },
- {
- 'target_name': 'v8_nosnapshot',
- 'type': 'static_library',
- 'dependencies': [
- 'v8_base',
- ],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
- '../../src/snapshot/snapshot-empty.cc',
- ],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- 'dependencies': ['js2c#host'],
- }, {
- 'toolsets': ['target'],
- 'dependencies': ['js2c'],
- }],
- ['component=="shared_library"', {
- 'defines': [
- 'BUILDING_V8_SHARED',
- 'V8_SHARED',
- ],
- }],
- ]
- },
- {
- 'target_name': 'v8_external_snapshot',
- 'type': 'static_library',
- 'conditions': [
- [ 'v8_use_external_startup_data==1', {
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- 'dependencies': [
- 'mksnapshot#host',
- 'js2c#host',
- 'natives_blob',
- ]}, {
- 'toolsets': ['target'],
- 'dependencies': [
- 'mksnapshot',
- 'js2c',
- 'natives_blob',
- ],
- }],
- ['component=="shared_library"', {
- 'defines': [
- 'V8_SHARED',
- 'BUILDING_V8_SHARED',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'V8_SHARED',
- 'USING_V8_SHARED',
- ],
- },
- }],
- # Extra snapshot blob for ignition.
- ['v8_separate_ignition_snapshot==1', {
- # This is concatenated to the other actions list of
- # v8_external_snapshot.
- 'actions': [
- {
- 'action_name': 'run_mksnapshot (ignition)',
- 'inputs': ['<(mksnapshot_exec)'],
- 'variables': {
- # TODO: Extract common mksnapshot_flags to a separate
- # variable.
- 'mksnapshot_flags_ignition': [
- '--ignition',
- ],
- 'conditions': [
- ['v8_random_seed!=0', {
- 'mksnapshot_flags_ignition': ['--random-seed', '<(v8_random_seed)'],
- }],
- ['v8_vector_stores!=0', {
- 'mksnapshot_flags_ignition': ['--vector-stores'],
- }],
- ],
- },
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition_host.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags_ignition)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_ignition_host.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }, {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags_ignition)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_ignition.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }],
- ],
- }, {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob_ignition.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags_ignition)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_ignition.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }],
- ],
- },
- ],
- }],
- ],
- 'dependencies': [
- 'v8_base',
- ],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '../../src/snapshot/natives-external.cc',
- '../../src/snapshot/snapshot-external.cc',
- ],
- 'actions': [
- {
- 'action_name': 'run_mksnapshot (external)',
- 'inputs': ['<(mksnapshot_exec)'],
- 'variables': {
- 'mksnapshot_flags': [],
- 'conditions': [
- ['v8_random_seed!=0', {
- 'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'],
- }],
- ['v8_vector_stores!=0', {
- 'mksnapshot_flags': ['--vector-stores'],
- }],
- ],
- },
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob_host.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }, {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }],
- ],
- }, {
- 'outputs': ['<(PRODUCT_DIR)/snapshot_blob.bin'],
- 'action': [
- '<(mksnapshot_exec)',
- '<@(mksnapshot_flags)',
- '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
- '<(embed_script)',
- '<(warmup_script)',
- ],
- }],
- ],
- },
- ],
- }],
- ],
- },
- {
- 'target_name': 'v8_base',
- 'type': 'static_library',
- 'dependencies': [
- 'v8_libbase',
- ],
- 'variables': {
- 'optimize': 'max',
- },
- 'include_dirs+': [
- '../..',
- # To be able to find base/trace_event/common/trace_event_common.h
- '../../..',
- ],
- 'defines': [
- # TODO(jochen): Remove again after this is globally turned on.
- 'V8_IMMINENT_DEPRECATION_WARNINGS',
- ],
- 'sources': [ ### gcmole(all) ###
- '../../include/v8-debug.h',
- '../../include/v8-experimental.h',
- '../../include/v8-platform.h',
- '../../include/v8-profiler.h',
- '../../include/v8-testing.h',
- '../../include/v8-util.h',
- '../../include/v8-version.h',
- '../../include/v8.h',
- '../../include/v8config.h',
- '../../src/accessors.cc',
- '../../src/accessors.h',
- '../../src/address-map.cc',
- '../../src/address-map.h',
- '../../src/allocation.cc',
- '../../src/allocation.h',
- '../../src/allocation-site-scopes.cc',
- '../../src/allocation-site-scopes.h',
- '../../src/api-experimental.cc',
- '../../src/api-experimental.h',
- '../../src/api.cc',
- '../../src/api.h',
- '../../src/api-arguments.cc',
- '../../src/api-arguments.h',
- '../../src/api-natives.cc',
- '../../src/api-natives.h',
- '../../src/arguments.cc',
- '../../src/arguments.h',
- '../../src/assembler.cc',
- '../../src/assembler.h',
- '../../src/assert-scope.h',
- '../../src/assert-scope.cc',
- '../../src/ast/ast-expression-rewriter.cc',
- '../../src/ast/ast-expression-rewriter.h',
- '../../src/ast/ast-expression-visitor.cc',
- '../../src/ast/ast-expression-visitor.h',
- '../../src/ast/ast-literal-reindexer.cc',
- '../../src/ast/ast-literal-reindexer.h',
- '../../src/ast/ast-numbering.cc',
- '../../src/ast/ast-numbering.h',
- '../../src/ast/ast-value-factory.cc',
- '../../src/ast/ast-value-factory.h',
- '../../src/ast/ast.cc',
- '../../src/ast/ast.h',
- '../../src/ast/modules.cc',
- '../../src/ast/modules.h',
- '../../src/ast/prettyprinter.cc',
- '../../src/ast/prettyprinter.h',
- '../../src/ast/scopeinfo.cc',
- '../../src/ast/scopeinfo.h',
- '../../src/ast/scopes.cc',
- '../../src/ast/scopes.h',
- '../../src/ast/variables.cc',
- '../../src/ast/variables.h',
- '../../src/atomic-utils.h',
- '../../src/background-parsing-task.cc',
- '../../src/background-parsing-task.h',
- '../../src/bailout-reason.cc',
- '../../src/bailout-reason.h',
- '../../src/basic-block-profiler.cc',
- '../../src/basic-block-profiler.h',
- '../../src/bignum-dtoa.cc',
- '../../src/bignum-dtoa.h',
- '../../src/bignum.cc',
- '../../src/bignum.h',
- '../../src/bit-vector.cc',
- '../../src/bit-vector.h',
- '../../src/bootstrapper.cc',
- '../../src/bootstrapper.h',
- '../../src/builtins.cc',
- '../../src/builtins.h',
- '../../src/cached-powers.cc',
- '../../src/cached-powers.h',
- '../../src/cancelable-task.cc',
- '../../src/cancelable-task.h',
- '../../src/char-predicates.cc',
- '../../src/char-predicates-inl.h',
- '../../src/char-predicates.h',
- '../../src/checks.h',
- '../../src/code-factory.cc',
- '../../src/code-factory.h',
- '../../src/code-stubs.cc',
- '../../src/code-stubs.h',
- '../../src/code-stubs-hydrogen.cc',
- '../../src/codegen.cc',
- '../../src/codegen.h',
- '../../src/collector.h',
- '../../src/compilation-cache.cc',
- '../../src/compilation-cache.h',
- '../../src/compilation-dependencies.cc',
- '../../src/compilation-dependencies.h',
- '../../src/compilation-statistics.cc',
- '../../src/compilation-statistics.h',
- '../../src/compiler/access-builder.cc',
- '../../src/compiler/access-builder.h',
- '../../src/compiler/access-info.cc',
- '../../src/compiler/access-info.h',
- '../../src/compiler/all-nodes.cc',
- '../../src/compiler/all-nodes.h',
- '../../src/compiler/ast-graph-builder.cc',
- '../../src/compiler/ast-graph-builder.h',
- '../../src/compiler/ast-loop-assignment-analyzer.cc',
- '../../src/compiler/ast-loop-assignment-analyzer.h',
- '../../src/compiler/basic-block-instrumentor.cc',
- '../../src/compiler/basic-block-instrumentor.h',
- '../../src/compiler/branch-elimination.cc',
- '../../src/compiler/branch-elimination.h',
- '../../src/compiler/bytecode-branch-analysis.cc',
- '../../src/compiler/bytecode-branch-analysis.h',
- '../../src/compiler/bytecode-graph-builder.cc',
- '../../src/compiler/bytecode-graph-builder.h',
- '../../src/compiler/change-lowering.cc',
- '../../src/compiler/change-lowering.h',
- '../../src/compiler/c-linkage.cc',
- '../../src/compiler/coalesced-live-ranges.cc',
- '../../src/compiler/coalesced-live-ranges.h',
- '../../src/compiler/code-generator-impl.h',
- '../../src/compiler/code-generator.cc',
- '../../src/compiler/code-generator.h',
- '../../src/compiler/code-stub-assembler.cc',
- '../../src/compiler/code-stub-assembler.h',
- '../../src/compiler/common-node-cache.cc',
- '../../src/compiler/common-node-cache.h',
- '../../src/compiler/common-operator-reducer.cc',
- '../../src/compiler/common-operator-reducer.h',
- '../../src/compiler/common-operator.cc',
- '../../src/compiler/common-operator.h',
- '../../src/compiler/control-builders.cc',
- '../../src/compiler/control-builders.h',
- '../../src/compiler/control-equivalence.cc',
- '../../src/compiler/control-equivalence.h',
- '../../src/compiler/control-flow-optimizer.cc',
- '../../src/compiler/control-flow-optimizer.h',
- '../../src/compiler/dead-code-elimination.cc',
- '../../src/compiler/dead-code-elimination.h',
- '../../src/compiler/diamond.h',
- '../../src/compiler/escape-analysis.cc',
- '../../src/compiler/escape-analysis.h',
- "../../src/compiler/escape-analysis-reducer.cc",
- "../../src/compiler/escape-analysis-reducer.h",
- '../../src/compiler/frame.cc',
- '../../src/compiler/frame.h',
- '../../src/compiler/frame-elider.cc',
- '../../src/compiler/frame-elider.h',
- "../../src/compiler/frame-states.cc",
- "../../src/compiler/frame-states.h",
- '../../src/compiler/gap-resolver.cc',
- '../../src/compiler/gap-resolver.h',
- '../../src/compiler/graph-reducer.cc',
- '../../src/compiler/graph-reducer.h',
- '../../src/compiler/graph-replay.cc',
- '../../src/compiler/graph-replay.h',
- '../../src/compiler/graph-trimmer.cc',
- '../../src/compiler/graph-trimmer.h',
- '../../src/compiler/graph-visualizer.cc',
- '../../src/compiler/graph-visualizer.h',
- '../../src/compiler/graph.cc',
- '../../src/compiler/graph.h',
- '../../src/compiler/greedy-allocator.cc',
- '../../src/compiler/greedy-allocator.h',
- '../../src/compiler/instruction-codes.h',
- '../../src/compiler/instruction-selector-impl.h',
- '../../src/compiler/instruction-selector.cc',
- '../../src/compiler/instruction-selector.h',
- '../../src/compiler/instruction-scheduler.cc',
- '../../src/compiler/instruction-scheduler.h',
- '../../src/compiler/instruction.cc',
- '../../src/compiler/instruction.h',
- '../../src/compiler/int64-lowering.cc',
- '../../src/compiler/int64-lowering.h',
- '../../src/compiler/js-builtin-reducer.cc',
- '../../src/compiler/js-builtin-reducer.h',
- '../../src/compiler/js-call-reducer.cc',
- '../../src/compiler/js-call-reducer.h',
- '../../src/compiler/js-context-specialization.cc',
- '../../src/compiler/js-context-specialization.h',
- '../../src/compiler/js-create-lowering.cc',
- '../../src/compiler/js-create-lowering.h',
- '../../src/compiler/js-frame-specialization.cc',
- '../../src/compiler/js-frame-specialization.h',
- '../../src/compiler/js-generic-lowering.cc',
- '../../src/compiler/js-generic-lowering.h',
- '../../src/compiler/js-global-object-specialization.cc',
- '../../src/compiler/js-global-object-specialization.h',
- '../../src/compiler/js-graph.cc',
- '../../src/compiler/js-graph.h',
- '../../src/compiler/js-inlining.cc',
- '../../src/compiler/js-inlining.h',
- '../../src/compiler/js-inlining-heuristic.cc',
- '../../src/compiler/js-inlining-heuristic.h',
- '../../src/compiler/js-intrinsic-lowering.cc',
- '../../src/compiler/js-intrinsic-lowering.h',
- '../../src/compiler/js-native-context-specialization.cc',
- '../../src/compiler/js-native-context-specialization.h',
- '../../src/compiler/js-operator.cc',
- '../../src/compiler/js-operator.h',
- '../../src/compiler/js-typed-lowering.cc',
- '../../src/compiler/js-typed-lowering.h',
- '../../src/compiler/jump-threading.cc',
- '../../src/compiler/jump-threading.h',
- '../../src/compiler/linkage.cc',
- '../../src/compiler/linkage.h',
- '../../src/compiler/liveness-analyzer.cc',
- '../../src/compiler/liveness-analyzer.h',
- '../../src/compiler/live-range-separator.cc',
- '../../src/compiler/live-range-separator.h',
- '../../src/compiler/load-elimination.cc',
- '../../src/compiler/load-elimination.h',
- '../../src/compiler/loop-analysis.cc',
- '../../src/compiler/loop-analysis.h',
- '../../src/compiler/loop-peeling.cc',
- '../../src/compiler/loop-peeling.h',
- '../../src/compiler/machine-operator-reducer.cc',
- '../../src/compiler/machine-operator-reducer.h',
- '../../src/compiler/machine-operator.cc',
- '../../src/compiler/machine-operator.h',
- '../../src/compiler/move-optimizer.cc',
- '../../src/compiler/move-optimizer.h',
- '../../src/compiler/node-aux-data.h',
- '../../src/compiler/node-cache.cc',
- '../../src/compiler/node-cache.h',
- '../../src/compiler/node-marker.cc',
- '../../src/compiler/node-marker.h',
- '../../src/compiler/node-matchers.cc',
- '../../src/compiler/node-matchers.h',
- '../../src/compiler/node-properties.cc',
- '../../src/compiler/node-properties.h',
- '../../src/compiler/node.cc',
- '../../src/compiler/node.h',
- '../../src/compiler/opcodes.cc',
- '../../src/compiler/opcodes.h',
- '../../src/compiler/operator-properties.cc',
- '../../src/compiler/operator-properties.h',
- '../../src/compiler/operator.cc',
- '../../src/compiler/operator.h',
- '../../src/compiler/osr.cc',
- '../../src/compiler/osr.h',
- '../../src/compiler/pipeline.cc',
- '../../src/compiler/pipeline.h',
- '../../src/compiler/pipeline-statistics.cc',
- '../../src/compiler/pipeline-statistics.h',
- '../../src/compiler/raw-machine-assembler.cc',
- '../../src/compiler/raw-machine-assembler.h',
- '../../src/compiler/register-allocator.cc',
- '../../src/compiler/register-allocator.h',
- '../../src/compiler/register-allocator-verifier.cc',
- '../../src/compiler/register-allocator-verifier.h',
- '../../src/compiler/representation-change.cc',
- '../../src/compiler/representation-change.h',
- '../../src/compiler/schedule.cc',
- '../../src/compiler/schedule.h',
- '../../src/compiler/scheduler.cc',
- '../../src/compiler/scheduler.h',
- '../../src/compiler/select-lowering.cc',
- '../../src/compiler/select-lowering.h',
- '../../src/compiler/simplified-lowering.cc',
- '../../src/compiler/simplified-lowering.h',
- '../../src/compiler/simplified-operator-reducer.cc',
- '../../src/compiler/simplified-operator-reducer.h',
- '../../src/compiler/simplified-operator.cc',
- '../../src/compiler/simplified-operator.h',
- '../../src/compiler/source-position.cc',
- '../../src/compiler/source-position.h',
- '../../src/compiler/state-values-utils.cc',
- '../../src/compiler/state-values-utils.h',
- '../../src/compiler/tail-call-optimization.cc',
- '../../src/compiler/tail-call-optimization.h',
- '../../src/compiler/type-hint-analyzer.cc',
- '../../src/compiler/type-hint-analyzer.h',
- '../../src/compiler/type-hints.cc',
- '../../src/compiler/type-hints.h',
- '../../src/compiler/typer.cc',
- '../../src/compiler/typer.h',
- '../../src/compiler/value-numbering-reducer.cc',
- '../../src/compiler/value-numbering-reducer.h',
- '../../src/compiler/verifier.cc',
- '../../src/compiler/verifier.h',
- '../../src/compiler/wasm-compiler.cc',
- '../../src/compiler/wasm-compiler.h',
- '../../src/compiler/wasm-linkage.cc',
- '../../src/compiler/zone-pool.cc',
- '../../src/compiler/zone-pool.h',
- '../../src/compiler.cc',
- '../../src/compiler.h',
- '../../src/context-measure.cc',
- '../../src/context-measure.h',
- '../../src/contexts-inl.h',
- '../../src/contexts.cc',
- '../../src/contexts.h',
- '../../src/conversions-inl.h',
- '../../src/conversions.cc',
- '../../src/conversions.h',
- '../../src/counters.cc',
- '../../src/counters.h',
- '../../src/crankshaft/compilation-phase.cc',
- '../../src/crankshaft/compilation-phase.h',
- '../../src/crankshaft/hydrogen-alias-analysis.h',
- '../../src/crankshaft/hydrogen-bce.cc',
- '../../src/crankshaft/hydrogen-bce.h',
- '../../src/crankshaft/hydrogen-canonicalize.cc',
- '../../src/crankshaft/hydrogen-canonicalize.h',
- '../../src/crankshaft/hydrogen-check-elimination.cc',
- '../../src/crankshaft/hydrogen-check-elimination.h',
- '../../src/crankshaft/hydrogen-dce.cc',
- '../../src/crankshaft/hydrogen-dce.h',
- '../../src/crankshaft/hydrogen-dehoist.cc',
- '../../src/crankshaft/hydrogen-dehoist.h',
- '../../src/crankshaft/hydrogen-environment-liveness.cc',
- '../../src/crankshaft/hydrogen-environment-liveness.h',
- '../../src/crankshaft/hydrogen-escape-analysis.cc',
- '../../src/crankshaft/hydrogen-escape-analysis.h',
- '../../src/crankshaft/hydrogen-flow-engine.h',
- '../../src/crankshaft/hydrogen-gvn.cc',
- '../../src/crankshaft/hydrogen-gvn.h',
- '../../src/crankshaft/hydrogen-infer-representation.cc',
- '../../src/crankshaft/hydrogen-infer-representation.h',
- '../../src/crankshaft/hydrogen-infer-types.cc',
- '../../src/crankshaft/hydrogen-infer-types.h',
- '../../src/crankshaft/hydrogen-instructions.cc',
- '../../src/crankshaft/hydrogen-instructions.h',
- '../../src/crankshaft/hydrogen-load-elimination.cc',
- '../../src/crankshaft/hydrogen-load-elimination.h',
- '../../src/crankshaft/hydrogen-mark-deoptimize.cc',
- '../../src/crankshaft/hydrogen-mark-deoptimize.h',
- '../../src/crankshaft/hydrogen-mark-unreachable.cc',
- '../../src/crankshaft/hydrogen-mark-unreachable.h',
- '../../src/crankshaft/hydrogen-osr.cc',
- '../../src/crankshaft/hydrogen-osr.h',
- '../../src/crankshaft/hydrogen-range-analysis.cc',
- '../../src/crankshaft/hydrogen-range-analysis.h',
- '../../src/crankshaft/hydrogen-redundant-phi.cc',
- '../../src/crankshaft/hydrogen-redundant-phi.h',
- '../../src/crankshaft/hydrogen-removable-simulates.cc',
- '../../src/crankshaft/hydrogen-removable-simulates.h',
- '../../src/crankshaft/hydrogen-representation-changes.cc',
- '../../src/crankshaft/hydrogen-representation-changes.h',
- '../../src/crankshaft/hydrogen-sce.cc',
- '../../src/crankshaft/hydrogen-sce.h',
- '../../src/crankshaft/hydrogen-store-elimination.cc',
- '../../src/crankshaft/hydrogen-store-elimination.h',
- '../../src/crankshaft/hydrogen-types.cc',
- '../../src/crankshaft/hydrogen-types.h',
- '../../src/crankshaft/hydrogen-uint32-analysis.cc',
- '../../src/crankshaft/hydrogen-uint32-analysis.h',
- '../../src/crankshaft/hydrogen.cc',
- '../../src/crankshaft/hydrogen.h',
- '../../src/crankshaft/lithium-allocator-inl.h',
- '../../src/crankshaft/lithium-allocator.cc',
- '../../src/crankshaft/lithium-allocator.h',
- '../../src/crankshaft/lithium-codegen.cc',
- '../../src/crankshaft/lithium-codegen.h',
- '../../src/crankshaft/lithium.cc',
- '../../src/crankshaft/lithium.h',
- '../../src/crankshaft/lithium-inl.h',
- '../../src/crankshaft/typing.cc',
- '../../src/crankshaft/typing.h',
- '../../src/crankshaft/unique.h',
- '../../src/date.cc',
- '../../src/date.h',
- '../../src/dateparser-inl.h',
- '../../src/dateparser.cc',
- '../../src/dateparser.h',
- '../../src/debug/debug-evaluate.cc',
- '../../src/debug/debug-evaluate.h',
- '../../src/debug/debug-frames.cc',
- '../../src/debug/debug-frames.h',
- '../../src/debug/debug-scopes.cc',
- '../../src/debug/debug-scopes.h',
- '../../src/debug/debug.cc',
- '../../src/debug/debug.h',
- '../../src/debug/liveedit.cc',
- '../../src/debug/liveedit.h',
- '../../src/deoptimizer.cc',
- '../../src/deoptimizer.h',
- '../../src/disasm.h',
- '../../src/disassembler.cc',
- '../../src/disassembler.h',
- '../../src/diy-fp.cc',
- '../../src/diy-fp.h',
- '../../src/double.h',
- '../../src/dtoa.cc',
- '../../src/dtoa.h',
- '../../src/effects.h',
- '../../src/elements-kind.cc',
- '../../src/elements-kind.h',
- '../../src/elements.cc',
- '../../src/elements.h',
- '../../src/execution.cc',
- '../../src/execution.h',
- '../../src/extensions/externalize-string-extension.cc',
- '../../src/extensions/externalize-string-extension.h',
- '../../src/extensions/free-buffer-extension.cc',
- '../../src/extensions/free-buffer-extension.h',
- '../../src/extensions/gc-extension.cc',
- '../../src/extensions/gc-extension.h',
- '../../src/extensions/statistics-extension.cc',
- '../../src/extensions/statistics-extension.h',
- '../../src/extensions/trigger-failure-extension.cc',
- '../../src/extensions/trigger-failure-extension.h',
- '../../src/external-reference-table.cc',
- '../../src/external-reference-table.h',
- '../../src/factory.cc',
- '../../src/factory.h',
- '../../src/fast-accessor-assembler.cc',
- '../../src/fast-accessor-assembler.h',
- '../../src/fast-dtoa.cc',
- '../../src/fast-dtoa.h',
- '../../src/field-index.h',
- '../../src/field-index-inl.h',
- '../../src/field-type.cc',
- '../../src/field-type.h',
- '../../src/fixed-dtoa.cc',
- '../../src/fixed-dtoa.h',
- '../../src/flag-definitions.h',
- '../../src/flags.cc',
- '../../src/flags.h',
- '../../src/frames-inl.h',
- '../../src/frames.cc',
- '../../src/frames.h',
- '../../src/full-codegen/full-codegen.cc',
- '../../src/full-codegen/full-codegen.h',
- '../../src/futex-emulation.cc',
- '../../src/futex-emulation.h',
- '../../src/gdb-jit.cc',
- '../../src/gdb-jit.h',
- '../../src/global-handles.cc',
- '../../src/global-handles.h',
- '../../src/globals.h',
- '../../src/handles-inl.h',
- '../../src/handles.cc',
- '../../src/handles.h',
- '../../src/hashmap.h',
- '../../src/heap-symbols.h',
- '../../src/heap/array-buffer-tracker.cc',
- '../../src/heap/array-buffer-tracker.h',
- '../../src/heap/memory-reducer.cc',
- '../../src/heap/memory-reducer.h',
- '../../src/heap/gc-idle-time-handler.cc',
- '../../src/heap/gc-idle-time-handler.h',
- '../../src/heap/gc-tracer.cc',
- '../../src/heap/gc-tracer.h',
- '../../src/heap/heap-inl.h',
- '../../src/heap/heap.cc',
- '../../src/heap/heap.h',
- '../../src/heap/incremental-marking-inl.h',
- '../../src/heap/incremental-marking-job.cc',
- '../../src/heap/incremental-marking-job.h',
- '../../src/heap/incremental-marking.cc',
- '../../src/heap/incremental-marking.h',
- '../../src/heap/mark-compact-inl.h',
- '../../src/heap/mark-compact.cc',
- '../../src/heap/mark-compact.h',
- '../../src/heap/object-stats.cc',
- '../../src/heap/object-stats.h',
- '../../src/heap/objects-visiting-inl.h',
- '../../src/heap/objects-visiting.cc',
- '../../src/heap/objects-visiting.h',
- '../../src/heap/page-parallel-job.h',
- '../../src/heap/remembered-set.cc',
- '../../src/heap/remembered-set.h',
- '../../src/heap/scavenge-job.h',
- '../../src/heap/scavenge-job.cc',
- '../../src/heap/scavenger-inl.h',
- '../../src/heap/scavenger.cc',
- '../../src/heap/scavenger.h',
- '../../src/heap/slot-set.h',
- '../../src/heap/spaces-inl.h',
- '../../src/heap/spaces.cc',
- '../../src/heap/spaces.h',
- '../../src/heap/store-buffer.cc',
- '../../src/heap/store-buffer.h',
- '../../src/i18n.cc',
- '../../src/i18n.h',
- '../../src/icu_util.cc',
- '../../src/icu_util.h',
- '../../src/ic/access-compiler.cc',
- '../../src/ic/access-compiler.h',
- '../../src/ic/call-optimization.cc',
- '../../src/ic/call-optimization.h',
- '../../src/ic/handler-compiler.cc',
- '../../src/ic/handler-compiler.h',
- '../../src/ic/ic-inl.h',
- '../../src/ic/ic-state.cc',
- '../../src/ic/ic-state.h',
- '../../src/ic/ic.cc',
- '../../src/ic/ic.h',
- '../../src/ic/ic-compiler.cc',
- '../../src/ic/ic-compiler.h',
- '../../src/identity-map.cc',
- '../../src/identity-map.h',
- '../../src/interface-descriptors.cc',
- '../../src/interface-descriptors.h',
- '../../src/interpreter/bytecodes.cc',
- '../../src/interpreter/bytecodes.h',
- '../../src/interpreter/bytecode-array-builder.cc',
- '../../src/interpreter/bytecode-array-builder.h',
- '../../src/interpreter/bytecode-array-iterator.cc',
- '../../src/interpreter/bytecode-array-iterator.h',
- '../../src/interpreter/bytecode-register-allocator.cc',
- '../../src/interpreter/bytecode-register-allocator.h',
- '../../src/interpreter/bytecode-generator.cc',
- '../../src/interpreter/bytecode-generator.h',
- '../../src/interpreter/bytecode-traits.h',
- '../../src/interpreter/constant-array-builder.cc',
- '../../src/interpreter/constant-array-builder.h',
- '../../src/interpreter/control-flow-builders.cc',
- '../../src/interpreter/control-flow-builders.h',
- '../../src/interpreter/handler-table-builder.cc',
- '../../src/interpreter/handler-table-builder.h',
- '../../src/interpreter/interpreter.cc',
- '../../src/interpreter/interpreter.h',
- '../../src/interpreter/interpreter-assembler.cc',
- '../../src/interpreter/interpreter-assembler.h',
- '../../src/interpreter/interpreter-intrinsics.cc',
- '../../src/interpreter/interpreter-intrinsics.h',
- '../../src/interpreter/source-position-table.cc',
- '../../src/interpreter/source-position-table.h',
- '../../src/isolate-inl.h',
- '../../src/isolate.cc',
- '../../src/isolate.h',
- '../../src/json-parser.h',
- '../../src/json-stringifier.h',
- '../../src/keys.h',
- '../../src/keys.cc',
- '../../src/layout-descriptor-inl.h',
- '../../src/layout-descriptor.cc',
- '../../src/layout-descriptor.h',
- '../../src/list-inl.h',
- '../../src/list.h',
- '../../src/locked-queue-inl.h',
- '../../src/locked-queue.h',
- '../../src/log-inl.h',
- '../../src/log-utils.cc',
- '../../src/log-utils.h',
- '../../src/log.cc',
- '../../src/log.h',
- '../../src/lookup.cc',
- '../../src/lookup.h',
- '../../src/macro-assembler.h',
- '../../src/machine-type.cc',
- '../../src/machine-type.h',
- '../../src/messages.cc',
- '../../src/messages.h',
- '../../src/msan.h',
- '../../src/objects-body-descriptors-inl.h',
- '../../src/objects-body-descriptors.h',
- '../../src/objects-debug.cc',
- '../../src/objects-inl.h',
- '../../src/objects-printer.cc',
- '../../src/objects.cc',
- '../../src/objects.h',
- '../../src/optimizing-compile-dispatcher.cc',
- '../../src/optimizing-compile-dispatcher.h',
- '../../src/ostreams.cc',
- '../../src/ostreams.h',
- '../../src/parsing/expression-classifier.h',
- '../../src/parsing/func-name-inferrer.cc',
- '../../src/parsing/func-name-inferrer.h',
- '../../src/parsing/parameter-initializer-rewriter.cc',
- '../../src/parsing/parameter-initializer-rewriter.h',
- '../../src/parsing/parser-base.h',
- '../../src/parsing/parser.cc',
- '../../src/parsing/parser.h',
- '../../src/parsing/pattern-rewriter.cc',
- '../../src/parsing/preparse-data-format.h',
- '../../src/parsing/preparse-data.cc',
- '../../src/parsing/preparse-data.h',
- '../../src/parsing/preparser.cc',
- '../../src/parsing/preparser.h',
- '../../src/parsing/rewriter.cc',
- '../../src/parsing/rewriter.h',
- '../../src/parsing/scanner-character-streams.cc',
- '../../src/parsing/scanner-character-streams.h',
- '../../src/parsing/scanner.cc',
- '../../src/parsing/scanner.h',
- '../../src/parsing/token.cc',
- '../../src/parsing/token.h',
- '../../src/pending-compilation-error-handler.cc',
- '../../src/pending-compilation-error-handler.h',
- '../../src/perf-jit.cc',
- '../../src/perf-jit.h',
- '../../src/profiler/allocation-tracker.cc',
- '../../src/profiler/allocation-tracker.h',
- '../../src/profiler/circular-queue-inl.h',
- '../../src/profiler/circular-queue.h',
- '../../src/profiler/cpu-profiler-inl.h',
- '../../src/profiler/cpu-profiler.cc',
- '../../src/profiler/cpu-profiler.h',
- '../../src/profiler/heap-profiler.cc',
- '../../src/profiler/heap-profiler.h',
- '../../src/profiler/heap-snapshot-generator-inl.h',
- '../../src/profiler/heap-snapshot-generator.cc',
- '../../src/profiler/heap-snapshot-generator.h',
- '../../src/profiler/profile-generator-inl.h',
- '../../src/profiler/profile-generator.cc',
- '../../src/profiler/profile-generator.h',
- '../../src/profiler/sampler.cc',
- '../../src/profiler/sampler.h',
- '../../src/profiler/sampling-heap-profiler.cc',
- '../../src/profiler/sampling-heap-profiler.h',
- '../../src/profiler/strings-storage.cc',
- '../../src/profiler/strings-storage.h',
- '../../src/profiler/unbound-queue-inl.h',
- '../../src/profiler/unbound-queue.h',
- '../../src/property-descriptor.cc',
- '../../src/property-descriptor.h',
- '../../src/property-details.h',
- '../../src/property.cc',
- '../../src/property.h',
- '../../src/prototype.h',
- '../../src/regexp/bytecodes-irregexp.h',
- '../../src/regexp/interpreter-irregexp.cc',
- '../../src/regexp/interpreter-irregexp.h',
- '../../src/regexp/jsregexp-inl.h',
- '../../src/regexp/jsregexp.cc',
- '../../src/regexp/jsregexp.h',
- '../../src/regexp/regexp-ast.cc',
- '../../src/regexp/regexp-ast.h',
- '../../src/regexp/regexp-macro-assembler-irregexp-inl.h',
- '../../src/regexp/regexp-macro-assembler-irregexp.cc',
- '../../src/regexp/regexp-macro-assembler-irregexp.h',
- '../../src/regexp/regexp-macro-assembler-tracer.cc',
- '../../src/regexp/regexp-macro-assembler-tracer.h',
- '../../src/regexp/regexp-macro-assembler.cc',
- '../../src/regexp/regexp-macro-assembler.h',
- '../../src/regexp/regexp-parser.cc',
- '../../src/regexp/regexp-parser.h',
- '../../src/regexp/regexp-stack.cc',
- '../../src/regexp/regexp-stack.h',
- '../../src/register-configuration.cc',
- '../../src/register-configuration.h',
- '../../src/runtime-profiler.cc',
- '../../src/runtime-profiler.h',
- '../../src/runtime/runtime-array.cc',
- '../../src/runtime/runtime-atomics.cc',
- '../../src/runtime/runtime-classes.cc',
- '../../src/runtime/runtime-collections.cc',
- '../../src/runtime/runtime-compiler.cc',
- '../../src/runtime/runtime-date.cc',
- '../../src/runtime/runtime-debug.cc',
- '../../src/runtime/runtime-forin.cc',
- '../../src/runtime/runtime-function.cc',
- '../../src/runtime/runtime-futex.cc',
- '../../src/runtime/runtime-generator.cc',
- '../../src/runtime/runtime-i18n.cc',
- '../../src/runtime/runtime-internal.cc',
- '../../src/runtime/runtime-interpreter.cc',
- '../../src/runtime/runtime-json.cc',
- '../../src/runtime/runtime-literals.cc',
- '../../src/runtime/runtime-liveedit.cc',
- '../../src/runtime/runtime-maths.cc',
- '../../src/runtime/runtime-numbers.cc',
- '../../src/runtime/runtime-object.cc',
- '../../src/runtime/runtime-observe.cc',
- '../../src/runtime/runtime-operators.cc',
- '../../src/runtime/runtime-proxy.cc',
- '../../src/runtime/runtime-regexp.cc',
- '../../src/runtime/runtime-scopes.cc',
- '../../src/runtime/runtime-simd.cc',
- '../../src/runtime/runtime-strings.cc',
- '../../src/runtime/runtime-symbol.cc',
- '../../src/runtime/runtime-test.cc',
- '../../src/runtime/runtime-typedarray.cc',
- '../../src/runtime/runtime-uri.cc',
- '../../src/runtime/runtime-utils.h',
- '../../src/runtime/runtime.cc',
- '../../src/runtime/runtime.h',
- '../../src/safepoint-table.cc',
- '../../src/safepoint-table.h',
- '../../src/signature.h',
- '../../src/simulator.h',
- '../../src/small-pointer-list.h',
- '../../src/snapshot/code-serializer.cc',
- '../../src/snapshot/code-serializer.h',
- '../../src/snapshot/deserializer.cc',
- '../../src/snapshot/deserializer.h',
- '../../src/snapshot/natives.h',
- '../../src/snapshot/natives-common.cc',
- '../../src/snapshot/partial-serializer.cc',
- '../../src/snapshot/partial-serializer.h',
- '../../src/snapshot/serializer.cc',
- '../../src/snapshot/serializer.h',
- '../../src/snapshot/serializer-common.cc',
- '../../src/snapshot/serializer-common.h',
- '../../src/snapshot/snapshot.h',
- '../../src/snapshot/snapshot-common.cc',
- '../../src/snapshot/snapshot-source-sink.cc',
- '../../src/snapshot/snapshot-source-sink.h',
- '../../src/snapshot/startup-serializer.cc',
- '../../src/snapshot/startup-serializer.h',
- '../../src/source-position.h',
- '../../src/splay-tree.h',
- '../../src/splay-tree-inl.h',
- '../../src/startup-data-util.cc',
- '../../src/startup-data-util.h',
- '../../src/string-builder.cc',
- '../../src/string-builder.h',
- '../../src/string-search.h',
- '../../src/string-stream.cc',
- '../../src/string-stream.h',
- '../../src/strtod.cc',
- '../../src/strtod.h',
- '../../src/ic/stub-cache.cc',
- '../../src/ic/stub-cache.h',
- '../../src/tracing/trace-event.cc',
- '../../src/tracing/trace-event.h',
- '../../src/transitions-inl.h',
- '../../src/transitions.cc',
- '../../src/transitions.h',
- '../../src/type-cache.cc',
- '../../src/type-cache.h',
- '../../src/type-feedback-vector-inl.h',
- '../../src/type-feedback-vector.cc',
- '../../src/type-feedback-vector.h',
- '../../src/type-info.cc',
- '../../src/type-info.h',
- '../../src/types.cc',
- '../../src/types.h',
- '../../src/typing-asm.cc',
- '../../src/typing-asm.h',
- '../../src/typing-reset.cc',
- '../../src/typing-reset.h',
- '../../src/unicode-inl.h',
- '../../src/unicode.cc',
- '../../src/unicode.h',
- '../../src/unicode-cache-inl.h',
- '../../src/unicode-cache.h',
- '../../src/unicode-decoder.cc',
- '../../src/unicode-decoder.h',
- '../../src/utils-inl.h',
- '../../src/utils.cc',
- '../../src/utils.h',
- '../../src/v8.cc',
- '../../src/v8.h',
- '../../src/v8memory.h',
- '../../src/v8threads.cc',
- '../../src/v8threads.h',
- '../../src/vector.h',
- '../../src/version.cc',
- '../../src/version.h',
- '../../src/vm-state-inl.h',
- '../../src/vm-state.h',
- '../../src/wasm/asm-wasm-builder.cc',
- '../../src/wasm/asm-wasm-builder.h',
- '../../src/wasm/ast-decoder.cc',
- '../../src/wasm/ast-decoder.h',
- '../../src/wasm/decoder.h',
- '../../src/wasm/encoder.cc',
- '../../src/wasm/encoder.h',
- '../../src/wasm/module-decoder.cc',
- '../../src/wasm/module-decoder.h',
- '../../src/wasm/wasm-js.cc',
- '../../src/wasm/wasm-js.h',
- '../../src/wasm/wasm-macro-gen.h',
- '../../src/wasm/wasm-module.cc',
- '../../src/wasm/wasm-module.h',
- '../../src/wasm/wasm-opcodes.cc',
- '../../src/wasm/wasm-opcodes.h',
- '../../src/wasm/wasm-result.cc',
- '../../src/wasm/wasm-result.h',
- '../../src/zone.cc',
- '../../src/zone.h',
- '../../src/zone-allocator.h',
- '../../src/zone-containers.h',
- '../../src/third_party/fdlibm/fdlibm.cc',
- '../../src/third_party/fdlibm/fdlibm.h',
- ],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ['v8_target_arch=="arm"', {
- 'sources': [ ### gcmole(arch:arm) ###
- '../../src/arm/assembler-arm-inl.h',
- '../../src/arm/assembler-arm.cc',
- '../../src/arm/assembler-arm.h',
- '../../src/arm/builtins-arm.cc',
- '../../src/arm/code-stubs-arm.cc',
- '../../src/arm/code-stubs-arm.h',
- '../../src/arm/codegen-arm.cc',
- '../../src/arm/codegen-arm.h',
- '../../src/arm/constants-arm.h',
- '../../src/arm/constants-arm.cc',
- '../../src/arm/cpu-arm.cc',
- '../../src/arm/deoptimizer-arm.cc',
- '../../src/arm/disasm-arm.cc',
- '../../src/arm/frames-arm.cc',
- '../../src/arm/frames-arm.h',
- '../../src/arm/interface-descriptors-arm.cc',
- '../../src/arm/interface-descriptors-arm.h',
- '../../src/arm/macro-assembler-arm.cc',
- '../../src/arm/macro-assembler-arm.h',
- '../../src/arm/simulator-arm.cc',
- '../../src/arm/simulator-arm.h',
- '../../src/compiler/arm/code-generator-arm.cc',
- '../../src/compiler/arm/instruction-codes-arm.h',
- '../../src/compiler/arm/instruction-scheduler-arm.cc',
- '../../src/compiler/arm/instruction-selector-arm.cc',
- '../../src/crankshaft/arm/lithium-arm.cc',
- '../../src/crankshaft/arm/lithium-arm.h',
- '../../src/crankshaft/arm/lithium-codegen-arm.cc',
- '../../src/crankshaft/arm/lithium-codegen-arm.h',
- '../../src/crankshaft/arm/lithium-gap-resolver-arm.cc',
- '../../src/crankshaft/arm/lithium-gap-resolver-arm.h',
- '../../src/debug/arm/debug-arm.cc',
- '../../src/full-codegen/arm/full-codegen-arm.cc',
- '../../src/ic/arm/access-compiler-arm.cc',
- '../../src/ic/arm/handler-compiler-arm.cc',
- '../../src/ic/arm/ic-arm.cc',
- '../../src/ic/arm/ic-compiler-arm.cc',
- '../../src/ic/arm/stub-cache-arm.cc',
- '../../src/regexp/arm/regexp-macro-assembler-arm.cc',
- '../../src/regexp/arm/regexp-macro-assembler-arm.h',
- ],
- }],
- ['v8_target_arch=="arm64"', {
- 'sources': [ ### gcmole(arch:arm64) ###
- '../../src/arm64/assembler-arm64.cc',
- '../../src/arm64/assembler-arm64.h',
- '../../src/arm64/assembler-arm64-inl.h',
- '../../src/arm64/builtins-arm64.cc',
- '../../src/arm64/codegen-arm64.cc',
- '../../src/arm64/codegen-arm64.h',
- '../../src/arm64/code-stubs-arm64.cc',
- '../../src/arm64/code-stubs-arm64.h',
- '../../src/arm64/constants-arm64.h',
- '../../src/arm64/cpu-arm64.cc',
- '../../src/arm64/decoder-arm64.cc',
- '../../src/arm64/decoder-arm64.h',
- '../../src/arm64/decoder-arm64-inl.h',
- '../../src/arm64/deoptimizer-arm64.cc',
- '../../src/arm64/disasm-arm64.cc',
- '../../src/arm64/disasm-arm64.h',
- '../../src/arm64/frames-arm64.cc',
- '../../src/arm64/frames-arm64.h',
- '../../src/arm64/instructions-arm64.cc',
- '../../src/arm64/instructions-arm64.h',
- '../../src/arm64/instrument-arm64.cc',
- '../../src/arm64/instrument-arm64.h',
- '../../src/arm64/interface-descriptors-arm64.cc',
- '../../src/arm64/interface-descriptors-arm64.h',
- '../../src/arm64/macro-assembler-arm64.cc',
- '../../src/arm64/macro-assembler-arm64.h',
- '../../src/arm64/macro-assembler-arm64-inl.h',
- '../../src/arm64/simulator-arm64.cc',
- '../../src/arm64/simulator-arm64.h',
- '../../src/arm64/utils-arm64.cc',
- '../../src/arm64/utils-arm64.h',
- '../../src/compiler/arm64/code-generator-arm64.cc',
- '../../src/compiler/arm64/instruction-codes-arm64.h',
- '../../src/compiler/arm64/instruction-scheduler-arm64.cc',
- '../../src/compiler/arm64/instruction-selector-arm64.cc',
- '../../src/crankshaft/arm64/delayed-masm-arm64.cc',
- '../../src/crankshaft/arm64/delayed-masm-arm64.h',
- '../../src/crankshaft/arm64/delayed-masm-arm64-inl.h',
- '../../src/crankshaft/arm64/lithium-arm64.cc',
- '../../src/crankshaft/arm64/lithium-arm64.h',
- '../../src/crankshaft/arm64/lithium-codegen-arm64.cc',
- '../../src/crankshaft/arm64/lithium-codegen-arm64.h',
- '../../src/crankshaft/arm64/lithium-gap-resolver-arm64.cc',
- '../../src/crankshaft/arm64/lithium-gap-resolver-arm64.h',
- '../../src/debug/arm64/debug-arm64.cc',
- '../../src/full-codegen/arm64/full-codegen-arm64.cc',
- '../../src/ic/arm64/access-compiler-arm64.cc',
- '../../src/ic/arm64/handler-compiler-arm64.cc',
- '../../src/ic/arm64/ic-arm64.cc',
- '../../src/ic/arm64/ic-compiler-arm64.cc',
- '../../src/ic/arm64/stub-cache-arm64.cc',
- '../../src/regexp/arm64/regexp-macro-assembler-arm64.cc',
- '../../src/regexp/arm64/regexp-macro-assembler-arm64.h',
- ],
- }],
- ['v8_target_arch=="ia32"', {
- 'sources': [ ### gcmole(arch:ia32) ###
- '../../src/ia32/assembler-ia32-inl.h',
- '../../src/ia32/assembler-ia32.cc',
- '../../src/ia32/assembler-ia32.h',
- '../../src/ia32/builtins-ia32.cc',
- '../../src/ia32/code-stubs-ia32.cc',
- '../../src/ia32/code-stubs-ia32.h',
- '../../src/ia32/codegen-ia32.cc',
- '../../src/ia32/codegen-ia32.h',
- '../../src/ia32/cpu-ia32.cc',
- '../../src/ia32/deoptimizer-ia32.cc',
- '../../src/ia32/disasm-ia32.cc',
- '../../src/ia32/frames-ia32.cc',
- '../../src/ia32/frames-ia32.h',
- '../../src/ia32/interface-descriptors-ia32.cc',
- '../../src/ia32/macro-assembler-ia32.cc',
- '../../src/ia32/macro-assembler-ia32.h',
- '../../src/compiler/ia32/code-generator-ia32.cc',
- '../../src/compiler/ia32/instruction-codes-ia32.h',
- '../../src/compiler/ia32/instruction-scheduler-ia32.cc',
- '../../src/compiler/ia32/instruction-selector-ia32.cc',
- '../../src/crankshaft/ia32/lithium-codegen-ia32.cc',
- '../../src/crankshaft/ia32/lithium-codegen-ia32.h',
- '../../src/crankshaft/ia32/lithium-gap-resolver-ia32.cc',
- '../../src/crankshaft/ia32/lithium-gap-resolver-ia32.h',
- '../../src/crankshaft/ia32/lithium-ia32.cc',
- '../../src/crankshaft/ia32/lithium-ia32.h',
- '../../src/debug/ia32/debug-ia32.cc',
- '../../src/full-codegen/ia32/full-codegen-ia32.cc',
- '../../src/ic/ia32/access-compiler-ia32.cc',
- '../../src/ic/ia32/handler-compiler-ia32.cc',
- '../../src/ic/ia32/ic-ia32.cc',
- '../../src/ic/ia32/ic-compiler-ia32.cc',
- '../../src/ic/ia32/stub-cache-ia32.cc',
- '../../src/regexp/ia32/regexp-macro-assembler-ia32.cc',
- '../../src/regexp/ia32/regexp-macro-assembler-ia32.h',
- ],
- }],
- ['v8_target_arch=="x87"', {
- 'sources': [ ### gcmole(arch:x87) ###
- '../../src/x87/assembler-x87-inl.h',
- '../../src/x87/assembler-x87.cc',
- '../../src/x87/assembler-x87.h',
- '../../src/x87/builtins-x87.cc',
- '../../src/x87/code-stubs-x87.cc',
- '../../src/x87/code-stubs-x87.h',
- '../../src/x87/codegen-x87.cc',
- '../../src/x87/codegen-x87.h',
- '../../src/x87/cpu-x87.cc',
- '../../src/x87/deoptimizer-x87.cc',
- '../../src/x87/disasm-x87.cc',
- '../../src/x87/frames-x87.cc',
- '../../src/x87/frames-x87.h',
- '../../src/x87/interface-descriptors-x87.cc',
- '../../src/x87/macro-assembler-x87.cc',
- '../../src/x87/macro-assembler-x87.h',
- '../../src/compiler/x87/code-generator-x87.cc',
- '../../src/compiler/x87/instruction-codes-x87.h',
- '../../src/compiler/x87/instruction-scheduler-x87.cc',
- '../../src/compiler/x87/instruction-selector-x87.cc',
- '../../src/crankshaft/x87/lithium-codegen-x87.cc',
- '../../src/crankshaft/x87/lithium-codegen-x87.h',
- '../../src/crankshaft/x87/lithium-gap-resolver-x87.cc',
- '../../src/crankshaft/x87/lithium-gap-resolver-x87.h',
- '../../src/crankshaft/x87/lithium-x87.cc',
- '../../src/crankshaft/x87/lithium-x87.h',
- '../../src/debug/x87/debug-x87.cc',
- '../../src/full-codegen/x87/full-codegen-x87.cc',
- '../../src/ic/x87/access-compiler-x87.cc',
- '../../src/ic/x87/handler-compiler-x87.cc',
- '../../src/ic/x87/ic-x87.cc',
- '../../src/ic/x87/ic-compiler-x87.cc',
- '../../src/ic/x87/stub-cache-x87.cc',
- '../../src/regexp/x87/regexp-macro-assembler-x87.cc',
- '../../src/regexp/x87/regexp-macro-assembler-x87.h',
- ],
- }],
- ['v8_target_arch=="mips" or v8_target_arch=="mipsel"', {
- 'sources': [ ### gcmole(arch:mipsel) ###
- '../../src/mips/assembler-mips.cc',
- '../../src/mips/assembler-mips.h',
- '../../src/mips/assembler-mips-inl.h',
- '../../src/mips/builtins-mips.cc',
- '../../src/mips/codegen-mips.cc',
- '../../src/mips/codegen-mips.h',
- '../../src/mips/code-stubs-mips.cc',
- '../../src/mips/code-stubs-mips.h',
- '../../src/mips/constants-mips.cc',
- '../../src/mips/constants-mips.h',
- '../../src/mips/cpu-mips.cc',
- '../../src/mips/deoptimizer-mips.cc',
- '../../src/mips/disasm-mips.cc',
- '../../src/mips/frames-mips.cc',
- '../../src/mips/frames-mips.h',
- '../../src/mips/interface-descriptors-mips.cc',
- '../../src/mips/macro-assembler-mips.cc',
- '../../src/mips/macro-assembler-mips.h',
- '../../src/mips/simulator-mips.cc',
- '../../src/mips/simulator-mips.h',
- '../../src/compiler/mips/code-generator-mips.cc',
- '../../src/compiler/mips/instruction-codes-mips.h',
- '../../src/compiler/mips/instruction-scheduler-mips.cc',
- '../../src/compiler/mips/instruction-selector-mips.cc',
- '../../src/crankshaft/mips/lithium-codegen-mips.cc',
- '../../src/crankshaft/mips/lithium-codegen-mips.h',
- '../../src/crankshaft/mips/lithium-gap-resolver-mips.cc',
- '../../src/crankshaft/mips/lithium-gap-resolver-mips.h',
- '../../src/crankshaft/mips/lithium-mips.cc',
- '../../src/crankshaft/mips/lithium-mips.h',
- '../../src/full-codegen/mips/full-codegen-mips.cc',
- '../../src/debug/mips/debug-mips.cc',
- '../../src/ic/mips/access-compiler-mips.cc',
- '../../src/ic/mips/handler-compiler-mips.cc',
- '../../src/ic/mips/ic-mips.cc',
- '../../src/ic/mips/ic-compiler-mips.cc',
- '../../src/ic/mips/stub-cache-mips.cc',
- '../../src/regexp/mips/regexp-macro-assembler-mips.cc',
- '../../src/regexp/mips/regexp-macro-assembler-mips.h',
- ],
- }],
- ['v8_target_arch=="mips64" or v8_target_arch=="mips64el"', {
- 'sources': [ ### gcmole(arch:mips64el) ###
- '../../src/mips64/assembler-mips64.cc',
- '../../src/mips64/assembler-mips64.h',
- '../../src/mips64/assembler-mips64-inl.h',
- '../../src/mips64/builtins-mips64.cc',
- '../../src/mips64/codegen-mips64.cc',
- '../../src/mips64/codegen-mips64.h',
- '../../src/mips64/code-stubs-mips64.cc',
- '../../src/mips64/code-stubs-mips64.h',
- '../../src/mips64/constants-mips64.cc',
- '../../src/mips64/constants-mips64.h',
- '../../src/mips64/cpu-mips64.cc',
- '../../src/mips64/deoptimizer-mips64.cc',
- '../../src/mips64/disasm-mips64.cc',
- '../../src/mips64/frames-mips64.cc',
- '../../src/mips64/frames-mips64.h',
- '../../src/mips64/interface-descriptors-mips64.cc',
- '../../src/mips64/macro-assembler-mips64.cc',
- '../../src/mips64/macro-assembler-mips64.h',
- '../../src/mips64/simulator-mips64.cc',
- '../../src/mips64/simulator-mips64.h',
- '../../src/compiler/mips64/code-generator-mips64.cc',
- '../../src/compiler/mips64/instruction-codes-mips64.h',
- '../../src/compiler/mips64/instruction-scheduler-mips64.cc',
- '../../src/compiler/mips64/instruction-selector-mips64.cc',
- '../../src/crankshaft/mips64/lithium-codegen-mips64.cc',
- '../../src/crankshaft/mips64/lithium-codegen-mips64.h',
- '../../src/crankshaft/mips64/lithium-gap-resolver-mips64.cc',
- '../../src/crankshaft/mips64/lithium-gap-resolver-mips64.h',
- '../../src/crankshaft/mips64/lithium-mips64.cc',
- '../../src/crankshaft/mips64/lithium-mips64.h',
- '../../src/debug/mips64/debug-mips64.cc',
- '../../src/full-codegen/mips64/full-codegen-mips64.cc',
- '../../src/ic/mips64/access-compiler-mips64.cc',
- '../../src/ic/mips64/handler-compiler-mips64.cc',
- '../../src/ic/mips64/ic-mips64.cc',
- '../../src/ic/mips64/ic-compiler-mips64.cc',
- '../../src/ic/mips64/stub-cache-mips64.cc',
- '../../src/regexp/mips64/regexp-macro-assembler-mips64.cc',
- '../../src/regexp/mips64/regexp-macro-assembler-mips64.h',
- ],
- }],
- ['v8_target_arch=="x64" or v8_target_arch=="x32"', {
- 'sources': [ ### gcmole(arch:x64) ###
- '../../src/crankshaft/x64/lithium-codegen-x64.cc',
- '../../src/crankshaft/x64/lithium-codegen-x64.h',
- '../../src/crankshaft/x64/lithium-gap-resolver-x64.cc',
- '../../src/crankshaft/x64/lithium-gap-resolver-x64.h',
- '../../src/crankshaft/x64/lithium-x64.cc',
- '../../src/crankshaft/x64/lithium-x64.h',
- '../../src/x64/assembler-x64-inl.h',
- '../../src/x64/assembler-x64.cc',
- '../../src/x64/assembler-x64.h',
- '../../src/x64/builtins-x64.cc',
- '../../src/x64/code-stubs-x64.cc',
- '../../src/x64/code-stubs-x64.h',
- '../../src/x64/codegen-x64.cc',
- '../../src/x64/codegen-x64.h',
- '../../src/x64/cpu-x64.cc',
- '../../src/x64/deoptimizer-x64.cc',
- '../../src/x64/disasm-x64.cc',
- '../../src/x64/frames-x64.cc',
- '../../src/x64/frames-x64.h',
- '../../src/x64/interface-descriptors-x64.cc',
- '../../src/x64/macro-assembler-x64.cc',
- '../../src/x64/macro-assembler-x64.h',
- '../../src/debug/x64/debug-x64.cc',
- '../../src/full-codegen/x64/full-codegen-x64.cc',
- '../../src/ic/x64/access-compiler-x64.cc',
- '../../src/ic/x64/handler-compiler-x64.cc',
- '../../src/ic/x64/ic-x64.cc',
- '../../src/ic/x64/ic-compiler-x64.cc',
- '../../src/ic/x64/stub-cache-x64.cc',
- '../../src/regexp/x64/regexp-macro-assembler-x64.cc',
- '../../src/regexp/x64/regexp-macro-assembler-x64.h',
- ],
- }],
- ['v8_target_arch=="x64"', {
- 'sources': [
- '../../src/compiler/x64/code-generator-x64.cc',
- '../../src/compiler/x64/instruction-codes-x64.h',
- '../../src/compiler/x64/instruction-scheduler-x64.cc',
- '../../src/compiler/x64/instruction-selector-x64.cc',
- ],
- }],
- ['v8_target_arch=="ppc" or v8_target_arch=="ppc64"', {
- 'sources': [ ### gcmole(arch:ppc) ###
- '../../src/compiler/ppc/code-generator-ppc.cc',
- '../../src/compiler/ppc/instruction-codes-ppc.h',
- '../../src/compiler/ppc/instruction-scheduler-ppc.cc',
- '../../src/compiler/ppc/instruction-selector-ppc.cc',
- '../../src/crankshaft/ppc/lithium-ppc.cc',
- '../../src/crankshaft/ppc/lithium-ppc.h',
- '../../src/crankshaft/ppc/lithium-codegen-ppc.cc',
- '../../src/crankshaft/ppc/lithium-codegen-ppc.h',
- '../../src/crankshaft/ppc/lithium-gap-resolver-ppc.cc',
- '../../src/crankshaft/ppc/lithium-gap-resolver-ppc.h',
- '../../src/debug/ppc/debug-ppc.cc',
- '../../src/full-codegen/ppc/full-codegen-ppc.cc',
- '../../src/ic/ppc/access-compiler-ppc.cc',
- '../../src/ic/ppc/handler-compiler-ppc.cc',
- '../../src/ic/ppc/ic-ppc.cc',
- '../../src/ic/ppc/ic-compiler-ppc.cc',
- '../../src/ic/ppc/stub-cache-ppc.cc',
- '../../src/ppc/assembler-ppc-inl.h',
- '../../src/ppc/assembler-ppc.cc',
- '../../src/ppc/assembler-ppc.h',
- '../../src/ppc/builtins-ppc.cc',
- '../../src/ppc/code-stubs-ppc.cc',
- '../../src/ppc/code-stubs-ppc.h',
- '../../src/ppc/codegen-ppc.cc',
- '../../src/ppc/codegen-ppc.h',
- '../../src/ppc/constants-ppc.h',
- '../../src/ppc/constants-ppc.cc',
- '../../src/ppc/cpu-ppc.cc',
- '../../src/ppc/deoptimizer-ppc.cc',
- '../../src/ppc/disasm-ppc.cc',
- '../../src/ppc/frames-ppc.cc',
- '../../src/ppc/frames-ppc.h',
- '../../src/ppc/interface-descriptors-ppc.cc',
- '../../src/ppc/macro-assembler-ppc.cc',
- '../../src/ppc/macro-assembler-ppc.h',
- '../../src/ppc/simulator-ppc.cc',
- '../../src/ppc/simulator-ppc.h',
- '../../src/regexp/ppc/regexp-macro-assembler-ppc.cc',
- '../../src/regexp/ppc/regexp-macro-assembler-ppc.h',
- ],
- }],
- ['v8_target_arch=="s390" or v8_target_arch=="s390x"', {
- 'sources': [ ### gcmole(arch:s390) ###
- '../../src/compiler/s390/code-generator-s390.cc',
- '../../src/compiler/s390/instruction-codes-s390.h',
- '../../src/compiler/s390/instruction-scheduler-s390.cc',
- '../../src/compiler/s390/instruction-selector-s390.cc',
- '../../src/crankshaft/s390/lithium-codegen-s390.cc',
- '../../src/crankshaft/s390/lithium-codegen-s390.h',
- '../../src/crankshaft/s390/lithium-gap-resolver-s390.cc',
- '../../src/crankshaft/s390/lithium-gap-resolver-s390.h',
- '../../src/crankshaft/s390/lithium-s390.cc',
- '../../src/crankshaft/s390/lithium-s390.h',
- '../../src/debug/s390/debug-s390.cc',
- '../../src/full-codegen/s390/full-codegen-s390.cc',
- '../../src/ic/s390/access-compiler-s390.cc',
- '../../src/ic/s390/handler-compiler-s390.cc',
- '../../src/ic/s390/ic-compiler-s390.cc',
- '../../src/ic/s390/ic-s390.cc',
- '../../src/ic/s390/stub-cache-s390.cc',
- '../../src/regexp/s390/regexp-macro-assembler-s390.cc',
- '../../src/regexp/s390/regexp-macro-assembler-s390.h',
- '../../src/s390/assembler-s390.cc',
- '../../src/s390/assembler-s390.h',
- '../../src/s390/assembler-s390-inl.h',
- '../../src/s390/builtins-s390.cc',
- '../../src/s390/codegen-s390.cc',
- '../../src/s390/codegen-s390.h',
- '../../src/s390/code-stubs-s390.cc',
- '../../src/s390/code-stubs-s390.h',
- '../../src/s390/constants-s390.cc',
- '../../src/s390/constants-s390.h',
- '../../src/s390/cpu-s390.cc',
- '../../src/s390/deoptimizer-s390.cc',
- '../../src/s390/disasm-s390.cc',
- '../../src/s390/frames-s390.cc',
- '../../src/s390/frames-s390.h',
- '../../src/s390/interface-descriptors-s390.cc',
- '../../src/s390/macro-assembler-s390.cc',
- '../../src/s390/macro-assembler-s390.h',
- '../../src/s390/simulator-s390.cc',
- '../../src/s390/simulator-s390.h',
- ],
- }],
- ['OS=="win"', {
- 'variables': {
- 'gyp_generators': '<!(echo $GYP_GENERATORS)',
- },
- 'msvs_disabled_warnings': [4351, 4355, 4800],
- # When building Official, the .lib is too large and exceeds the 2G
- # limit. This breaks it into multiple pieces to avoid the limit.
- # See http://crbug.com/485155.
- 'msvs_shard': 4,
- }],
- ['component=="shared_library"', {
- 'defines': [
- 'BUILDING_V8_SHARED',
- 'V8_SHARED',
- ],
- }],
- ['v8_postmortem_support=="true"', {
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/debug-support.cc',
- ]
- }],
- ['v8_enable_i18n_support==1', {
- 'dependencies': [
- '<(icu_gyp_path):icui18n',
- '<(icu_gyp_path):icuuc',
- ]
- }, { # v8_enable_i18n_support==0
- 'sources!': [
- '../../src/i18n.cc',
- '../../src/i18n.h',
- ],
- }],
- ['OS=="win" and v8_enable_i18n_support==1', {
- 'dependencies': [
- '<(icu_gyp_path):icudata',
- ],
- }],
- ['icu_use_data_file_flag==1', {
- 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE'],
- }, { # else icu_use_data_file_flag !=1
- 'conditions': [
- ['OS=="win"', {
- 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_SHARED'],
- }, {
- 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC'],
- }],
- ],
- }],
- ],
- },
- {
- 'target_name': 'v8_libbase',
- 'type': 'static_library',
- 'variables': {
- 'optimize': 'max',
- },
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '../../src/base/accounting-allocator.cc',
- '../../src/base/accounting-allocator.h',
- '../../src/base/adapters.h',
- '../../src/base/atomicops.h',
- '../../src/base/atomicops_internals_arm64_gcc.h',
- '../../src/base/atomicops_internals_arm_gcc.h',
- '../../src/base/atomicops_internals_atomicword_compat.h',
- '../../src/base/atomicops_internals_mac.h',
- '../../src/base/atomicops_internals_mips_gcc.h',
- '../../src/base/atomicops_internals_mips64_gcc.h',
- '../../src/base/atomicops_internals_portable.h',
- '../../src/base/atomicops_internals_ppc_gcc.h',
- '../../src/base/atomicops_internals_s390_gcc.h',
- '../../src/base/atomicops_internals_tsan.h',
- '../../src/base/atomicops_internals_x86_gcc.cc',
- '../../src/base/atomicops_internals_x86_gcc.h',
- '../../src/base/atomicops_internals_x86_msvc.h',
- '../../src/base/bits.cc',
- '../../src/base/bits.h',
- '../../src/base/build_config.h',
- '../../src/base/compiler-specific.h',
- '../../src/base/cpu.cc',
- '../../src/base/cpu.h',
- '../../src/base/division-by-constant.cc',
- '../../src/base/division-by-constant.h',
- '../../src/base/flags.h',
- '../../src/base/functional.cc',
- '../../src/base/functional.h',
- '../../src/base/iterator.h',
- '../../src/base/lazy-instance.h',
- '../../src/base/logging.cc',
- '../../src/base/logging.h',
- '../../src/base/macros.h',
- '../../src/base/once.cc',
- '../../src/base/once.h',
- '../../src/base/platform/elapsed-timer.h',
- '../../src/base/platform/time.cc',
- '../../src/base/platform/time.h',
- '../../src/base/platform/condition-variable.cc',
- '../../src/base/platform/condition-variable.h',
- '../../src/base/platform/mutex.cc',
- '../../src/base/platform/mutex.h',
- '../../src/base/platform/platform.h',
- '../../src/base/platform/semaphore.cc',
- '../../src/base/platform/semaphore.h',
- '../../src/base/safe_conversions.h',
- '../../src/base/safe_conversions_impl.h',
- '../../src/base/safe_math.h',
- '../../src/base/safe_math_impl.h',
- '../../src/base/smart-pointers.h',
- '../../src/base/sys-info.cc',
- '../../src/base/sys-info.h',
- '../../src/base/utils/random-number-generator.cc',
- '../../src/base/utils/random-number-generator.h',
- ],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ['OS=="linux"', {
- 'conditions': [
- ['nacl_target_arch=="none"', {
- 'link_settings': {
- 'libraries': [
- '-ldl',
- '-lrt'
- ],
- },
- }, {
- 'defines': [
- 'V8_LIBRT_NOT_AVAILABLE=1',
- ],
- }],
- ],
- 'sources': [
- '../../src/base/platform/platform-linux.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }
- ],
- ['OS=="android"', {
- 'sources': [
- '../../src/base/platform/platform-posix.cc'
- ],
- 'link_settings': {
- 'target_conditions': [
- ['_toolset=="host"', {
- # Only include libdl and librt on host builds because they
- # are included by default on Android target builds, and we
- # don't want to re-include them here since this will change
- # library order and break (see crbug.com/469973).
- 'libraries': [
- '-ldl',
- '-lrt'
- ]
- }]
- ]
- },
- 'conditions': [
- ['host_os=="mac"', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'sources': [
- '../../src/base/platform/platform-macos.cc'
- ]
- }, {
- 'sources': [
- '../../src/base/platform/platform-linux.cc'
- ]
- }],
- ],
- }, {
- 'sources': [
- '../../src/base/platform/platform-linux.cc'
- ]
- }],
- ],
- },
- ],
- ['OS=="qnx"', {
- 'link_settings': {
- 'target_conditions': [
- ['_toolset=="host" and host_os=="linux"', {
- 'libraries': [
- '-lrt'
- ],
- }],
- ['_toolset=="target"', {
- 'libraries': [
- '-lbacktrace'
- ],
- }],
- ],
- },
- 'sources': [
- '../../src/base/platform/platform-posix.cc',
- '../../src/base/qnx-math.h',
- ],
- 'target_conditions': [
- ['_toolset=="host" and host_os=="linux"', {
- 'sources': [
- '../../src/base/platform/platform-linux.cc'
- ],
- }],
- ['_toolset=="host" and host_os=="mac"', {
- 'sources': [
- '../../src/base/platform/platform-macos.cc'
- ],
- }],
- ['_toolset=="target"', {
- 'sources': [
- '../../src/base/platform/platform-qnx.cc'
- ],
- }],
- ],
- },
- ],
- ['OS=="freebsd"', {
- 'link_settings': {
- 'libraries': [
- '-L/usr/local/lib -lexecinfo',
- ]},
- 'sources': [
- '../../src/base/platform/platform-freebsd.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }
- ],
- ['OS=="openbsd"', {
- 'link_settings': {
- 'libraries': [
- '-L/usr/local/lib -lexecinfo',
- ]},
- 'sources': [
- '../../src/base/platform/platform-openbsd.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }
- ],
- ['OS=="netbsd"', {
- 'link_settings': {
- 'libraries': [
- '-L/usr/pkg/lib -Wl,-R/usr/pkg/lib -lexecinfo',
- ]},
- 'sources': [
- '../../src/base/platform/platform-openbsd.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }
- ],
- ['OS=="aix"', {
- 'sources': [
- '../../src/base/platform/platform-aix.cc',
- '../../src/base/platform/platform-posix.cc'
- ]},
- ],
- ['OS=="solaris"', {
- 'link_settings': {
- 'libraries': [
- '-lnsl -lrt',
- ]},
- 'sources': [
- '../../src/base/platform/platform-solaris.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }
- ],
- ['OS=="mac"', {
- 'sources': [
- '../../src/base/platform/platform-macos.cc',
- '../../src/base/platform/platform-posix.cc'
- ]},
- ],
- ['OS=="win"', {
- 'defines': [
- '_CRT_RAND_S' # for rand_s()
- ],
- 'variables': {
- 'gyp_generators': '<!(echo $GYP_GENERATORS)',
- },
- 'conditions': [
- ['gyp_generators=="make"', {
- 'variables': {
- 'build_env': '<!(uname -o)',
- },
- 'conditions': [
- ['build_env=="Cygwin"', {
- 'sources': [
- '../../src/base/platform/platform-cygwin.cc',
- '../../src/base/platform/platform-posix.cc'
- ],
- }, {
- 'sources': [
- '../../src/base/platform/platform-win32.cc',
- '../../src/base/win32-headers.h',
- ],
- }],
- ],
- 'link_settings': {
- 'libraries': [ '-lwinmm', '-lws2_32' ],
- },
- }, {
- 'sources': [
- '../../src/base/platform/platform-win32.cc',
- '../../src/base/win32-headers.h',
- ],
- 'msvs_disabled_warnings': [4351, 4355, 4800],
- 'link_settings': {
- 'libraries': [ '-lwinmm.lib', '-lws2_32.lib' ],
- },
- }],
- ],
- }],
- ],
- },
- {
- 'target_name': 'v8_libplatform',
- 'type': 'static_library',
- 'variables': {
- 'optimize': 'max',
- },
- 'dependencies': [
- 'v8_libbase',
- ],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '../../include/libplatform/libplatform.h',
- '../../src/libplatform/default-platform.cc',
- '../../src/libplatform/default-platform.h',
- '../../src/libplatform/task-queue.cc',
- '../../src/libplatform/task-queue.h',
- '../../src/libplatform/worker-thread.cc',
- '../../src/libplatform/worker-thread.h',
- ],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '../../include',
- ],
- },
- },
- {
- 'target_name': 'natives_blob',
- 'type': 'none',
- 'conditions': [
- [ 'v8_use_external_startup_data==1', {
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'dependencies': ['js2c#host'],
- }, {
- 'dependencies': ['js2c'],
- }],
- ],
- 'actions': [{
- 'action_name': 'concatenate_natives_blob',
- 'inputs': [
- '../../tools/concatenate-files.py',
- '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
- '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
- '<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
- '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
- ],
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'outputs': [
- '<(PRODUCT_DIR)/natives_blob_host.bin',
- ],
- 'action': [
- 'python', '<@(_inputs)', '<(PRODUCT_DIR)/natives_blob_host.bin'
- ],
- }, {
- 'outputs': [
- '<(PRODUCT_DIR)/natives_blob.bin',
- ],
- 'action': [
- 'python', '<@(_inputs)', '<(PRODUCT_DIR)/natives_blob.bin'
- ],
- }],
- ],
- }, {
- 'outputs': [
- '<(PRODUCT_DIR)/natives_blob.bin',
- ],
- 'action': [
- 'python', '<@(_inputs)', '<(PRODUCT_DIR)/natives_blob.bin'
- ],
- }],
- ],
- }],
- }],
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host', 'target'],
- }, {
- 'toolsets': ['target'],
- }],
- ]
- },
- {
- 'target_name': 'js2c',
- 'type': 'none',
- 'conditions': [
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host'],
- }, {
- 'toolsets': ['target'],
- }],
- ['v8_enable_i18n_support==1', {
- 'variables': {
- 'i18n_library_files': [
- '../../src/js/i18n.js',
- ],
- },
- }, {
- 'variables': {
- 'i18n_library_files': [],
- },
- }],
- ],
- 'variables': {
- 'library_files': [
- '../../src/js/macros.py',
- '../../src/messages.h',
- '../../src/js/prologue.js',
- '../../src/js/runtime.js',
- '../../src/js/v8natives.js',
- '../../src/js/symbol.js',
- '../../src/js/array.js',
- '../../src/js/string.js',
- '../../src/js/uri.js',
- '../../src/js/math.js',
- '../../src/third_party/fdlibm/fdlibm.js',
- '../../src/js/regexp.js',
- '../../src/js/arraybuffer.js',
- '../../src/js/typedarray.js',
- '../../src/js/iterator-prototype.js',
- '../../src/js/generator.js',
- '../../src/js/object-observe.js',
- '../../src/js/collection.js',
- '../../src/js/weak-collection.js',
- '../../src/js/collection-iterator.js',
- '../../src/js/promise.js',
- '../../src/js/messages.js',
- '../../src/js/json.js',
- '../../src/js/array-iterator.js',
- '../../src/js/string-iterator.js',
- '../../src/js/templates.js',
- '../../src/js/spread.js',
- '../../src/js/proxy.js',
- '../../src/debug/mirrors.js',
- '../../src/debug/debug.js',
- '../../src/debug/liveedit.js',
- ],
- 'experimental_library_files': [
- '../../src/js/macros.py',
- '../../src/messages.h',
- '../../src/js/generator.js',
- '../../src/js/harmony-atomics.js',
- '../../src/js/harmony-regexp-exec.js',
- '../../src/js/harmony-object-observe.js',
- '../../src/js/harmony-sharedarraybuffer.js',
- '../../src/js/harmony-simd.js',
- '../../src/js/harmony-species.js',
- '../../src/js/harmony-unicode-regexps.js',
- '../../src/js/harmony-string-padding.js',
- '../../src/js/promise-extra.js',
- ],
- 'libraries_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
- 'libraries_experimental_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
- 'libraries_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
- 'libraries_experimental_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
- },
- 'actions': [
- {
- 'action_name': 'js2c',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(library_files)',
- '<@(i18n_library_files)'
- ],
- 'outputs': ['<(SHARED_INTERMEDIATE_DIR)/libraries.cc'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
- 'CORE',
- '<@(library_files)',
- '<@(i18n_library_files)'
- ],
- },
- {
- 'action_name': 'js2c_bin',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(library_files)',
- '<@(i18n_library_files)'
- ],
- 'outputs': ['<@(libraries_bin_file)'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
- 'CORE',
- '<@(library_files)',
- '<@(i18n_library_files)',
- '--startup_blob', '<@(libraries_bin_file)',
- '--nojs',
- ],
- },
- {
- 'action_name': 'js2c_experimental',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(experimental_library_files)',
- ],
- 'outputs': ['<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
- 'EXPERIMENTAL',
- '<@(experimental_library_files)'
- ],
- },
- {
- 'action_name': 'js2c_experimental_bin',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(experimental_library_files)',
- ],
- 'outputs': ['<@(libraries_experimental_bin_file)'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
- 'EXPERIMENTAL',
- '<@(experimental_library_files)',
- '--startup_blob', '<@(libraries_experimental_bin_file)',
- '--nojs',
- ],
- },
- {
- 'action_name': 'js2c_extras',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(v8_extra_library_files)',
- ],
- 'outputs': ['<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
- 'EXTRAS',
- '<@(v8_extra_library_files)',
- ],
- },
- {
- 'action_name': 'js2c_extras_bin',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(v8_extra_library_files)',
- ],
- 'outputs': ['<@(libraries_extras_bin_file)'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
- 'EXTRAS',
- '<@(v8_extra_library_files)',
- '--startup_blob', '<@(libraries_extras_bin_file)',
- '--nojs',
- ],
- },
- {
- 'action_name': 'js2c_experimental_extras',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(v8_experimental_extra_library_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
- ],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
- 'EXPERIMENTAL_EXTRAS',
- '<@(v8_experimental_extra_library_files)',
- ],
- },
- {
- 'action_name': 'js2c_experimental_extras_bin',
- 'inputs': [
- '../../tools/js2c.py',
- '<@(v8_experimental_extra_library_files)',
- ],
- 'outputs': ['<@(libraries_experimental_extras_bin_file)'],
- 'action': [
- 'python',
- '../../tools/js2c.py',
- '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
- 'EXPERIMENTAL_EXTRAS',
- '<@(v8_experimental_extra_library_files)',
- '--startup_blob', '<@(libraries_experimental_extras_bin_file)',
- '--nojs',
- ],
- },
- ],
- },
- {
- 'target_name': 'postmortem-metadata',
- 'type': 'none',
- 'variables': {
- 'heapobject_files': [
- '../../src/objects.h',
- '../../src/objects-inl.h',
- ],
- },
- 'actions': [
- {
- 'action_name': 'gen-postmortem-metadata',
- 'inputs': [
- '../../tools/gen-postmortem-metadata.py',
- '<@(heapobject_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/debug-support.cc',
- ],
- 'action': [
- 'python',
- '../../tools/gen-postmortem-metadata.py',
- '<@(_outputs)',
- '<@(heapobject_files)'
- ]
- }
- ]
- },
- {
- 'target_name': 'mksnapshot',
- 'type': 'executable',
- 'dependencies': ['v8_base', 'v8_nosnapshot', 'v8_libplatform'],
- 'include_dirs+': [
- '../..',
- ],
- 'sources': [
- '../../src/snapshot/mksnapshot.cc',
- ],
- 'conditions': [
- ['v8_enable_i18n_support==1', {
- 'dependencies': [
- '<(icu_gyp_path):icui18n',
- '<(icu_gyp_path):icuuc',
- ]
- }],
- ['want_separate_host_toolset==1', {
- 'toolsets': ['host'],
- }, {
- 'toolsets': ['target'],
- }],
- ],
- },
- ],
-}
diff --git a/tools/ic-explorer.html b/tools/ic-explorer.html
index 43b486a5..ad1737a6 100644
--- a/tools/ic-explorer.html
+++ b/tools/ic-explorer.html
@@ -1,338 +1,350 @@
<html>
- <head>
-<style>
- .entry-details {
- }
- .entry-details TD {
- }
- .details {
- width: 2em;
- border: 1px black dotted;
- }
- .count {
- text-align: right;
- width: 5em;
- font-family: monospace;
- }
- .percentage {
- text-align: right;
- width: 5em;
- font-family: monospace;
- }
- .key {
- padding-left: 1em;
- }
- .drilldown-group-title {
- font-weight: bold;
- padding: 0.5em 0 0.2em 0;
- }
-</style>
- <script>
-"use strict"
-var entries = [];
+<!--
+Copyright 2016 the V8 project authors. All rights reserved. Use of this source
+code is governed by a BSD-style license that can be found in the LICENSE file.
+-->
-class Entry {
- constructor(id, line) {
- this.id = id;
- this.line = line;
- var parts = line.split(" ");
- if (parts.length < 6) return
- this.isValid = false;
- if (parts[0][0] !== "[") return;
- if (parts[1] === "patching") return;
- this.type = parts[0].substr(1);
- this.category = "Other";
- if (this.type.indexOf("Store") !== -1) {
- this.category = "Store";
- } else if (this.type.indexOf("Load") !== -1) {
- this.category = "Load";
+<head>
+ <style>
+ .entry-details {}
+
+ .entry-details TD {}
+
+ .details {
+ width: 2em;
+ border: 1px black dotted;
+ }
+
+ .count {
+ text-align: right;
+ width: 5em;
+ font-family: monospace;
+ }
+
+ .percentage {
+ text-align: right;
+ width: 5em;
+ font-family: monospace;
+ }
+
+ .key {
+ padding-left: 1em;
}
- if (this.type.length == 0) return;
- if (this.type.indexOf('BinaryOpIC(') === 0) {
- this.type = "BinaryOpIC";
- var split = parts[0].split('(');
- this.state = "(" + split[1] + " => " + parts[2];
- var offset = this.parsePositionAndFile(parts, 6);
- if (offset == -1) return
- if (this.file === undefined) return
- this.file = this.file.slice(0,-1);
- } else {
- var offset = this.parsePositionAndFile(parts, 2);
- if (offset == -1) return
- this.state = parts[++offset];
- if (this.type !== "CompareIC") {
- // if there is no address we have a smi key
- var address = parts[++offset];
- if (address !== undefined && address.indexOf("0x") === 0) {
- this.key = parts.slice(++offset).join(" ");
+
+ .drilldown-group-title {
+ font-weight: bold;
+ padding: 0.5em 0 0.2em 0;
+ }
+ </style>
+ <script>
+ "use strict"
+ var entries = [];
+
+ class Entry {
+ constructor(id, line) {
+ this.id = id;
+ this.line = line;
+ var parts = line.split(" ");
+ if (parts.length < 6) return
+ this.isValid = false;
+ if (parts[0][0] !== "[") return;
+ if (parts[1] === "patching") return;
+ this.type = parts[0].substr(1);
+ this.category = "Other";
+ if (this.type.indexOf("Store") !== -1) {
+ this.category = "Store";
+ } else if (this.type.indexOf("Load") !== -1) {
+ this.category = "Load";
+ }
+ if (this.type.length == 0) return;
+ if (this.type.indexOf('BinaryOpIC(') === 0) {
+ this.type = "BinaryOpIC";
+ var split = parts[0].split('(');
+ this.state = "(" + split[1] + " => " + parts[2];
+ var offset = this.parsePositionAndFile(parts, 6);
+ if (offset == -1) return
+ if (this.file === undefined) return
+ this.file = this.file.slice(0, -1);
} else {
- this.key = address;
+ var offset = this.parsePositionAndFile(parts, 2);
+ if (offset == -1) return
+ this.state = parts[++offset];
+ if (this.type !== "CompareIC") {
+ // if there is no address we have a smi key
+ var address = parts[++offset];
+ if (address !== undefined && address.indexOf("0x") === 0) {
+ this.key = parts.slice(++offset).join(" ");
+ } else {
+ this.key = address;
+ }
+ }
}
+ this.filePosition = this.file + " " + this.position;
+ if (this.key) {
+ var isStringKey = false
+ if (this.key.indexOf("<String[") === 0) {
+ isStringKey = true;
+ this.key = "\"" + this.key.slice(this.key.indexOf(']') + 3);
+ } else if (this.key.indexOf("<") === 0) {
+ this.key = this.key.slice(1);
+ }
+ if (this.key.endsWith(">]")) {
+ this.key = this.key.slice(0, -2);
+ } else if (this.key.endsWith("]")) {
+ this.key = this.key.slice(0, -1);
+ }
+ if (isStringKey) {
+ this.key = this.key + "\"";
+ }
+ }
+ this.isValid = true;
}
- }
- this.filePosition = this.file + " " + this.position;
- if (this.key) {
- var isStringKey = false
- if (this.key.indexOf("<String[") === 0) {
- isStringKey = true;
- this.key = "\"" + this.key.slice(this.key.indexOf(']')+3);
- } else if (this.key.indexOf("<") === 0) {
- this.key = this.key.slice(1);
- }
- if (this.key.endsWith(">]")) {
- this.key = this.key.slice(0, -2);
- } else if (this.key.endsWith("]")) {
- this.key = this.key.slice(0, -1);
- }
- if (isStringKey) {
- this.key = this.key + "\"";
+
+ parsePositionAndFile(parts, start) {
+ // find the position of 'at' in the parts array.
+ var offset = start;
+ for (var i = start + 1; i < parts.length; i++) {
+ offset++;
+ if (parts[i] == 'at') break;
+ }
+ if (parts[offset] !== 'at') return -1;
+ this.position = parts.slice(start, offset).join(' ');
+ offset += 1;
+ this.isNative = parts[offset] == "native"
+ offset += this.isNative ? 1 : 0;
+ this.file = parts[offset];
+ return offset;
}
}
- this.isValid = true;
- }
-
- parsePositionAndFile(parts, start) {
- // find the position of 'at' in the parts array.
- var offset = start;
- for (var i = start+1; i<parts.length; i++) {
- offset++;
- if (parts[i] == 'at') break;
- }
- if (parts[offset] !== 'at') return -1;
- this.position = parts.slice(start, offset).join(' ');
- offset += 1;
- this.isNative = parts[offset] == "native"
- offset += this.isNative ? 1 : 0;
- this.file = parts[offset];
- return offset;
- }
-}
-function loadFile() {
- var files = document.getElementById("uploadInput").files;
+ function loadFile() {
+ var files = document.getElementById("uploadInput").files;
- var file = files[0];
- var reader = new FileReader();
+ var file = files[0];
+ var reader = new FileReader();
- reader.onload = function(evt) {
- entries = [];
- var end = this.result.length;
- var current = 0;
- var next = 0;
- var line;
- var i = 0;
- var entry;
- while (current < end) {
- next = this.result.indexOf("\n", current);
- if (next === -1) break;
- i++;
-
- line = this.result.substring(current, next);
- current = next+1;
- entry = new Entry(i, line);
- if (entry.isValid) entries.push(entry);
+ reader.onload = function(evt) {
+ entries = [];
+ var end = this.result.length;
+ var current = 0;
+ var next = 0;
+ var line;
+ var i = 0;
+ var entry;
+ while (current < end) {
+ next = this.result.indexOf("\n", current);
+ if (next === -1) break;
+ i++;
+
+ line = this.result.substring(current, next);
+ current = next + 1;
+ entry = new Entry(i, line);
+ if (entry.isValid) entries.push(entry);
+ }
+
+ document.getElementById("count").innerHTML = i;
+ updateTable();
+ }
+ reader.readAsText(file);
+ initGroupKeySelect();
}
-
- document.getElementById("count").innerHTML = i;
- updateTable();
- }
- reader.readAsText(file);
- initGroupKeySelect();
-}
-var properties = ['type', 'category', 'file', 'filePosition', 'state' , 'key', 'isNative']
+ var properties = ['type', 'category', 'file', 'filePosition', 'state',
+ 'key', 'isNative'
+ ]
-class Group {
- constructor(property, key, entry) {
- this.property = property;
- this.key = key;
- this.count = 1;
- this.entries = [entry];
- this.percentage = undefined;
- this.groups = undefined;
- }
-
- add(entry) {
- this.count ++;
- this.entries.push(entry)
- }
-
- createSubGroups() {
- this.groups = {};
- for (var i=0; i<properties.length; i++) {
- var subProperty = properties[i];
- if (this.property == subProperty) continue;
- this.groups[subProperty] = groupBy(this.entries, subProperty);
- }
- }
-}
+ class Group {
+ constructor(property, key, entry) {
+ this.property = property;
+ this.key = key;
+ this.count = 1;
+ this.entries = [entry];
+ this.percentage = undefined;
+ this.groups = undefined;
+ }
+
+ add(entry) {
+ this.count++;
+ this.entries.push(entry)
+ }
-function groupBy(entries, property) {
- var accumulator = {};
- accumulator.__proto__ = null;
- var length = entries.length;
- for (var i = 0; i < length; i++) {
- var entry = entries[i];
- var key = entry[property];
- if (accumulator[key] == undefined) {
- accumulator[key] = new Group(property, key, entry)
- } else {
- var group = accumulator[key];
- if (group.entries == undefined) console.log([group, entry]);
- group.add(entry)
+ createSubGroups() {
+ this.groups = {};
+ for (var i = 0; i < properties.length; i++) {
+ var subProperty = properties[i];
+ if (this.property == subProperty) continue;
+ this.groups[subProperty] = groupBy(this.entries, subProperty);
+ }
+ }
}
- }
- var result = []
- for (var key in accumulator) {
- var group = accumulator[key];
- group.percentage = Math.round(group.count / length * 100 * 100) / 100;
- result.push(group);
- }
- result.sort((a,b) => { return b.count - a.count });
- return result;
-}
+ function groupBy(entries, property) {
+ var accumulator = {};
+ accumulator.__proto__ = null;
+ var length = entries.length;
+ for (var i = 0; i < length; i++) {
+ var entry = entries[i];
+ var key = entry[property];
+ if (accumulator[key] == undefined) {
+ accumulator[key] = new Group(property, key, entry)
+ } else {
+ var group = accumulator[key];
+ if (group.entries == undefined) console.log([group, entry]);
+ group.add(entry)
+ }
+ }
+ var result = []
+ for (var key in accumulator) {
+ var group = accumulator[key];
+ group.percentage = Math.round(group.count / length * 100 * 100) / 100;
+ result.push(group);
+ }
+ result.sort((a, b) => {
+ return b.count - a.count
+ });
+ return result;
+ }
-function updateTable() {
- var select = document.getElementById("group-key");
- var key = select.options[select.selectedIndex].text;
- console.log(key);
- var tableBody = document.getElementById("table-body");
- removeAllChildren(tableBody);
- var groups = groupBy(entries, key, true);
- display(groups, tableBody);
-}
-function selecedOption(node) {
- return node.options[node.selectedIndex]
-}
+ function updateTable() {
+ var select = document.getElementById("group-key");
+ var key = select.options[select.selectedIndex].text;
+ console.log(key);
+ var tableBody = document.getElementById("table-body");
+ removeAllChildren(tableBody);
+ var groups = groupBy(entries, key, true);
+ display(groups, tableBody);
+ }
-function removeAllChildren(node) {
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
-}
+ function selecedOption(node) {
+ return node.options[node.selectedIndex]
+ }
-function display(entries, parent) {
- var fragment = document.createDocumentFragment();
+ function removeAllChildren(node) {
+ while (node.firstChild) {
+ node.removeChild(node.firstChild);
+ }
+ }
- function td(tr, content, className) {
- var td = document.createElement("td");
- td.innerHTML = content;
- td.className = className
- tr.appendChild(td);
- return td
- }
- var max = Math.min(1000, entries.length)
- for (var i = 0; i<max; i++) {
- var entry = entries[i];
- var tr = document.createElement("tr");
- tr.entry = entry;
- td(tr, '<span onclick="toggleDetails(this)">details</a>', 'details');
- td(tr, entry.percentage +"%", 'percentage');
- td(tr, entry.count, 'count');
- td(tr, entry.key, 'key');
- fragment.appendChild(tr);
- }
- var omitted = entries.length - max;
- if (omitted > 0) {
- var tr = document.createElement("tr");
- var td = td(tr, 'Omitted ' + omitted + " entries.");
- td.colSpan = 4;
- fragment.appendChild(tr);
- }
- parent.appendChild(fragment);
-}
+ function display(entries, parent) {
+ var fragment = document.createDocumentFragment();
-function displayDrilldown(entry, previousSibling) {
- var tr = document.createElement('tr');
- tr.className = "entry-details";
- tr.style.display = "none";
- // indent by one td.
- tr.appendChild(document.createElement("td"));
- var td = document.createElement("td");
- td.colSpan = 3;
- for (var key in entry.groups) {
- td.appendChild(displayDrilldownGroup(entry, key));
- }
- tr.appendChild(td);
- // Append the new TR after previousSibling.
- previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling)
-}
+ function td(tr, content, className) {
+ var td = document.createElement("td");
+ td.innerHTML = content;
+ td.className = className
+ tr.appendChild(td);
+ return td
+ }
+ var max = Math.min(1000, entries.length)
+ for (var i = 0; i < max; i++) {
+ var entry = entries[i];
+ var tr = document.createElement("tr");
+ tr.entry = entry;
+ td(tr, '<span onclick="toggleDetails(this)">details</a>', 'details');
+ td(tr, entry.percentage + "%", 'percentage');
+ td(tr, entry.count, 'count');
+ td(tr, entry.key, 'key');
+ fragment.appendChild(tr);
+ }
+ var omitted = entries.length - max;
+ if (omitted > 0) {
+ var tr = document.createElement("tr");
+ var td = td(tr, 'Omitted ' + omitted + " entries.");
+ td.colSpan = 4;
+ fragment.appendChild(tr);
+ }
+ parent.appendChild(fragment);
+ }
-function displayDrilldownGroup(entry, key) {
- var max = 20;
- var group = entry.groups[key];
- var div = document.createElement("div")
- div.className = 'drilldown-group-title'
- div.innerHTML = key + ' [top ' + max + ']';
- var table = document.createElement("table");
- display(group.slice(0, max), table, false)
- div.appendChild(table);
- return div;
-}
+ function displayDrilldown(entry, previousSibling) {
+ var tr = document.createElement('tr');
+ tr.className = "entry-details";
+ tr.style.display = "none";
+ // indent by one td.
+ tr.appendChild(document.createElement("td"));
+ var td = document.createElement("td");
+ td.colSpan = 3;
+ for (var key in entry.groups) {
+ td.appendChild(displayDrilldownGroup(entry, key));
+ }
+ tr.appendChild(td);
+ // Append the new TR after previousSibling.
+ previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling)
+ }
-function toggleDetails(node) {
- var tr = node.parentNode.parentNode;
- var entry = tr.entry;
+ function displayDrilldownGroup(entry, key) {
+ var max = 20;
+ var group = entry.groups[key];
+ var div = document.createElement("div")
+ div.className = 'drilldown-group-title'
+ div.innerHTML = key + ' [top ' + max + ']';
+ var table = document.createElement("table");
+ display(group.slice(0, max), table, false)
+ div.appendChild(table);
+ return div;
+ }
- // Create subgroup in-place if the don't exist yet.
- if (entry.groups === undefined) {
- entry.createSubGroups();
- displayDrilldown(entry, tr);
- }
- var details = tr.nextSibling;
- var display = details.style.display;
- if (display != "none") {
- display = "none";
- }else {
- display = "table-row"
- };
- details.style.display = display;
-}
+ function toggleDetails(node) {
+ var tr = node.parentNode.parentNode;
+ var entry = tr.entry;
-function initGroupKeySelect() {
- var select = document.getElementById("group-key");
- for (var i in properties) {
- var option = document.createElement("option");
- option.text = properties[i];
- select.add(option);
- }
-}
+ // Create subgroup in-place if the don't exist yet.
+ if (entry.groups === undefined) {
+ entry.createSubGroups();
+ displayDrilldown(entry, tr);
+ }
+ var details = tr.nextSibling;
+ var display = details.style.display;
+ if (display != "none") {
+ display = "none";
+ } else {
+ display = "table-row"
+ };
+ details.style.display = display;
+ }
+ function initGroupKeySelect() {
+ var select = document.getElementById("group-key");
+ for (var i in properties) {
+ var option = document.createElement("option");
+ option.text = properties[i];
+ select.add(option);
+ }
+ }
</script>
- </head>
- <body>
- <h1>
+</head>
+
+<body>
+ <h1>
<span style="color: #00FF00">I</span>
<span style="color: #FF00FF">C</span>
<span style="color: #00FFFF">E</span>
- </h1>
- Your IC-Explorer.
- <h2>Usage</h2>
- Run your script with <code>--trace_ic</code> and upload on this page:<br/>
- <code>/path/to/d8 --trace_ic your_script.js > trace.txt</code>
- <h2>Data</h2>
- <form name="fileForm">
- <p>
- <input id="uploadInput" type="file" name="files" onchange="loadFile();" >
- trace entries: <span id="count">0</span>
- </p>
- </form>
- <h2>Result</h2>
+ </h1> Your IC-Explorer.
+ <h2>Usage</h2> Run your script with <code>--trace_ic</code> and upload on this page:<br/>
+ <code>/path/to/d8 --trace_ic your_script.js > trace.txt</code>
+ <h2>Data</h2>
+ <form name="fileForm">
<p>
+ <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace
+ entries: <span id="count">0</span>
+ </p>
+ </form>
+ <h2>Result</h2>
+ <p>
Group-Key:
<select id="group-key" onchange="updateTable()"></select>
- </p>
- <p>
- <table id="table" width="100%">
- <tbody id="table-body">
- </tbody>
- </table>
- </p>
- </body>
+ </p>
+ <p>
+ <table id="table" width="100%">
+ <tbody id="table-body">
+ </tbody>
+ </table>
+ </p>
+</body>
+
</html>
diff --git a/tools/ignition/bytecode_dispatches_report.py b/tools/ignition/bytecode_dispatches_report.py
new file mode 100755
index 00000000..1c140141
--- /dev/null
+++ b/tools/ignition/bytecode_dispatches_report.py
@@ -0,0 +1,258 @@
+#! /usr/bin/python
+#
+# Copyright 2016 the V8 project 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 argparse
+import heapq
+import json
+from matplotlib import colors
+from matplotlib import pyplot
+import numpy
+import struct
+
+
+__DESCRIPTION = """
+Process v8.ignition_dispatches_counters.json and list top counters,
+or plot a dispatch heatmap.
+
+Please note that those handlers that may not or will never dispatch
+(e.g. Return or Throw) do not show up in the results.
+"""
+
+
+__HELP_EPILOGUE = """
+examples:
+ # Print the hottest bytecodes in descending order, reading from
+ # default filename v8.ignition_dispatches_counters.json (default mode)
+ $ tools/ignition/bytecode_dispatches_report.py
+
+ # Print the hottest 15 bytecode dispatch pairs reading from data.json
+ $ tools/ignition/bytecode_dispatches_report.py -t -n 15 data.json
+
+ # Save heatmap to default filename v8.ignition_dispatches_counters.svg
+ $ tools/ignition/bytecode_dispatches_report.py -p
+
+ # Save heatmap to filename data.svg
+ $ tools/ignition/bytecode_dispatches_report.py -p -o data.svg
+
+ # Open the heatmap in an interactive viewer
+ $ tools/ignition/bytecode_dispatches_report.py -p -i
+
+ # Display the top 5 sources and destinations of dispatches to/from LdaZero
+ $ tools/ignition/bytecode_dispatches_report.py -f LdaZero -n 5
+"""
+
+__COUNTER_BITS = struct.calcsize("P") * 8 # Size in bits of a pointer
+__COUNTER_MAX = 2**__COUNTER_BITS - 1
+
+
+def warn_if_counter_may_have_saturated(dispatches_table):
+ for source, counters_from_source in dispatches_table.items():
+ for destination, counter in counters_from_source.items():
+ if counter == __COUNTER_MAX:
+ print "WARNING: {} -> {} may have saturated.".format(source,
+ destination)
+
+
+def find_top_bytecode_dispatch_pairs(dispatches_table, top_count):
+ def flattened_counters_generator():
+ for source, counters_from_source in dispatches_table.items():
+ for destination, counter in counters_from_source.items():
+ yield source, destination, counter
+
+ return heapq.nlargest(top_count, flattened_counters_generator(),
+ key=lambda x: x[2])
+
+
+def print_top_bytecode_dispatch_pairs(dispatches_table, top_count):
+ top_bytecode_dispatch_pairs = (
+ find_top_bytecode_dispatch_pairs(dispatches_table, top_count))
+ print "Top {} bytecode dispatch pairs:".format(top_count)
+ for source, destination, counter in top_bytecode_dispatch_pairs:
+ print "{:>12d}\t{} -> {}".format(counter, source, destination)
+
+
+def find_top_bytecodes(dispatches_table):
+ top_bytecodes = []
+ for bytecode, counters_from_bytecode in dispatches_table.items():
+ top_bytecodes.append((bytecode, sum(counters_from_bytecode.values())))
+ top_bytecodes.sort(key=lambda x: x[1], reverse=True)
+ return top_bytecodes
+
+
+def print_top_bytecodes(dispatches_table):
+ top_bytecodes = find_top_bytecodes(dispatches_table)
+ print "Top bytecodes:"
+ for bytecode, counter in top_bytecodes:
+ print "{:>12d}\t{}".format(counter, bytecode)
+
+
+def find_top_dispatch_sources(dispatches_table, destination, top_count):
+ def source_counters_generator():
+ for source, table_row in dispatches_table.items():
+ if destination in table_row:
+ yield source, table_row[destination]
+
+ return heapq.nlargest(top_count, source_counters_generator(),
+ key=lambda x: x[1])
+
+
+def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode,
+ top_count):
+ top_sources = find_top_dispatch_sources(dispatches_table, bytecode, top_count)
+ top_destinations = heapq.nlargest(top_count,
+ dispatches_table[bytecode].items(),
+ key=lambda x: x[1])
+
+ print "Top sources of dispatches to {}:".format(bytecode)
+ for source_name, counter in top_sources:
+ print "{:>12d}\t{}".format(counter, source_name)
+
+ print "\nTop destinations of dispatches from {}:".format(bytecode)
+ for destination_name, counter in top_destinations:
+ print "{:>12d}\t{}".format(counter, destination_name)
+
+
+def build_counters_matrix(dispatches_table):
+ labels = sorted(dispatches_table.keys())
+
+ counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int)
+ for from_index, from_name in enumerate(labels):
+ current_row = dispatches_table[from_name];
+ for to_index, to_name in enumerate(labels):
+ counters_matrix[from_index, to_index] = current_row.get(to_name, 0)
+
+ # Reverse y axis for a nicer appearance
+ xlabels = labels
+ ylabels = list(reversed(xlabels))
+ counters_matrix = numpy.flipud(counters_matrix)
+
+ return counters_matrix, xlabels, ylabels
+
+
+def plot_dispatches_table(dispatches_table, figure, axis):
+ counters_matrix, xlabels, ylabels = build_counters_matrix(dispatches_table)
+
+ image = axis.pcolor(
+ counters_matrix,
+ cmap="jet",
+ norm=colors.LogNorm(),
+ edgecolor="grey",
+ linestyle="dotted",
+ linewidth=0.5
+ )
+
+ axis.xaxis.set(
+ ticks=numpy.arange(0.5, len(xlabels)),
+ label="From bytecode handler"
+ )
+ axis.xaxis.tick_top()
+ axis.set_xlim(0, len(xlabels))
+ axis.set_xticklabels(xlabels, rotation="vertical")
+
+ axis.yaxis.set(
+ ticks=numpy.arange(0.5, len(ylabels)),
+ label="To bytecode handler",
+ ticklabels=ylabels
+ )
+ axis.set_ylim(0, len(ylabels))
+
+ figure.colorbar(
+ image,
+ ax=axis,
+ fraction=0.01,
+ pad=0.01
+ )
+
+
+def parse_command_line():
+ command_line_parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=__DESCRIPTION,
+ epilog=__HELP_EPILOGUE
+ )
+ command_line_parser.add_argument(
+ "--plot-size", "-s",
+ metavar="N",
+ default=30,
+ help="shorter side in inches of the output plot (default 30)"
+ )
+ command_line_parser.add_argument(
+ "--plot", "-p",
+ action="store_true",
+ help="plot dispatch pairs heatmap"
+ )
+ command_line_parser.add_argument(
+ "--interactive", "-i",
+ action="store_true",
+ help="open the heatmap in an interactive viewer, instead of writing to file"
+ )
+ command_line_parser.add_argument(
+ "--top-bytecode-dispatch-pairs", "-t",
+ action="store_true",
+ help="print the top bytecode dispatch pairs"
+ )
+ command_line_parser.add_argument(
+ "--top-entries-count", "-n",
+ metavar="N",
+ type=int,
+ default=10,
+ help="print N top entries when running with -t or -f (default 10)"
+ )
+ command_line_parser.add_argument(
+ "--top-dispatches-for-bytecode", "-f",
+ metavar="<bytecode name>",
+ help="print top dispatch sources and destinations to the specified bytecode"
+ )
+ command_line_parser.add_argument(
+ "--output-filename", "-o",
+ metavar="<output filename>",
+ default="v8.ignition_dispatches_table.svg",
+ help=("file to save the plot file to. File type is deduced from the "
+ "extension. PDF, SVG, PNG supported")
+ )
+ command_line_parser.add_argument(
+ "input_filename",
+ metavar="<input filename>",
+ default="v8.ignition_dispatches_table.json",
+ nargs='?',
+ help="Ignition counters JSON file"
+ )
+
+ return command_line_parser.parse_args()
+
+
+def main():
+ program_options = parse_command_line()
+
+ with open(program_options.input_filename) as stream:
+ dispatches_table = json.load(stream)
+
+ warn_if_counter_may_have_saturated(dispatches_table)
+
+ if program_options.plot:
+ figure, axis = pyplot.subplots()
+ plot_dispatches_table(dispatches_table, figure, axis)
+
+ if program_options.interactive:
+ pyplot.show()
+ else:
+ figure.set_size_inches(program_options.plot_size,
+ program_options.plot_size)
+ pyplot.savefig(program_options.output_filename)
+ elif program_options.top_bytecode_dispatch_pairs:
+ print_top_bytecode_dispatch_pairs(
+ dispatches_table, program_options.top_entries_count)
+ elif program_options.top_dispatches_for_bytecode:
+ print_top_dispatch_sources_and_destinations(
+ dispatches_table, program_options.top_dispatches_for_bytecode,
+ program_options.top_entries_count)
+ else:
+ print_top_bytecodes(dispatches_table)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/ignition/bytecode_dispatches_report_test.py b/tools/ignition/bytecode_dispatches_report_test.py
new file mode 100644
index 00000000..523dac29
--- /dev/null
+++ b/tools/ignition/bytecode_dispatches_report_test.py
@@ -0,0 +1,54 @@
+# Copyright 2016 the V8 project 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 bytecode_dispatches_report as bdr
+import unittest
+
+
+class BytecodeDispatchesReportTest(unittest.TestCase):
+ def test_find_top_counters(self):
+ top_counters = bdr.find_top_bytecode_dispatch_pairs({
+ "a": {"a": 10, "b": 8, "c": 99},
+ "b": {"a": 1, "b": 4, "c": 1},
+ "c": {"a": 42, "b": 3, "c": 7}}, 5)
+ self.assertListEqual(top_counters, [
+ ('a', 'c', 99),
+ ('c', 'a', 42),
+ ('a', 'a', 10),
+ ('a', 'b', 8),
+ ('c', 'c', 7)])
+
+ def test_build_counters_matrix(self):
+ counters_matrix, xlabels, ylabels = bdr.build_counters_matrix({
+ "a": {"a": 10, "b": 8, "c": 7},
+ "b": {"a": 1, "c": 4},
+ "c": {"a": 42, "b": 12, "c": 99}})
+ self.assertTrue((counters_matrix == [[42, 12, 99],
+ [ 1, 0, 4],
+ [10, 8, 7]]).all())
+ self.assertListEqual(xlabels, ['a', 'b', 'c'])
+ self.assertListEqual(ylabels, ['c', 'b', 'a'])
+
+ def test_find_top_bytecodes(self):
+ top_dispatch_sources = bdr.find_top_bytecodes({
+ "a": {"a": 10, "b": 8, "c": 7},
+ "b": {"a": 1, "c": 4},
+ "c": {"a": 42, "b": 12, "c": 99}
+ })
+ self.assertListEqual(top_dispatch_sources, [
+ ('c', 153),
+ ('a', 25),
+ ('b', 5)
+ ])
+
+ def test_find_top_dispatch_sources(self):
+ top_dispatch_sources = bdr.find_top_dispatch_sources({
+ "a": {"a": 10, "b": 8, "c": 7},
+ "b": {"a": 1, "c": 4},
+ "c": {"a": 42, "b": 12, "c": 99}
+ }, "b", 10)
+ self.assertListEqual(top_dispatch_sources, [
+ ("c", 12),
+ ("a", 8)
+ ])
diff --git a/tools/ignition/linux_perf_bytecode_annotate.py b/tools/ignition/linux_perf_bytecode_annotate.py
new file mode 100755
index 00000000..6681190d
--- /dev/null
+++ b/tools/ignition/linux_perf_bytecode_annotate.py
@@ -0,0 +1,174 @@
+#! /usr/bin/python2
+#
+# Copyright 2016 the V8 project 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 argparse
+import collections
+import os
+import subprocess
+import sys
+
+
+__DESCRIPTION = """
+Processes a perf.data sample file and annotates the hottest instructions in a
+given bytecode handler.
+"""
+
+
+__HELP_EPILOGUE = """
+Note:
+ This tool uses the disassembly of interpreter's bytecode handler codegen
+ from out/<arch>.debug/d8. you should ensure that this binary is in-sync with
+ the version used to generate the perf profile.
+
+ Also, the tool depends on the symbol offsets from perf samples being accurate.
+ As such, you should use the ":pp" suffix for events.
+
+Examples:
+ EVENT_TYPE=cycles:pp tools/run-perf.sh out/x64.release/d8
+ tools/ignition/linux_perf_bytecode_annotate.py Add
+"""
+
+
+def bytecode_offset_generator(perf_stream, bytecode_name):
+ skip_until_end_of_chain = False
+ bytecode_symbol = "BytecodeHandler:" + bytecode_name;
+
+ for line in perf_stream:
+ # Lines starting with a "#" are comments, skip them.
+ if line[0] == "#":
+ continue
+ line = line.strip()
+
+ # Empty line signals the end of the callchain.
+ if not line:
+ skip_until_end_of_chain = False
+ continue
+
+ if skip_until_end_of_chain:
+ continue
+
+ symbol_and_offset = line.split(" ", 1)[1]
+
+ if symbol_and_offset.startswith("BytecodeHandler:"):
+ skip_until_end_of_chain = True
+
+ if symbol_and_offset.startswith(bytecode_symbol):
+ yield int(symbol_and_offset.split("+", 1)[1], 16)
+
+
+def bytecode_offset_counts(bytecode_offsets):
+ offset_counts = collections.defaultdict(int)
+ for offset in bytecode_offsets:
+ offset_counts[offset] += 1
+ return offset_counts
+
+
+def bytecode_disassembly_generator(ignition_codegen, bytecode_name):
+ name_string = "name = " + bytecode_name
+ for line in ignition_codegen:
+ if line.startswith(name_string):
+ break
+
+ # Found the bytecode disassembly.
+ for line in ignition_codegen:
+ line = line.strip()
+ # Blank line marks the end of the bytecode's disassembly.
+ if not line:
+ return
+
+ # Only yield disassembly output.
+ if not line.startswith("0x"):
+ continue
+
+ yield line
+
+
+def print_disassembly_annotation(offset_counts, bytecode_disassembly):
+ total = sum(offset_counts.values())
+ offsets = sorted(offset_counts, reverse=True)
+ def next_offset():
+ return offsets.pop() if offsets else -1
+
+ current_offset = next_offset()
+ print current_offset;
+
+ for line in bytecode_disassembly:
+ disassembly_offset = int(line.split()[1])
+ if disassembly_offset == current_offset:
+ count = offset_counts[current_offset]
+ percentage = 100.0 * count / total
+ print "{:>8d} ({:>5.1f}%) ".format(count, percentage),
+ current_offset = next_offset()
+ else:
+ print " ",
+ print line
+
+ if offsets:
+ print ("WARNING: Offsets not empty. Output is most likely invalid due to "
+ "a mismatch between perf output and debug d8 binary.")
+
+
+def parse_command_line():
+ command_line_parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=__DESCRIPTION,
+ epilog=__HELP_EPILOGUE)
+
+ command_line_parser.add_argument(
+ "--arch", "-a",
+ help="The architecture (default: x64)",
+ default="x64",
+ )
+ command_line_parser.add_argument(
+ "--input", "-i",
+ help="perf sample file to process (default: perf.data)",
+ default="perf.data",
+ metavar="<perf filename>",
+ dest="perf_filename"
+ )
+ command_line_parser.add_argument(
+ "--output", "-o",
+ help="output file name (stdout if omitted)",
+ type=argparse.FileType("wt"),
+ default=sys.stdout,
+ metavar="<output filename>",
+ dest="output_stream"
+ )
+ command_line_parser.add_argument(
+ "bytecode_name",
+ metavar="<bytecode name>",
+ nargs="?",
+ help="The bytecode handler to annotate"
+ )
+
+ return command_line_parser.parse_args()
+
+
+def main():
+ program_options = parse_command_line()
+ perf = subprocess.Popen(["perf", "script", "-f", "ip,sym,symoff",
+ "-i", program_options.perf_filename],
+ stdout=subprocess.PIPE)
+
+ v8_root_path = os.path.dirname(__file__) + "/../../"
+ d8_path = "{}/out/{}.debug/d8".format(v8_root_path, program_options.arch)
+ d8_codegen = subprocess.Popen([d8_path, "--ignition",
+ "--trace-ignition-codegen", "-e", "1"],
+ stdout=subprocess.PIPE)
+
+ bytecode_offsets = bytecode_offset_generator(
+ perf.stdout, program_options.bytecode_name)
+ offset_counts = bytecode_offset_counts(bytecode_offsets)
+
+ bytecode_disassembly = bytecode_disassembly_generator(
+ d8_codegen.stdout, program_options.bytecode_name)
+
+ print_disassembly_annotation(offset_counts, bytecode_disassembly)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/ignition/linux_perf_bytecode_annotate_test.py b/tools/ignition/linux_perf_bytecode_annotate_test.py
new file mode 100644
index 00000000..15abbeda
--- /dev/null
+++ b/tools/ignition/linux_perf_bytecode_annotate_test.py
@@ -0,0 +1,85 @@
+# Copyright 2016 the V8 project 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 StringIO
+import unittest
+import linux_perf_bytecode_annotate as bytecode_annotate
+
+
+PERF_SCRIPT_OUTPUT = """
+# This line is a comment
+# This should be ignored too
+#
+# cdefab01 aRandomSymbol::Name(to, be, ignored)
+
+ 00000000 firstSymbol
+ 00000123 secondSymbol
+
+ 01234567 foo
+ abcdef76 BytecodeHandler:bar+0x12
+ 76543210 baz
+ abcdef76 BytecodeHandler:bar+0x16
+ 76543210 baz
+
+ 01234567 foo
+ abcdef76 BytecodeHandler:foo+0x1
+ 76543210 baz
+ abcdef76 BytecodeHandler:bar+0x2
+ 76543210 bar
+
+ abcdef76 BytecodeHandler:bar+0x19
+
+ abcdef76 BytecodeHandler:bar+0x12
+
+ abcdef76 BytecodeHandler:bar+0x12
+"""
+
+
+D8_CODEGEN_OUTPUT = """
+kind = BYTECODE_HANDLER
+name = foo
+compiler = turbofan
+Instructions (size = 3)
+0x3101394a3c0 0 55 push rbp
+0x3101394a3c1 1 ffe3 jmp rbx
+
+kind = BYTECODE_HANDLER
+name = bar
+compiler = turbofan
+Instructions (size = 5)
+0x3101394b3c0 0 55 push rbp
+0x3101394b3c1 1 4883c428 REX.W addq rsp,0x28
+# Unexpected comment
+0x3101394b3c5 5 ffe3 jmp rbx
+
+kind = BYTECODE_HANDLER
+name = baz
+compiler = turbofan
+Instructions (size = 5)
+0x3101394c3c0 0 55 push rbp
+0x3101394c3c1 1 4883c428 REX.W addq rsp,0x28
+0x3101394c3c5 5 ffe3 jmp rbx
+"""
+
+
+class LinuxPerfBytecodeAnnotateTest(unittest.TestCase):
+
+ def test_bytecode_offset_generator(self):
+ perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
+ offsets = list(
+ bytecode_annotate.bytecode_offset_generator(perf_stream, "bar"))
+ self.assertListEqual(offsets, [18, 25, 18, 18])
+
+ def test_bytecode_disassembly_generator(self):
+ codegen_stream = StringIO.StringIO(D8_CODEGEN_OUTPUT)
+ disassembly = list(
+ bytecode_annotate.bytecode_disassembly_generator(codegen_stream, "bar"))
+ self.assertListEqual(disassembly, [
+ "0x3101394b3c0 0 55 push rbp",
+ "0x3101394b3c1 1 4883c428 REX.W addq rsp,0x28",
+ "0x3101394b3c5 5 ffe3 jmp rbx"])
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tools/ignition/linux_perf_report.py b/tools/ignition/linux_perf_report.py
new file mode 100755
index 00000000..fbf562c2
--- /dev/null
+++ b/tools/ignition/linux_perf_report.py
@@ -0,0 +1,222 @@
+#! /usr/bin/python2
+#
+# Copyright 2016 the V8 project 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 argparse
+import collections
+import re
+import subprocess
+import sys
+
+
+__DESCRIPTION = """
+Processes a perf.data sample file and reports the hottest Ignition bytecodes,
+or write an input file for flamegraph.pl.
+"""
+
+
+__HELP_EPILOGUE = """
+examples:
+ # Get a flamegraph for Ignition bytecode handlers on Octane benchmark,
+ # without considering the time spent compiling JS code, entry trampoline
+ # samples and other non-Ignition samples.
+ #
+ $ tools/run-perf.sh out/x64.release/d8 \\
+ --ignition --noturbo --nocrankshaft run.js
+ $ tools/ignition/linux_perf_report.py --flamegraph -o out.collapsed
+ $ flamegraph.pl --colors js out.collapsed > out.svg
+
+ # Same as above, but show all samples, including time spent compiling JS code,
+ # entry trampoline samples and other samples.
+ $ # ...
+ $ tools/ignition/linux_perf_report.py \\
+ --flamegraph --show-all -o out.collapsed
+ $ # ...
+
+ # Same as above, but show full function signatures in the flamegraph.
+ $ # ...
+ $ tools/ignition/linux_perf_report.py \\
+ --flamegraph --show-full-signatures -o out.collapsed
+ $ # ...
+
+ # See the hottest bytecodes on Octane benchmark, by number of samples.
+ #
+ $ tools/run-perf.sh out/x64.release/d8 \\
+ --ignition --noturbo --nocrankshaft octane/run.js
+ $ tools/ignition/linux_perf_report.py
+"""
+
+
+COMPILER_SYMBOLS_RE = re.compile(
+ r"v8::internal::(?:\(anonymous namespace\)::)?Compile|v8::internal::Parser")
+
+
+def strip_function_parameters(symbol):
+ if symbol[-1] != ')': return symbol
+ pos = 1
+ parenthesis_count = 0
+ for c in reversed(symbol):
+ if c == ')':
+ parenthesis_count += 1
+ elif c == '(':
+ parenthesis_count -= 1
+ if parenthesis_count == 0:
+ break
+ else:
+ pos += 1
+ return symbol[:-pos]
+
+
+def collapsed_callchains_generator(perf_stream, show_all=False,
+ show_full_signatures=False):
+ current_chain = []
+ skip_until_end_of_chain = False
+ compiler_symbol_in_chain = False
+
+ for line in perf_stream:
+ # Lines starting with a "#" are comments, skip them.
+ if line[0] == "#":
+ continue
+
+ line = line.strip()
+
+ # Empty line signals the end of the callchain.
+ if not line:
+ if not skip_until_end_of_chain and current_chain and show_all:
+ current_chain.append("[other]")
+ yield current_chain
+ # Reset parser status.
+ current_chain = []
+ skip_until_end_of_chain = False
+ compiler_symbol_in_chain = False
+ continue
+
+ if skip_until_end_of_chain:
+ continue
+
+ symbol = line.split(" ", 1)[1]
+ if not show_full_signatures:
+ symbol = strip_function_parameters(symbol)
+ current_chain.append(symbol)
+
+ if symbol.startswith("BytecodeHandler:"):
+ yield current_chain
+ skip_until_end_of_chain = True
+ elif symbol == "Stub:CEntryStub" and compiler_symbol_in_chain:
+ if show_all:
+ current_chain[-1] = "[compiler]"
+ yield current_chain
+ skip_until_end_of_chain = True
+ elif COMPILER_SYMBOLS_RE.match(symbol):
+ compiler_symbol_in_chain = True
+ elif symbol == "Builtin:InterpreterEntryTrampoline":
+ if len(current_chain) == 1:
+ yield ["[entry trampoline]"]
+ else:
+ # If we see an InterpreterEntryTrampoline which is not at the top of the
+ # chain and doesn't have a BytecodeHandler above it, then we have
+ # skipped the top BytecodeHandler due to the top-level stub not building
+ # a frame. File the chain in the [misattributed] bucket.
+ current_chain[-1] = "[misattributed]"
+ yield current_chain
+ skip_until_end_of_chain = True
+
+
+def calculate_samples_count_per_callchain(callchains):
+ chain_counters = collections.defaultdict(int)
+ for callchain in callchains:
+ key = ";".join(reversed(callchain))
+ chain_counters[key] += 1
+ return chain_counters.items()
+
+
+def calculate_samples_count_per_handler(callchains):
+ def strip_handler_prefix_if_any(handler):
+ return handler if handler[0] == "[" else handler.split(":", 1)[1]
+
+ handler_counters = collections.defaultdict(int)
+ for callchain in callchains:
+ handler = strip_handler_prefix_if_any(callchain[-1])
+ handler_counters[handler] += 1
+ return handler_counters.items()
+
+
+def write_flamegraph_input_file(output_stream, callchains):
+ for callchain, count in calculate_samples_count_per_callchain(callchains):
+ output_stream.write("{}; {}\n".format(callchain, count))
+
+
+def write_handlers_report(output_stream, callchains):
+ handler_counters = calculate_samples_count_per_handler(callchains)
+ samples_num = sum(counter for _, counter in handler_counters)
+ # Sort by decreasing number of samples
+ handler_counters.sort(key=lambda entry: entry[1], reverse=True)
+ for bytecode_name, count in handler_counters:
+ output_stream.write(
+ "{}\t{}\t{:.3f}%\n".format(bytecode_name, count,
+ 100. * count / samples_num))
+
+
+def parse_command_line():
+ command_line_parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=__DESCRIPTION,
+ epilog=__HELP_EPILOGUE)
+
+ command_line_parser.add_argument(
+ "perf_filename",
+ help="perf sample file to process (default: perf.data)",
+ nargs="?",
+ default="perf.data",
+ metavar="<perf filename>"
+ )
+ command_line_parser.add_argument(
+ "--flamegraph", "-f",
+ help="output an input file for flamegraph.pl, not a report",
+ action="store_true",
+ dest="output_flamegraph"
+ )
+ command_line_parser.add_argument(
+ "--show-all", "-a",
+ help="show samples outside Ignition bytecode handlers",
+ action="store_true"
+ )
+ command_line_parser.add_argument(
+ "--show-full-signatures", "-s",
+ help="show full signatures instead of function names",
+ action="store_true"
+ )
+ command_line_parser.add_argument(
+ "--output", "-o",
+ help="output file name (stdout if omitted)",
+ type=argparse.FileType('wt'),
+ default=sys.stdout,
+ metavar="<output filename>",
+ dest="output_stream"
+ )
+
+ return command_line_parser.parse_args()
+
+
+def main():
+ program_options = parse_command_line()
+
+ perf = subprocess.Popen(["perf", "script", "-f", "ip,sym",
+ "-i", program_options.perf_filename],
+ stdout=subprocess.PIPE)
+
+ callchains = collapsed_callchains_generator(
+ perf.stdout, program_options.show_all,
+ program_options.show_full_signatures)
+
+ if program_options.output_flamegraph:
+ write_flamegraph_input_file(program_options.output_stream, callchains)
+ else:
+ write_handlers_report(program_options.output_stream, callchains)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/ignition/linux_perf_report_test.py b/tools/ignition/linux_perf_report_test.py
new file mode 100644
index 00000000..d9cef75d
--- /dev/null
+++ b/tools/ignition/linux_perf_report_test.py
@@ -0,0 +1,147 @@
+# Copyright 2016 the V8 project 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 linux_perf_report as ipr
+import StringIO
+import unittest
+
+
+PERF_SCRIPT_OUTPUT = """
+# This line is a comment
+# This should be ignored too
+#
+# cdefab01 aRandomSymbol::Name(to, be, ignored)
+
+ 00000000 firstSymbol
+ 00000123 secondSymbol
+
+ 01234567 foo
+ abcdef76 BytecodeHandler:bar
+ 76543210 baz
+
+# Indentation shouldn't matter (neither should this line)
+
+ 01234567 foo
+ abcdef76 BytecodeHandler:bar
+ 76543210 baz
+
+ 01234567 beep
+ abcdef76 BytecodeHandler:bar
+ 76543210 baz
+
+ 01234567 hello
+ abcdef76 v8::internal::Compiler
+ 00000000 Stub:CEntryStub
+ 76543210 world
+ 11111111 BytecodeHandler:nope
+
+ 00000000 Lost
+ 11111111 Builtin:InterpreterEntryTrampoline
+ 22222222 bar
+
+ 11111111 Builtin:InterpreterEntryTrampoline
+ 22222222 bar
+"""
+
+
+class LinuxPerfReportTest(unittest.TestCase):
+ def test_collapsed_callchains_generator(self):
+ perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
+ callchains = list(ipr.collapsed_callchains_generator(perf_stream))
+ self.assertListEqual(callchains, [
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ["[entry trampoline]"],
+ ])
+
+ def test_collapsed_callchains_generator_show_other(self):
+ perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
+ callchains = list(ipr.collapsed_callchains_generator(perf_stream,
+ show_all=True))
+ self.assertListEqual(callchains, [
+ ['firstSymbol', 'secondSymbol', '[other]'],
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ["hello", "v8::internal::Compiler", "[compiler]"],
+ ["Lost", "[misattributed]"],
+ ["[entry trampoline]"],
+ ])
+
+ def test_calculate_samples_count_per_callchain(self):
+ counters = ipr.calculate_samples_count_per_callchain([
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ["hello", "v8::internal::Compiler", "[compiler]"],
+ ])
+ self.assertItemsEqual(counters, [
+ ('BytecodeHandler:bar;foo', 2),
+ ('BytecodeHandler:bar;beep', 1),
+ ('[compiler];v8::internal::Compiler;hello', 1),
+ ])
+
+ def test_calculate_samples_count_per_callchain(self):
+ counters = ipr.calculate_samples_count_per_callchain([
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ])
+ self.assertItemsEqual(counters, [
+ ('BytecodeHandler:bar;foo', 2),
+ ('BytecodeHandler:bar;beep', 1),
+ ])
+
+ def test_calculate_samples_count_per_handler_show_compile(self):
+ counters = ipr.calculate_samples_count_per_handler([
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ["hello", "v8::internal::Compiler", "[compiler]"],
+ ])
+ self.assertItemsEqual(counters, [
+ ("bar", 3),
+ ("[compiler]", 1)
+ ])
+
+ def test_calculate_samples_count_per_handler_(self):
+ counters = ipr.calculate_samples_count_per_handler([
+ ["foo", "BytecodeHandler:bar"],
+ ["foo", "BytecodeHandler:bar"],
+ ["beep", "BytecodeHandler:bar"],
+ ])
+ self.assertItemsEqual(counters, [("bar", 3)])
+
+ def test_multiple_handlers(self):
+ perf_stream = StringIO.StringIO("""
+ 0000 foo(bar)
+ 1234 BytecodeHandler:first
+ 5678 a::random::call<to>(something, else)
+ 9abc BytecodeHandler:second
+ def0 otherIrrelevant(stuff)
+ 1111 entrypoint
+ """)
+ callchains = list(ipr.collapsed_callchains_generator(perf_stream, False))
+ self.assertListEqual(callchains, [
+ ["foo", "BytecodeHandler:first"],
+ ])
+
+ def test_compiler_symbols_regex(self):
+ compiler_symbols = [
+ "v8::internal::Parser",
+ "v8::internal::(anonymous namespace)::Compile",
+ "v8::internal::Compiler::foo",
+ ]
+ for compiler_symbol in compiler_symbols:
+ self.assertTrue(ipr.COMPILER_SYMBOLS_RE.match(compiler_symbol))
+
+ def test_strip_function_parameters(self):
+ def should_match(signature, name):
+ self.assertEqual(ipr.strip_function_parameters(signature), name)
+
+ should_match("foo(bar)", "foo"),
+ should_match("Foo(foomatic::(anonymous)::bar(baz))", "Foo"),
+ should_match("v8::(anonymous ns)::bar<thing(with, parentheses)>(baz, poe)",
+ "v8::(anonymous ns)::bar<thing(with, parentheses)>")
diff --git a/tools/jsfunfuzz/jsfunfuzz.gyp b/tools/jsfunfuzz/jsfunfuzz.gyp
index fb0e5f49..8938e445 100644
--- a/tools/jsfunfuzz/jsfunfuzz.gyp
+++ b/tools/jsfunfuzz/jsfunfuzz.gyp
@@ -13,8 +13,8 @@
'../../src/d8.gyp:d8_run',
],
'includes': [
- '../../build/features.gypi',
- '../../build/isolate.gypi',
+ '../../gypfiles/features.gypi',
+ '../../gypfiles/isolate.gypi',
],
'sources': [
'jsfunfuzz.isolate',
diff --git a/tools/mingw-generate-makefiles.sh b/tools/mingw-generate-makefiles.sh
index 32af52d3..67715fc1 100755
--- a/tools/mingw-generate-makefiles.sh
+++ b/tools/mingw-generate-makefiles.sh
@@ -27,7 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Monkey-patch GYP.
-cat > build/gyp/gyp.mingw << EOF
+cat > tools/gyp/gyp.mingw << EOF
#!/usr/bin/env python
# Copyright (c) 2009 Google Inc. All rights reserved.
@@ -74,11 +74,11 @@ EOF
find out -name '*.mk' -or -name 'Makefile*' -exec rm {} \;
# Generate fresh Makefiles.
-mv build/gyp/gyp build/gyp/gyp.original
-mv build/gyp/gyp.mingw build/gyp/gyp
+mv tools/gyp/gyp tools/gyp/gyp.original
+mv tools/gyp/gyp.mingw tools/gyp/gyp
make out/Makefile.ia32
-mv build/gyp/gyp build/gyp/gyp.mingw
-mv build/gyp/gyp.original build/gyp/gyp
+mv tools/gyp/gyp tools/gyp/gyp.mingw
+mv tools/gyp/gyp.original tools/gyp/gyp
# Patch generated Makefiles: replace most backslashes with forward slashes,
# fix library names in linker flags.
diff --git a/tools/parser-shell.gyp b/tools/parser-shell.gyp
index 77ed1eb2..4ef1a82d 100644
--- a/tools/parser-shell.gyp
+++ b/tools/parser-shell.gyp
@@ -30,14 +30,14 @@
'v8_code': 1,
'v8_enable_i18n_support%': 1,
},
- 'includes': ['../build/toolchain.gypi', '../build/features.gypi'],
+ 'includes': ['../gypfiles/toolchain.gypi', '../gypfiles/features.gypi'],
'targets': [
{
'target_name': 'parser-shell',
'type': 'executable',
'dependencies': [
- '../tools/gyp/v8.gyp:v8',
- '../tools/gyp/v8.gyp:v8_libplatform',
+ '../src/v8.gyp:v8',
+ '../src/v8.gyp:v8_libplatform',
],
'conditions': [
['v8_enable_i18n_support==1', {
@@ -50,10 +50,6 @@
'include_dirs+': [
'..',
],
- 'defines': [
- # TODO(jochen): Remove again after this is globally turned on.
- 'V8_IMMINENT_DEPRECATION_WARNINGS',
- ],
'sources': [
'parser-shell.cc',
'shell-utils.h',
diff --git a/tools/perf-to-html.py b/tools/perf-to-html.py
index 63faeb1d..7ec9c50f 100755
--- a/tools/perf-to-html.py
+++ b/tools/perf-to-html.py
@@ -115,8 +115,8 @@ class Benchmark:
self.name_ = name
self.tests_ = {}
for test in data:
- # strip off "<name>/" prefix
- test_name = test.split("/")[1]
+ # strip off "<name>/" prefix, allowing for subsequent "/"s
+ test_name = test.split("/", 1)[1]
self.appendResult(test_name, data[test])
# tests is a dictionary of Results
diff --git a/tools/release/auto_roll.py b/tools/release/auto_roll.py
index b71cac5a..243b029b 100755
--- a/tools/release/auto_roll.py
+++ b/tools/release/auto_roll.py
@@ -18,7 +18,9 @@ https://github.com/v8/v8/wiki/Triaging%20issues
Please close rolling in case of a roll revert:
https://v8-roll.appspot.com/
-This only works with a Google account.""")
+This only works with a Google account.
+
+CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel""")
class Preparation(Step):
MESSAGE = "Preparation."
diff --git a/tools/release/create_release.py b/tools/release/create_release.py
index 7477ea14..14d44b4b 100755
--- a/tools/release/create_release.py
+++ b/tools/release/create_release.py
@@ -223,6 +223,27 @@ class CommitBranch(Step):
os.remove(self.Config("CHANGELOG_ENTRY_FILE"))
+class FixBrokenTag(Step):
+ MESSAGE = "Check for a missing tag and fix that instead."
+
+ def RunStep(self):
+ commit = None
+ try:
+ commit = self.GitLog(
+ n=1, format="%H",
+ grep=self["commit_title"],
+ branch="origin/%s" % self["version"],
+ )
+ except GitFailedException:
+ # In the normal case, the remote doesn't exist yet and git will fail.
+ pass
+ if commit:
+ print "Found %s. Trying to repair tag and bail out." % self["version"]
+ self.Git("tag %s %s" % (self["version"], commit))
+ self.Git("push origin refs/tags/%s" % self["version"])
+ return True
+
+
class PushBranch(Step):
MESSAGE = "Push changes."
@@ -303,6 +324,7 @@ class CreateRelease(ScriptsBase):
SetVersion,
EnableMergeWatchlist,
CommitBranch,
+ FixBrokenTag,
PushBranch,
TagRevision,
CleanUp,
diff --git a/tools/release/test_scripts.py b/tools/release/test_scripts.py
index 05457c92..417f739f 100644
--- a/tools/release/test_scripts.py
+++ b/tools/release/test_scripts.py
@@ -970,6 +970,8 @@ Performance and stability improvements on all platforms."""
cb=self.WriteFakeWatchlistsFile),
Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
cb=CheckVersionCommit),
+ Cmd("git log -1 --format=%H --grep=\"Version 3.22.5\" origin/3.22.5",
+ ""),
Cmd("git push origin "
"refs/heads/work-branch:refs/pending/heads/3.22.5 "
"push_hash:refs/pending-tags/heads/3.22.5 "
@@ -1041,6 +1043,8 @@ Please close rolling in case of a roll revert:
https://v8-roll.appspot.com/
This only works with a Google account.
+CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
+
TBR=reviewer@chromium.org"""
# Snippet from the original DEPS file.
diff --git a/tools/run-deopt-fuzzer.gyp b/tools/run-deopt-fuzzer.gyp
index 73f0aaf7..9eb6b538 100644
--- a/tools/run-deopt-fuzzer.gyp
+++ b/tools/run-deopt-fuzzer.gyp
@@ -13,8 +13,8 @@
'../src/d8.gyp:d8_run',
],
'includes': [
- '../build/features.gypi',
- '../build/isolate.gypi',
+ '../gypfiles/features.gypi',
+ '../gypfiles/isolate.gypi',
],
'sources': [
'run-deopt-fuzzer.isolate',
diff --git a/tools/run-deopt-fuzzer.py b/tools/run-deopt-fuzzer.py
index 970aa8e6..928c71b7 100755
--- a/tools/run-deopt-fuzzer.py
+++ b/tools/run-deopt-fuzzer.py
@@ -399,6 +399,7 @@ def Execute(arch, mode, args, options, suites, workspace):
"gc_stress": False,
"gcov_coverage": False,
"ignition": False,
+ "ignition_turbofan": False,
"isolates": options.isolates,
"mode": mode,
"no_i18n": False,
diff --git a/tools/run-perf.sh b/tools/run-perf.sh
index 24053b40..03123fdb 100755
--- a/tools/run-perf.sh
+++ b/tools/run-perf.sh
@@ -13,6 +13,7 @@ SAMPLE_EVERY_N_CYCLES=10000
SAMPLE_RATE_CONFIG_FILE="/proc/sys/kernel/perf_event_max_sample_rate"
KERNEL_MAP_CONFIG_FILE="/proc/sys/kernel/kptr_restrict"
CALL_GRAPH_METHOD="fp" # dwarf does not play nice with JITted objects.
+EVENT_TYPE=${EVENT_TYPE:=cycles:u}
########## Usage
@@ -46,7 +47,7 @@ fi
echo "Running..."
perf record -R \
- -e cycles:u \
+ -e $EVENT_TYPE \
-c $SAMPLE_EVERY_N_CYCLES \
--call-graph $CALL_GRAPH_METHOD \
-i $@ --perf_basic_prof
diff --git a/tools/run-tests.py b/tools/run-tests.py
index a380c97a..b1c71dd0 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -105,6 +105,7 @@ TIMEOUT_DEFAULT = 60
VARIANTS = ["default", "stress", "turbofan"]
EXHAUSTIVE_VARIANTS = VARIANTS + [
+ "ignition",
"nocrankshaft",
"turbofan_opt",
]
@@ -194,6 +195,8 @@ SLOW_ARCHS = ["android_arm",
"mips64el",
"nacl_ia32",
"nacl_x64",
+ "s390",
+ "s390x",
"x87",
"arm64"]
@@ -253,6 +256,9 @@ def BuildOptions():
default="")
result.add_option("--ignition", help="Skip tests which don't run in ignition",
default=False, action="store_true")
+ result.add_option("--ignition-turbofan",
+ help="Skip tests which don't run in ignition_turbofan",
+ default=False, action="store_true")
result.add_option("--isolates", help="Whether to test isolates",
default=False, action="store_true")
result.add_option("-j", help="The number of parallel tasks to run",
@@ -335,7 +341,7 @@ def BuildOptions():
result.add_option("--time", help="Print timing information after running",
default=False, action="store_true")
result.add_option("-t", "--timeout", help="Timeout in seconds",
- default= -1, type="int")
+ default=TIMEOUT_DEFAULT, type="int")
result.add_option("--tsan",
help="Regard test expectations for TSAN",
default=False, action="store_true")
@@ -378,6 +384,10 @@ def BuildbotToV8Mode(config):
def SetupEnvironment(options):
"""Setup additional environment variables."""
+
+ # Many tests assume an English interface.
+ os.environ['LANG'] = 'en_US.UTF-8'
+
symbolizer = 'external_symbolizer_path=%s' % (
os.path.join(
BASE_DIR, 'third_party', 'llvm-build', 'Release+Asserts', 'bin',
@@ -591,6 +601,11 @@ def Main():
return 1
SetupEnvironment(options)
+ if options.swarming:
+ # Swarming doesn't print how isolated commands are called. Lets make this
+ # less cryptic by printing it ourselves.
+ print ' '.join(sys.argv)
+
exit_code = 0
if not options.no_presubmit:
print ">>> running presubmit tests"
@@ -663,19 +678,16 @@ def Execute(arch, mode, args, options, suites):
# Populate context object.
mode_flags = MODES[mode]["flags"]
- timeout = options.timeout
- if timeout == -1:
- # Simulators are slow, therefore allow a longer default timeout.
- if arch in SLOW_ARCHS:
- timeout = 2 * TIMEOUT_DEFAULT;
- else:
- timeout = TIMEOUT_DEFAULT;
- timeout *= MODES[mode]["timeout_scalefactor"]
+ # Simulators are slow, therefore allow a longer timeout.
+ if arch in SLOW_ARCHS:
+ options.timeout *= 2
+
+ options.timeout *= MODES[mode]["timeout_scalefactor"]
if options.predictable:
# Predictable mode is slower.
- timeout *= 2
+ options.timeout *= 2
# TODO(machenbach): Remove temporary verbose output on windows after
# debugging driver-hung-up on XP.
@@ -685,7 +697,8 @@ def Execute(arch, mode, args, options, suites):
)
ctx = context.Context(arch, MODES[mode]["execution_mode"], shell_dir,
mode_flags, verbose_output,
- timeout, options.isolates,
+ options.timeout,
+ options.isolates,
options.command_prefix,
options.extra_flags,
options.no_i18n,
@@ -711,6 +724,7 @@ def Execute(arch, mode, args, options, suites):
"gc_stress": options.gc_stress,
"gcov_coverage": options.gcov_coverage,
"ignition": options.ignition,
+ "ignition_turbofan": options.ignition_turbofan,
"isolates": options.isolates,
"mode": MODES[mode]["status_mode"],
"no_i18n": options.no_i18n,
diff --git a/tools/run-valgrind.gyp b/tools/run-valgrind.gyp
index d06be933..02dd26d2 100644
--- a/tools/run-valgrind.gyp
+++ b/tools/run-valgrind.gyp
@@ -13,8 +13,8 @@
'../src/d8.gyp:d8_run',
],
'includes': [
- '../build/features.gypi',
- '../build/isolate.gypi',
+ '../gypfiles/features.gypi',
+ '../gypfiles/isolate.gypi',
],
'sources': [
'run-valgrind.isolate',
diff --git a/tools/run_perf.py b/tools/run_perf.py
index db4245f4..1dd03bd5 100755
--- a/tools/run_perf.py
+++ b/tools/run_perf.py
@@ -612,6 +612,21 @@ class Platform(object):
class DesktopPlatform(Platform):
def __init__(self, options):
super(DesktopPlatform, self).__init__(options)
+ self.command_prefix = []
+
+ if options.prioritize or options.affinitize != None:
+ self.command_prefix = ["schedtool"]
+ if options.prioritize:
+ self.command_prefix += ["-n", "-20"]
+ if options.affinitize != None:
+ # schedtool expects a bit pattern when setting affinity, where each
+ # bit set to '1' corresponds to a core where the process may run on.
+ # First bit corresponds to CPU 0. Since the 'affinitize' parameter is
+ # a core number, we need to map to said bit pattern.
+ cpu = int(options.affinitize)
+ core = 1 << cpu
+ self.command_prefix += ["-a", ("0x%x" % core)]
+ self.command_prefix += ["-e"]
def PreExecution(self):
pass
@@ -627,15 +642,18 @@ class DesktopPlatform(Platform):
suffix = ' - without patch' if no_patch else ''
shell_dir = self.shell_dir_no_patch if no_patch else self.shell_dir
title = ">>> %%s (#%d)%s:" % ((count + 1), suffix)
+ command = self.command_prefix + runnable.GetCommand(shell_dir,
+ self.extra_flags)
try:
output = commands.Execute(
- runnable.GetCommand(shell_dir, self.extra_flags),
- timeout=runnable.timeout,
+ command,
+ timeout=runnable.timeout,
)
except OSError as e: # pragma: no cover
print title % "OSError"
print e
return ""
+
print title % "Stdout"
print output.stdout
if output.stderr: # pragma: no cover
@@ -788,6 +806,107 @@ class AndroidPlatform(Platform): # pragma: no cover
stdout = ""
return stdout
+class CustomMachineConfiguration:
+ def __init__(self, disable_aslr = False, governor = None):
+ self.aslr_backup = None
+ self.governor_backup = None
+ self.disable_aslr = disable_aslr
+ self.governor = governor
+
+ def __enter__(self):
+ if self.disable_aslr:
+ self.aslr_backup = CustomMachineConfiguration.GetASLR()
+ CustomMachineConfiguration.SetASLR(0)
+ if self.governor != None:
+ self.governor_backup = CustomMachineConfiguration.GetCPUGovernor()
+ CustomMachineConfiguration.SetCPUGovernor(self.governor)
+ return self
+
+ def __exit__(self, type, value, traceback):
+ if self.aslr_backup != None:
+ CustomMachineConfiguration.SetASLR(self.aslr_backup)
+ if self.governor_backup != None:
+ CustomMachineConfiguration.SetCPUGovernor(self.governor_backup)
+
+ @staticmethod
+ def GetASLR():
+ try:
+ with open("/proc/sys/kernel/randomize_va_space", "r") as f:
+ return int(f.readline().strip())
+ except Exception as e:
+ print "Failed to get current ASLR settings."
+ raise e
+
+ @staticmethod
+ def SetASLR(value):
+ try:
+ with open("/proc/sys/kernel/randomize_va_space", "w") as f:
+ f.write(str(value))
+ except Exception as e:
+ print "Failed to update ASLR to %s." % value
+ print "Are we running under sudo?"
+ raise e
+
+ new_value = CustomMachineConfiguration.GetASLR()
+ if value != new_value:
+ raise Exception("Present value is %s" % new_value)
+
+ @staticmethod
+ def GetCPUCoresRange():
+ try:
+ with open("/sys/devices/system/cpu/present", "r") as f:
+ indexes = f.readline()
+ first, last = map(int, indexes.split("-"))
+ return range(first, last + 1)
+ except Exception as e:
+ print "Failed to retrieve number of CPUs."
+ raise e
+
+ @staticmethod
+ def GetCPUPathForId(cpu_index):
+ ret = "/sys/devices/system/cpu/cpu"
+ ret += str(cpu_index)
+ ret += "/cpufreq/scaling_governor"
+ return ret
+
+ @staticmethod
+ def GetCPUGovernor():
+ try:
+ cpu_indices = CustomMachineConfiguration.GetCPUCoresRange()
+ ret = None
+ for cpu_index in cpu_indices:
+ cpu_device = CustomMachineConfiguration.GetCPUPathForId(cpu_index)
+ with open(cpu_device, "r") as f:
+ # We assume the governors of all CPUs are set to the same value
+ val = f.readline().strip()
+ if ret == None:
+ ret = val
+ elif ret != val:
+ raise Exception("CPU cores have differing governor settings")
+ return ret
+ except Exception as e:
+ print "Failed to get the current CPU governor."
+ print "Is the CPU governor disabled? Check BIOS."
+ raise e
+
+ @staticmethod
+ def SetCPUGovernor(value):
+ try:
+ cpu_indices = CustomMachineConfiguration.GetCPUCoresRange()
+ for cpu_index in cpu_indices:
+ cpu_device = CustomMachineConfiguration.GetCPUPathForId(cpu_index)
+ with open(cpu_device, "w") as f:
+ f.write(value)
+
+ except Exception as e:
+ print "Failed to change CPU governor to %s." % value
+ print "Are we running under sudo?"
+ raise e
+
+ cur_value = CustomMachineConfiguration.GetCPUGovernor()
+ if cur_value != value:
+ raise Exception("Could not set CPU governor. Present value is %s"
+ % cur_value )
# TODO: Implement results_processor.
def Main(args):
@@ -822,6 +941,27 @@ def Main(args):
help="JavaScript engine binary. By default, d8 under "
"architecture-specific build dir. "
"Not supported in conjunction with outdir-no-patch.")
+ parser.add_option("--prioritize",
+ help="Raise the priority to nice -20 for the benchmarking "
+ "process.Requires Linux, schedtool, and sudo privileges.",
+ default=False, action="store_true")
+ parser.add_option("--affinitize",
+ help="Run benchmarking process on the specified core. "
+ "For example: "
+ "--affinitize=0 will run the benchmark process on core 0. "
+ "--affinitize=3 will run the benchmark process on core 3. "
+ "Requires Linux, schedtool, and sudo privileges.",
+ default=None)
+ parser.add_option("--noaslr",
+ help="Disable ASLR for the duration of the benchmarked "
+ "process. Requires Linux and sudo privileges.",
+ default=False, action="store_true")
+ parser.add_option("--cpu-governor",
+ help="Set cpu governor to specified policy for the "
+ "duration of the benchmarked process. Typical options: "
+ "'powersave' for more stable results, or 'performance' "
+ "for shorter completion time of suite, with potentially "
+ "more noise in results.")
(options, args) = parser.parse_args(args)
@@ -872,56 +1012,60 @@ def Main(args):
else:
options.shell_dir_no_patch = None
+ prev_aslr = None
+ prev_cpu_gov = None
platform = Platform.GetPlatform(options)
results = Results()
results_no_patch = Results()
- for path in args:
- path = os.path.abspath(path)
+ with CustomMachineConfiguration(governor = options.cpu_governor,
+ disable_aslr = options.noaslr) as conf:
+ for path in args:
+ path = os.path.abspath(path)
- if not os.path.exists(path): # pragma: no cover
- results.errors.append("Configuration file %s does not exist." % path)
- continue
+ if not os.path.exists(path): # pragma: no cover
+ results.errors.append("Configuration file %s does not exist." % path)
+ continue
- with open(path) as f:
- suite = json.loads(f.read())
+ with open(path) as f:
+ suite = json.loads(f.read())
- # If no name is given, default to the file name without .json.
- suite.setdefault("name", os.path.splitext(os.path.basename(path))[0])
+ # If no name is given, default to the file name without .json.
+ suite.setdefault("name", os.path.splitext(os.path.basename(path))[0])
- # Setup things common to one test suite.
- platform.PreExecution()
+ # Setup things common to one test suite.
+ platform.PreExecution()
- # Build the graph/trace tree structure.
- default_parent = DefaultSentinel(default_binary_name)
- root = BuildGraphConfigs(suite, options.arch, default_parent)
+ # Build the graph/trace tree structure.
+ default_parent = DefaultSentinel(default_binary_name)
+ root = BuildGraphConfigs(suite, options.arch, default_parent)
- # Callback to be called on each node on traversal.
- def NodeCB(node):
- platform.PreTests(node, path)
+ # Callback to be called on each node on traversal.
+ def NodeCB(node):
+ platform.PreTests(node, path)
- # Traverse graph/trace tree and interate over all runnables.
- for runnable in FlattenRunnables(root, NodeCB):
- print ">>> Running suite: %s" % "/".join(runnable.graphs)
+ # Traverse graph/trace tree and interate over all runnables.
+ for runnable in FlattenRunnables(root, NodeCB):
+ print ">>> Running suite: %s" % "/".join(runnable.graphs)
- def Runner():
- """Output generator that reruns several times."""
- for i in xrange(0, max(1, runnable.run_count)):
- # TODO(machenbach): Allow timeout per arch like with run_count per
- # arch.
- yield platform.Run(runnable, i)
+ def Runner():
+ """Output generator that reruns several times."""
+ for i in xrange(0, max(1, runnable.run_count)):
+ # TODO(machenbach): Allow timeout per arch like with run_count per
+ # arch.
+ yield platform.Run(runnable, i)
- # Let runnable iterate over all runs and handle output.
- result, result_no_patch = runnable.Run(
+ # Let runnable iterate over all runs and handle output.
+ result, result_no_patch = runnable.Run(
Runner, trybot=options.shell_dir_no_patch)
- results += result
- results_no_patch += result_no_patch
- platform.PostExecution()
-
- if options.json_test_results:
- results.WriteToFile(options.json_test_results)
- else: # pragma: no cover
- print results
+ results += result
+ results_no_patch += result_no_patch
+ platform.PostExecution()
+
+ if options.json_test_results:
+ results.WriteToFile(options.json_test_results)
+ else: # pragma: no cover
+ print results
if options.json_test_results_no_patch:
results_no_patch.WriteToFile(options.json_test_results_no_patch)
diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py
index e0aec0bb..f3d11a8b 100644
--- a/tools/testrunner/local/execution.py
+++ b/tools/testrunner/local/execution.py
@@ -248,7 +248,6 @@ class Runner(object):
self.total += 1
def _ProcessTestNormal(self, test, result, pool):
- self.indicator.AboutToRun(test)
test.output = result[1]
test.duration = result[2]
has_unexpected_output = test.suite.HasUnexpectedOutput(test)
@@ -285,7 +284,6 @@ class Runner(object):
if test.run == 1 and result[1].HasTimedOut():
# If we get a timeout in the first run, we are already in an
# unpredictable state. Just report it as a failure and don't rerun.
- self.indicator.AboutToRun(test)
test.output = result[1]
self.remaining -= 1
self.failed.append(test)
@@ -294,16 +292,13 @@ class Runner(object):
# From the second run on, check for different allocations. If a
# difference is found, call the indicator twice to report both tests.
# All runs of each test are counted as one for the statistic.
- self.indicator.AboutToRun(test)
self.remaining -= 1
self.failed.append(test)
self.indicator.HasRun(test, True)
- self.indicator.AboutToRun(test)
test.output = result[1]
self.indicator.HasRun(test, True)
elif test.run >= 3:
# No difference on the third run -> report a success.
- self.indicator.AboutToRun(test)
self.remaining -= 1
self.succeeded += 1
test.output = result[1]
diff --git a/tools/testrunner/local/progress.py b/tools/testrunner/local/progress.py
index 4e1be3e4..33e27e15 100644
--- a/tools/testrunner/local/progress.py
+++ b/tools/testrunner/local/progress.py
@@ -34,6 +34,7 @@ import time
from . import execution
from . import junit_output
+from . import statusfile
ABS_PATH_PREFIX = os.getcwd() + os.sep
@@ -53,9 +54,6 @@ class ProgressIndicator(object):
def Done(self):
pass
- def AboutToRun(self, test):
- pass
-
def HasRun(self, test, has_unexpected_output):
pass
@@ -146,10 +144,6 @@ class SimpleProgressIndicator(ProgressIndicator):
class VerboseProgressIndicator(SimpleProgressIndicator):
- def AboutToRun(self, test):
- print 'Starting %s...' % test.GetLabel()
- sys.stdout.flush()
-
def HasRun(self, test, has_unexpected_output):
if has_unexpected_output:
if test.output.HasCrashed():
@@ -200,10 +194,8 @@ class CompactProgressIndicator(ProgressIndicator):
self.PrintProgress('Done')
print "" # Line break.
- def AboutToRun(self, test):
- self.PrintProgress(test.GetLabel())
-
def HasRun(self, test, has_unexpected_output):
+ self.PrintProgress(test.GetLabel())
if has_unexpected_output:
self.ClearLine(self.last_status_length)
self.PrintFailureHeader(test)
@@ -329,6 +321,12 @@ class JsonTestProgressIndicator(ProgressIndicator):
# Buildbot might start out with an empty file.
complete_results = json.loads(f.read() or "[]")
+ duration_mean = None
+ if self.tests:
+ # Get duration mean.
+ duration_mean = (
+ sum(t.duration for t in self.tests) / float(len(self.tests)))
+
# Sort tests by duration.
timed_tests = [t for t in self.tests if t.duration is not None]
timed_tests.sort(lambda a, b: cmp(b.duration, a.duration))
@@ -338,6 +336,7 @@ class JsonTestProgressIndicator(ProgressIndicator):
"flags": test.flags,
"command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""),
"duration": test.duration,
+ "marked_slow": statusfile.IsSlow(test.outcomes),
} for test in timed_tests[:20]
]
@@ -346,6 +345,8 @@ class JsonTestProgressIndicator(ProgressIndicator):
"mode": self.mode,
"results": self.results,
"slowest_tests": slowest_tests,
+ "duration_mean": duration_mean,
+ "test_total": len(self.tests),
})
with open(self.json_test_results, "w") as f:
diff --git a/tools/testrunner/local/statusfile.py b/tools/testrunner/local/statusfile.py
index 7e96cc37..fde62379 100644
--- a/tools/testrunner/local/statusfile.py
+++ b/tools/testrunner/local/statusfile.py
@@ -36,6 +36,7 @@ TIMEOUT = "TIMEOUT"
CRASH = "CRASH"
SLOW = "SLOW"
FAST_VARIANTS = "FAST_VARIANTS"
+NO_IGNITION = "NO_IGNITION"
NO_VARIANTS = "NO_VARIANTS"
# These are just for the status files and are mapped below in DEFS:
FAIL_OK = "FAIL_OK"
@@ -46,7 +47,8 @@ ALWAYS = "ALWAYS"
KEYWORDS = {}
for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FAIL_OK,
- FAST_VARIANTS, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY, ALWAYS]:
+ FAST_VARIANTS, NO_IGNITION, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY,
+ ALWAYS]:
KEYWORDS[key] = key
DEFS = {FAIL_OK: [FAIL, OKAY],
@@ -70,6 +72,10 @@ def IsSlow(outcomes):
return SLOW in outcomes
+def NoIgnitionVariant(outcomes):
+ return NO_IGNITION in outcomes
+
+
def OnlyStandardVariant(outcomes):
return NO_VARIANTS in outcomes
diff --git a/tools/testrunner/local/testsuite.py b/tools/testrunner/local/testsuite.py
index f43d008b..8e8b4769 100644
--- a/tools/testrunner/local/testsuite.py
+++ b/tools/testrunner/local/testsuite.py
@@ -41,7 +41,8 @@ ALL_VARIANT_FLAGS = {
"turbofan": [["--turbo"]],
"turbofan_opt": [["--turbo", "--always-opt"]],
"nocrankshaft": [["--nocrankshaft"]],
- "ignition": [["--ignition", "--turbo"]],
+ "ignition": [["--ignition"]],
+ "ignition_turbofan": [["--ignition", "--turbo", "--turbo-from-bytecode"]],
"preparser": [["--min-preparse-length=0"]],
}
@@ -51,14 +52,17 @@ FAST_VARIANT_FLAGS = {
"stress": [["--stress-opt"]],
"turbofan": [["--turbo"]],
"nocrankshaft": [["--nocrankshaft"]],
- "ignition": [["--ignition", "--turbo"]],
+ "ignition": [["--ignition"]],
+ "ignition_turbofan": [["--ignition", "--turbo", "--turbo-from-bytecode"]],
"preparser": [["--min-preparse-length=0"]],
}
ALL_VARIANTS = set(["default", "stress", "turbofan", "turbofan_opt",
- "nocrankshaft", "ignition", "preparser"])
+ "nocrankshaft", "ignition", "ignition_turbofan",
+ "preparser"])
FAST_VARIANTS = set(["default", "turbofan"])
STANDARD_VARIANT = set(["default"])
+IGNITION_VARIANT = set(["ignition"])
class VariantGenerator(object):
@@ -69,12 +73,15 @@ class VariantGenerator(object):
self.standard_variant = STANDARD_VARIANT & variants
def FilterVariantsByTest(self, testcase):
- if testcase.outcomes and statusfile.OnlyStandardVariant(
- testcase.outcomes):
- return self.standard_variant
- if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
- return self.fast_variants
- return self.all_variants
+ result = self.all_variants
+ if testcase.outcomes:
+ if statusfile.OnlyStandardVariant(testcase.outcomes):
+ return self.standard_variant
+ if statusfile.OnlyFastVariants(testcase.outcomes):
+ result = self.fast_variants
+ if statusfile.NoIgnitionVariant(testcase.outcomes):
+ result = result - IGNITION_VARIANT
+ return result
def GetFlagSets(self, testcase, variant):
if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
diff --git a/tools/testrunner/network/network_execution.py b/tools/testrunner/network/network_execution.py
index c842aba5..a9544017 100644
--- a/tools/testrunner/network/network_execution.py
+++ b/tools/testrunner/network/network_execution.py
@@ -203,7 +203,6 @@ class NetworkedRunner(execution.Runner):
[constants.INFORM_DURATION, perf_key, test.duration,
self.context.arch, self.context.mode],
self.local_socket)
- self.indicator.AboutToRun(test)
has_unexpected_output = test.suite.HasUnexpectedOutput(test)
if has_unexpected_output:
self.failed.append(test)
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index ba7401a2..5534355f 100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -83,7 +83,7 @@ function TickProcessor(
pairwiseTimedRange,
onlySummary) {
LogReader.call(this, {
- 'shared-library': { parsers: [null, parseInt, parseInt],
+ 'shared-library': { parsers: [null, parseInt, parseInt, parseInt],
processor: this.processSharedLibrary },
'code-creation': {
parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'],
@@ -242,13 +242,13 @@ TickProcessor.prototype.processLogFileInTest = function(fileName) {
TickProcessor.prototype.processSharedLibrary = function(
- name, startAddr, endAddr) {
- var entry = this.profile_.addLibrary(name, startAddr, endAddr);
+ name, startAddr, endAddr, aslrSlide) {
+ var entry = this.profile_.addLibrary(name, startAddr, endAddr, aslrSlide);
this.setCodeType(entry.getName(), 'SHARED_LIB');
var self = this;
var libFuncs = this.cppEntriesProvider_.parseVmSymbols(
- name, startAddr, endAddr, function(fName, fStart, fEnd) {
+ name, startAddr, endAddr, aslrSlide, function(fName, fStart, fEnd) {
self.profile_.addStaticCode(fName, fStart, fEnd);
self.setCodeType(fName, 'CPP');
});
@@ -559,7 +559,7 @@ function CppEntriesProvider() {
CppEntriesProvider.prototype.parseVmSymbols = function(
- libName, libStart, libEnd, processorFunc) {
+ libName, libStart, libEnd, libASLRSlide, processorFunc) {
this.loadSymbols(libName);
var prevEntry;
@@ -588,6 +588,7 @@ CppEntriesProvider.prototype.parseVmSymbols = function(
} else if (funcInfo === false) {
break;
}
+ funcInfo.start += libASLRSlide;
if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) {
funcInfo.start += libStart;
}
diff --git a/tools/try_perf.py b/tools/try_perf.py
index fbd4036d..5565b808 100755
--- a/tools/try_perf.py
+++ b/tools/try_perf.py
@@ -44,6 +44,7 @@ PUBLIC_BENCHMARKS = [
'octane-tf-pr',
'simdjs',
'sunspider',
+ 'wasm',
]
V8_BASE = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
diff --git a/tools/verify_source_deps.py b/tools/verify_source_deps.py
index 50caace7..56e31565 100755
--- a/tools/verify_source_deps.py
+++ b/tools/verify_source_deps.py
@@ -24,10 +24,10 @@ V8_INCLUDE_BASE = os.path.join(V8_BASE, 'include')
GYP_FILES = [
os.path.join(V8_BASE, 'src', 'd8.gyp'),
+ os.path.join(V8_BASE, 'src', 'v8.gyp'),
os.path.join(V8_BASE, 'src', 'third_party', 'vtune', 'v8vtune.gyp'),
os.path.join(V8_BASE, 'test', 'cctest', 'cctest.gyp'),
os.path.join(V8_BASE, 'test', 'unittests', 'unittests.gyp'),
- os.path.join(V8_BASE, 'tools', 'gyp', 'v8.gyp'),
os.path.join(V8_BASE, 'tools', 'parser-shell.gyp'),
]
diff --git a/tools/whitespace.txt b/tools/whitespace.txt
index d1395f5d..c571b763 100644
--- a/tools/whitespace.txt
+++ b/tools/whitespace.txt
@@ -5,4 +5,4 @@ Try to write something funny. And please don't add trailing whitespace.
A Smi balks into a war and says:
"I'm so deoptimized today!"
The doubles heard this and started to unbox.
-The Smi looked at them when a crazy v8-autoroll account showed up..
+The Smi looked at them when a crazy v8-autoroll account showed NaN..