diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-07-25 19:30:07 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-07-26 08:31:50 +0200 |
commit | 6a31d05340b22fc413ee83eaacd0a5565bbbe799 (patch) | |
tree | 78f9e1c2f417244842f6422f17e1816e70317100 /deps/v8/tools | |
parent | 4d94bb2b1f72b6b612983a517a39c5545724a3ad (diff) | |
download | android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.tar.gz android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.tar.bz2 android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.zip |
deps: update V8 to 6.8.275.24
PR-URL: https://github.com/nodejs/node/pull/21079
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Diffstat (limited to 'deps/v8/tools')
49 files changed, 2478 insertions, 2805 deletions
diff --git a/deps/v8/tools/codemap.js b/deps/v8/tools/codemap.js index df6770f9a8..1fa2c52e5c 100644 --- a/deps/v8/tools/codemap.js +++ b/deps/v8/tools/codemap.js @@ -178,6 +178,15 @@ CodeMap.prototype.findInTree_ = function(tree, addr) { return node && this.isAddressBelongsTo_(addr, node) ? node : null; }; +/** + * Embedded builtins are located in the shared library but should be attributed + * according to the dynamically generated code-create events. + * + * @private + */ +CodeMap.prototype.isEmbeddedBuiltin_ = function(entry) { + return entry.type == "CPP" && /v8_\w*embedded_blob_/.test(entry.name); +}; /** * Finds a code entry that contains the specified address. Both static and @@ -196,7 +205,10 @@ CodeMap.prototype.findAddress = function(addr) { result = this.findInTree_(this.libraries_, addr); if (!result) return null; } - return { entry : result.value, offset : addr - result.key }; + if (!this.isEmbeddedBuiltin_(result.value)) { + // Embedded builtins are handled in the following dynamic section. + return { entry : result.value, offset : addr - result.key }; + } } var min = this.dynamics_.findMin(); var max = this.dynamics_.findMax(); diff --git a/deps/v8/tools/dev/gm.py b/deps/v8/tools/dev/gm.py index 6dfd46bf7b..3513664c28 100755 --- a/deps/v8/tools/dev/gm.py +++ b/deps/v8/tools/dev/gm.py @@ -246,7 +246,7 @@ class Config(object): return_code, output = _CallWithOutput("autoninja -C %s %s" % (path, targets)) - if return_code != 0 and "FAILED: gen/snapshot.cc" in output: + if return_code != 0 and "FAILED: snapshot_blob.bin" in output: csa_trap = re.compile("Specify option( --csa-trap-on-node=[^ ]*)") match = csa_trap.search(output) extra_opt = match.group(1) if match else "" diff --git a/deps/v8/tools/format-torque.py b/deps/v8/tools/format-torque.py new file mode 100755 index 0000000000..3470d2f3c3 --- /dev/null +++ b/deps/v8/tools/format-torque.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright 2014 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 program either generates the parser files for Torque, generating +the source and header files directly in V8's src directory.""" + +import subprocess +import sys +import re +from subprocess import Popen, PIPE + +if len(sys.argv) < 2 or len(sys.argv) > 3: + print "invalid number of arguments" + sys.exit(-1) + +use_stdout = True +if len(sys.argv) == 3 and sys.argv[1] == '-i': + use_stdout = False + +filename = sys.argv[len(sys.argv) - 1] + +with open(filename, 'r') as content_file: + content = content_file.read() +p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE) +output, err = p.communicate(content) +rc = p.returncode +if (rc <> 0): + sys.exit(rc); +if use_stdout: + print output +else: + output_file = open(filename, 'w') + output_file.write(output); + output_file.close() diff --git a/deps/v8/tools/gcmole/BUILD.gn b/deps/v8/tools/gcmole/BUILD.gn index 65f11223ba..a77473f0f9 100644 --- a/deps/v8/tools/gcmole/BUILD.gn +++ b/deps/v8/tools/gcmole/BUILD.gn @@ -23,6 +23,11 @@ group("v8_run_gcmole") { "../../testing/gtest/include/gtest/gtest_prod.h", "../../third_party/googletest/src/googletest/include/gtest/gtest_prod.h", "../../third_party/icu/source/", + "$target_gen_dir/../../torque-generated/", + ] + + deps = [ + "../../:run_torque", ] if (v8_gcmole) { diff --git a/deps/v8/tools/gcmole/gcmole.lua b/deps/v8/tools/gcmole/gcmole.lua index d832041361..ae17fdc5f6 100644 --- a/deps/v8/tools/gcmole/gcmole.lua +++ b/deps/v8/tools/gcmole/gcmole.lua @@ -112,6 +112,7 @@ local function MakeClangCommandLine( .. " -DV8_INTL_SUPPORT" .. " -I./" .. " -Iinclude/" + .. " -Iout/Release/gen" .. " -Ithird_party/icu/source/common" .. " -Ithird_party/icu/source/i18n" .. " " .. arch_options diff --git a/deps/v8/tools/gcmole/run-gcmole.py b/deps/v8/tools/gcmole/run-gcmole.py index 88799e3d6c..cb4c74e31c 100755 --- a/deps/v8/tools/gcmole/run-gcmole.py +++ b/deps/v8/tools/gcmole/run-gcmole.py @@ -4,6 +4,7 @@ # found in the LICENSE file. import os +import os.path import signal import subprocess import sys @@ -17,6 +18,11 @@ BASE_PATH = os.path.dirname(os.path.dirname(GCMOLE_PATH)) assert len(sys.argv) == 2 +if not os.path.isfile("out/Release/gen/torque-generated/builtin-definitions-from-dsl.h"): + print "Expected generated headers in out/Release/gen." + print "Either build v8 in out/Release or change gcmole.lua:115" + sys.exit(-1) + proc = subprocess.Popen( [LUA, DRIVER, sys.argv[1]], env={'CLANG_BIN': CLANG_BIN, 'CLANG_PLUGINS': CLANG_PLUGINS}, diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py index fd9bf713da..97f2ac9c63 100644 --- a/deps/v8/tools/gen-postmortem-metadata.py +++ b/deps/v8/tools/gen-postmortem-metadata.py @@ -201,8 +201,8 @@ consts_misc = [ { 'name': 'jsarray_buffer_was_neutered_shift', 'value': 'JSArrayBuffer::WasNeutered::kShift' }, - { 'name': 'context_idx_closure', - 'value': 'Context::CLOSURE_INDEX' }, + { 'name': 'context_idx_scope_info', + 'value': 'Context::SCOPE_INFO_INDEX' }, { 'name': 'context_idx_native', 'value': 'Context::NATIVE_CONTEXT_INDEX' }, { 'name': 'context_idx_prev', @@ -211,9 +211,6 @@ consts_misc = [ 'value': 'Context::EXTENSION_INDEX' }, { 'name': 'context_min_slots', 'value': 'Context::MIN_CONTEXT_SLOTS' }, - { 'name': 'context_idx_embedder_data', - 'value': 'Internals::kContextEmbedderDataIndex' }, - { 'name': 'namedictionaryshape_prefix_size', 'value': 'NameDictionaryShape::kPrefixSize' }, @@ -234,8 +231,6 @@ consts_misc = [ 'value': 'SimpleNumberDictionaryShape::kPrefixSize' }, { 'name': 'simplenumberdictionaryshape_entry_size', 'value': 'SimpleNumberDictionaryShape::kEntrySize' }, - - { 'name': 'type_JSError__JS_ERROR_TYPE', 'value': 'JS_ERROR_TYPE' }, ]; # diff --git a/deps/v8/tools/grokdump.py b/deps/v8/tools/grokdump.py index 0246a18bfe..86239b118a 100755 --- a/deps/v8/tools/grokdump.py +++ b/deps/v8/tools/grokdump.py @@ -3323,7 +3323,7 @@ DUMP_FILE_RE = re.compile(r"[-_0-9a-zA-Z][-\._0-9a-zA-Z]*\.dmp$") class InspectionWebServer(BaseHTTPServer.HTTPServer): def __init__(self, port_number, switches, minidump_name): BaseHTTPServer.HTTPServer.__init__( - self, ('', port_number), InspectionWebHandler) + self, ('localhost', port_number), InspectionWebHandler) splitpath = os.path.split(minidump_name) self.dumppath = splitpath[0] self.dumpfilename = splitpath[1] diff --git a/deps/v8/tools/heap-stats/details-selection.html b/deps/v8/tools/heap-stats/details-selection.html index 67a27ae284..04b274a8d1 100644 --- a/deps/v8/tools/heap-stats/details-selection.html +++ b/deps/v8/tools/heap-stats/details-selection.html @@ -100,18 +100,20 @@ found in the LICENSE file. --> </select> </li> <li> - <label for="dataset-select"> - Data set + <label for="data-view-select"> + Data view </label> - <select id="dataset-select"> + <select id="data-view-select"> <option>No data</option> </select> </li> <li> - <input type="checkbox" id="merge-categories" checked=checked /> - <label for="merge-categories"> - Merge categories + <label for="dataset-select"> + Data set </label> + <select id="dataset-select"> + <option>No data</option> + </select> </li> <li> <label for="gc-select"> diff --git a/deps/v8/tools/heap-stats/details-selection.js b/deps/v8/tools/heap-stats/details-selection.js index 5e9ffc5f94..1e9cc83cff 100644 --- a/deps/v8/tools/heap-stats/details-selection.js +++ b/deps/v8/tools/heap-stats/details-selection.js @@ -8,6 +8,10 @@ const details_selection_template = document.currentScript.ownerDocument.querySelector( '#details-selection-template'); +const VIEW_BY_INSTANCE_TYPE = 'by-instance-type'; +const VIEW_BY_INSTANCE_CATEGORY = 'by-instance-category'; +const VIEW_BY_FIELD_TYPE = 'by-field-type'; + class DetailsSelection extends HTMLElement { constructor() { super(); @@ -15,14 +19,14 @@ class DetailsSelection extends HTMLElement { shadowRoot.appendChild(details_selection_template.content.cloneNode(true)); this.isolateSelect.addEventListener( 'change', e => this.handleIsolateChange(e)); + this.dataViewSelect.addEventListener( + 'change', e => this.notifySelectionChanged(e)); this.datasetSelect.addEventListener( 'change', e => this.notifySelectionChanged(e)); this.gcSelect.addEventListener( - 'change', e => this.notifySelectionChanged(e)); + 'change', e => this.notifySelectionChanged(e)); this.$('#csv-export-btn') .addEventListener('click', e => this.exportCurrentSelection(e)); - this.$('#merge-categories') - .addEventListener('change', e => this.notifySelectionChanged(e)); this.$('#category-filter-btn') .addEventListener('click', e => this.filterCurrentSelection(e)); this.$('#category-auto-filter-btn') @@ -62,6 +66,10 @@ class DetailsSelection extends HTMLElement { return this.shadowRoot.querySelectorAll(query); } + get dataViewSelect() { + return this.$('#data-view-select'); + } + get datasetSelect() { return this.$('#dataset-select'); } @@ -128,6 +136,7 @@ class DetailsSelection extends HTMLElement { resetUI(resetIsolateSelect) { if (resetIsolateSelect) removeAllChildren(this.isolateSelect); + removeAllChildren(this.dataViewSelect); removeAllChildren(this.datasetSelect); removeAllChildren(this.gcSelect); this.clearCategories(); @@ -149,6 +158,13 @@ class DetailsSelection extends HTMLElement { } this.resetUI(false); this.populateSelect( + '#data-view-select', [ + [VIEW_BY_INSTANCE_TYPE, 'Selected instance types'], + [VIEW_BY_INSTANCE_CATEGORY, 'Selected type categories'], + [VIEW_BY_FIELD_TYPE, 'Field type statistics'] + ], + (key, label) => label, VIEW_BY_INSTANCE_TYPE); + this.populateSelect( '#dataset-select', this.selectedIsolate.data_sets.entries(), null, 'live'); this.populateSelect( @@ -168,14 +184,19 @@ class DetailsSelection extends HTMLElement { notifySelectionChanged(e) { if (!this.selection.isolate) return; + this.selection.data_view = this.dataViewSelect.value; this.selection.categories = {}; - for (let category of CATEGORIES.keys()) { - const selected = this.selectedInCategory(category); - if (selected.length > 0) this.selection.categories[category] = selected; + if (this.selection.data_view === VIEW_BY_FIELD_TYPE) { + this.$('#categories').style.display = 'none'; + } else { + for (let category of CATEGORIES.keys()) { + const selected = this.selectedInCategory(category); + if (selected.length > 0) this.selection.categories[category] = selected; + } + this.$('#categories').style.display = 'block'; } this.selection.category_names = CATEGORY_NAMES; this.selection.data_set = this.datasetSelect.value; - this.selection.merge_categories = this.$('#merge-categories').checked; this.selection.gc = this.gcSelect.value; this.setButtonState(false); this.updatePercentagesInCategory(); diff --git a/deps/v8/tools/heap-stats/global-timeline.js b/deps/v8/tools/heap-stats/global-timeline.js index a32cf59135..1c9d4028a1 100644 --- a/deps/v8/tools/heap-stats/global-timeline.js +++ b/deps/v8/tools/heap-stats/global-timeline.js @@ -57,6 +57,26 @@ class GlobalTimeline extends HTMLElement { } } + getFieldData() { + const labels = ['Time', 'Ptr compression benefit', 'Embedder fields', + 'Tagged fields', 'Other raw fields', 'Unboxed doubles']; + const chart_data = [labels]; + const isolate_data = this.data[this.selection.isolate]; + Object.keys(isolate_data.gcs).forEach(gc_key => { + const gc_data = isolate_data.gcs[gc_key]; + const data_set = gc_data[this.selection.data_set].field_data; + const data = []; + data.push(gc_data.time * kMillis2Seconds); + data.push(data_set.tagged_fields / KB / 2); // Pointer compression benefit + data.push(data_set.embedder_fields / KB); + data.push(data_set.tagged_fields / KB); + data.push(data_set.other_raw_fields / KB); + data.push(data_set.unboxed_double_fields / KB); + chart_data.push(data); + }); + return chart_data; + } + getCategoryData() { const categories = Object.keys(this.selection.categories) .map(k => this.selection.category_names.get(k)); @@ -102,14 +122,19 @@ class GlobalTimeline extends HTMLElement { return chart_data; } - drawChart() { - console.assert(this.data, 'invalid data'); - console.assert(this.selection, 'invalid selection'); + getChartData() { + switch (this.selection.data_view) { + case VIEW_BY_FIELD_TYPE: + return this.getFieldData(); + case VIEW_BY_INSTANCE_CATEGORY: + return this.getCategoryData(); + case VIEW_BY_INSTANCE_TYPE: + default: + return this.getInstanceTypeData(); + } + } - const chart_data = (this.selection.merge_categories) ? - this.getCategoryData() : - this.getInstanceTypeData(); - const data = google.visualization.arrayToDataTable(chart_data); + getChartOptions() { const options = { isStacked: true, hAxis: { @@ -126,6 +151,27 @@ class GlobalTimeline extends HTMLElement { pointSize: 5, explorer: {}, }; + switch (this.selection.data_view) { + case VIEW_BY_FIELD_TYPE: + // Overlay pointer compression benefit on top of the graph + return Object.assign(options, { + series: {0: {type: 'line', lineDashStyle: [13, 13]}}, + }); + case VIEW_BY_INSTANCE_CATEGORY: + case VIEW_BY_INSTANCE_TYPE: + default: + return options; + } + } + + drawChart() { + console.assert(this.data, 'invalid data'); + console.assert(this.selection, 'invalid selection'); + + const chart_data = this.getChartData(); + + const data = google.visualization.arrayToDataTable(chart_data); + const options = this.getChartOptions(); const chart = new google.visualization.AreaChart(this.$('#chart')); this.show(); chart.draw(data, google.charts.Line.convertOptions(options)); diff --git a/deps/v8/tools/heap-stats/histogram-viewer.js b/deps/v8/tools/heap-stats/histogram-viewer.js index d252f4cb1b..240c6cbc7e 100644 --- a/deps/v8/tools/heap-stats/histogram-viewer.js +++ b/deps/v8/tools/heap-stats/histogram-viewer.js @@ -38,7 +38,10 @@ class HistogramViewer extends HTMLElement { } isValid() { - return this.data && this.selection; + return this.data && this.selection && + (this.selection.data_view === VIEW_BY_INSTANCE_CATEGORY || + this.selection.data_view === VIEW_BY_INSTANCE_TYPE); + ; } hide() { @@ -49,11 +52,21 @@ class HistogramViewer extends HTMLElement { this.$('#container').style.display = 'block'; } + getOverallValue() { + switch (this.selection.data_view) { + case VIEW_BY_FIELD_TYPE: + return NaN; + case VIEW_BY_INSTANCE_CATEGORY: + return this.getPropertyForCategory('overall'); + case VIEW_BY_INSTANCE_TYPE: + default: + return this.getPropertyForInstanceTypes('overall'); + } + } + stateChanged() { if (this.isValid()) { - const overall_bytes = (this.selection.merge_categories) ? - this.getPropertyForCategory('overall') : - this.getPropertyForInstanceTypes('overall'); + const overall_bytes = this.getOverallValue(); this.$('#overall').innerHTML = `Overall: ${overall_bytes / KB} KB`; this.drawChart(); } else { @@ -143,10 +156,20 @@ class HistogramViewer extends HTMLElement { return [labels, ...data]; } + getChartData() { + switch (this.selection.data_view) { + case VIEW_BY_FIELD_TYPE: + return this.getFieldData(); + case VIEW_BY_INSTANCE_CATEGORY: + return this.getCategoryData(); + case VIEW_BY_INSTANCE_TYPE: + default: + return this.getInstanceTypeData(); + } + } + drawChart() { - const chart_data = (this.selection.merge_categories) ? - this.getCategoryData() : - this.getInstanceTypeData(); + const chart_data = this.getChartData(); const data = google.visualization.arrayToDataTable(chart_data); const options = { legend: {position: 'top', maxLines: '1'}, diff --git a/deps/v8/tools/heap-stats/trace-file-reader.js b/deps/v8/tools/heap-stats/trace-file-reader.js index 4ad1269835..03684978de 100644 --- a/deps/v8/tools/heap-stats/trace-file-reader.js +++ b/deps/v8/tools/heap-stats/trace-file-reader.js @@ -126,6 +126,16 @@ class TraceFileReader extends HTMLElement { } } + addFieldTypeData(data, isolate, gc_id, data_set, tagged_fields, + embedder_fields, unboxed_double_fields, other_raw_fields) { + data[isolate].gcs[gc_id][data_set].field_data = { + tagged_fields, + embedder_fields, + unboxed_double_fields, + other_raw_fields + }; + } + addInstanceTypeData(data, isolate, gc_id, data_set, instance_type, entry) { data[isolate].gcs[gc_id][data_set].instance_type_data[instance_type] = { overall: entry.overall, @@ -194,6 +204,13 @@ class TraceFileReader extends HTMLElement { const time = entry.time; const gc_id = entry.id; data[isolate].gcs[gc_id].time = time; + + const field_data = entry.field_data; + this.addFieldTypeData(data, isolate, gc_id, data_set, + field_data.tagged_fields, field_data.embedder_fields, + field_data.unboxed_double_fields, + field_data.other_raw_fields); + data[isolate].gcs[gc_id][data_set].bucket_sizes = entry.bucket_sizes; for (let [instance_type, value] of Object.entries( @@ -251,6 +268,12 @@ class TraceFileReader extends HTMLElement { data[entry.isolate].gcs[entry.id].time = entry.time; if ('zone' in entry) data[entry.isolate].gcs[entry.id].malloced = entry.zone; + } else if (entry.type === 'field_data') { + this.createOrUpdateEntryIfNeeded(data, entry); + this.createDatasetIfNeeded(data, entry, entry.key); + this.addFieldTypeData(data, entry.isolate, entry.id, entry.key, + entry.tagged_fields, entry.embedder_fields, + entry.unboxed_double_fields, entry.other_raw_fields); } else if (entry.type === 'instance_type_data') { if (entry.id in data[entry.isolate].gcs) { this.createOrUpdateEntryIfNeeded(data, entry); diff --git a/deps/v8/tools/make-torque-parser.py b/deps/v8/tools/make-torque-parser.py new file mode 100755 index 0000000000..43ed7840cc --- /dev/null +++ b/deps/v8/tools/make-torque-parser.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# Copyright 2014 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 program either generates the parser files for Torque, generating +the source and header files directly in V8's src directory.""" + +import subprocess +import sys +import os +import ntpath +import re + +cwd = os.getcwd() +tools = ntpath.dirname(sys.argv[0]); +grammar = tools + '/../src/torque/Torque.g4' +basename = ntpath.basename(grammar) +dirname = ntpath.dirname(grammar) +os.chdir(dirname) +cargs = ['java', '-Xmx500M', 'org.antlr.v4.Tool', '-visitor', basename] +result = subprocess.call(cargs) +os.chdir(cwd) + +def fix_file(filename): + is_header = re.search(r'\.h', filename) <> None; + header_macro = filename.upper(); + header_macro = re.sub('\.', '_', header_macro); + header_macro = "V8_TORQUE_" + header_macro + '_'; + + copyright = '// Copyright 2018 the V8 project authors. All rights reserved.\n' + copyright += '// Use of this source code is governed by a BSD-style license that can be\n' + copyright += '// found in the LICENSE file.\n' + file_path = tools + '/../src/torque/' + filename; + temp_file_path = file_path + '.tmp' + output_file = open(temp_file_path, 'w') + output_file.write(copyright); + if is_header: + output_file.write('#ifndef ' + header_macro + '\n'); + output_file.write('#define ' + header_macro + '\n'); + + with open(file_path) as f: + content = f.readlines() + for x in content: + x = re.sub(';;', ';', x) + x = re.sub('antlr4-runtime\.h', './antlr4-runtime.h', x) + x = re.sub(' TorqueParser.antlr4', ' explicit TorqueParser(antlr4', x) + x = re.sub(' TorqueLexer.antlr4', ' explicit TorqueLexer(antlr4', x) + if not re.search('= 0', x): + x = re.sub('virtual', '', x) + output_file.write(x) + + if is_header: + output_file.write('#endif // ' + header_macro + '\n'); + output_file.close(); + + subprocess.call(['rm', file_path]) + subprocess.call(['mv', temp_file_path, file_path]) + +fix_file('TorqueBaseListener.h'); +fix_file('TorqueBaseListener.cpp'); +fix_file('TorqueBaseVisitor.h'); +fix_file('TorqueBaseVisitor.cpp'); +fix_file('TorqueLexer.h'); +fix_file('TorqueLexer.cpp'); +fix_file('TorqueParser.h'); +fix_file('TorqueParser.cpp'); +fix_file('TorqueListener.h'); +fix_file('TorqueListener.cpp'); +fix_file('TorqueVisitor.h'); +fix_file('TorqueVisitor.cpp'); diff --git a/deps/v8/tools/node/build_gn.py b/deps/v8/tools/node/build_gn.py index e95c3491e7..83071adbfe 100755 --- a/deps/v8/tools/node/build_gn.py +++ b/deps/v8/tools/node/build_gn.py @@ -25,15 +25,20 @@ import sys import node_common GN_ARGS = [ - "v8_monolithic = true", - "is_component_build = false", - "v8_use_external_startup_data = false", - "use_custom_libcxx = false", - "use_sysroot = false", + "v8_monolithic=true", + "is_component_build=false", + "v8_use_external_startup_data=false", + "use_custom_libcxx=false", ] BUILD_TARGET = "v8_monolith" +def FindTargetOs(flags): + for flag in flags: + if flag.startswith("target_os="): + return flag[len("target_os="):].strip('"') + raise Exception('No target_os was set.') + def FindGn(options): if options.host_os == "linux": os_path = "linux64" @@ -46,57 +51,93 @@ def FindGn(options): return os.path.join(options.v8_path, "buildtools", os_path, "gn") def GenerateBuildFiles(options): - print "Setting GN args." gn = FindGn(options) - gn_args = [] - gn_args.extend(GN_ARGS) + gn_args = list(GN_ARGS) + target_os = FindTargetOs(options.flag) + if target_os != "win": + gn_args.append("use_sysroot=false") + for flag in options.flag: flag = flag.replace("=1", "=true") flag = flag.replace("=0", "=false") flag = flag.replace("target_cpu=ia32", "target_cpu=\"x86\"") gn_args.append(flag) - if options.mode == "DEBUG": - gn_args.append("is_debug = true") + if options.mode == "Debug": + gn_args.append("is_debug=true") else: - gn_args.append("is_debug = false") + gn_args.append("is_debug=false") + + flattened_args = ' '.join(gn_args) + if options.extra_gn_args: + flattened_args += ' ' + options.extra_gn_args - if not os.path.isdir(options.build_path): - os.makedirs(options.build_path) - with open(os.path.join(options.build_path, "args.gn"), "w") as args_file: - args_file.write("\n".join(gn_args)) - subprocess.check_call([gn, "gen", "-C", options.build_path], - cwd=options.v8_path) + args = [gn, "gen", options.build_path, "-q", "--args=" + flattened_args] + subprocess.check_call(args) def Build(options): - print "Building." depot_tools = node_common.EnsureDepotTools(options.v8_path, False) ninja = os.path.join(depot_tools, "ninja") - subprocess.check_call([ninja, "-v", "-C", options.build_path, BUILD_TARGET], - cwd=options.v8_path) + if sys.platform == 'win32': + # Required because there is an extension-less file called "ninja". + ninja += ".exe" + args = [ninja, "-C", options.build_path, BUILD_TARGET] + if options.max_load: + args += ["-l" + options.max_load] + if options.max_jobs: + args += ["-j" + options.max_jobs] + else: + with open(os.path.join(options.build_path, "args.gn")) as f: + if "use_goma = true" in f.read(): + args += ["-j500"] + subprocess.check_call(args) def ParseOptions(args): parser = argparse.ArgumentParser( description="Build %s with GN" % BUILD_TARGET) parser.add_argument("--mode", help="Build mode (Release/Debug)") - parser.add_argument("--v8_path", help="Path to V8") - parser.add_argument("--build_path", help="Path to build result") + parser.add_argument("--v8_path", help="Path to V8", required=True) + parser.add_argument("--build_path", help="Path to build result", + required=True) parser.add_argument("--flag", help="Translate GYP flag to GN", action="append") parser.add_argument("--host_os", help="Current operating system") + parser.add_argument("--bundled-win-toolchain", + help="Value for DEPOT_TOOLS_WIN_TOOLCHAIN") + parser.add_argument("--bundled-win-toolchain-root", + help="Value for DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT") + parser.add_argument("--depot-tools", help="Absolute path to depot_tools") + parser.add_argument("--extra-gn-args", help="Additional GN args") + parser.add_argument("--build", help="Run ninja as opposed to gn gen.", + action="store_true") + parser.add_argument("--max-jobs", help="ninja's -j parameter") + parser.add_argument("--max-load", help="ninja's -l parameter") options = parser.parse_args(args) - assert options.host_os - assert options.mode == "Debug" or options.mode == "Release" + options.build_path = os.path.abspath(options.build_path) - assert options.v8_path - options.v8_path = os.path.abspath(options.v8_path) - assert os.path.isdir(options.v8_path) + if not options.build: + assert options.host_os + assert options.mode == "Debug" or options.mode == "Release" + + options.v8_path = os.path.abspath(options.v8_path) + assert os.path.isdir(options.v8_path) - assert options.build_path - options.build_path = os.path.abspath(options.build_path) return options + if __name__ == "__main__": options = ParseOptions(sys.argv[1:]) - GenerateBuildFiles(options) - Build(options) + # Build can result in running gn gen, so need to set environment variables + # for build as well as generate. + if options.bundled_win_toolchain: + os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN'] = options.bundled_win_toolchain + if options.bundled_win_toolchain_root: + os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT'] = ( + options.bundled_win_toolchain_root) + if options.depot_tools: + os.environ['PATH'] = ( + options.depot_tools + os.path.pathsep + os.environ['PATH']) + if not options.build: + GenerateBuildFiles(options) + else: + Build(options) diff --git a/deps/v8/tools/node/fetch_deps.py b/deps/v8/tools/node/fetch_deps.py index 945dbb7677..26b9d6a72f 100755 --- a/deps/v8/tools/node/fetch_deps.py +++ b/deps/v8/tools/node/fetch_deps.py @@ -43,18 +43,21 @@ GCLIENT_SOLUTION = [ ] def EnsureGit(v8_path): + def git(args): + # shell=True needed on Windows to resolve git.bat. + return subprocess.check_output( + "git " + args, cwd=v8_path, shell=True).strip() + expected_git_dir = os.path.join(v8_path, ".git") - actual_git_dir = subprocess.check_output( - ["git", "rev-parse", "--absolute-git-dir"], cwd=v8_path).strip() + actual_git_dir = git("rev-parse --absolute-git-dir") if expected_git_dir == actual_git_dir: print "V8 is tracked stand-alone by git." return False print "Initializing temporary git repository in v8." - subprocess.check_call(["git", "init"], cwd=v8_path) - subprocess.check_call(["git", "config", "user.name", "\"Ada Lovelace\""], cwd=v8_path) - subprocess.check_call(["git", "config", "user.email", "\"ada@lovela.ce\""], cwd=v8_path) - subprocess.check_call(["git", "commit", "--allow-empty", "-m", "init"], - cwd=v8_path) + git("init") + git("config user.name \"Ada Lovelace\"") + git("config user.email ada@lovela.ce") + git("commit --allow-empty -m init") return True def FetchDeps(v8_path): @@ -86,8 +89,8 @@ def FetchDeps(v8_path): os.path.join(v8_path, os.pardir, ".gclient_entries")) if os.path.isfile(gclient_entries): os.remove(gclient_entries) - # Enable building with GN for configure script. - return True + + return depot_tools if __name__ == "__main__": diff --git a/deps/v8/tools/node/node_common.py b/deps/v8/tools/node/node_common.py index 72fbd9641a..de2e98d909 100755 --- a/deps/v8/tools/node/node_common.py +++ b/deps/v8/tools/node/node_common.py @@ -4,6 +4,7 @@ # found in the LICENSE file. import os +import pipes import shutil import stat import subprocess @@ -22,7 +23,10 @@ def EnsureDepotTools(v8_path, fetch_if_not_exist): pass if fetch_if_not_exist: print "Checking out depot_tools." - subprocess.check_call(["git", "clone", DEPOT_TOOLS_URL, depot_tools]) + # shell=True needed on Windows to resolve git.bat. + subprocess.check_call("git clone {} {}".format( + pipes.quote(DEPOT_TOOLS_URL), + pipes.quote(depot_tools)), shell=True) return depot_tools return None depot_tools = _Get(v8_path) diff --git a/deps/v8/tools/parser-shell.cc b/deps/v8/tools/parser-shell.cc deleted file mode 100644 index bcee2b8258..0000000000 --- a/deps/v8/tools/parser-shell.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2014 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. - -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <string> -#include <vector> -#include "src/v8.h" - -#include "include/libplatform/libplatform.h" -#include "src/api.h" -#include "src/compiler.h" -#include "src/objects-inl.h" -#include "src/parsing/parse-info.h" -#include "src/parsing/parsing.h" -#include "src/parsing/preparse-data.h" -#include "src/parsing/preparser.h" -#include "src/parsing/scanner-character-streams.h" -#include "tools/shell-utils.h" - -using namespace v8::internal; - -class StringResource8 : public v8::String::ExternalOneByteStringResource { - public: - StringResource8(const char* data, int length) - : data_(data), length_(length) { } - virtual size_t length() const { return length_; } - virtual const char* data() const { return data_; } - - private: - const char* data_; - int length_; -}; - -v8::base::TimeDelta RunBaselineParser(const char* fname, Encoding encoding, - int repeat, v8::Isolate* isolate, - v8::Local<v8::Context> context) { - int length = 0; - const byte* source = ReadFileAndRepeat(fname, &length, repeat); - v8::Local<v8::String> source_handle; - switch (encoding) { - case UTF8: { - source_handle = v8::String::NewFromUtf8( - isolate, reinterpret_cast<const char*>(source), - v8::NewStringType::kNormal).ToLocalChecked(); - break; - } - case UTF16: { - source_handle = - v8::String::NewFromTwoByte( - isolate, reinterpret_cast<const uint16_t*>(source), - v8::NewStringType::kNormal, length / 2).ToLocalChecked(); - break; - } - case LATIN1: { - StringResource8* string_resource = - new StringResource8(reinterpret_cast<const char*>(source), length); - source_handle = v8::String::NewExternalOneByte(isolate, string_resource) - .ToLocalChecked(); - break; - } - } - v8::base::TimeDelta parse_time1; - Handle<Script> script = - reinterpret_cast<i::Isolate*>(isolate)->factory()->NewScript( - v8::Utils::OpenHandle(*source_handle)); - ParseInfo info(script); - v8::base::ElapsedTimer timer; - timer.Start(); - bool success = - parsing::ParseProgram(&info, reinterpret_cast<i::Isolate*>(isolate)); - parse_time1 = timer.Elapsed(); - if (!success) { - fprintf(stderr, "Parsing failed\n"); - return v8::base::TimeDelta(); - } - return parse_time1; -} - - -int main(int argc, char* argv[]) { - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - v8::V8::InitializeICUDefaultLocation(argv[0]); - std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); - v8::V8::InitializePlatform(platform.get()); - v8::V8::Initialize(); - v8::V8::InitializeExternalStartupData(argv[0]); - - Encoding encoding = LATIN1; - std::vector<std::string> fnames; - std::string benchmark; - int repeat = 1; - for (int i = 0; i < argc; ++i) { - if (strcmp(argv[i], "--latin1") == 0) { - encoding = LATIN1; - } else if (strcmp(argv[i], "--utf8") == 0) { - encoding = UTF8; - } else if (strcmp(argv[i], "--utf16") == 0) { - encoding = UTF16; - } else if (strncmp(argv[i], "--benchmark=", 12) == 0) { - benchmark = std::string(argv[i]).substr(12); - } else if (strncmp(argv[i], "--repeat=", 9) == 0) { - std::string repeat_str = std::string(argv[i]).substr(9); - repeat = atoi(repeat_str.c_str()); - } else if (i > 0 && argv[i][0] != '-') { - fnames.push_back(std::string(argv[i])); - } - } - v8::Isolate::CreateParams create_params; - create_params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); - v8::Isolate* isolate = v8::Isolate::New(create_params); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); - DCHECK(!context.IsEmpty()); - { - v8::Context::Scope scope(context); - double first_parse_total = 0; - for (size_t i = 0; i < fnames.size(); i++) { - v8::base::TimeDelta time = RunBaselineParser( - fnames[i].c_str(), encoding, repeat, isolate, context); - first_parse_total += time.InMillisecondsF(); - } - if (benchmark.empty()) benchmark = "Baseline"; - printf("%s(ParseRunTime): %.f ms\n", benchmark.c_str(), - first_parse_total); - } - } - v8::V8::Dispose(); - v8::V8::ShutdownPlatform(); - delete create_params.array_buffer_allocator; - return 0; -} diff --git a/deps/v8/tools/presubmit.py b/deps/v8/tools/presubmit.py index 29469be758..40d4630ec7 100755 --- a/deps/v8/tools/presubmit.py +++ b/deps/v8/tools/presubmit.py @@ -283,7 +283,7 @@ class SourceProcessor(SourceFileProcessor): Check that all files include a copyright notice and no trailing whitespaces. """ - RELEVANT_EXTENSIONS = ['.js', '.cc', '.h', '.py', '.c', '.status'] + RELEVANT_EXTENSIONS = ['.js', '.cc', '.h', '.py', '.c', '.status', '.tq', '.g4'] def __init__(self): self.runtime_function_call_pattern = self.CreateRuntimeFunctionCallMatcher() diff --git a/deps/v8/tools/release/auto_roll.py b/deps/v8/tools/release/auto_roll.py index ea83bfcd36..83c3d343aa 100755 --- a/deps/v8/tools/release/auto_roll.py +++ b/deps/v8/tools/release/auto_roll.py @@ -20,7 +20,7 @@ Please close rolling in case of a roll revert: https://v8-roll.appspot.com/ This only works with a Google account. -CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel""") +CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel""") class Preparation(Step): MESSAGE = "Preparation." diff --git a/deps/v8/tools/release/common_includes.py b/deps/v8/tools/release/common_includes.py index 5dd60df459..0f12d910da 100644 --- a/deps/v8/tools/release/common_includes.py +++ b/deps/v8/tools/release/common_includes.py @@ -57,6 +57,13 @@ RELEASE_WORKDIR = "/tmp/v8-release-scripts-work-dir/" V8_BASE = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +# Add our copy of depot_tools to the PATH as many scripts use tools from there, +# e.g. git-cl, fetch, git-new-branch etc, and we can not depend on depot_tools +# being in the PATH on the LUCI bots. +path_to_depot_tools = os.path.join(V8_BASE, 'third_party', 'depot_tools') +new_path = path_to_depot_tools + os.pathsep + os.environ.get('PATH') +os.environ['PATH'] = new_path + def TextToFile(text, file_name): with open(file_name, "w") as f: @@ -760,16 +767,24 @@ class UploadStep(Step): MESSAGE = "Upload for code review." def RunStep(self): + reviewer = None if self._options.reviewer: print "Using account %s for review." % self._options.reviewer reviewer = self._options.reviewer - else: + + tbr_reviewer = None + if self._options.tbr_reviewer: + print "Using account %s for TBR review." % self._options.tbr_reviewer + tbr_reviewer = self._options.tbr_reviewer + + if not reviewer and not tbr_reviewer: print "Please enter the email address of a V8 reviewer for your patch: ", self.DieNoManualMode("A reviewer must be specified in forced mode.") reviewer = self.ReadLine() + self.GitUpload(reviewer, self._options.author, self._options.force_upload, bypass_hooks=self._options.bypass_upload_hooks, - cc=self._options.cc) + cc=self._options.cc, tbr_reviewer=tbr_reviewer) def MakeStep(step_class=Step, number=0, state=None, config=None, @@ -822,6 +837,8 @@ class ScriptsBase(object): help="File to write results summary to.") parser.add_argument("-r", "--reviewer", default="", help="The account name to be used for reviews.") + parser.add_argument("--tbr-reviewer", "--tbr", default="", + help="The account name to be used for TBR reviews.") parser.add_argument("-s", "--step", help="Specify the step where to start work. Default: 0.", default=0, type=int) @@ -866,6 +883,11 @@ class ScriptsBase(object): if not options: return 1 + # Ensure temp dir exists for state files. + state_dir = os.path.dirname(self._config["PERSISTFILE_BASENAME"]) + if not os.path.exists(state_dir): + os.makedirs(state_dir) + state_file = "%s-state.json" % self._config["PERSISTFILE_BASENAME"] if options.step == 0 and os.path.exists(state_file): os.remove(state_file) diff --git a/deps/v8/tools/release/git_recipes.py b/deps/v8/tools/release/git_recipes.py index 9dedae8a93..9deaee891b 100644 --- a/deps/v8/tools/release/git_recipes.py +++ b/deps/v8/tools/release/git_recipes.py @@ -207,12 +207,14 @@ class GitRecipesMixin(object): def GitUpload(self, reviewer="", author="", force=False, cq=False, cq_dry_run=False, bypass_hooks=False, cc="", private=False, - **kwargs): + tbr_reviewer="", **kwargs): args = ["cl upload --send-mail"] if author: args += ["--email", Quoted(author)] if reviewer: args += ["-r", Quoted(reviewer)] + if tbr_reviewer: + args += ["--tbrs", Quoted(tbr_reviewer)] if force: args.append("-f") if cq: diff --git a/deps/v8/tools/release/releases.py b/deps/v8/tools/release/releases.py deleted file mode 100755 index 7b659ccb80..0000000000 --- a/deps/v8/tools/release/releases.py +++ /dev/null @@ -1,576 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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 retrieves the history of all V8 branches and -# their corresponding Chromium revisions. - -# Requires a chromium checkout with branch heads: -# gclient sync --with_branch_heads -# gclient fetch - -import argparse -import csv -import itertools -import json -import os -import re -import sys - -from common_includes import * - -CONFIG = { - "BRANCHNAME": "retrieve-v8-releases", - "PERSISTFILE_BASENAME": "/tmp/v8-releases-tempfile", -} - -# Expression for retrieving the bleeding edge revision from a commit message. -PUSH_MSG_SVN_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") -PUSH_MSG_GIT_RE = re.compile(r".* \(based on ([a-fA-F0-9]+)\)$") - -# Expression for retrieving the merged patches from a merge commit message -# (old and new format). -MERGE_MESSAGE_RE = re.compile(r"^.*[M|m]erged (.+)(\)| into).*$", re.M) - -CHERRY_PICK_TITLE_GIT_RE = re.compile(r"^.* \(cherry\-pick\)\.?$") - -# New git message for cherry-picked CLs. One message per line. -MERGE_MESSAGE_GIT_RE = re.compile(r"^Merged ([a-fA-F0-9]+)\.?$") - -# Expression for retrieving reverted patches from a commit message (old and -# new format). -ROLLBACK_MESSAGE_RE = re.compile(r"^.*[R|r]ollback of (.+)(\)| in).*$", re.M) - -# New git message for reverted CLs. One message per line. -ROLLBACK_MESSAGE_GIT_RE = re.compile(r"^Rollback of ([a-fA-F0-9]+)\.?$") - -# Expression for retrieving the code review link. -REVIEW_LINK_RE = re.compile(r"^Review URL: (.+)$", re.M) - -# Expression with three versions (historical) for extracting the v8 revision -# from the chromium DEPS file. -DEPS_RE = re.compile(r"""^\s*(?:["']v8_revision["']: ["']""" - """|\(Var\("googlecode_url"\) % "v8"\) \+ "\/trunk@""" - """|"http\:\/\/v8\.googlecode\.com\/svn\/trunk@)""" - """([^"']+)["'].*$""", re.M) - -# Expression to pick tag and revision for bleeding edge tags. To be used with -# output of 'svn log'. -BLEEDING_EDGE_TAGS_RE = re.compile( - r"A \/tags\/([^\s]+) \(from \/branches\/bleeding_edge\:(\d+)\)") - -OMAHA_PROXY_URL = "http://omahaproxy.appspot.com/" - -def SortBranches(branches): - """Sort branches with version number names.""" - return sorted(branches, key=SortingKey, reverse=True) - - -def FilterDuplicatesAndReverse(cr_releases): - """Returns the chromium releases in reverse order filtered by v8 revision - duplicates. - - cr_releases is a list of [cr_rev, v8_hsh] reverse-sorted by cr_rev. - """ - last = "" - result = [] - for release in reversed(cr_releases): - if last == release[1]: - continue - last = release[1] - result.append(release) - return result - - -def BuildRevisionRanges(cr_releases): - """Returns a mapping of v8 revision -> chromium ranges. - The ranges are comma-separated, each range has the form R1:R2. The newest - entry is the only one of the form R1, as there is no end range. - - cr_releases is a list of [cr_rev, v8_hsh] reverse-sorted by cr_rev. - cr_rev either refers to a chromium commit position or a chromium branch - number. - """ - range_lists = {} - cr_releases = FilterDuplicatesAndReverse(cr_releases) - - # Visit pairs of cr releases from oldest to newest. - for cr_from, cr_to in itertools.izip( - cr_releases, itertools.islice(cr_releases, 1, None)): - - # Assume the chromium revisions are all different. - assert cr_from[0] != cr_to[0] - - ran = "%s:%d" % (cr_from[0], int(cr_to[0]) - 1) - - # Collect the ranges in lists per revision. - range_lists.setdefault(cr_from[1], []).append(ran) - - # Add the newest revision. - if cr_releases: - range_lists.setdefault(cr_releases[-1][1], []).append(cr_releases[-1][0]) - - # Stringify and comma-separate the range lists. - return dict((hsh, ", ".join(ran)) for hsh, ran in range_lists.iteritems()) - - -def MatchSafe(match): - if match: - return match.group(1) - else: - return "" - - -class Preparation(Step): - MESSAGE = "Preparation." - - def RunStep(self): - self.CommonPrepare() - self.PrepareBranch() - - -class RetrieveV8Releases(Step): - MESSAGE = "Retrieve all V8 releases." - - def ExceedsMax(self, releases): - return (self._options.max_releases > 0 - and len(releases) > self._options.max_releases) - - def GetMasterHashFromPush(self, title): - return MatchSafe(PUSH_MSG_GIT_RE.match(title)) - - def GetMergedPatches(self, body): - patches = MatchSafe(MERGE_MESSAGE_RE.search(body)) - if not patches: - patches = MatchSafe(ROLLBACK_MESSAGE_RE.search(body)) - if patches: - # Indicate reverted patches with a "-". - patches = "-%s" % patches - return patches - - def GetMergedPatchesGit(self, body): - patches = [] - for line in body.splitlines(): - patch = MatchSafe(MERGE_MESSAGE_GIT_RE.match(line)) - if patch: - patches.append(patch) - patch = MatchSafe(ROLLBACK_MESSAGE_GIT_RE.match(line)) - if patch: - patches.append("-%s" % patch) - return ", ".join(patches) - - - def GetReleaseDict( - self, git_hash, master_position, master_hash, branch, version, - patches, cl_body): - revision = self.GetCommitPositionNumber(git_hash) - return { - # The cr commit position number on the branch. - "revision": revision, - # The git revision on the branch. - "revision_git": git_hash, - # The cr commit position number on master. - "master_position": master_position, - # The same for git. - "master_hash": master_hash, - # The branch name. - "branch": branch, - # The version for displaying in the form 3.26.3 or 3.26.3.12. - "version": version, - # The date of the commit. - "date": self.GitLog(n=1, format="%ci", git_hash=git_hash), - # Merged patches if available in the form 'r1234, r2345'. - "patches_merged": patches, - # Default for easier output formatting. - "chromium_revision": "", - # Default for easier output formatting. - "chromium_branch": "", - # Link to the CL on code review. Candiates pushes are not uploaded, - # so this field will be populated below with the recent roll CL link. - "review_link": MatchSafe(REVIEW_LINK_RE.search(cl_body)), - # Link to the commit message on google code. - "revision_link": ("https://code.google.com/p/v8/source/detail?r=%s" - % revision), - } - - def GetRelease(self, git_hash, branch): - self.ReadAndPersistVersion() - base_version = [self["major"], self["minor"], self["build"]] - version = ".".join(base_version) - body = self.GitLog(n=1, format="%B", git_hash=git_hash) - - patches = "" - if self["patch"] != "0": - version += ".%s" % self["patch"] - if CHERRY_PICK_TITLE_GIT_RE.match(body.splitlines()[0]): - patches = self.GetMergedPatchesGit(body) - else: - patches = self.GetMergedPatches(body) - - if SortingKey("4.2.69") <= SortingKey(version): - master_hash = self.GetLatestReleaseBase(version=version) - else: - # Legacy: Before version 4.2.69, the master revision was determined - # by commit message. - title = self.GitLog(n=1, format="%s", git_hash=git_hash) - master_hash = self.GetMasterHashFromPush(title) - master_position = "" - if master_hash: - master_position = self.GetCommitPositionNumber(master_hash) - return self.GetReleaseDict( - git_hash, master_position, master_hash, branch, version, - patches, body), self["patch"] - - def GetReleasesFromBranch(self, branch): - self.GitReset(self.vc.RemoteBranch(branch)) - if branch == self.vc.MasterBranch(): - return self.GetReleasesFromMaster() - - releases = [] - try: - for git_hash in self.GitLog(format="%H").splitlines(): - if VERSION_FILE not in self.GitChangedFiles(git_hash): - continue - if self.ExceedsMax(releases): - break # pragma: no cover - if not self.GitCheckoutFileSafe(VERSION_FILE, git_hash): - break # pragma: no cover - - release, patch_level = self.GetRelease(git_hash, branch) - releases.append(release) - - # Follow branches only until their creation point. - # TODO(machenbach): This omits patches if the version file wasn't - # manipulated correctly. Find a better way to detect the point where - # the parent of the branch head leads to the trunk branch. - if branch != self.vc.CandidateBranch() and patch_level == "0": - break - - # Allow Ctrl-C interrupt. - except (KeyboardInterrupt, SystemExit): # pragma: no cover - pass - - # Clean up checked-out version file. - self.GitCheckoutFileSafe(VERSION_FILE, "HEAD") - return releases - - def GetReleaseFromRevision(self, revision): - releases = [] - try: - if (VERSION_FILE not in self.GitChangedFiles(revision) or - not self.GitCheckoutFileSafe(VERSION_FILE, revision)): - print "Skipping revision %s" % revision - return [] # pragma: no cover - - branches = map( - str.strip, - self.Git("branch -r --contains %s" % revision).strip().splitlines(), - ) - branch = "" - for b in branches: - if b.startswith("origin/"): - branch = b.split("origin/")[1] - break - if b.startswith("branch-heads/"): - branch = b.split("branch-heads/")[1] - break - else: - print "Could not determine branch for %s" % revision - - release, _ = self.GetRelease(revision, branch) - releases.append(release) - - # Allow Ctrl-C interrupt. - except (KeyboardInterrupt, SystemExit): # pragma: no cover - pass - - # Clean up checked-out version file. - self.GitCheckoutFileSafe(VERSION_FILE, "HEAD") - return releases - - - def RunStep(self): - self.GitCreateBranch(self._config["BRANCHNAME"]) - releases = [] - if self._options.branch == 'recent': - # List every release from the last 7 days. - revisions = self.GetRecentReleases(max_age=7 * DAY_IN_SECONDS) - for revision in revisions: - releases += self.GetReleaseFromRevision(revision) - elif self._options.branch == 'all': # pragma: no cover - # Retrieve the full release history. - for branch in self.vc.GetBranches(): - releases += self.GetReleasesFromBranch(branch) - releases += self.GetReleasesFromBranch(self.vc.CandidateBranch()) - releases += self.GetReleasesFromBranch(self.vc.MasterBranch()) - else: # pragma: no cover - # Retrieve history for a specified branch. - assert self._options.branch in (self.vc.GetBranches() + - [self.vc.CandidateBranch(), self.vc.MasterBranch()]) - releases += self.GetReleasesFromBranch(self._options.branch) - - self["releases"] = sorted(releases, - key=lambda r: SortingKey(r["version"]), - reverse=True) - - -class UpdateChromiumCheckout(Step): - MESSAGE = "Update the chromium checkout." - - def RunStep(self): - cwd = self._options.chromium - self.GitFetchOrigin("+refs/heads/*:refs/remotes/origin/*", - "+refs/branch-heads/*:refs/remotes/branch-heads/*", - cwd=cwd) - # Update v8 checkout in chromium. - self.GitFetchOrigin(cwd=os.path.join(cwd, "v8")) - - -def ConvertToCommitNumber(step, revision): - # Simple check for git hashes. - if revision.isdigit() and len(revision) < 8: - return revision - return step.GetCommitPositionNumber( - revision, cwd=os.path.join(step._options.chromium, "v8")) - - -class RetrieveChromiumV8Releases(Step): - MESSAGE = "Retrieve V8 releases from Chromium DEPS." - - def RunStep(self): - cwd = self._options.chromium - - # All v8 revisions we are interested in. - releases_dict = dict((r["revision_git"], r) for r in self["releases"]) - - cr_releases = [] - count_past_last_v8 = 0 - try: - for git_hash in self.GitLog( - format="%H", grep="V8", branch="origin/master", - path="DEPS", cwd=cwd).splitlines(): - deps = self.GitShowFile(git_hash, "DEPS", cwd=cwd) - match = DEPS_RE.search(deps) - if match: - cr_rev = self.GetCommitPositionNumber(git_hash, cwd=cwd) - if cr_rev: - v8_hsh = match.group(1) - cr_releases.append([cr_rev, v8_hsh]) - - if count_past_last_v8: - count_past_last_v8 += 1 # pragma: no cover - - if count_past_last_v8 > 20: - break # pragma: no cover - - # Stop as soon as we find a v8 revision that we didn't fetch in the - # v8-revision-retrieval part above (i.e. a revision that's too old). - # Just iterate a few more times in case there were reverts. - if v8_hsh not in releases_dict: - count_past_last_v8 += 1 # pragma: no cover - - # Allow Ctrl-C interrupt. - except (KeyboardInterrupt, SystemExit): # pragma: no cover - pass - - # Add the chromium ranges to the v8 candidates and master releases. - all_ranges = BuildRevisionRanges(cr_releases) - - for hsh, ranges in all_ranges.iteritems(): - releases_dict.get(hsh, {})["chromium_revision"] = ranges - - -# TODO(machenbach): Unify common code with method above. -class RetrieveChromiumBranches(Step): - MESSAGE = "Retrieve Chromium branch information." - - def RunStep(self): - cwd = self._options.chromium - - # All v8 revisions we are interested in. - releases_dict = dict((r["revision_git"], r) for r in self["releases"]) - - # Filter out irrelevant branches. - branches = filter(lambda r: re.match(r"branch-heads/\d+", r), - self.GitRemotes(cwd=cwd)) - - # Transform into pure branch numbers. - branches = map(lambda r: int(re.match(r"branch-heads/(\d+)", r).group(1)), - branches) - - branches = sorted(branches, reverse=True) - - cr_branches = [] - count_past_last_v8 = 0 - try: - for branch in branches: - deps = self.GitShowFile( - "refs/branch-heads/%d" % branch, "DEPS", cwd=cwd) - match = DEPS_RE.search(deps) - if match: - v8_hsh = match.group(1) - cr_branches.append([str(branch), v8_hsh]) - - if count_past_last_v8: - count_past_last_v8 += 1 # pragma: no cover - - if count_past_last_v8 > 20: - break # pragma: no cover - - # Stop as soon as we find a v8 revision that we didn't fetch in the - # v8-revision-retrieval part above (i.e. a revision that's too old). - # Just iterate a few more times in case there were reverts. - if v8_hsh not in releases_dict: - count_past_last_v8 += 1 # pragma: no cover - - # Allow Ctrl-C interrupt. - except (KeyboardInterrupt, SystemExit): # pragma: no cover - pass - - # Add the chromium branches to the v8 candidate releases. - all_ranges = BuildRevisionRanges(cr_branches) - for revision, ranges in all_ranges.iteritems(): - releases_dict.get(revision, {})["chromium_branch"] = ranges - - -class RetrieveInformationOnChromeReleases(Step): - MESSAGE = 'Retrieves relevant information on the latest Chrome releases' - - def Run(self): - - params = None - result_raw = self.ReadURL( - OMAHA_PROXY_URL + "all.json", - params, - wait_plan=[5, 20] - ) - recent_releases = json.loads(result_raw) - - canaries = [] - - for current_os in recent_releases: - for current_version in current_os["versions"]: - if current_version["channel"] != "canary": - continue - - current_candidate = self._CreateCandidate(current_version) - canaries.append(current_candidate) - - chrome_releases = {"canaries": canaries} - self["chrome_releases"] = chrome_releases - - def _GetGitHashForV8Version(self, v8_version): - if v8_version == "N/A": - return "" - - real_v8_version = v8_version - if v8_version.split(".")[3]== "0": - real_v8_version = v8_version[:-2] - - try: - return self.GitGetHashOfTag(real_v8_version) - except GitFailedException: - return "" - - def _CreateCandidate(self, current_version): - params = None - url_to_call = (OMAHA_PROXY_URL + "v8.json?version=" - + current_version["previous_version"]) - result_raw = self.ReadURL( - url_to_call, - params, - wait_plan=[5, 20] - ) - previous_v8_version = json.loads(result_raw)["v8_version"] - v8_previous_version_hash = self._GetGitHashForV8Version(previous_v8_version) - - current_v8_version = current_version["v8_version"] - v8_version_hash = self._GetGitHashForV8Version(current_v8_version) - - current_candidate = { - "chrome_version": current_version["version"], - "os": current_version["os"], - "release_date": current_version["current_reldate"], - "v8_version": current_v8_version, - "v8_version_hash": v8_version_hash, - "v8_previous_version": previous_v8_version, - "v8_previous_version_hash": v8_previous_version_hash, - } - return current_candidate - - -class CleanUp(Step): - MESSAGE = "Clean up." - - def RunStep(self): - self.CommonCleanup() - - -class WriteOutput(Step): - MESSAGE = "Print output." - - def Run(self): - - output = { - "releases": self["releases"], - "chrome_releases": self["chrome_releases"], - } - - if self._options.csv: - with open(self._options.csv, "w") as f: - writer = csv.DictWriter(f, - ["version", "branch", "revision", - "chromium_revision", "patches_merged"], - restval="", - extrasaction="ignore") - for release in self["releases"]: - writer.writerow(release) - if self._options.json: - with open(self._options.json, "w") as f: - f.write(json.dumps(output)) - if not self._options.csv and not self._options.json: - print output # pragma: no cover - - -class Releases(ScriptsBase): - def _PrepareOptions(self, parser): - parser.add_argument("-b", "--branch", default="recent", - help=("The branch to analyze. If 'all' is specified, " - "analyze all branches. If 'recent' (default) " - "is specified, track beta, stable and " - "candidates.")) - parser.add_argument("-c", "--chromium", - help=("The path to your Chromium src/ " - "directory to automate the V8 roll.")) - parser.add_argument("--csv", help="Path to a CSV file for export.") - parser.add_argument("-m", "--max-releases", type=int, default=0, - help="The maximum number of releases to track.") - parser.add_argument("--json", help="Path to a JSON file for export.") - - def _ProcessOptions(self, options): # pragma: no cover - options.force_readline_defaults = True - return True - - def _Config(self): - return { - "BRANCHNAME": "retrieve-v8-releases", - "PERSISTFILE_BASENAME": "/tmp/v8-releases-tempfile", - } - - def _Steps(self): - - return [ - Preparation, - RetrieveV8Releases, - UpdateChromiumCheckout, - RetrieveChromiumV8Releases, - RetrieveChromiumBranches, - RetrieveInformationOnChromeReleases, - CleanUp, - WriteOutput, - ] - - -if __name__ == "__main__": # pragma: no cover - sys.exit(Releases().Run()) diff --git a/deps/v8/tools/release/test_scripts.py b/deps/v8/tools/release/test_scripts.py index 25aa803daf..565b2b7c8f 100755 --- a/deps/v8/tools/release/test_scripts.py +++ b/deps/v8/tools/release/test_scripts.py @@ -43,8 +43,6 @@ import merge_to_branch from merge_to_branch import MergeToBranch import push_to_candidates from push_to_candidates import * -import releases -from releases import Releases from auto_tag import AutoTag import roll_merge from roll_merge import RollMerge @@ -97,38 +95,6 @@ class ToplevelTest(unittest.TestCase): ] self.assertEquals(expected, NormalizeVersionTags(input)) - def testSortBranches(self): - S = releases.SortBranches - self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2]) - self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2]) - self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2]) - - def testFilterDuplicatesAndReverse(self): - F = releases.FilterDuplicatesAndReverse - self.assertEquals([], F([])) - self.assertEquals([["100", "10"]], F([["100", "10"]])) - self.assertEquals([["99", "9"], ["100", "10"]], - F([["100", "10"], ["99", "9"]])) - self.assertEquals([["98", "9"], ["100", "10"]], - F([["100", "10"], ["99", "9"], ["98", "9"]])) - self.assertEquals([["98", "9"], ["99", "10"]], - F([["100", "10"], ["99", "10"], ["98", "9"]])) - - def testBuildRevisionRanges(self): - B = releases.BuildRevisionRanges - self.assertEquals({}, B([])) - self.assertEquals({"10": "100"}, B([["100", "10"]])) - self.assertEquals({"10": "100", "9": "99:99"}, - B([["100", "10"], ["99", "9"]])) - self.assertEquals({"10": "100", "9": "97:99"}, - B([["100", "10"], ["98", "9"], ["97", "9"]])) - self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"}, - B([["100", "10"], ["99", "9"], ["91", "3"]])) - self.assertEquals({"13": "101", "12": "100:100", "9": "94:97", - "3": "91:93, 98:99"}, - B([["101", "13"], ["100", "12"], ["98", "3"], - ["94", "9"], ["91", "3"]])) - def testMakeComment(self): self.assertEquals("# Line 1\n# Line 2\n#", MakeComment(" Line 1\n Line 2\n")) @@ -1037,7 +1003,7 @@ Please close rolling in case of a roll revert: https://v8-roll.appspot.com/ This only works with a Google account. -CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel +CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel TBR=reviewer@chromium.org""" @@ -1308,251 +1274,6 @@ LOG=N args += ["-s", "4"] RollMerge(TEST_CONFIG, self).Run(args) - def testReleases(self): - c_hash1_commit_log = """Update V8 to Version 4.2.71. - -Cr-Commit-Position: refs/heads/master@{#5678} -""" - c_hash2_commit_log = """Revert something. - -BUG=12345 - -Reason: -> Some reason. -> Cr-Commit-Position: refs/heads/master@{#12345} -> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4 - -Review URL: https://codereview.chromium.org/12345 - -Cr-Commit-Position: refs/heads/master@{#4567} -git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b - -""" - c_hash3_commit_log = """Simple. - -git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b - -""" - c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick). - -Merged abc12. - -Review URL: fake.com - -Cr-Commit-Position: refs/heads/candidates@{#234} -""" - c_hash_123_commit_log = """Version 3.3.1.0 - -git-svn-id: googlecode@123 0039-1c4b -""" - c_hash_345_commit_log = """Version 3.4.0. - -Cr-Commit-Position: refs/heads/candidates@{#345} -""" - c_hash_456_commit_log = """Version 4.2.71. - -Cr-Commit-Position: refs/heads/4.2.71@{#1} -""" - c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n" - - json_output = self.MakeEmptyTempFile() - csv_output = self.MakeEmptyTempFile() - self.WriteFakeVersionFile() - - TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() - chrome_dir = TEST_CONFIG["CHROMIUM"] - chrome_v8_dir = os.path.join(chrome_dir, "v8") - os.makedirs(chrome_v8_dir) - - def ResetVersion(major, minor, build, patch=0): - return lambda: self.WriteFakeVersionFile(major=major, - minor=minor, - build=build, - patch=patch) - - self.Expect([ - Cmd("git status -s -uno", ""), - Cmd("git checkout -f origin/master", ""), - Cmd("git fetch", ""), - Cmd("git branch", " branch1\n* branch2\n"), - Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""), - Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), - Cmd("git rev-list --max-age=395200 --tags", - "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"), - Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"), - Cmd("git describe --tags hash_234", "3.3.1.1"), - Cmd("git describe --tags hash_123", "3.21.2"), - Cmd("git describe --tags hash_345", "3.22.3"), - Cmd("git describe --tags hash_456", "4.2.71"), - Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE), - Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 3, 1, 1)), - Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"), - Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), - Cmd("git log -1 --format=%s hash_234", ""), - Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), - Cmd("git log -1 --format=%ci hash_234", "18:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE), - Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 21, 2)), - Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"), - Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), - Cmd("git log -1 --format=%s hash_123", ""), - Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), - Cmd("git log -1 --format=%ci hash_123", "03:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE), - Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 3)), - Cmd("git branch -r --contains hash_345", " origin/candidates\n"), - Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), - Cmd("git log -1 --format=%s hash_345", ""), - Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), - Cmd("git log -1 --format=%ci hash_345", ""), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE), - Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "", - cb=ResetVersion(4, 2, 71)), - Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"), - Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), - Cmd("git log -1 --format=%H 4.2.71", "hash_456"), - Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"), - Cmd("git log -1 --format=%H hash_456^", "master_456"), - Cmd("git log -1 --format=%B master_456", - "Cr-Commit-Position: refs/heads/master@{#456}"), - Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), - Cmd("git log -1 --format=%ci hash_456", "02:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* " - "+refs/branch-heads/*:refs/remotes/branch-heads/*", "", - cwd=chrome_dir), - Cmd("git fetch origin", "", cwd=chrome_v8_dir), - Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS", - "c_hash1\nc_hash2\nc_hash3\n", - cwd=chrome_dir), - Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log, - cwd=chrome_dir), - Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log, - cwd=chrome_dir), - Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log, - cwd=chrome_dir), - Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir), - Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345", - cwd=chrome_dir), - URL("http://omahaproxy.appspot.com/all.json", """[{ - "os": "win", - "versions": [{ - "version": "2.2.2.2", - "v8_version": "22.2.2.2", - "current_reldate": "04/09/15", - "os": "win", - "channel": "canary", - "previous_version": "1.1.1.0" - }] - }]"""), - URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{ - "chromium_version": "1.1.1.0", - "v8_version": "11.1.1.0" - }"""), - Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"), - Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"), - Cmd("git checkout -f origin/master", ""), - Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "") - ]) - - args = ["-c", TEST_CONFIG["CHROMIUM"], - "--json", json_output, - "--csv", csv_output, - "--max-releases", "1"] - Releases(TEST_CONFIG, self).Run(args) - - # Check expected output. - csv = ("4.2.71,4.2.71,1,5678,\r\n" - "3.22.3,candidates,345,4567:5677,\r\n" - "3.21.2,3.21,123,,\r\n" - "3.3.1.1,3.3,234,,abc12\r\n") - self.assertEquals(csv, FileToText(csv_output)) - - expected_json = {"chrome_releases":{ - "canaries": [ - { - "chrome_version": "2.2.2.2", - "os": "win", - "release_date": "04/09/15", - "v8_version": "22.2.2.2", - "v8_version_hash": "v8_version_hash", - "v8_previous_version": "11.1.1.0", - "v8_previous_version_hash": "v8_previous_version_hash" - }]}, - "releases":[ - { - "revision": "1", - "revision_git": "hash_456", - "master_position": "456", - "master_hash": "master_456", - "patches_merged": "", - "version": "4.2.71", - "chromium_revision": "5678", - "branch": "4.2.71", - "review_link": "", - "date": "02:15", - "chromium_branch": "", - # FIXME(machenbach): Fix revisions link for git. - "revision_link": "https://code.google.com/p/v8/source/detail?r=1", - }, - { - "revision": "345", - "revision_git": "hash_345", - "master_position": "", - "master_hash": "", - "patches_merged": "", - "version": "3.22.3", - "chromium_revision": "4567:5677", - "branch": "candidates", - "review_link": "", - "date": "", - "chromium_branch": "7", - "revision_link": "https://code.google.com/p/v8/source/detail?r=345", - }, - { - "revision": "123", - "revision_git": "hash_123", - "patches_merged": "", - "master_position": "", - "master_hash": "", - "version": "3.21.2", - "chromium_revision": "", - "branch": "3.21", - "review_link": "", - "date": "03:15", - "chromium_branch": "", - "revision_link": "https://code.google.com/p/v8/source/detail?r=123", - }, - { - "revision": "234", - "revision_git": "hash_234", - "patches_merged": "abc12", - "master_position": "", - "master_hash": "", - "version": "3.3.1.1", - "chromium_revision": "", - "branch": "3.3", - "review_link": "fake.com", - "date": "18:15", - "chromium_branch": "", - "revision_link": "https://code.google.com/p/v8/source/detail?r=234", - },], - } - self.assertEquals(expected_json, json.loads(FileToText(json_output))) - def testMergeToBranch(self): TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile() TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) @@ -1678,250 +1399,5 @@ NOTREECHECKS=true args += ["-s", "4"] MergeToBranch(TEST_CONFIG, self).Run(args) - def testReleases(self): - c_hash1_commit_log = """Update V8 to Version 4.2.71. - -Cr-Commit-Position: refs/heads/master@{#5678} -""" - c_hash2_commit_log = """Revert something. - -BUG=12345 - -Reason: -> Some reason. -> Cr-Commit-Position: refs/heads/master@{#12345} -> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4 - -Review URL: https://codereview.chromium.org/12345 - -Cr-Commit-Position: refs/heads/master@{#4567} -git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b - -""" - c_hash3_commit_log = """Simple. - -git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b - -""" - c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick). - -Merged abc12. - -Review URL: fake.com - -Cr-Commit-Position: refs/heads/candidates@{#234} -""" - c_hash_123_commit_log = """Version 3.3.1.0 - -git-svn-id: googlecode@123 0039-1c4b -""" - c_hash_345_commit_log = """Version 3.4.0. - -Cr-Commit-Position: refs/heads/candidates@{#345} -""" - c_hash_456_commit_log = """Version 4.2.71. - -Cr-Commit-Position: refs/heads/4.2.71@{#1} -""" - c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n" - - json_output = self.MakeEmptyTempFile() - csv_output = self.MakeEmptyTempFile() - self.WriteFakeVersionFile() - - TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() - chrome_dir = TEST_CONFIG["CHROMIUM"] - chrome_v8_dir = os.path.join(chrome_dir, "v8") - os.makedirs(chrome_v8_dir) - - def ResetVersion(major, minor, build, patch=0): - return lambda: self.WriteFakeVersionFile(major=major, - minor=minor, - build=build, - patch=patch) - - self.Expect([ - Cmd("git status -s -uno", ""), - Cmd("git checkout -f origin/master", ""), - Cmd("git fetch", ""), - Cmd("git branch", " branch1\n* branch2\n"), - Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""), - Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), - Cmd("git rev-list --max-age=395200 --tags", - "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"), - Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"), - Cmd("git describe --tags hash_234", "3.3.1.1"), - Cmd("git describe --tags hash_123", "3.21.2"), - Cmd("git describe --tags hash_345", "3.22.3"), - Cmd("git describe --tags hash_456", "4.2.71"), - Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE), - Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 3, 1, 1)), - Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"), - Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), - Cmd("git log -1 --format=%s hash_234", ""), - Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), - Cmd("git log -1 --format=%ci hash_234", "18:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE), - Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 21, 2)), - Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"), - Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), - Cmd("git log -1 --format=%s hash_123", ""), - Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), - Cmd("git log -1 --format=%ci hash_123", "03:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE), - Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 3)), - Cmd("git branch -r --contains hash_345", " origin/candidates\n"), - Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), - Cmd("git log -1 --format=%s hash_345", ""), - Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), - Cmd("git log -1 --format=%ci hash_345", ""), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE), - Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "", - cb=ResetVersion(4, 2, 71)), - Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"), - Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), - Cmd("git log -1 --format=%H 4.2.71", "hash_456"), - Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"), - Cmd("git log -1 --format=%H hash_456^", "master_456"), - Cmd("git log -1 --format=%B master_456", - "Cr-Commit-Position: refs/heads/master@{#456}"), - Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), - Cmd("git log -1 --format=%ci hash_456", "02:15"), - Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", - cb=ResetVersion(3, 22, 5)), - Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* " - "+refs/branch-heads/*:refs/remotes/branch-heads/*", "", - cwd=chrome_dir), - Cmd("git fetch origin", "", cwd=chrome_v8_dir), - Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS", - "c_hash1\nc_hash2\nc_hash3\n", - cwd=chrome_dir), - Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log, - cwd=chrome_dir), - Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log, - cwd=chrome_dir), - Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir), - Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log, - cwd=chrome_dir), - Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir), - Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345", - cwd=chrome_dir), - URL("http://omahaproxy.appspot.com/all.json", """[{ - "os": "win", - "versions": [{ - "version": "2.2.2.2", - "v8_version": "22.2.2.2", - "current_reldate": "04/09/15", - "os": "win", - "channel": "canary", - "previous_version": "1.1.1.0" - }] - }]"""), - URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{ - "chromium_version": "1.1.1.0", - "v8_version": "11.1.1.0" - }"""), - Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"), - Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"), - Cmd("git checkout -f origin/master", ""), - Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "") - ]) - - args = ["-c", TEST_CONFIG["CHROMIUM"], - "--json", json_output, - "--csv", csv_output, - "--max-releases", "1"] - Releases(TEST_CONFIG, self).Run(args) - - # Check expected output. - csv = ("4.2.71,4.2.71,1,5678,\r\n" - "3.22.3,candidates,345,4567:5677,\r\n" - "3.21.2,3.21,123,,\r\n" - "3.3.1.1,3.3,234,,abc12\r\n") - self.assertEquals(csv, FileToText(csv_output)) - - expected_json = {"chrome_releases":{ - "canaries": [ - { - "chrome_version": "2.2.2.2", - "os": "win", - "release_date": "04/09/15", - "v8_version": "22.2.2.2", - "v8_version_hash": "v8_version_hash", - "v8_previous_version": "11.1.1.0", - "v8_previous_version_hash": "v8_previous_version_hash" - }]}, - "releases":[ - { - "revision": "1", - "revision_git": "hash_456", - "master_position": "456", - "master_hash": "master_456", - "patches_merged": "", - "version": "4.2.71", - "chromium_revision": "5678", - "branch": "4.2.71", - "review_link": "", - "date": "02:15", - "chromium_branch": "", - # FIXME(machenbach): Fix revisions link for git. - "revision_link": "https://code.google.com/p/v8/source/detail?r=1", - }, - { - "revision": "345", - "revision_git": "hash_345", - "master_position": "", - "master_hash": "", - "patches_merged": "", - "version": "3.22.3", - "chromium_revision": "4567:5677", - "branch": "candidates", - "review_link": "", - "date": "", - "chromium_branch": "7", - "revision_link": "https://code.google.com/p/v8/source/detail?r=345", - }, - { - "revision": "123", - "revision_git": "hash_123", - "patches_merged": "", - "master_position": "", - "master_hash": "", - "version": "3.21.2", - "chromium_revision": "", - "branch": "3.21", - "review_link": "", - "date": "03:15", - "chromium_branch": "", - "revision_link": "https://code.google.com/p/v8/source/detail?r=123", - }, - { - "revision": "234", - "revision_git": "hash_234", - "patches_merged": "abc12", - "master_position": "", - "master_hash": "", - "version": "3.3.1.1", - "chromium_revision": "", - "branch": "3.3", - "review_link": "fake.com", - "date": "18:15", - "chromium_branch": "", - "revision_link": "https://code.google.com/p/v8/source/detail?r=234", - },], - } - self.assertEquals(expected_json, json.loads(FileToText(json_output))) - if __name__ == '__main__': unittest.main() diff --git a/deps/v8/tools/run_perf.py b/deps/v8/tools/run_perf.py index 2bd4372453..e0a9fc3b59 100755 --- a/deps/v8/tools/run_perf.py +++ b/deps/v8/tools/run_perf.py @@ -11,6 +11,7 @@ Call e.g. with tools/run-perf.py --arch ia32 some_suite.json The suite json format is expected to be: { "path": <relative path chunks to perf resources and main file>, + "owners": [<list of email addresses of benchmark owners (required)>], "name": <optional suite name, file name is default>, "archs": [<architecture name for which this suite is run>, ...], "binary": <name of binary to run, default "d8">, @@ -55,6 +56,7 @@ A suite without "tests" is considered a performance test itself. Full example (suite with one runner): { "path": ["."], + "owner": ["username@chromium.org"], "flags": ["--expose-gc"], "test_flags": ["5"], "archs": ["ia32", "x64"], @@ -74,6 +76,7 @@ Full example (suite with one runner): Full example (suite with several runners): { "path": ["."], + "owner": ["username@chromium.org", "otherowner@google.com"], "flags": ["--expose-gc"], "archs": ["ia32", "x64"], "run_count": 5, @@ -389,6 +392,7 @@ class DefaultSentinel(Node): self.stddev_regexp = None self.units = "score" self.total = False + self.owners = [] class GraphConfig(Node): @@ -401,6 +405,7 @@ class GraphConfig(Node): self._suite = suite assert isinstance(suite.get("path", []), list) + assert isinstance(suite.get("owners", []), list) assert isinstance(suite["name"], basestring) assert isinstance(suite.get("flags", []), list) assert isinstance(suite.get("test_flags", []), list) @@ -411,6 +416,7 @@ class GraphConfig(Node): self.graphs = parent.graphs[:] + [suite["name"]] self.flags = parent.flags[:] + suite.get("flags", []) self.test_flags = parent.test_flags[:] + suite.get("test_flags", []) + self.owners = parent.owners[:] + suite.get("owners", []) # Values independent of parent node. self.resources = suite.get("resources", []) @@ -451,6 +457,7 @@ class TraceConfig(GraphConfig): def __init__(self, suite, parent, arch): super(TraceConfig, self).__init__(suite, parent, arch) assert self.results_regexp + assert self.owners def CreateMeasurement(self, perform_measurement): if not perform_measurement: diff --git a/deps/v8/tools/testrunner/local/variants.py b/deps/v8/tools/testrunner/local/variants.py index 1c29f1d195..f7669c39b9 100644 --- a/deps/v8/tools/testrunner/local/variants.py +++ b/deps/v8/tools/testrunner/local/variants.py @@ -7,6 +7,7 @@ ALL_VARIANT_FLAGS = { "code_serializer": [["--cache=code"]], "default": [[]], "future": [["--future"]], + "gc_stats": [["--gc_stats=1"]], # Alias of exhaustive variants, but triggering new test framework features. "infra_staging": [[]], "liftoff": [["--liftoff"]], @@ -22,7 +23,7 @@ ALL_VARIANT_FLAGS = { # Trigger stress sampling allocation profiler with sample interval = 2^14 "stress_sampling": [["--stress-sampling-allocation-profiler=16384"]], "trusted": [["--no-untrusted-code-mitigations"]], - "wasm_traps": [["--wasm-trap-handler", "--invoke-weak-callbacks"]], + "no_wasm_traps": [["--no-wasm-trap-handler"]], } SLOW_VARIANTS = set([ diff --git a/deps/v8/tools/testrunner/num_fuzzer.py b/deps/v8/tools/testrunner/num_fuzzer.py index 77effc1847..b55dd2102d 100755 --- a/deps/v8/tools/testrunner/num_fuzzer.py +++ b/deps/v8/tools/testrunner/num_fuzzer.py @@ -81,6 +81,10 @@ class NumFuzzer(base_runner.BaseTestRunner): parser.add_option("--combine-min", default=2, type="int", help="Minimum number of tests to combine") + # Miscellaneous + parser.add_option("--variants", default='default', + help="Comma-separated list of testing variants") + return parser @@ -97,6 +101,10 @@ class NumFuzzer(base_runner.BaseTestRunner): options.min_group_size, options.max_group_size) raise base_runner.TestRunnerError() + if options.variants != 'default': + print ('Only default testing variant is supported with numfuzz') + raise base_runner.TestRunnerError() + return True def _get_default_suite_names(self): diff --git a/deps/v8/tools/testrunner/standard_runner.py b/deps/v8/tools/testrunner/standard_runner.py index bea00476f4..6957ad5205 100755 --- a/deps/v8/tools/testrunner/standard_runner.py +++ b/deps/v8/tools/testrunner/standard_runner.py @@ -33,7 +33,6 @@ MORE_VARIANTS = [ "stress", "stress_background_compile", "stress_incremental_marking", - "wasm_traps", ] VARIANT_ALIASES = { @@ -44,7 +43,7 @@ VARIANT_ALIASES = { # Shortcut for the two above ("more" first - it has the longer running tests). "exhaustive": MORE_VARIANTS + VARIANTS, # Additional variants, run on a subset of bots. - "extra": ["future", "liftoff", "trusted"], + "extra": ["future", "liftoff", "no_wasm_traps", "trusted"], } GC_STRESS_FLAGS = ["--gc-interval=500", "--stress-compaction", @@ -166,6 +165,11 @@ class StandardTestRunner(base_runner.BaseTestRunner): options.extra_flags.append("--invoke-weak-callbacks") options.extra_flags.append("--omit-quit") + if self.build_config.no_snap: + # Speed up slow nosnap runs. Allocation verification is covered by + # running mksnapshot on other builders. + options.extra_flags.append("--no-turbo-verify-allocation") + if options.novfp3: options.extra_flags.append("--noenable-vfp3") @@ -266,6 +270,7 @@ class StandardTestRunner(base_runner.BaseTestRunner): variables.update({ 'gc_stress': options.gc_stress or options.random_gc_stress, + 'gc_fuzzer': options.random_gc_stress, 'novfp3': options.novfp3, 'simulator_run': simulator_run, }) diff --git a/deps/v8/tools/try_perf.py b/deps/v8/tools/try_perf.py index b77ccafa63..483dfe7199 100755 --- a/deps/v8/tools/try_perf.py +++ b/deps/v8/tools/try_perf.py @@ -52,6 +52,7 @@ PUBLIC_BENCHMARKS = [ 'sunspider', 'unity', 'wasm', + 'web-tooling-benchmark', ] V8_BASE = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) diff --git a/deps/v8/tools/turbolizer/code-view.js b/deps/v8/tools/turbolizer/code-view.js index 7f9728a83a..0b190b92ba 100644 --- a/deps/v8/tools/turbolizer/code-view.js +++ b/deps/v8/tools/turbolizer/code-view.js @@ -5,166 +5,257 @@ "use strict"; class CodeView extends View { - constructor(divID, PR, sourceText, sourcePosition, broker) { - super(divID, broker, null, false); + static get MAIN_SOURCE() { + return "main function"; + } + static get INLINED_SOURCE() { + return "inlined function"; + } + + createViewElement() { + const sourceContainer = document.createElement("div"); + sourceContainer.classList.add("source-container"); + return sourceContainer; + } + + constructor(parentId, broker, sourceResolver, sourceFunction, codeMode) { + super(parentId, broker, null, false); let view = this; - view.PR = PR; view.mouseDown = false; view.broker = broker; - view.allSpans = []; - - var selectionHandler = { - clear: function() { broker.clear(selectionHandler); }, - select: function(items, selected) { - var handler = this; - var broker = view.broker; - for (let span of items) { - if (selected) { - span.classList.add("selected"); - } else { - span.classList.remove("selected"); - } - } - var locations = []; - for (var span of items) { - locations.push({pos_start: span.start, pos_end: span.end}); - } - broker.clear(selectionHandler); - broker.select(selectionHandler, locations, selected); + view.source = null; + view.sourceResolver = sourceResolver; + view.source = sourceFunction; + view.codeMode = codeMode; + this.lineToSourcePositions = new Map(); + this.sourcePositionToHtmlElement = new Map(); + this.showAdditionalInliningPosition = false; + + const selectionHandler = { + clear: function () { + view.selection.clear(); + view.updateSelection(); + broker.broadcastClear(this) }, - selectionDifference: function(span1, inclusive1, span2, inclusive2) { - var pos1 = span1.start; - var pos2 = span2.start; - var result = []; - var lineListDiv = view.divNode.firstChild.firstChild.childNodes; - for (var i = 0; i < lineListDiv.length; i++) { - var currentLineElement = lineListDiv[i]; - var spans = currentLineElement.childNodes; - for (var j = 0; j < spans.length; ++j) { - var currentSpan = spans[j]; - if (currentSpan.start > pos1 || - (inclusive1 && currentSpan.start == pos1)) { - if (currentSpan.start < pos2 || - (inclusive2 && currentSpan.start == pos2)) { - result.push(currentSpan); - } - } - } + select: function (sourcePositions, selected) { + const locations = []; + for (var sourcePosition of sourcePositions) { + locations.push(sourcePosition); + sourceResolver.addInliningPositions(sourcePosition, locations); } - return result; + if (locations.length == 0) return; + view.selection.select(locations, selected); + view.updateSelection(); + broker.broadcastSourcePositionSelect(this, locations, selected); }, - brokeredSelect: function(locations, selected) { - let firstSelect = view.selection.isEmpty(); - for (let location of locations) { - let start = location.pos_start; - let end = location.pos_end; - if (start && end) { - let lower = 0; - let upper = view.allSpans.length; - if (upper > 0) { - while ((upper - lower) > 1) { - var middle = Math.floor((upper + lower) / 2); - var lineStart = view.allSpans[middle].start; - if (lineStart < start) { - lower = middle; - } else if (lineStart > start) { - upper = middle; - } else { - lower = middle; - break; - } - } - var currentSpan = view.allSpans[lower]; - var currentLineElement = currentSpan.parentNode; - if ((currentSpan.start <= start && start < currentSpan.end) || - (currentSpan.start <= end && end < currentSpan.end)) { - if (firstSelect) { - makeContainerPosVisible( - view.divNode, currentLineElement.offsetTop); - firstSelect = false; - } - view.selection.select(currentSpan, selected); - } - } - } + brokeredSourcePositionSelect: function (locations, selected) { + const firstSelect = view.selection.isEmpty(); + for (const location of locations) { + const translated = sourceResolver.translateToSourceId(view.source.sourceId, location); + if (!translated) continue; + view.selection.select(translated, selected); } + view.updateSelection(firstSelect); + }, + brokeredClear: function () { + view.selection.clear(); + view.updateSelection(); }, - brokeredClear: function() { view.selection.clear(); }, }; - view.selection = new Selection(selectionHandler); - broker.addSelectionHandler(selectionHandler); + view.selection = new Selection(sourcePositionToStringKey); + broker.addSourcePositionHandler(selectionHandler); + this.selectionHandler = selectionHandler; + this.initializeCode(); + } - view.handleSpanMouseDown = function(e) { - e.stopPropagation(); - if (!e.shiftKey) { - view.selection.clear(); - } - view.selection.select(this, true); - view.mouseDown = true; + addSourcePositionToLine(lineNumber, sourcePosition) { + const lineNumberString = anyToString(lineNumber); + if (!this.lineToSourcePositions.has(lineNumberString)) { + this.lineToSourcePositions.set(lineNumberString, []); } + this.lineToSourcePositions.get(lineNumberString).push(sourcePosition); + } - view.handleSpanMouseMove = function(e) { - if (view.mouseDown) { - view.selection.extendTo(this); - } + addHtmlElementToSourcePosition(sourcePosition, element) { + const key = sourcePositionToStringKey(sourcePosition); + if (this.sourcePositionToHtmlElement.has(key)) { + console.log("Warning: duplicate source position", sourcePosition); } + this.sourcePositionToHtmlElement.set(key, element); + } - view.handleCodeMouseDown = function(e) { view.selection.clear(); } + getHtmlElementForSourcePosition(sourcePosition) { + const key = sourcePositionToStringKey(lineNumber); + return this.sourcePositionToHtmlElement.get(key); + } + + updateSelection(scrollIntoView) { + const mkVisible = new ViewElements(this.divNode.parentNode); + for (const [sp, el] of this.sourcePositionToHtmlElement.entries()) { + const isSelected = this.selection.isKeySelected(sp); + mkVisible.consider(el, isSelected); + el.classList.toggle("selected", isSelected); + } + mkVisible.apply(scrollIntoView); + } - document.addEventListener('mouseup', function(e) { - view.mouseDown = false; - }, false); + initializeContent(data, rememberedSelection) { + this.data = data; + } - view.initializeCode(sourceText, sourcePosition); + getCodeHtmlElementName() { + return `source-pre-${this.source.sourceId}`; } - initializeContent(data, rememberedSelection) { this.data = data; } + getCodeHeaderHtmlElementName() { + return `source-pre-${this.source.sourceId}-header`; + } - initializeCode(sourceText, sourcePosition) { + getHtmlCodeLines() { + const lineListDiv = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`).childNodes; + return lineListDiv; + } + + onSelectLine(lineNumber, doClear) { + const sourcePositions = this.lineToSourcePositions.get(anyToString(lineNumber)); + if (doClear) { + this.selectionHandler.clear(); + } + if (!sourcePositions) return; + this.selectionHandler.select(sourcePositions, undefined); + } + + onSelectSourcePosition(sourcePosition, doClear) { + if (doClear) { + this.selectionHandler.clear(); + } + this.selectionHandler.select([sourcePosition], undefined); + } + + initializeCode() { var view = this; + const source = this.source; + const sourceText = source.sourceText; + if (!sourceText) return; + const sourceContainer = view.divNode; + if (this.codeMode == CodeView.MAIN_SOURCE) { + sourceContainer.classList.add("main-source"); + } else { + sourceContainer.classList.add("inlined-source"); + } + var codeHeader = document.createElement("div"); + codeHeader.setAttribute("id", this.getCodeHeaderHtmlElementName()); + codeHeader.classList.add("code-header"); + var codeFileFunction = document.createElement("div"); + codeFileFunction.classList.add("code-file-function"); + codeFileFunction.innerHTML = `${source.sourceName}:${source.functionName}`; + codeHeader.appendChild(codeFileFunction); + var codeModeDiv = document.createElement("div"); + codeModeDiv.classList.add("code-mode"); + codeModeDiv.innerHTML = `${this.codeMode}`; + codeHeader.appendChild(codeModeDiv); + var clearDiv = document.createElement("div"); + clearDiv.style = "clear:both;" + codeHeader.appendChild(clearDiv); + sourceContainer.appendChild(codeHeader); var codePre = document.createElement("pre"); + codePre.setAttribute("id", this.getCodeHtmlElementName()); codePre.classList.add("prettyprint"); - view.divNode.innerHTML = ""; - view.divNode.appendChild(codePre); + sourceContainer.appendChild(codePre); + + codeHeader.onclick = function myFunction() { + if (codePre.style.display === "none") { + codePre.style.display = "block"; + } else { + codePre.style.display = "none"; + } + } if (sourceText != "") { codePre.classList.add("linenums"); codePre.textContent = sourceText; try { // Wrap in try to work when offline. - view.PR.prettyPrint(); + PR.prettyPrint(undefined, sourceContainer); } catch (e) { + console.log(e); } - view.divNode.onmousedown = this.handleCodeMouseDown; + view.divNode.onclick = function (e) { + view.selectionHandler.clear(); + } - var base = sourcePosition; - var current = 0; - var lineListDiv = view.divNode.firstChild.firstChild.childNodes; + const base = source.startPosition; + let current = 0; + const lineListDiv = this.getHtmlCodeLines(); + let newlineAdjust = 0; for (let i = 0; i < lineListDiv.length; i++) { - var currentLineElement = lineListDiv[i]; + // Line numbers are not zero-based. + const lineNumber = i + 1; + const currentLineElement = lineListDiv[i]; currentLineElement.id = "li" + i; - var pos = base + current; - currentLineElement.pos = pos; - var spans = currentLineElement.childNodes; + currentLineElement.dataset.lineNumber = lineNumber; + const spans = currentLineElement.childNodes; for (let j = 0; j < spans.length; ++j) { - var currentSpan = spans[j]; - if (currentSpan.nodeType == 1) { - currentSpan.start = pos; - currentSpan.end = pos + currentSpan.textContent.length; - currentSpan.onmousedown = this.handleSpanMouseDown; - currentSpan.onmousemove = this.handleSpanMouseMove; - view.allSpans.push(currentSpan); - } + const currentSpan = spans[j]; + const pos = base + current; + const end = pos + currentSpan.textContent.length; current += currentSpan.textContent.length; - pos = base + current; + this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust); + newlineAdjust = 0; } + + this.insertLineNumber(currentLineElement, lineNumber); + while ((current < sourceText.length) && - (sourceText[current] == '\n' || sourceText[current] == '\r')) { + (sourceText[current] == '\n' || sourceText[current] == '\r')) { ++current; + ++newlineAdjust; } } } } - deleteContent() {} + insertSourcePositions(currentSpan, lineNumber, pos, end, adjust) { + const view = this; + const sps = this.sourceResolver.sourcePositionsInRange(this.source.sourceId, pos - adjust, end); + for (const sourcePosition of sps) { + view.addSourcePositionToLine(lineNumber, sourcePosition); + const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.firstChild : currentSpan; + const replacementNode = textnode.splitText(Math.max(0, sourcePosition.scriptOffset - pos)); + const span = document.createElement('span'); + span.setAttribute("scriptOffset", sourcePosition.scriptOffset); + span.classList.add("source-position") + const marker = document.createElement('span'); + marker.classList.add("marker") + span.appendChild(marker); + const inlining = this.sourceResolver.getInliningForPosition(sourcePosition); + if (inlining != undefined && view.showAdditionalInliningPosition) { + const sourceName = this.sourceResolver.getSourceName(inlining.sourceId); + const inliningMarker = document.createElement('span'); + inliningMarker.classList.add("inlining-marker") + inliningMarker.setAttribute("data-descr", `${sourceName} was inlined here`) + span.appendChild(inliningMarker); + } + span.onclick = function (e) { + e.stopPropagation(); + view.onSelectSourcePosition(sourcePosition, !e.shiftKey) + }; + view.addHtmlElementToSourcePosition(sourcePosition, span); + textnode.parentNode.insertBefore(span, replacementNode); + } + } + + insertLineNumber(lineElement, lineNumber) { + const view = this; + const lineNumberElement = document.createElement("div"); + lineNumberElement.classList.add("line-number"); + lineNumberElement.innerText = lineNumber; + lineNumberElement.onclick = function (e) { + e.stopPropagation(); + view.onSelectLine(lineNumber, !e.shiftKey); + } + lineElement.insertBefore(lineNumberElement, lineElement.firstChild) + } + + deleteContent() { } } diff --git a/deps/v8/tools/turbolizer/constants.js b/deps/v8/tools/turbolizer/constants.js index da92c45abc..7e9045ef22 100644 --- a/deps/v8/tools/turbolizer/constants.js +++ b/deps/v8/tools/turbolizer/constants.js @@ -11,7 +11,6 @@ var SOURCE_PANE_ID = 'left'; var SOURCE_COLLAPSE_ID = 'source-shrink'; var SOURCE_EXPAND_ID = 'source-expand'; var INTERMEDIATE_PANE_ID = 'middle'; -var EMPTY_PANE_ID = 'empty'; var GRAPH_PANE_ID = 'graph'; var SCHEDULE_PANE_ID = 'schedule'; var GENERATED_PANE_ID = 'right'; diff --git a/deps/v8/tools/turbolizer/disassembly-view.js b/deps/v8/tools/turbolizer/disassembly-view.js index ecee04988c..75ef061262 100644 --- a/deps/v8/tools/turbolizer/disassembly-view.js +++ b/deps/v8/tools/turbolizer/disassembly-view.js @@ -5,22 +5,39 @@ "use strict"; class DisassemblyView extends TextView { - constructor(id, broker) { - super(id, broker, null, false); + createViewElement() { + const pane = document.createElement('div'); + pane.setAttribute('id', "disassembly"); + pane.innerHTML = + `<pre id='disassembly-text-pre' class='prettyprint prettyprinted'> + <ul id='disassembly-list' class='nolinenums noindent'> + </ul> + </pre>`; + return pane; + } + + constructor(parentId, broker) { + super(parentId, broker, null, false); let view = this; let ADDRESS_STYLE = { css: 'tag', - location: function(text) { - ADDRESS_STYLE.last_address = text; - return undefined; + assignSourcePosition: function (text) { + return SOURCE_POSITION_HEADER_STYLE.currentSourcePosition; + }, + linkHandler: function (text, fragment) { + if (fragment.sourcePosition === undefined) return undefined; + return (e) => { + e.stopPropagation(); + if (!e.shiftKey) { + view.sourcePositionSelectionHandler.clear(); + } + view.sourcePositionSelectionHandler.select([fragment.sourcePosition], true); + }; } }; let ADDRESS_LINK_STYLE = { - css: 'tag', - link: function(text) { - view.select(function(location) { return location.address == text; }, true, true); - } + css: 'tag' }; let UNCLASSIFIED_STYLE = { css: 'com' @@ -33,52 +50,47 @@ class DisassemblyView extends TextView { }; let POSITION_STYLE = { css: 'com', - location: function(text) { + location: function (text) { view.pos_start = Number(text); } }; let OPCODE_STYLE = { css: 'kwd', - location: function(text) { - if (BLOCK_HEADER_STYLE.block_id != undefined) { - return { - address: ADDRESS_STYLE.last_address, - block_id: BLOCK_HEADER_STYLE.block_id - }; - } else { - return { - address: ADDRESS_STYLE.last_address - }; - } - } }; const BLOCK_HEADER_STYLE = { - css: 'com', - block_id: -1, - location: function(text) { + css: ['com', 'block'], + blockId: function (text) { let matches = /\d+/.exec(text); if (!matches) return undefined; BLOCK_HEADER_STYLE.block_id = Number(matches[0]); - return { - block_id: BLOCK_HEADER_STYLE.block_id - }; + return BLOCK_HEADER_STYLE.block_id; }, + linkHandler: function (text) { + let matches = /\d+/.exec(text); + if (!matches) return undefined; + const blockId = matches[0]; + return function (e) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.blockSelectionHandler.select([blockId], true); + }; + } }; const SOURCE_POSITION_HEADER_STYLE = { css: 'com', - location: function(text) { - let matches = /(\d+):(\d+)/.exec(text); + sourcePosition: function (text) { + let matches = view.SOURCE_POSITION_HEADER_REGEX.exec(text); if (!matches) return undefined; - let li = Number(matches[1]); - if (view.pos_lines === null) return undefined; - let pos = view.pos_lines[li-1] + Number(matches[2]); - return { - pos_start: pos, - pos_end: pos + 1 - }; + const scriptOffset = Number(matches[3]); + const inliningId = matches[1] === 'not inlined' ? -1 : Number(matches[2]); + const sp = { scriptOffset: scriptOffset, inliningId: inliningId }; + SOURCE_POSITION_HEADER_STYLE.currentSourcePosition = sp; + return sp; }, }; - view.SOURCE_POSITION_HEADER_REGEX = /^(\s*-- .+:)(\d+:\d+)( --)/; + view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/; let patterns = [ [ [/^0x[0-9a-f]{8,16}/, ADDRESS_STYLE, 1], @@ -119,36 +131,6 @@ class DisassemblyView extends TextView { view.setPatterns(patterns); } - lineLocation(li) { - let view = this; - let result = undefined; - for (let i = 0; i < li.children.length; ++i) { - let fragment = li.children[i]; - let location = fragment.location; - if (location != null) { - if (location.block_id != undefined) { - if (result === undefined) result = {}; - result.block_id = location.block_id; - } - if (location.address != undefined) { - if (result === undefined) result = {}; - result.address = location.address; - } - if (location.pos_start != undefined && location.pos_end != undefined) { - if (result === undefined) result = {}; - result.pos_start = location.pos_start; - result.pos_end = location.pos_end; - } - else if (view.pos_start != -1) { - if (result === undefined) result = {}; - result.pos_start = view.pos_start; - result.pos_end = result.pos_start + 1; - } - } - } - return result; - } - initializeContent(data, rememberedSelection) { this.data = data; super.initializeContent(data, rememberedSelection); @@ -164,13 +146,13 @@ class DisassemblyView extends TextView { // Comment lines for line 0 include sourcePosition already, only need to // add sourcePosition for lines > 0. view.pos_lines[0] = sourcePosition; - if (sourceText != "") { + if (sourceText && sourceText != "") { let base = sourcePosition; let current = 0; let source_lines = sourceText.split("\n"); for (let i = 1; i < source_lines.length; i++) { // Add 1 for newline character that is split off. - current += source_lines[i-1].length + 1; + current += source_lines[i - 1].length + 1; view.pos_lines[i] = base + current; } } @@ -209,16 +191,6 @@ class DisassemblyView extends TextView { processLine(line) { let view = this; - let func = function(match, p1, p2, p3) { - let nums = p2.split(":"); - let li = Number(nums[0]); - let pos = Number(nums[1]); - if(li === 0) - pos -= view.pos_lines[0]; - li++; - return p1 + li + ":" + pos + p3; - }; - line = line.replace(view.SOURCE_POSITION_HEADER_REGEX, func); let fragments = super.processLine(line); // Add profiling data per instruction if available. @@ -230,7 +202,7 @@ class DisassemblyView extends TextView { let count = view.addr_event_counts[event][matches[1]]; let str = " "; let css_cls = "prof"; - if(count !== undefined) { + if (count !== undefined) { let perc = count / view.total_event_counts[event] * 100; let col = { r: 255, g: 255, b: 255 }; diff --git a/deps/v8/tools/turbolizer/empty-view.js b/deps/v8/tools/turbolizer/empty-view.js deleted file mode 100644 index 66caf59d8f..0000000000 --- a/deps/v8/tools/turbolizer/empty-view.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 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. - -"use strict"; - -class EmptyView extends View { - constructor(id, broker) { - super(id, broker); - this.svg = this.divElement.append("svg").attr('version','1.1').attr("width", "100%"); - } - - initializeContent(data, rememberedSelection) { - this.svg.attr("height", document.documentElement.clientHeight + "px"); - } - - deleteContent() { - } -} diff --git a/deps/v8/tools/turbolizer/graph-layout.js b/deps/v8/tools/turbolizer/graph-layout.js index e9b44b4d2c..1c52aac4a1 100644 --- a/deps/v8/tools/turbolizer/graph-layout.js +++ b/deps/v8/tools/turbolizer/graph-layout.js @@ -447,7 +447,7 @@ function layoutNodeGraph(graph) { }); graph.maxBackEdgeNumber = 0; - graph.visibleEdges.each(function (e) { + graph.visibleEdges.selectAll("path").each(function (e) { if (e.isBackEdge()) { e.backEdgeNumber = ++graph.maxBackEdgeNumber; } else { @@ -489,5 +489,4 @@ function redetermineGraphBoundingBox(graph) { graph.maxGraphX = graph.maxGraphNodeX + graph.maxBackEdgeNumber * MINIMUM_EDGE_SEPARATION; - } diff --git a/deps/v8/tools/turbolizer/graph-view.js b/deps/v8/tools/turbolizer/graph-view.js index cdbc40c8f0..31669de803 100644 --- a/deps/v8/tools/turbolizer/graph-view.js +++ b/deps/v8/tools/turbolizer/graph-view.js @@ -4,16 +4,31 @@ "use strict"; +function nodeToStringKey(n) { + return "" + n.id; +} + class GraphView extends View { - constructor (d3, id, nodes, edges, broker) { + createViewElement() { + const pane = document.createElement('div'); + pane.setAttribute('id', "graph"); + return pane; + } + + constructor(d3, id, broker, showPhaseByName) { super(id, broker); var graph = this; + this.showPhaseByName = showPhaseByName - var svg = this.divElement.append("svg").attr('version','1.1').attr("width", "100%"); + var svg = this.divElement.append("svg").attr('version', '1.1') + .attr("width", "100%") + .attr("height", "100%"); + svg.on("mousedown", function (d) { graph.svgMouseDown.call(graph, d); }); + svg.on("mouseup", function (d) { graph.svgMouseUp.call(graph, d); }); graph.svg = svg; - graph.nodes = nodes || []; - graph.edges = edges || []; + graph.nodes = []; + graph.edges = []; graph.minGraphX = 0; graph.maxGraphX = 1; @@ -26,77 +41,52 @@ class GraphView extends View { justDragged: false, justScaleTransGraph: false, lastKeyDown: -1, - showTypes: false + showTypes: false, + hideDead: false }; - var selectionHandler = { - clear: function() { - broker.clear(selectionHandler); + this.selectionHandler = { + clear: function () { + graph.state.selection.clear(); + broker.broadcastClear(this); + graph.updateGraphVisibility(); }, - select: function(items, selected) { - var locations = []; - for (var d of items) { - if (selected) { - d.classList.add("selected"); - } else { - d.classList.remove("selected"); + select: function (nodes, selected) { + let locations = []; + for (const node of nodes) { + if (node.sourcePosition) { + locations.push(node.sourcePosition); } - var data = d.__data__; - locations.push({ pos_start: data.pos, pos_end: data.pos + 1, node_id: data.id}); } - broker.select(selectionHandler, locations, selected); - }, - selectionDifference: function(span1, inclusive1, span2, inclusive2) { - // Should not be called + graph.state.selection.select(nodes, selected); + broker.broadcastSourcePositionSelect(this, locations, selected); + graph.updateGraphVisibility(); }, - brokeredSelect: function(locations, selected) { - var test = [].entries().next(); - var selection = graph.nodes - .filter(function(n) { - var pos = n.pos; - for (var location of locations) { - var start = location.pos_start; - var end = location.pos_end; - var id = location.node_id; - if (end != undefined) { - if (pos >= start && pos < end) { - return true; - } - } else if (start != undefined) { - if (pos === start) { - return true; - } - } else { - if (n.id === id) { - return true; - } - } - } - return false; + brokeredNodeSelect: function (locations, selected) { + let selection = graph.nodes + .filter(function (n) { + return locations.has(nodeToStringKey(n)) + && (!graph.state.hideDead || n.isLive()); }); - var newlySelected = new Set(); - selection.forEach(function(n) { - newlySelected.add(n); - if (!n.visible) { - n.visible = true; - } + graph.state.selection.select(selection, selected); + // Update edge visibility based on selection. + graph.nodes.forEach((n) => { + if (graph.state.selection.isSelected(n)) n.visible = true; }); - graph.updateGraphVisibility(); - graph.visibleNodes.each(function(n) { - if (newlySelected.has(n)) { - graph.state.selection.select(this, selected); - } + graph.edges.forEach(function (e) { + e.visible = e.visible || + (graph.state.selection.isSelected(e.source) && graph.state.selection.isSelected(e.target)); }); graph.updateGraphVisibility(); - graph.viewSelection(); }, - brokeredClear: function() { + brokeredClear: function () { graph.state.selection.clear(); + graph.updateGraphVisibility(); } }; - broker.addSelectionHandler(selectionHandler); + broker.addNodeHandler(this.selectionHandler); - graph.state.selection = new Selection(selectionHandler); + graph.state.selection = new Selection(nodeToStringKey); var defs = svg.append('svg:defs'); defs.append('svg:marker') @@ -110,51 +100,47 @@ class GraphView extends View { .attr('d', 'M0,-4L8,0L0,4'); this.graphElement = svg.append("g"); - graph.visibleEdges = this.graphElement.append("g").selectAll("g"); - graph.visibleNodes = this.graphElement.append("g").selectAll("g"); + graph.visibleEdges = this.graphElement.append("g"); + graph.visibleNodes = this.graphElement.append("g"); graph.drag = d3.behavior.drag() - .origin(function(d){ - return {x: d.x, y: d.y}; + .origin(function (d) { + return { x: d.x, y: d.y }; }) - .on("drag", function(args){ + .on("drag", function (args) { graph.state.justDragged = true; graph.dragmove.call(graph, args); }) - d3.select("#upload").on("click", partial(this.uploadAction, graph)); d3.select("#layout").on("click", partial(this.layoutAction, graph)); d3.select("#show-all").on("click", partial(this.showAllAction, graph)); - d3.select("#hide-dead").on("click", partial(this.hideDeadAction, graph)); + d3.select("#toggle-hide-dead").on("click", partial(this.toggleHideDead, graph)); d3.select("#hide-unselected").on("click", partial(this.hideUnselectedAction, graph)); d3.select("#hide-selected").on("click", partial(this.hideSelectedAction, graph)); d3.select("#zoom-selection").on("click", partial(this.zoomSelectionAction, graph)); d3.select("#toggle-types").on("click", partial(this.toggleTypesAction, graph)); - d3.select("#search-input").on("keydown", partial(this.searchInputAction, graph)); // listen for key events - d3.select(window).on("keydown", function(e){ + d3.select(window).on("keydown", function (e) { graph.svgKeyDown.call(graph); }) - .on("keyup", function(){ + .on("keyup", function () { graph.svgKeyUp.call(graph); }); - svg.on("mousedown", function(d){graph.svgMouseDown.call(graph, d);}); - svg.on("mouseup", function(d){graph.svgMouseUp.call(graph, d);}); graph.dragSvg = d3.behavior.zoom() - .on("zoom", function(){ - if (d3.event.sourceEvent.shiftKey){ + .on("zoom", function () { + if (d3.event.sourceEvent.shiftKey) { return false; - } else{ + } else { graph.zoomed.call(graph); } return true; }) - .on("zoomstart", function(){ + .on("zoomstart", function () { if (!d3.event.sourceEvent.shiftKey) d3.select('body').style("cursor", "move"); }) - .on("zoomend", function(){ + .on("zoomend", function () { d3.select('body').style("cursor", "auto"); }); @@ -184,16 +170,16 @@ class GraphView extends View { getEdgeFrontier(nodes, inEdges, edgeFilter) { let frontier = new Set(); - nodes.forEach(function(element) { - var edges = inEdges ? element.__data__.inputs : element.__data__.outputs; + for (const n of nodes) { + var edges = inEdges ? n.inputs : n.outputs; var edgeNumber = 0; - edges.forEach(function(edge) { + edges.forEach(function (edge) { if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) { frontier.add(edge); } ++edgeNumber; }); - }); + } return frontier; } @@ -204,13 +190,13 @@ class GraphView extends View { var edgeFrontier = graph.getEdgeFrontier(nodes, inEdges, edgeFilter); // Control key toggles edges rather than just turning them on if (d3.event.ctrlKey) { - edgeFrontier.forEach(function(edge) { + edgeFrontier.forEach(function (edge) { if (edge.visible) { newState = false; } }); } - edgeFrontier.forEach(function(edge) { + edgeFrontier.forEach(function (edge) { edge.visible = newState; if (newState) { var node = inEdges ? edge.source : edge.target; @@ -220,9 +206,7 @@ class GraphView extends View { }); graph.updateGraphVisibility(); if (newState) { - return graph.visibleNodes.filter(function(n) { - return frontier.has(n); - }); + return frontier; } else { return undefined; } @@ -243,6 +227,7 @@ class GraphView extends View { this.viewSelection(); } this.updateGraphVisibility(); + this.fitGraphViewToWindow(); } deleteContent() { @@ -263,15 +248,19 @@ class GraphView extends View { }; } - createGraph(data, initiallyVisibileIds) { + createGraph(data, rememberedSelection) { var g = this; g.nodes = data.nodes; g.nodeMap = []; - g.nodes.forEach(function(n, i){ + g.nodes.forEach(function (n, i) { n.__proto__ = Node; n.visible = false; n.x = 0; n.y = 0; + if (typeof n.pos === "number") { + // Backwards compatibility. + n.sourcePosition = { scriptOffset: n.pos, inliningId: -1 }; + } n.rank = MAX_RANK_SENTINEL; n.inputs = []; n.outputs = []; @@ -284,12 +273,12 @@ class GraphView extends View { n.typebbox = g.measureText(n.getDisplayType()); var innerwidth = Math.max(n.labelbbox.width, n.typebbox.width); n.width = Math.alignUp(innerwidth + NODE_INPUT_WIDTH * 2, - NODE_INPUT_WIDTH); + NODE_INPUT_WIDTH); var innerheight = Math.max(n.labelbbox.height, n.typebbox.height); n.normalheight = innerheight + 20; }); g.edges = []; - data.edges.forEach(function(e, i){ + data.edges.forEach(function (e, i) { var t = g.nodeMap[e.target]; var s = g.nodeMap[e.source]; var newEdge = new Edge(t, e.index, s, e.type); @@ -300,10 +289,10 @@ class GraphView extends View { s.cfg = true; } }); - g.nodes.forEach(function(n, i) { - n.visible = isNodeInitiallyVisible(n); - if (initiallyVisibileIds != undefined) { - if (initiallyVisibileIds.has(n.id)) { + g.nodes.forEach(function (n, i) { + n.visible = isNodeInitiallyVisible(n) && (!g.state.hideDead || n.isLive()); + if (rememberedSelection != undefined) { + if (rememberedSelection.has(nodeToStringKey(n))) { n.visible = true; } } @@ -317,25 +306,24 @@ class GraphView extends View { connectVisibleSelectedNodes() { var graph = this; - graph.state.selection.selection.forEach(function(element) { - var edgeNumber = 0; - element.__data__.inputs.forEach(function(edge) { + for (const n of graph.state.selection) { + n.inputs.forEach(function (edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } }); - element.__data__.outputs.forEach(function(edge) { + n.outputs.forEach(function (edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } }); - }); + } } updateInputAndOutputBubbles() { var g = this; var s = g.visibleBubbles; - s.classed("filledBubbleStyle", function(c) { + s.classed("filledBubbleStyle", function (c) { var components = this.id.split(','); if (components[0] == "ib") { var edge = g.nodeMap[components[3]].inputs[components[2]]; @@ -343,7 +331,7 @@ class GraphView extends View { } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 2; } - }).classed("halfFilledBubbleStyle", function(c) { + }).classed("halfFilledBubbleStyle", function (c) { var components = this.id.split(','); if (components[0] == "ib") { var edge = g.nodeMap[components[3]].inputs[components[2]]; @@ -351,7 +339,7 @@ class GraphView extends View { } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 1; } - }).classed("bubbleStyle", function(c) { + }).classed("bubbleStyle", function (c) { var components = this.id.split(','); if (components[0] == "ib") { var edge = g.nodeMap[components[3]].inputs[components[2]]; @@ -360,7 +348,7 @@ class GraphView extends View { return g.nodeMap[components[1]].areAnyOutputsVisible() == 0; } }); - s.each(function(c) { + s.each(function (c) { var components = this.id.split(','); if (components[0] == "ob") { var from = g.nodeMap[components[1]]; @@ -373,29 +361,26 @@ class GraphView extends View { } attachSelection(s) { - var graph = this; - if (s.size != 0) { - this.visibleNodes.each(function(n) { - if (s.has(this.__data__.id)) { - graph.state.selection.select(this, true); - } - }); - } + const graph = this; + if (!(s instanceof Set)) return; + graph.selectionHandler.clear(); + const selected = graph.nodes.filter((n) => + s.has(graph.state.selection.stringKey(n)) && (!graph.state.hideDead || n.isLive())); + graph.selectionHandler.select(selected, true); } detachSelection() { - var selection = this.state.selection.detachSelection(); - var s = new Set(); - for (var i of selection) { - s.add(i.__data__.id); - }; - return s; + return this.state.selection.detachSelection(); } - pathMouseDown(path, d) { + pathMouseUp(path, d) { d3.event.stopPropagation(); - this.state.selection.clear(); - this.state.selection.add(path); + const edge = path.datum(); + if (!d3.event.shiftKey) { + this.selectionHandler.clear(); + } + this.selectionHandler.select([edge.source, edge.target], true); + return false; }; nodeMouseDown(node, d) { @@ -404,62 +389,35 @@ class GraphView extends View { } nodeMouseUp(d3node, d) { - var graph = this, - state = graph.state, - consts = graph.consts; - - var mouseDownNode = state.mouseDownNode; + let graph = this; + let state = graph.state; - if (!mouseDownNode) return; + if (!state.mouseDownNode) return; if (state.justDragged) { // dragged, not clicked redetermineGraphBoundingBox(graph); state.justDragged = false; - } else{ + } else { // clicked, not dragged var extend = d3.event.shiftKey; - var selection = graph.state.selection; if (!extend) { - selection.clear(); + graph.selectionHandler.clear(); } - selection.select(d3node[0][0], true); + graph.selectionHandler.select([d3node.datum()], undefined); } } - selectSourcePositions(start, end, selected) { - var graph = this; - var map = []; - var sel = graph.nodes.filter(function(n) { - var pos = (n.pos === undefined) - ? -1 - : n.getFunctionRelativeSourcePosition(graph); - if (pos >= start && pos < end) { - map[n.id] = true; - n.visible = true; - } - }); - graph.updateGraphVisibility(); - graph.visibleNodes.filter(function(n) { return map[n.id]; }) - .each(function(n) { - var selection = graph.state.selection; - selection.select(d3.select(this), selected); - }); - } - selectAllNodes(inEdges, filter) { var graph = this; if (!d3.event.shiftKey) { graph.state.selection.clear(); } - graph.state.selection.select(graph.visibleNodes[0], true); + const allVisibleNodes = graph.nodes.filter((n) => n.visible); + graph.state.selection.select(allVisibleNodes, true); graph.updateGraphVisibility(); } - uploadAction(graph) { - document.getElementById("hidden-file-upload").click(); - } - layoutAction(graph) { graph.updateGraphVisibility(); graph.layoutGraph(); @@ -468,36 +426,50 @@ class GraphView extends View { } showAllAction(graph) { - graph.nodes.filter(function(n) { n.visible = true; }) - graph.edges.filter(function(e) { e.visible = true; }) + graph.nodes.forEach(function (n) { + n.visible = !graph.state.hideDead || n.isLive(); + }); + graph.edges.forEach(function (e) { + e.visible = !graph.state.hideDead || (e.source.isLive() && e.target.isLive()); + }); graph.updateGraphVisibility(); graph.viewWholeGraph(); } - hideDeadAction(graph) { - graph.nodes.filter(function(n) { if (!n.isLive()) n.visible = false; }) + toggleHideDead(graph) { + graph.state.hideDead = !graph.state.hideDead; + if (graph.state.hideDead) graph.hideDead(); + var element = document.getElementById('toggle-hide-dead'); + element.classList.toggle('button-input-toggled', graph.state.hideDead); + } + + hideDead() { + const graph = this; + graph.nodes.filter(function (n) { + if (!n.isLive()) { + n.visible = false; + graph.state.selection.select([n], false); + } + }) graph.updateGraphVisibility(); } hideUnselectedAction(graph) { - var unselected = graph.visibleNodes.filter(function(n) { - return !this.classList.contains("selected"); - }); - unselected.each(function(n) { - n.visible = false; + graph.nodes.forEach(function (n) { + if (!graph.state.selection.isSelected(n)) { + n.visible = false; + } }); graph.updateGraphVisibility(); } hideSelectedAction(graph) { - var selected = graph.visibleNodes.filter(function(n) { - return this.classList.contains("selected"); - }); - selected.each(function(n) { - n.visible = false; + graph.nodes.forEach(function (n) { + if (graph.state.selection.isSelected(n)) { + n.visible = false; + } }); - graph.state.selection.clear(); - graph.updateGraphVisibility(); + graph.selectionHandler.clear(); } zoomSelectionAction(graph) { @@ -508,34 +480,34 @@ class GraphView extends View { graph.toggleTypes(); } - searchInputAction(graph) { + searchInputAction(graph, searchBar) { if (d3.event.keyCode == 13) { - graph.state.selection.clear(); - var query = this.value; + graph.selectionHandler.clear(); + var query = searchBar.value; window.sessionStorage.setItem("lastSearch", query); + if (query.length == 0) return; var reg = new RegExp(query); - var filterFunction = function(n) { + var filterFunction = function (n) { return (reg.exec(n.getDisplayLabel()) != null || - (graph.state.showTypes && reg.exec(n.getDisplayType())) || - reg.exec(n.opcode) != null); + (graph.state.showTypes && reg.exec(n.getDisplayType())) || + (reg.exec(n.getTitle())) || + reg.exec(n.opcode) != null); }; - if (d3.event.ctrlKey) { - graph.nodes.forEach(function(n, i) { - if (filterFunction(n)) { - n.visible = true; + + const selection = graph.nodes.filter( + function (n, i) { + if ((d3.event.ctrlKey || n.visible) && filterFunction(n)) { + if (d3.event.ctrlKey) n.visible = true; + return true; } + return false; }); - graph.updateGraphVisibility(); - } - var selected = graph.visibleNodes.each(function(n) { - if (filterFunction(n)) { - graph.state.selection.select(this, true); - } - }); + + graph.selectionHandler.select(selection, true); graph.connectVisibleSelectedNodes(); graph.updateGraphVisibility(); - this.blur(); + searchBar.blur(); graph.viewSelection(); } d3.event.stopPropagation(); @@ -546,15 +518,15 @@ class GraphView extends View { } svgMouseUp() { - var graph = this, - state = graph.state; + const graph = this; + const state = graph.state; if (state.justScaleTransGraph) { // Dragged state.justScaleTransGraph = false; } else { // Clicked - if (state.mouseDownNode == null) { - graph.state.selection.clear(); + if (state.mouseDownNode == null && !d3.event.shiftKey) { + graph.selectionHandler.clear(); } } state.mouseDownNode = null; @@ -566,16 +538,16 @@ class GraphView extends View { var graph = this; // Don't handle key press repetition - if(state.lastKeyDown !== -1) return; + if (state.lastKeyDown !== -1) return; - var showSelectionFrontierNodes = function(inEdges, filter, select) { - var frontier = graph.getNodeFrontier(state.selection.selection, inEdges, filter); - if (frontier != undefined) { + var showSelectionFrontierNodes = function (inEdges, filter, select) { + var frontier = graph.getNodeFrontier(state.selection, inEdges, filter); + if (frontier != undefined && frontier.size) { if (select) { if (!d3.event.shiftKey) { state.selection.clear(); } - state.selection.select(frontier[0], true); + state.selection.select(frontier, true); } graph.updateGraphVisibility(); } @@ -584,81 +556,85 @@ class GraphView extends View { var allowRepetition = true; var eventHandled = true; // unless the below switch defaults - switch(d3.event.keyCode) { - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - // '1'-'9' - showSelectionFrontierNodes(true, + switch (d3.event.keyCode) { + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + // '1'-'9' + showSelectionFrontierNodes(true, (edge, index) => { return index == (d3.event.keyCode - 49); }, false); - break; - case 97: - case 98: - case 99: - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - // 'numpad 1'-'numpad 9' - showSelectionFrontierNodes(true, + break; + case 97: + case 98: + case 99: + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + // 'numpad 1'-'numpad 9' + showSelectionFrontierNodes(true, (edge, index) => { return index == (d3.event.keyCode - 97); }, false); - break; - case 67: - // 'c' - showSelectionFrontierNodes(true, + break; + case 67: + // 'c' + showSelectionFrontierNodes(d3.event.altKey, (edge, index) => { return edge.type == 'control'; }, - false); - break; - case 69: - // 'e' - showSelectionFrontierNodes(true, - (edge, index) => { return edge.type == 'effect'; }, - false); - break; - case 79: - // 'o' - showSelectionFrontierNodes(false, undefined, false); - break; - case 73: - // 'i' - showSelectionFrontierNodes(true, undefined, false); - break; - case 65: - // 'a' - graph.selectAllNodes(); - allowRepetition = false; - break; - case 38: - case 40: { - showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true); - break; - } - case 82: - // 'r' - if (!d3.event.ctrlKey) { - this.layoutAction(this); - } else { - eventHandled = false; + true); + break; + case 69: + // 'e' + showSelectionFrontierNodes(d3.event.altKey, + (edge, index) => { return edge.type == 'effect'; }, + true); + break; + case 79: + // 'o' + showSelectionFrontierNodes(false, undefined, false); + break; + case 73: + // 'i' + showSelectionFrontierNodes(true, undefined, false); + break; + case 65: + // 'a' + graph.selectAllNodes(); + allowRepetition = false; + break; + case 38: + case 40: { + showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true); + break; } - break; - case 191: - // '/' - document.getElementById("search-input").focus(); - document.getElementById("search-input").select(); - break; - default: - eventHandled = false; - break; + case 82: + // 'r' + if (!d3.event.ctrlKey) { + this.layoutAction(this); + } else { + eventHandled = false; + } + break; + case 83: + // 's' + graph.selectOrigins(); + break; + case 191: + // '/' + document.getElementById("search-input").focus(); + document.getElementById("search-input").select(); + break; + default: + eventHandled = false; + break; } if (eventHandled) { d3.event.preventDefault(); @@ -672,127 +648,142 @@ class GraphView extends View { this.state.lastKeyDown = -1 }; - layoutEdges() { - var graph = this; - graph.maxGraphX = graph.maxGraphNodeX; - this.visibleEdges.attr("d", function(edge){ - return edge.generatePath(graph); - }); - } - layoutGraph() { layoutNodeGraph(this); } + selectOrigins() { + const state = this.state; + const origins = []; + let phase = null; + for (const n of state.selection) { + if (n.origin) { + const node = this.nodeMap[n.origin.nodeId]; + origins.push(node); + phase = n.origin.phase; + } + } + if (origins.length) { + state.selection.clear(); + state.selection.select(origins, true); + if (phase) { + this.showPhaseByName(phase); + } + } + } + // call to propagate changes to graph updateGraphVisibility() { + let graph = this; + let state = graph.state; - var graph = this, - state = graph.state; - - var filteredEdges = graph.edges.filter(function(e) { return e.isVisible(); }); - var visibleEdges = graph.visibleEdges.data(filteredEdges, function(edge) { + var filteredEdges = graph.edges.filter(function (e) { + return e.isVisible(); + }); + const selEdges = graph.visibleEdges.selectAll("path").data(filteredEdges, function (edge) { return edge.stringID(); }); + // remove old links + selEdges.exit().remove(); + // add new paths - visibleEdges.enter() + selEdges.enter() .append('path') - .style('marker-end','url(#end-arrow)') - .classed('hidden', function(e) { + .style('marker-end', 'url(#end-arrow)') + .classed('hidden', function (e) { return !e.isVisible(); }) - .attr("id", function(edge){ return "e," + edge.stringID(); }) - .on("mousedown", function(d){ - graph.pathMouseDown.call(graph, d3.select(this), d); + .attr("id", function (edge) { return "e," + edge.stringID(); }) + .on("mouseup", function (d) { + graph.pathMouseUp.call(graph, d3.select(this), d); }) .attr("adjacentToHover", "false"); // Set the correct styles on all of the paths - visibleEdges.classed('value', function(e) { + selEdges.classed('value', function (e) { return e.type == 'value' || e.type == 'context'; - }).classed('control', function(e) { + }).classed('control', function (e) { return e.type == 'control'; - }).classed('effect', function(e) { + }).classed('effect', function (e) { return e.type == 'effect'; - }).classed('frame-state', function(e) { + }).classed('frame-state', function (e) { return e.type == 'frame-state'; - }).attr('stroke-dasharray', function(e) { + }).attr('stroke-dasharray', function (e) { if (e.type == 'frame-state') return "10,10"; return (e.type == 'effect') ? "5,5" : ""; }); - // remove old links - visibleEdges.exit().remove(); - - graph.visibleEdges = visibleEdges; - - // update existing nodes - var filteredNodes = graph.nodes.filter(function(n) { return n.visible; }); - graph.visibleNodes = graph.visibleNodes.data(filteredNodes, function(d) { + // select existing nodes + var filteredNodes = graph.nodes.filter(function (n) { + return n.visible; + }); + let selNodes = graph.visibleNodes.selectAll("g").data(filteredNodes, function (d) { return d.id; }); - graph.visibleNodes.attr("transform", function(n){ - return "translate(" + n.x + "," + n.y + ")"; - }).select('rect'). - attr(HEIGHT, function(d) { return graph.getNodeHeight(d); }); + + // remove old nodes + selNodes.exit().remove(); // add new nodes - var newGs = graph.visibleNodes.enter() + var newGs = selNodes.enter() .append("g"); - newGs.classed("turbonode", function(n) { return true; }) - .classed("control", function(n) { return n.isControl(); }) - .classed("live", function(n) { return n.isLive(); }) - .classed("dead", function(n) { return !n.isLive(); }) - .classed("javascript", function(n) { return n.isJavaScript(); }) - .classed("input", function(n) { return n.isInput(); }) - .classed("simplified", function(n) { return n.isSimplified(); }) - .classed("machine", function(n) { return n.isMachine(); }) - .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")";}) - .on("mousedown", function(d){ + newGs.classed("turbonode", function (n) { return true; }) + .classed("control", function (n) { return n.isControl(); }) + .classed("live", function (n) { return n.isLive(); }) + .classed("dead", function (n) { return !n.isLive(); }) + .classed("javascript", function (n) { return n.isJavaScript(); }) + .classed("input", function (n) { return n.isInput(); }) + .classed("simplified", function (n) { return n.isSimplified(); }) + .classed("machine", function (n) { return n.isMachine(); }) + .on("mousedown", function (d) { graph.nodeMouseDown.call(graph, d3.select(this), d); }) - .on("mouseup", function(d){ + .on("mouseup", function (d) { graph.nodeMouseUp.call(graph, d3.select(this), d); }) - .on('mouseover', function(d){ + .on('mouseover', function (d) { var nodeSelection = d3.select(this); let node = graph.nodeMap[d.id]; - let adjInputEdges = graph.visibleEdges.filter(e => { return e.target === node; }); - let adjOutputEdges = graph.visibleEdges.filter(e => { return e.source === node; }); + let visibleEdges = graph.visibleEdges.selectAll('path'); + let adjInputEdges = visibleEdges.filter(e => { return e.target === node; }); + let adjOutputEdges = visibleEdges.filter(e => { return e.source === node; }); adjInputEdges.attr('relToHover', "input"); adjOutputEdges.attr('relToHover', "output"); let adjInputNodes = adjInputEdges.data().map(e => e.source); - graph.visibleNodes.data(adjInputNodes, function(d) { + let visibleNodes = graph.visibleNodes.selectAll("g"); + visibleNodes.data(adjInputNodes, function (d) { return d.id; }).attr('relToHover', "input"); let adjOutputNodes = adjOutputEdges.data().map(e => e.target); - graph.visibleNodes.data(adjOutputNodes, function(d) { + visibleNodes.data(adjOutputNodes, function (d) { return d.id; }).attr('relToHover', "output"); graph.updateGraphVisibility(); }) - .on('mouseout', function(d){ + .on('mouseout', function (d) { var nodeSelection = d3.select(this); let node = graph.nodeMap[d.id]; - let adjEdges = graph.visibleEdges.filter(e => { return e.target === node || e.source === node; }); + let visibleEdges = graph.visibleEdges.selectAll('path'); + let adjEdges = visibleEdges.filter(e => { return e.target === node || e.source === node; }); adjEdges.attr('relToHover', "none"); let adjNodes = adjEdges.data().map(e => e.target).concat(adjEdges.data().map(e => e.source)); - let nodes = graph.visibleNodes.data(adjNodes, function(d) { + let visibleNodes = graph.visibleNodes.selectAll("g"); + let nodes = visibleNodes.data(adjNodes, function (d) { return d.id; }).attr('relToHover', "none"); graph.updateGraphVisibility(); }) - .call(graph.drag); + .call(graph.drag) newGs.append("rect") .attr("rx", 10) .attr("ry", 10) - .attr(WIDTH, function(d) { + .attr(WIDTH, function (d) { return d.getTotalNodeWidth(); }) - .attr(HEIGHT, function(d) { + .attr(HEIGHT, function (d) { return graph.getNodeHeight(d); }) @@ -801,18 +792,18 @@ class GraphView extends View { var x = d.getInputX(i); var y = -DEFAULT_NODE_BUBBLE_RADIUS; var s = g.append('circle') - .classed("filledBubbleStyle", function(c) { + .classed("filledBubbleStyle", function (c) { return d.inputs[i].isVisible(); - } ) - .classed("bubbleStyle", function(c) { + }) + .classed("bubbleStyle", function (c) { return !d.inputs[i].isVisible(); - } ) + }) .attr("id", "ib," + d.inputs[i].stringID()) .attr("r", DEFAULT_NODE_BUBBLE_RADIUS) - .attr("transform", function(d) { + .attr("transform", function (d) { return "translate(" + x + "," + y + ")"; }) - .on("mousedown", function(d){ + .on("mousedown", function (d) { var components = this.id.split(','); var node = graph.nodeMap[components[3]]; var edge = node.inputs[components[2]]; @@ -826,21 +817,21 @@ class GraphView extends View { var x = d.getOutputX(); var y = graph.getNodeHeight(d) + DEFAULT_NODE_BUBBLE_RADIUS; var s = g.append('circle') - .classed("filledBubbleStyle", function(c) { + .classed("filledBubbleStyle", function (c) { return d.areAnyOutputsVisible() == 2; - } ) - .classed("halFilledBubbleStyle", function(c) { + }) + .classed("halFilledBubbleStyle", function (c) { return d.areAnyOutputsVisible() == 1; - } ) - .classed("bubbleStyle", function(c) { + }) + .classed("bubbleStyle", function (c) { return d.areAnyOutputsVisible() == 0; - } ) + }) .attr("id", "ob," + d.id) .attr("r", DEFAULT_NODE_BUBBLE_RADIUS) - .attr("transform", function(d) { + .attr("transform", function (d) { return "translate(" + x + "," + y + ")"; }) - .on("mousedown", function(d) { + .on("mousedown", function (d) { d.setOutputVisibility(d.areAnyOutputsVisible() == 0); d3.event.stopPropagation(); graph.updateGraphVisibility(); @@ -848,56 +839,66 @@ class GraphView extends View { } } - newGs.each(function(d){ + newGs.each(function (d) { appendInputAndOutputBubbles(d3.select(this), d); }); - newGs.each(function(d){ + newGs.each(function (d) { d3.select(this).append("text") .classed("label", true) - .attr("text-anchor","right") + .attr("text-anchor", "right") .attr("dx", 5) .attr("dy", 5) .append('tspan') - .text(function(l) { + .text(function (l) { return d.getDisplayLabel(); }) .append("title") - .text(function(l) { + .text(function (l) { return d.getTitle(); }) if (d.type != undefined) { d3.select(this).append("text") .classed("label", true) .classed("type", true) - .attr("text-anchor","right") + .attr("text-anchor", "right") .attr("dx", 5) .attr("dy", d.labelbbox.height + 5) .append('tspan') - .text(function(l) { + .text(function (l) { return d.getDisplayType(); }) .append("title") - .text(function(l) { + .text(function (l) { return d.getType(); }) } }); - graph.visibleNodes.select('.type').each(function (d) { + selNodes.select('.type').each(function (d) { this.setAttribute('visibility', graph.state.showTypes ? 'visible' : 'hidden'); }); - // remove old nodes - graph.visibleNodes.exit().remove(); + selNodes + .classed("selected", function (n) { + if (state.selection.isSelected(n)) return true; + return false; + }) + .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }) + .select('rect') + .attr(HEIGHT, function (d) { return graph.getNodeHeight(d); }); graph.visibleBubbles = d3.selectAll('circle'); graph.updateInputAndOutputBubbles(); - graph.layoutEdges(); + graph.maxGraphX = graph.maxGraphNodeX; + selEdges.attr("d", function (edge) { + return edge.generatePath(graph); + }); graph.svg.style.height = '100%'; + redetermineGraphBoundingBox(this); } getVisibleTranslation(translate, scale) { @@ -957,12 +958,12 @@ class GraphView extends View { translateClipped(translate, scale, transition) { var graph = this; - var graphNode = this.graphElement[0][0]; + var graphNode = this.graphElement.node(); var translate = this.getVisibleTranslation(translate, scale); if (transition) { graphNode.classList.add('visible-transition'); clearTimeout(graph.transitionTimout); - graph.transitionTimout = setTimeout(function(){ + graph.transitionTimout = setTimeout(function () { graphNode.classList.remove('visible-transition'); }, 1000); } @@ -972,15 +973,15 @@ class GraphView extends View { graph.dragSvg.scale(scale); } - zoomed(){ + zoomed() { this.state.justScaleTransGraph = true; - var scale = this.dragSvg.scale(); + var scale = this.dragSvg.scale(); this.translateClipped(d3.event.translate, scale); } getSvgViewDimensions() { - var canvasWidth = this.parentNode.clientWidth; + var canvasWidth = this.container.clientWidth; var documentElement = document.documentElement; var canvasHeight = documentElement.clientHeight; return [canvasWidth, canvasHeight]; @@ -1002,7 +1003,6 @@ class GraphView extends View { } fitGraphViewToWindow() { - this.svg.attr("height", document.documentElement.clientHeight + "px"); this.translateClipped(this.dragSvg.translate(), this.dragSvg.scale()); } @@ -1010,11 +1010,7 @@ class GraphView extends View { var graph = this; graph.state.showTypes = !graph.state.showTypes; var element = document.getElementById('toggle-types'); - if (graph.state.showTypes) { - element.classList.add('button-input-toggled'); - } else { - element.classList.remove('button-input-toggled'); - } + element.classList.toggle('button-input-toggled', graph.state.showTypes); graph.updateGraphVisibility(); } @@ -1022,8 +1018,8 @@ class GraphView extends View { var graph = this; var minX, maxX, minY, maxY; var hasSelection = false; - graph.visibleNodes.each(function(n) { - if (this.classList.contains("selected")) { + graph.visibleNodes.selectAll("g").each(function (n) { + if (graph.state.selection.isSelected(n)) { hasSelection = true; minX = minX ? Math.min(minX, n.x) : n.x; maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) : @@ -1035,8 +1031,8 @@ class GraphView extends View { }); if (hasSelection) { graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, - maxX + NODE_INPUT_WIDTH, maxY + 60, - true); + maxX + NODE_INPUT_WIDTH, maxY + 60, + true); } } @@ -1048,7 +1044,7 @@ class GraphView extends View { var scale = Math.min(dimensions[0] / width, dimensions[1] / height); scale = Math.min(1.5, scale); scale = Math.max(graph.minScale(), scale); - var translation = [-minX*scale, -minY*scale]; + var translation = [-minX * scale, -minY * scale]; translation = graph.getVisibleTranslation(translation, scale); graph.translateClipped(translation, scale, transition); } diff --git a/deps/v8/tools/turbolizer/index.html b/deps/v8/tools/turbolizer/index.html index 2167d21a14..a37fdda491 100644 --- a/deps/v8/tools/turbolizer/index.html +++ b/deps/v8/tools/turbolizer/index.html @@ -3,13 +3,11 @@ <head> <title>Turbolizer</title> <link rel="stylesheet" href="turbo-visualizer.css" /> + <link rel="stylesheet" href="prettify.css" /> + <link rel="icon" type="image/png" href="turbolizer.png"> </head> <body> - <div id="left" class="viewpane"> - <div id='source-text'> - <pre id='source-text-pre'\> - </div> - </div> + <div id="left" class="viewpane scrollable"></div> <div class="resizer-left"></div> <div id="middle" class="viewpane"> <div id="graph-toolbox-anchor"> @@ -18,7 +16,7 @@ alt="layout graph" class="button-input"> <input id="show-all" type="image" title="show all nodes" src="expand-all.jpg" alt="show all nodes" class="button-input"> - <input id="hide-dead" type="image" title="only live nodes" src="live.png" + <input id="toggle-hide-dead" type="image" title="show only live nodes" src="live.png" alt="only live nodes" class="button-input"> <input id="hide-unselected" type="image" title="hide unselected nodes" src="hide-unselected.png" alt="hide unselected nodes" class="button-input"> @@ -36,33 +34,17 @@ </select> </span> </div> - <div id="load-file"> - <input type="file" id="hidden-file-upload"> + <input id="upload-helper" type="file"> <input id="upload" type="image" title="load graph" class="button-input" src="upload-icon.png" alt="upload graph"> </div> - <div id="empty" width="100%" height="100%"></div> - <div id="graph" width="100%" height="100%"></div> - <div id="schedule" width="100%"> - <pre id="schedule-text-pre" class='prettyprint prettyprinted'> - <ul id="schedule-list" class='nolinenums noindent'> - </ul> - </pre> - </div> <div id='text-placeholder' width="0px" height="0px" style="position: absolute; top:100000px;" ><svg><text text-anchor="right"> <tspan white-space="inherit" id="text-measure"/> </text></svg></div> </div> <div class="resizer-right"></div> - <div id="right" class="viewpane"> - <div id='disassembly'> - <pre id='disassembly-text-pre' class='prettyprint prettyprinted'> - <ul id='disassembly-list' class='nolinenums noindent'> - </ul> - </pre> - </div> - </div> + <div id="right" class="viewpane scrollable"></div> <div id="source-collapse" class="collapse-pane"> <input id="source-expand" type="image" title="show source" src="right-arrow.png" class="button-input invisible"> @@ -76,19 +58,18 @@ src="right-arrow.png" class="button-input"> </div> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> - <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> - <script src="https://cdn.jsdelivr.net/filesaver.js/0.1/FileSaver.min.js"></script> + <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="monkey.js"></script> <script src="util.js"></script> <script src="lang-disassembly.js"></script> <script src="node.js"></script> <script src="edge.js"></script> + <script src="source-resolver.js"></script> <script src="selection.js"></script> <script src="selection-broker.js"></script> <script src="constants.js"></script> <script src="view.js"></script> <script src="text-view.js"></script> - <script src="empty-view.js"></script> <script src="code-view.js"></script> <script src="graph-layout.js"></script> <script src="graph-view.js"></script> diff --git a/deps/v8/tools/turbolizer/node.js b/deps/v8/tools/turbolizer/node.js index b718cdc4df..237b4d2b2d 100644 --- a/deps/v8/tools/turbolizer/node.js +++ b/deps/v8/tools/turbolizer/node.js @@ -57,7 +57,11 @@ var Node = { } else { propsString = "[" + this.properties + "]"; } - return this.title + "\n" + propsString + "\n" + this.opinfo; + let title = this.title + "\n" + propsString + "\n" + this.opinfo; + if (this.origin) { + title += `\nOrigin: #${this.origin.nodeId} in phase ${this.origin.phase}/${this.origin.reducer}`; + } + return title; }, getDisplayLabel: function() { var result = this.id + ":" + this.label; diff --git a/deps/v8/tools/turbolizer/schedule-view.js b/deps/v8/tools/turbolizer/schedule-view.js index ef4789211d..0864fceea7 100644 --- a/deps/v8/tools/turbolizer/schedule-view.js +++ b/deps/v8/tools/turbolizer/schedule-view.js @@ -5,124 +5,159 @@ "use strict"; class ScheduleView extends TextView { - constructor(id, broker) { - super(id, broker, null, false); - let view = this; - let BLOCK_STYLE = { - css: 'tag' - }; - const BLOCK_HEADER_STYLE = { - css: 'com', - block_id: -1, - location: function(text) { - let matches = /\d+/.exec(text); - if (!matches) return undefined; - BLOCK_HEADER_STYLE.block_id = Number(matches[0]); - return { - block_id: BLOCK_HEADER_STYLE.block_id - }; - }, - }; - const BLOCK_LINK_STYLE = { - css: 'tag', - link: function(text) { - let id = Number(text.substr(1)); - view.select(function(location) { return location.block_id == id; }, true, true); - } - }; - const ID_STYLE = { - css: 'tag', - location: function(text) { - let matches = /\d+/.exec(text); - return { - node_id: Number(matches[0]), - block_id: BLOCK_HEADER_STYLE.block_id - }; - }, - }; - const ID_LINK_STYLE = { - css: 'tag', - link: function(text) { - let id = Number(text); - view.select(function(location) { return location.node_id == id; }, true, true); + + createViewElement() { + const pane = document.createElement('div'); + pane.setAttribute('id', "schedule"); + pane.innerHTML = + `<pre id='schedule-text-pre' class='prettyprint prettyprinted'> + <ul id='schedule-list' class='nolinenums noindent'> + </ul> + </pre>`; + return pane; + } + + constructor(parentId, broker) { + super(parentId, broker, null, false); + } + + attachSelection(s) { + const view = this; + if (!(s instanceof Set)) return; + view.selectionHandler.clear(); + view.blockSelectionHandler.clear(); + view.sourcePositionSelectionHandler.clear(); + const selected = new Array(); + for (const key of s) selected.push(key); + view.selectionHandler.select(selected, true); + } + + createElementFromString(htmlString) { + var div = document.createElement('div'); + div.innerHTML = htmlString.trim(); + return div.firstChild; + } + + + elementForBlock(block) { + const view = this; + function createElement(tag, cls, content) { + const el = document.createElement(tag); + if (isIterable(cls)) { + for (const c of cls) el.classList.add(c); + } else { + el.classList.add(cls); } - }; - const NODE_STYLE = { css: 'kwd' }; - const GOTO_STYLE = { css: 'kwd', - goto_id: -2, - location: function(text) { - return { - node_id: GOTO_STYLE.goto_id--, - block_id: BLOCK_HEADER_STYLE.block_id - }; + if (content != undefined) el.innerHTML = content; + return el; + } + + function mkNodeLinkHandler(nodeId) { + return function (e) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.selectionHandler.select([nodeId], true); + }; + } + + function createElementForNode(node) { + const nodeEl = createElement("div", "node"); + const node_id = createElement("div", ["node-id", "tag", "clickable"], node.id); + node_id.onclick = mkNodeLinkHandler(node.id); + view.addHtmlElementForNodeId(node.id, node_id); + nodeEl.appendChild(node_id); + const node_label = createElement("div", "node-label", node.label); + nodeEl.appendChild(node_label); + if (node.inputs.length > 0) { + const node_parameters = createElement("div", ["parameter-list", "comma-sep-list"]); + for (const param of node.inputs) { + const paramEl = createElement("div", ["parameter", "tag", "clickable"], param); + node_parameters.appendChild(paramEl); + paramEl.onclick = mkNodeLinkHandler(param); + view.addHtmlElementForNodeId(param, paramEl); + } + nodeEl.appendChild(node_parameters); } + return nodeEl; } - const ARROW_STYLE = { css: 'kwd' }; - let patterns = [ - [ - [/^--- BLOCK B\d+/, BLOCK_HEADER_STYLE, 1], - [/^\s+\d+: /, ID_STYLE, 2], - [/^\s+Goto/, GOTO_STYLE, 6], - [/^.*/, null, -1] - ], - [ - [/^ +/, null], - [/^\(deferred\)/, BLOCK_HEADER_STYLE], - [/^B\d+/, BLOCK_LINK_STYLE], - [/^<-/, ARROW_STYLE], - [/^->/, ARROW_STYLE], - [/^,/, null], - [/^---/, BLOCK_HEADER_STYLE, -1] - ], - // Parse opcode including [] - [ - [/^[A-Za-z0-9_]+(\[.*\])?$/, NODE_STYLE, -1], - [/^[A-Za-z0-9_]+(\[(\[.*?\]|.)*?\])?/, NODE_STYLE, 3] - ], - // Parse optional parameters - [ - [/^ /, null, 4], - [/^\(/, null], - [/^\d+/, ID_LINK_STYLE], - [/^, /, null], - [/^\)$/, null, -1], - [/^\)/, null, 4], - ], - [ - [/^ -> /, ARROW_STYLE, 5], - [/^.*/, null, -1] - ], - [ - [/^B\d+$/, BLOCK_LINK_STYLE, -1], - [/^B\d+/, BLOCK_LINK_STYLE], - [/^, /, null] - ], - [ - [/^ -> /, ARROW_STYLE], - [/^B\d+$/, BLOCK_LINK_STYLE, -1] - ] - ]; - this.setPatterns(patterns); + + function mkBlockLinkHandler(blockId) { + return function (e) { + e.stopPropagation(); + if (!e.shiftKey) { + view.blockSelectionHandler.clear(); + } + view.blockSelectionHandler.select(["" + blockId], true); + }; + } + + const schedule_block = createElement("div", "schedule-block"); + const block_id = createElement("div", ["block-id", "com", "clickable"], block.id); + block_id.onclick = mkBlockLinkHandler(block.id); + schedule_block.appendChild(block_id); + const block_pred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); + for (const pred of block.pred) { + const predEl = createElement("div", ["block-id", "com", "clickable"], pred); + predEl.onclick = mkBlockLinkHandler(pred); + block_pred.appendChild(predEl); + } + if (block.pred.length) schedule_block.appendChild(block_pred); + const nodes = createElement("div", "nodes"); + for (const node of block.nodes) { + nodes.appendChild(createElementForNode(node, block.id)); + } + schedule_block.appendChild(nodes); + const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); + for (const succ of block.succ) { + const succEl = createElement("div", ["block-id", "com", "clickable"], succ); + succEl.onclick = mkBlockLinkHandler(succ); + block_succ.appendChild(succEl); + } + if (block.succ.length) schedule_block.appendChild(block_succ); + this.addHtmlElementForBlockId(block.id, schedule_block); + return schedule_block; } - initializeContent(data, rememberedSelection) { - super.initializeContent(data, rememberedSelection); - var graph = this; - var locations = []; - for (var id of rememberedSelection) { - locations.push({ node_id : id }); + addBlocks(blocks) { + for (const block of blocks) { + const blockEl = this.elementForBlock(block); + this.divNode.appendChild(blockEl); } - this.selectLocations(locations, true, true); + } + + initializeContent(data, rememberedSelection) { + this.clearText(); + this.schedule = data.schedule + this.addBlocks(data.schedule.blocks); + this.attachSelection(rememberedSelection); } detachSelection() { - var selection = this.selection.detachSelection(); - var s = new Set(); - for (var i of selection) { - if (i.location.node_id != undefined && i.location.node_id > 0) { - s.add(i.location.node_id); + this.blockSelection.clear(); + this.sourcePositionSelection.clear(); + return this.selection.detachSelection(); + } + + lineString(node) { + return `${node.id}: ${node.label}(${node.inputs.join(", ")})` + } + + searchInputAction(view, searchBar) { + d3.event.stopPropagation(); + this.selectionHandler.clear(); + const query = searchBar.value; + if (query.length == 0) return; + const select = []; + window.sessionStorage.setItem("lastSearch", query); + const reg = new RegExp(query); + for (const node of this.schedule.nodes) { + if (node === undefined) continue; + if (reg.exec(this.lineString(node)) != null) { + select.push(node.id) } - }; - return s; + } + this.selectionHandler.select(select, true); } } diff --git a/deps/v8/tools/turbolizer/selection-broker.js b/deps/v8/tools/turbolizer/selection-broker.js index 822cf1ce1f..0ae006aa01 100644 --- a/deps/v8/tools/turbolizer/selection-broker.js +++ b/deps/v8/tools/turbolizer/selection-broker.js @@ -2,98 +2,72 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var SelectionBroker = function() { - this.brokers = []; - this.dispatching = false; - this.lastDispatchingHandler = null; - this.nodePositionMap = []; - this.sortedPositionList = []; - this.positionNodeMap = []; -}; +class SelectionBroker { + constructor(sourceResolver) { + this.sourcePositionHandlers = []; + this.nodeHandlers = []; + this.blockHandlers = []; + this.sourceResolver = sourceResolver; + }; -SelectionBroker.prototype.addSelectionHandler = function(handler) { - this.brokers.push(handler); -} + addSourcePositionHandler(handler) { + this.sourcePositionHandlers.push(handler); + } -SelectionBroker.prototype.setNodePositionMap = function(map) { - let broker = this; - if (!map) return; - broker.nodePositionMap = map; - broker.positionNodeMap = []; - broker.sortedPositionList = []; - let next = 0; - for (let i in broker.nodePositionMap) { - broker.sortedPositionList[next] = Number(broker.nodePositionMap[i]); - broker.positionNodeMap[next++] = i; + addNodeHandler(handler) { + this.nodeHandlers.push(handler); } - broker.sortedPositionList = sortUnique(broker.sortedPositionList, - function(a,b) { return a - b; }); - this.positionNodeMap.sort(function(a,b) { - let result = broker.nodePositionMap[a] - broker.nodePositionMap[b]; - if (result != 0) return result; - return a - b; - }); -} -SelectionBroker.prototype.select = function(from, locations, selected) { - let broker = this; - if (!broker.dispatching) { - broker.lastDispatchingHandler = from; - try { - broker.dispatching = true; - let enrichLocations = function(locations) { - result = []; - for (let location of locations) { - let newLocation = {}; - if (location.pos_start != undefined) { - newLocation.pos_start = location.pos_start; - } - if (location.pos_end != undefined) { - newLocation.pos_end = location.pos_end; - } - if (location.node_id != undefined) { - newLocation.node_id = location.node_id; - } - if (location.block_id != undefined) { - newLocation.block_id = location.block_id; - } - if (newLocation.pos_start == undefined && - newLocation.pos_end == undefined && - newLocation.node_id != undefined) { - if (broker.nodePositionMap && broker.nodePositionMap[location.node_id]) { - newLocation.pos_start = broker.nodePositionMap[location.node_id]; - newLocation.pos_end = location.pos_start + 1; - } - } - result.push(newLocation); - } - return result; - } - locations = enrichLocations(locations); - for (var b of this.brokers) { - if (b != from) { - b.brokeredSelect(locations, selected); - } + addBlockHandler(handler) { + this.blockHandlers.push(handler); + } + + broadcastSourcePositionSelect(from, sourcePositions, selected) { + let broker = this; + sourcePositions = sourcePositions.filter((l) => { + if (typeof l.scriptOffset == 'undefined' + || typeof l.inliningId == 'undefined') { + console.log("Warning: invalid source position"); + return false; } + return true; + }); + for (var b of this.sourcePositionHandlers) { + if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected); } - finally { - broker.dispatching = false; + const nodes = this.sourceResolver.sourcePositionsToNodeIds(sourcePositions); + for (var b of this.nodeHandlers) { + if (b != from) b.brokeredNodeSelect(nodes, selected); } } -} -SelectionBroker.prototype.clear = function(from) { - this.lastDispatchingHandler = null; - if (!this.dispatching) { - try { - this.dispatching = true; - this.brokers.forEach(function(b) { - if (b != from) { - b.brokeredClear(); - } - }); - } finally { - this.dispatching = false; + broadcastNodeSelect(from, nodes, selected) { + let broker = this; + for (var b of this.nodeHandlers) { + if (b != from) b.brokeredNodeSelect(nodes, selected); } + const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes); + for (var b of this.sourcePositionHandlers) { + if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected); + } + } + + broadcastBlockSelect(from, blocks, selected) { + let broker = this; + for (var b of this.blockHandlers) { + if (b != from) b.brokeredBlockSelect(blocks, selected); + } + } + + broadcastClear(from) { + this.sourcePositionHandlers.forEach(function (b) { + if (b != from) b.brokeredClear(); + }); + this.nodeHandlers.forEach(function (b) { + if (b != from) b.brokeredClear(); + }); + this.blockHandlers.forEach(function (b) { + if (b != from) b.brokeredClear(); + }); } } diff --git a/deps/v8/tools/turbolizer/selection.js b/deps/v8/tools/turbolizer/selection.js index 26f1bde197..9bd937c84a 100644 --- a/deps/v8/tools/turbolizer/selection.js +++ b/deps/v8/tools/turbolizer/selection.js @@ -2,107 +2,59 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var Selection = function(handler) { - this.handler = handler; - this.selectionBase = null; - this.lastSelection = null; - this.selection = new Set(); -} - - -Selection.prototype.isEmpty = function() { - return this.selection.size == 0; -} - - -Selection.prototype.clear = function() { - var handler = this.handler; - this.selectionBase = null; - this.lastSelection = null; - handler.select(this.selection, false); - handler.clear(); - this.selection = new Set(); -} +class Selection { + constructor(stringKeyFnc) { + this.selection = new Map(); + this.stringKey = stringKeyFnc; + } + isEmpty() { + return this.selection.size == 0; + } -count = 0; + clear() { + this.selection = new Map(); + } -Selection.prototype.select = function(s, isSelected) { - var handler = this.handler; - if (!(Symbol.iterator in Object(s))) { s = [s]; } - if (isSelected) { - let first = true; - for (let i of s) { - if (first) { - this.selectionBase = i; - this.lastSelection = i; - first = false; + select(s, isSelected) { + if (!isIterable(s)) { s = [s]; } + for (const i of s) { + if (!i) continue; + if (isSelected == undefined) { + isSelected = !this.selection.has(this.stringKey(i)); } - this.selection.add(i); - } - handler.select(this.selection, true); - } else { - let unselectSet = new Set(); - for (let i of s) { - if (this.selection.has(i)) { - unselectSet.add(i); - this.selection.delete(i); + if (isSelected) { + this.selection.set(this.stringKey(i), i); + } else { + this.selection.delete(this.stringKey(i)); } } - handler.select(unselectSet, false); } -} + isSelected(i) { + return this.selection.has(this.stringKey(i)); + } -Selection.prototype.extendTo = function(pos) { - if (pos == this.lastSelection || this.lastSelection === null) return; + isKeySelected(key) { + return this.selection.has(key); + } - var handler = this.handler; - var pos_diff = handler.selectionDifference(pos, true, this.lastSelection, false); - var unselect_diff = []; - if (pos_diff.length == 0) { - pos_diff = handler.selectionDifference(this.selectionBase, false, pos, true); - if (pos_diff.length != 0) { - unselect_diff = handler.selectionDifference(this.lastSelection, true, this.selectionBase, false); - this.selection = new Set(); - this.selection.add(this.selectionBase); - for (var d of pos_diff) { - this.selection.add(d); - } - } else { - unselect_diff = handler.selectionDifference(this.lastSelection, true, pos, false); - for (var d of unselect_diff) { - this.selection.delete(d); - } - } - } else { - unselect_diff = handler.selectionDifference(this.selectionBase, false, this.lastSelection, true); - if (unselect_diff != 0) { - pos_diff = handler.selectionDifference(pos, true, this.selectionBase, false); - if (pos_diff.length == 0) { - unselect_diff = handler.selectionDifference(pos, false, this.lastSelection, true); - } - for (var d of unselect_diff) { - this.selection.delete(d); - } - } - if (pos_diff.length != 0) { - for (var d of pos_diff) { - this.selection.add(d); - } + selectedKeys() { + var result = new Set(); + for (var i of this.selection.keys()) { + result.add(i); } + return result; } - handler.select(unselect_diff, false); - handler.select(pos_diff, true); - this.lastSelection = pos; -} - -Selection.prototype.detachSelection = function() { - var result = new Set(); - for (var i of this.selection) { - result.add(i); + detachSelection() { + var result = new Set(); + for (var i of this.selection.keys()) { + result.add(i); + } + this.clear(); + return result; } - this.clear(); - return result; + + [Symbol.iterator]() { return this.selection.values() } } diff --git a/deps/v8/tools/turbolizer/source-resolver.js b/deps/v8/tools/turbolizer/source-resolver.js new file mode 100644 index 0000000000..dd3732ad56 --- /dev/null +++ b/deps/v8/tools/turbolizer/source-resolver.js @@ -0,0 +1,326 @@ +// Copyright 2018 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. + +function sourcePositionLe(a, b) { + if (a.inliningId == b.inliningId) { + return a.scriptOffset - b.scriptOffset; + } + return a.inliningId - b.inliningId; +} + +function sourcePositionEq(a, b) { + return a.inliningId == b.inliningId && + a.scriptOffset == b.scriptOffset; +} + +function sourcePositionToStringKey(sourcePosition) { + if (!sourcePosition) return "undefined"; + return "" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset; +} + +class SourceResolver { + constructor() { + // Maps node ids to source positions. + this.nodePositionMap = []; + // Maps source ids to source objects. + this.sources = []; + // Maps inlining ids to inlining objects. + this.inlinings = []; + // Maps source position keys to inlinings. + this.inliningsMap = new Map(); + // Maps source position keys to node ids. + this.positionToNodes = new Map(); + // Maps phase ids to phases. + this.phases = []; + // Maps phase names to phaseIds. + this.phaseNames = new Map(); + // The disassembly phase is stored separately. + this.disassemblyPhase = undefined; + } + + setSources(sources, mainBackup) { + if (sources) { + for (let [sourceId, source] of Object.entries(sources)) { + this.sources[sourceId] = source; + this.sources[sourceId].sourcePositions = []; + } + } + // This is a fallback if the JSON is incomplete (e.g. due to compiler crash). + if (!this.sources[-1]) { + this.sources[-1] = mainBackup; + this.sources[-1].sourcePositions = []; + } + } + + setInlinings(inlinings) { + if (inlinings) { + for (const [inliningId, inlining] of Object.entries(inlinings)) { + this.inlinings[inliningId] = inlining; + this.inliningsMap.set(sourcePositionToStringKey(inlining.inliningPosition), inlining); + } + } + // This is a default entry for the script itself that helps + // keep other code more uniform. + this.inlinings[-1] = { sourceId: -1 }; + } + + setNodePositionMap(map) { + if (!map) return; + if (typeof map[0] != 'object') { + const alternativeMap = {}; + for (const [nodeId, scriptOffset] of Object.entries(map)) { + alternativeMap[nodeId] = { scriptOffset: scriptOffset, inliningId: -1 }; + } + map = alternativeMap; + }; + + for (const [nodeId, sourcePosition] of Object.entries(map)) { + if (sourcePosition == undefined) { + console.log("Warning: undefined source position ", sourcePosition, " for nodeId ", nodeId); + } + const inliningId = sourcePosition.inliningId; + const inlining = this.inlinings[inliningId]; + if (inlining) { + const sourceId = inlining.sourceId; + this.sources[sourceId].sourcePositions.push(sourcePosition); + } + this.nodePositionMap[nodeId] = sourcePosition; + let key = sourcePositionToStringKey(sourcePosition); + if (!this.positionToNodes.has(key)) { + this.positionToNodes.set(key, []); + } + this.positionToNodes.get(key).push(nodeId); + } + for (const [sourceId, source] of Object.entries(this.sources)) { + source.sourcePositions = sortUnique(source.sourcePositions, + sourcePositionLe, sourcePositionEq); + } + } + + sourcePositionsToNodeIds(sourcePositions) { + const nodeIds = new Set(); + for (const sp of sourcePositions) { + let key = sourcePositionToStringKey(sp); + let nodeIdsForPosition = this.positionToNodes.get(key); + if (!nodeIdsForPosition) continue; + for (const nodeId of nodeIdsForPosition) { + nodeIds.add(nodeId); + } + } + return nodeIds; + } + + nodeIdsToSourcePositions(nodeIds) { + const sourcePositions = new Map(); + for (const nodeId of nodeIds) { + let sp = this.nodePositionMap[nodeId]; + let key = sourcePositionToStringKey(sp); + sourcePositions.set(key, sp); + } + const sourcePositionArray = []; + for (const sp of sourcePositions.values()) { + sourcePositionArray.push(sp); + } + return sourcePositionArray; + } + + forEachSource(f) { + this.sources.forEach(f); + } + + translateToSourceId(sourceId, location) { + for (const position of this.getInlineStack(location)) { + let inlining = this.inlinings[position.inliningId]; + if (!inlining) continue; + if (inlining.sourceId == sourceId) { + return position; + } + } + return location; + } + + addInliningPositions(sourcePosition, locations) { + let inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); + if (!inlining) return; + let sourceId = inlining.sourceId + const source = this.sources[sourceId]; + for (const sp of source.sourcePositions) { + locations.push(sp); + this.addInliningPositions(sp, locations); + } + } + + getInliningForPosition(sourcePosition) { + return this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); + } + + getSource(sourceId) { + return this.sources[sourceId]; + } + + getSourceName(sourceId) { + const source = this.sources[sourceId]; + return `${source.sourceName}:${source.functionName}`; + } + + sourcePositionFor(sourceId, scriptOffset) { + if (!this.sources[sourceId]) { + return null; + } + const list = this.sources[sourceId].sourcePositions; + for (let i = 0; i < list.length; i++) { + const sourcePosition = list[i] + const position = sourcePosition.scriptOffset; + const nextPosition = list[Math.min(i + 1, list.length - 1)].scriptOffset; + if ((position <= scriptOffset && scriptOffset < nextPosition)) { + return sourcePosition; + } + } + return null; + } + + sourcePositionsInRange(sourceId, start, end) { + if (!this.sources[sourceId]) return []; + const res = []; + const list = this.sources[sourceId].sourcePositions; + for (let i = 0; i < list.length; i++) { + const sourcePosition = list[i] + if (start <= sourcePosition.scriptOffset && sourcePosition.scriptOffset < end) { + res.push(sourcePosition); + } + } + return res; + } + + getInlineStack(sourcePosition) { + if (!sourcePosition) { + return []; + } + let inliningStack = []; + let cur = sourcePosition; + while (cur && cur.inliningId != -1) { + inliningStack.push(cur); + let inlining = this.inlinings[cur.inliningId]; + if (!inlining) { + break; + } + cur = inlining.inliningPosition; + } + if (cur && cur.inliningId == -1) { + inliningStack.push(cur); + } + return inliningStack; + } + + parsePhases(phases) { + for (const [phaseId, phase] of Object.entries(phases)) { + if (phase.type == 'disassembly') { + this.disassemblyPhase = phase; + } else if (phase.type == 'schedule') { + this.phases.push(this.parseSchedule(phase)) + this.phaseNames.set(phase.name, this.phases.length); + } else { + this.phases.push(phase); + this.phaseNames.set(phase.name, this.phases.length); + } + } + } + + repairPhaseId(anyPhaseId) { + return Math.max(0, Math.min(anyPhaseId, this.phases.length - 1)) + } + + getPhase(phaseId) { + return this.phases[phaseId]; + } + + getPhaseIdByName(phaseName) { + return this.phaseNames.get(phaseName); + } + + forEachPhase(f) { + this.phases.forEach(f); + } + + parseSchedule(phase) { + function createNode(state, match) { + let inputs = []; + if (match.groups.args) { + const nodeIdsString = match.groups.args.replace(/\s/g, ''); + const nodeIdStrings = nodeIdsString.split(','); + inputs = nodeIdStrings.map((n) => Number.parseInt(n, 10)); + } + const node = {id: Number.parseInt(match.groups.id, 10), + label: match.groups.label, + inputs: inputs}; + if (match.groups.blocks) { + const nodeIdsString = match.groups.blocks.replace(/\s/g, '').replace(/B/g,''); + const nodeIdStrings = nodeIdsString.split(','); + const successors = nodeIdStrings.map((n) => Number.parseInt(n, 10)); + state.currentBlock.succ = successors; + } + state.nodes[node.id] = node; + state.currentBlock.nodes.push(node); + } + function createBlock(state, match) { + let predecessors = []; + if (match.groups.in) { + const blockIdsString = match.groups.in.replace(/\s/g, '').replace(/B/g, ''); + const blockIdStrings = blockIdsString.split(','); + predecessors = blockIdStrings.map((n) => Number.parseInt(n, 10)); + } + const block = {id: Number.parseInt(match.groups.id, 10), + isDeferred: match.groups.deferred != undefined, + pred: predecessors.sort(), + succ: [], + nodes: []}; + state.blocks[block.id] = block; + state.currentBlock = block; + } + function setGotoSuccessor(state, match) { + state.currentBlock.succ = [Number.parseInt(match.groups.successor.replace(/\s/g, ''), 10)]; + } + const rules = [ + { + lineRegexps: + [ /^\s*(?<id>\d+):\ (?<label>.*)\((?<args>.*)\)$/, + /^\s*(?<id>\d+):\ (?<label>.*)\((?<args>.*)\)\ ->\ (?<blocks>.*)$/, + /^\s*(?<id>\d+):\ (?<label>.*)$/ + ], + process: createNode + }, + { + lineRegexps: + [/^\s*---\s*BLOCK\ B(?<id>\d+)\s*(?<deferred>\(deferred\))?(\ <-\ )?(?<in>[^-]*)?\ ---$/ + ], + process: createBlock + }, + { + lineRegexps: + [/^\s*Goto\s*->\s*B(?<successor>\d+)\s*$/ + ], + process: setGotoSuccessor + } + ]; + + const lines = phase.data.split(/[\n]/); + const state = { currentBlock: undefined, blocks: [], nodes: [] }; + + nextLine: + for (const line of lines) { + for (const rule of rules) { + for (const lineRegexp of rule.lineRegexps) { + const match = line.match(lineRegexp); + if (match) { + rule.process(state, match); + continue nextLine; + } + } + } + console.log("Warning: unmatched schedule line \"" + line + "\""); + } + phase.schedule = state; + return phase; + } +} diff --git a/deps/v8/tools/turbolizer/text-view.js b/deps/v8/tools/turbolizer/text-view.js index 6822500dde..3abc5024b3 100644 --- a/deps/v8/tools/turbolizer/text-view.js +++ b/deps/v8/tools/turbolizer/text-view.js @@ -4,43 +4,174 @@ "use strict"; +function anyToString(x) { + return "" + x; +} + class TextView extends View { - constructor(id, broker, patterns, allowSpanSelection) { + constructor(id, broker, patterns) { super(id, broker); let view = this; - view.hide(); view.textListNode = view.divNode.getElementsByTagName('ul')[0]; - view.fillerSvgElement = view.divElement.append("svg").attr('version','1.1').attr("width", "0"); view.patterns = patterns; - view.allowSpanSelection = allowSpanSelection; - view.nodeToLineMap = []; - var selectionHandler = { - clear: function() { - broker.clear(selectionHandler); - }, - select: function(items, selected) { - for (let i of items) { - if (selected) { - i.classList.add("selected"); - } else { - i.classList.remove("selected"); - } - } - broker.clear(selectionHandler); - broker.select(selectionHandler, view.getLocations(items), selected); + view.nodeIdToHtmlElementsMap = new Map(); + view.blockIdToHtmlElementsMap = new Map(); + view.sourcePositionToHtmlElementsMap = new Map(); + view.blockIdtoNodeIds = new Map(); + view.nodeIdToBlockId = []; + view.selection = new Selection(anyToString); + view.blockSelection = new Selection(anyToString); + view.sourcePositionSelection = new Selection(sourcePositionToStringKey); + const selectionHandler = { + clear: function () { + view.selection.clear(); + view.updateSelection(); + broker.broadcastClear(selectionHandler); }, - selectionDifference: function(span1, inclusive1, span2, inclusive2) { - return null; + select: function (nodeIds, selected) { + view.selection.select(nodeIds, selected); + const blockIds = view.blockIdsForNodeIds(nodeIds); + view.blockSelection.select(blockIds, selected); + view.updateSelection(); + broker.broadcastNodeSelect(selectionHandler, view.selection.selectedKeys(), selected); + broker.broadcastBlockSelect(view.blockSelectionHandler, blockIds, selected); }, - brokeredSelect: function(locations, selected) { - view.selectLocations(locations, selected, true); + brokeredNodeSelect: function (nodeIds, selected) { + const firstSelect = view.blockSelection.isEmpty(); + view.selection.select(nodeIds, selected); + const blockIds = view.blockIdsForNodeIds(nodeIds); + view.blockSelection.select(blockIds, selected); + view.updateSelection(firstSelect); }, - brokeredClear: function() { + brokeredClear: function () { view.selection.clear(); + view.updateSelection(); } }; - view.selection = new Selection(selectionHandler); - broker.addSelectionHandler(selectionHandler); + this.selectionHandler = selectionHandler; + broker.addNodeHandler(selectionHandler); + view.divNode.onmouseup = function (e) { + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + } + const blockSelectionHandler = { + clear: function () { + view.blockSelection.clear(); + view.updateSelection(); + broker.broadcastClear(blockSelectionHandler); + }, + select: function (blockIds, selected) { + view.blockSelection.select(blockIds, selected); + view.updateSelection(); + broker.broadcastBlockSelect(blockSelectionHandler, blockIds, selected); + }, + brokeredBlockSelect: function (blockIds, selected) { + const firstSelect = view.blockSelection.isEmpty(); + view.blockSelection.select(blockIds, selected); + view.updateSelection(firstSelect); + }, + brokeredClear: function () { + view.blockSelection.clear(); + view.updateSelection(); + } + }; + this.blockSelectionHandler = blockSelectionHandler; + broker.addBlockHandler(blockSelectionHandler); + const sourcePositionSelectionHandler = { + clear: function () { + view.sourcePositionSelection.clear(); + view.updateSelection(); + broker.broadcastClear(sourcePositionSelectionHandler); + }, + select: function (sourcePositions, selected) { + view.sourcePositionSelection.select(sourcePositions, selected); + view.updateSelection(); + broker.broadcastSourcePositionSelect(sourcePositionSelectionHandler, sourcePositions, selected); + }, + brokeredSourcePositionSelect: function (sourcePositions, selected) { + const firstSelect = view.sourcePositionSelection.isEmpty(); + view.sourcePositionSelection.select(sourcePositions, selected); + view.updateSelection(firstSelect); + }, + brokeredClear: function () { + view.sourcePositionSelection.clear(); + view.updateSelection(); + } + }; + view.sourcePositionSelectionHandler = sourcePositionSelectionHandler; + broker.addSourcePositionHandler(sourcePositionSelectionHandler); + } + + addHtmlElementForNodeId(anyNodeId, htmlElement) { + const nodeId = anyToString(anyNodeId); + if (!this.nodeIdToHtmlElementsMap.has(nodeId)) { + this.nodeIdToHtmlElementsMap.set(nodeId, []); + } + this.nodeIdToHtmlElementsMap.get(nodeId).push(htmlElement); + } + + addHtmlElementForSourcePosition(sourcePosition, htmlElement) { + const key = sourcePositionToStringKey(sourcePosition); + if (!this.sourcePositionToHtmlElementsMap.has(key)) { + this.sourcePositionToHtmlElementsMap.set(key, []); + } + this.sourcePositionToHtmlElementsMap.get(key).push(htmlElement); + } + + addHtmlElementForBlockId(anyBlockId, htmlElement) { + const blockId = anyToString(anyBlockId); + if (!this.blockIdToHtmlElementsMap.has(blockId)) { + this.blockIdToHtmlElementsMap.set(blockId, []); + } + this.blockIdToHtmlElementsMap.get(blockId).push(htmlElement); + } + + addNodeIdToBlockId(anyNodeId, anyBlockId) { + const blockId = anyToString(anyBlockId); + if (!this.blockIdtoNodeIds.has(blockId)) { + this.blockIdtoNodeIds.set(blockId, []); + } + this.blockIdtoNodeIds.get(blockId).push(anyToString(anyNodeId)); + this.nodeIdToBlockId[anyNodeId] = blockId; + } + + blockIdsForNodeIds(nodeIds) { + const blockIds = []; + for (const nodeId of nodeIds) { + const blockId = this.nodeIdToBlockId[nodeId]; + if (blockId == undefined) continue; + blockIds.push(blockId); + } + return blockIds; + } + + updateSelection(scrollIntoView) { + if (this.divNode.parentNode == null) return; + const mkVisible = new ViewElements(this.divNode.parentNode); + const view = this; + for (const [nodeId, elements] of this.nodeIdToHtmlElementsMap.entries()) { + const isSelected = view.selection.isSelected(nodeId); + for (const element of elements) { + mkVisible.consider(element, isSelected); + element.classList.toggle("selected", isSelected); + } + } + for (const [blockId, elements] of this.blockIdToHtmlElementsMap.entries()) { + const isSelected = view.blockSelection.isSelected(blockId); + for (const element of elements) { + mkVisible.consider(element, isSelected); + element.classList.toggle("selected", isSelected); + } + } + for (const [sourcePositionKey, elements] of this.sourcePositionToHtmlElementsMap.entries()) { + const isSelected = view.sourcePositionSelection.isKeySelected(sourcePositionKey); + for (const element of elements) { + mkVisible.consider(element, isSelected); + element.classList.toggle("selected", isSelected); + } + } + mkVisible.apply(scrollIntoView); } setPatterns(patterns) { @@ -55,77 +186,68 @@ class TextView extends View { } } - sameLocation(l1, l2) { + createFragment(text, style) { let view = this; - if (l1.block_id != undefined && l2.block_id != undefined && - l1.block_id == l2.block_id && l1.node_id === undefined) { - return true; - } + let fragment = document.createElement("SPAN"); - if (l1.address != undefined && l1.address == l2.address) { - return true; + if (style.blockId != undefined) { + const blockId = style.blockId(text); + if (blockId != undefined) { + fragment.blockId = blockId; + this.addHtmlElementForBlockId(blockId, fragment); + } } - let node1 = l1.node_id; - let node2 = l2.node_id; + if (typeof style.link == 'function') { + fragment.classList.add('linkable-text'); + fragment.onmouseup = function (e) { + e.stopPropagation(); + style.link(text) + }; + } - if (node1 === undefined || node2 == undefined) { - if (l1.pos_start === undefined || l2.pos_start == undefined) { - return false; - } - if (l1.pos_start == -1 || l2.pos_start == -1) { - return false; - } - if (l1.pos_start < l2.pos_start) { - return l1.pos_end > l2.pos_start; - } { - return l1.pos_start < l2.pos_end; + if (typeof style.nodeId == 'function') { + const nodeId = style.nodeId(text); + if (nodeId != undefined) { + fragment.nodeId = nodeId; + this.addHtmlElementForNodeId(nodeId, fragment); } } - return l1.node_id == l2.node_id; - } - - selectLocations(locations, selected, makeVisible) { - let view = this; - let s = new Set(); - for (let l of locations) { - for (let i = 0; i < view.textListNode.children.length; ++i) { - let child = view.textListNode.children[i]; - if (child.location != undefined && view.sameLocation(l, child.location)) { - s.add(child); - } + if (typeof style.sourcePosition === 'function') { + const sourcePosition = style.sourcePosition(text); + if (sourcePosition != undefined) { + fragment.sourcePosition = sourcePosition; + //this.addHtmlElementForNodeId(nodeId, fragment); } } - view.selectCommon(s, selected, makeVisible); - } - getLocations(items) { - let result = []; - let lastObject = null; - for (let i of items) { - if (i.location) { - result.push(i.location); - } + if (typeof style.assignSourcePosition === 'function') { + fragment.sourcePosition = style.assignSourcePosition(); + this.addHtmlElementForSourcePosition(fragment.sourcePosition, fragment) } - return result; - } - createFragment(text, style) { - let view = this; - let span = document.createElement("SPAN"); - span.onmousedown = function(e) { - view.mouseDownSpan(span, e); + if (typeof style.assignBlockId === 'function') { + fragment.blockId = style.assignBlockId(); + this.addNodeIdToBlockId(fragment.nodeId, fragment.blockId); } - if (style != undefined) { - span.classList.add(style); + + if (typeof style.linkHandler == 'function') { + const handler = style.linkHandler(text, fragment) + if (handler !== undefined) { + fragment.classList.add('linkable-text'); + fragment.onmouseup = handler; + } } - span.innerHTML = text; - return span; - } - appendFragment(li, fragment) { - li.appendChild(fragment); + if (style.css != undefined) { + const css = isIterable(style.css) ? style.css : [style.css]; + for (const cls of css) { + fragment.classList.add(cls); + } + } + fragment.innerHTML = text; + return fragment; } processLine(line) { @@ -141,18 +263,8 @@ class TextView extends View { let style = pattern[1] != null ? pattern[1] : {}; let text = matches[0]; if (text != '') { - let fragment = view.createFragment(matches[0], style.css); - if (style.link) { - fragment.classList.add('linkable-text'); - fragment.link = style.link; - } + let fragment = view.createFragment(matches[0], style); result.push(fragment); - if (style.location != undefined) { - let location = style.location(text); - if (location != undefined) { - fragment.location = location; - } - } } line = line.substr(matches[0].length); } @@ -162,7 +274,7 @@ class TextView extends View { } if (line == "") { if (nextPatternSet != -1) { - throw("illegal parsing state in text-view in patternSet" + patternSet); + throw ("illegal parsing state in text-view in patternSet" + patternSet); } return result; } @@ -171,90 +283,22 @@ class TextView extends View { } } if (beforeLine == line) { - throw("input not consumed in text-view in patternSet" + patternSet); + throw ("input not consumed in text-view in patternSet" + patternSet); } } } - select(s, selected, makeVisible) { - let view = this; - view.selection.clear(); - view.selectCommon(s, selected, makeVisible); - } - - selectCommon(s, selected, makeVisible) { - let view = this; - let firstSelect = makeVisible && view.selection.isEmpty(); - if ((typeof s) === 'function') { - for (let i = 0; i < view.textListNode.children.length; ++i) { - let child = view.textListNode.children[i]; - if (child.location && s(child.location)) { - if (firstSelect) { - makeContainerPosVisible(view.parentNode, child.offsetTop); - firstSelect = false; - } - view.selection.select(child, selected); - } - } - } else if (typeof s[Symbol.iterator] === 'function') { - if (firstSelect) { - for (let i of s) { - makeContainerPosVisible(view.parentNode, i.offsetTop); - break; - } - } - view.selection.select(s, selected); - } else { - if (firstSelect) { - makeContainerPosVisible(view.parentNode, s.offsetTop); - } - view.selection.select(s, selected); - } - } - - mouseDownLine(li, e) { - let view = this; - e.stopPropagation(); - if (!e.shiftKey) { - view.selection.clear(); - } - if (li.location != undefined) { - view.selectLocations([li.location], true, false); - } - } - - mouseDownSpan(span, e) { - let view = this; - if (view.allowSpanSelection) { - e.stopPropagation(); - if (!e.shiftKey) { - view.selection.clear(); - } - select(li, true); - } else if (span.link) { - span.link(span.textContent); - e.stopPropagation(); - } - } - processText(text) { let view = this; let textLines = text.split(/[\n]/); let lineNo = 0; for (let line of textLines) { let li = document.createElement("LI"); - li.onmousedown = function(e) { - view.mouseDownLine(li, e); - } li.className = "nolinenums"; li.lineNo = lineNo++; let fragments = view.processLine(line); for (let fragment of fragments) { - view.appendFragment(li, fragment); - } - let lineLocation = view.lineLocation(li); - if (lineLocation != undefined) { - li.location = lineLocation; + li.appendChild(fragment); } view.textListNode.appendChild(li); } @@ -262,15 +306,8 @@ class TextView extends View { initializeContent(data, rememberedSelection) { let view = this; - view.selection.clear(); view.clearText(); view.processText(data); - var fillerSize = document.documentElement.clientHeight - - view.textListNode.clientHeight; - if (fillerSize < 0) { - fillerSize = 0; - } - view.fillerSvgElement.attr("height", fillerSize); } deleteContent() { @@ -279,18 +316,4 @@ class TextView extends View { isScrollable() { return true; } - - detachSelection() { - return null; - } - - lineLocation(li) { - let view = this; - for (let i = 0; i < li.children.length; ++i) { - let fragment = li.children[i]; - if (fragment.location != undefined && !view.allowSpanSelection) { - return fragment.location; - } - } - } } diff --git a/deps/v8/tools/turbolizer/turbo-visualizer.css b/deps/v8/tools/turbolizer/turbo-visualizer.css index 95fcba7928..80fcb8e5c0 100644 --- a/deps/v8/tools/turbolizer/turbo-visualizer.css +++ b/deps/v8/tools/turbolizer/turbo-visualizer.css @@ -50,24 +50,73 @@ background-color: #FFFF33; } +.selected.block, +.selected.block-id, +.selected.schedule-block { + background-color: #AAFFAA; +} + +ol.linenums { + -webkit-padding-start: 8px; +} + +.line-number { + display:inline-block; + min-width: 3ex; + text-align: right; + color: gray; + padding-right:1ex; + font-size: 10px; + user-select: none; +} + +.line-number:hover { + background-color: #CCCCCC; +} + .prettyprint ol.linenums > li { list-style-type: decimal; - !important + padding-top: 3px; + display: block; +} + +.source-container { + border-bottom: 2px solid #AAAAAA; +} + +.code-header { + background-color: #CCCCCC; + padding-left: 1em; + padding-right: 1em; + padding-top: 1ex; + padding-bottom: 1ex; + font-family: monospace; + user-select: none; +} + +.main-source .code-header { + border-top: 2px solid #AAAAAA; + font-weight: bold; +} + +.code-header .code-file-function { + font-family: monospace; + float: left; + user-select: text; } +.code-header .code-mode { + float: right; + font-family: sans-serif; + font-size: small; +} -body { +html, body { margin: 0; padding: 0; - height: 100vh; - width: 100vw; - overflow:hidden; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + /*height: 99vh; + width: 99vw;*/ + overflow: hidden; } p { @@ -95,7 +144,7 @@ g.unsorted rect { } div.scrollable { - overflow-y: _croll; overflow-x: hidden; + overflow-y: auto; overflow-x: hidden; } g.turbonode[relToHover="input"] rect { @@ -243,10 +292,13 @@ span.linkable-text:hover { #left { float: left; + user-select: none; } #middle { - float:left; background-color: #F8F8F8; + float:left; + background-color: #F8F8F8; + user-select: none; } #right { @@ -267,6 +319,11 @@ span.linkable-text:hover { left: 0; } +#graph { + width: 100%; + height: 100%; +} + #graph-toolbox-anchor { height: 0px; } @@ -308,7 +365,7 @@ span.linkable-text:hover { padding: 0.5em; } -#hidden-file-upload { +#upload-helper { display: none; } @@ -363,4 +420,165 @@ text { .resizer-right.dragged { background: orange; +} + +.source-position { + /* border-left: 1px solid #FF3333; */ + width: 0; + display: inline-block; +} + +.source-position .inlining-marker { + content: ""; + position: relative; + display: inline-block; + top: -0.5ex; + margin-left: -4px; + margin-right: -4px; + border-width: 5px; + border-style: solid; + border-color: #555 transparent transparent transparent; +} + +.source-position .marker { + content: ""; + display: inline-block; + position: relative; + bottom: -1ex; + width: 0px; + margin-left: -4px; + margin-right: -4px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent #555 transparent; +} + +.source-position.selected .marker { + border-color: transparent transparent #F00 transparent; +} + +.source-position .inlining-marker:hover { + border-color: transparent transparent #AA5 transparent; +} + +.source-position .inlining-marker[data-descr]:hover::after { + content: attr(data-descr); + position: absolute; + font-size: 10px; + z-index: 1; + background-color: #555; + color: #fff; + text-align: center; + border-radius: 6px; + padding: 6px; + top: 6px; + left: 50%; + margin-left: -80px; +} + +#schedule { + font-family: monospace; +} + +.schedule-block { + margin: 5px; + background-color: white; +} + +.schedule-block .block-id { + display: inline-block; + font-size:large; + text-decoration: underline; +} + +.schedule-block .block-id:hover { + font-weight: bold; +} + +.schedule-block > .block-id::before { + content: "Block B"; +} + +.schedule-block .block-list { + display: inline-block; +} + +.schedule-block .block-list * { + display: inline-block; +} + +.schedule-block .block-list .block-id { + padding-left: 1ex; +} + +.schedule-block .block-list .block-id:before { + content: "B"; +} + +.schedule-block .predecessor-list::before { + display: inline-block; + content: " \2B05 "; + padding-left: 1ex; + padding-right: 1ex; +} + +.schedule-block .successor-list::before { + display: inline-block; + content: " \2B95 "; + padding-left: 1ex; + padding-right: 1ex; +} + +.schedule-block .nodes { + padding-left: 5px; +} + +.schedule-block .nodes .node * { + display:inline-block; +} + +.schedule-block .nodes .node .node-id { + padding-right: 1ex; + min-width: 5ex; + text-align: right; +} + +.schedule-block .nodes .node .node-id:after { + content: ":"; +} + +.schedule-block .nodes .node .node-label { + user-select: text; +} + +.schedule-block .nodes .node .parameter-list:before { + content: "("; +} + +.schedule-block .nodes .node .parameter-list:after { + content: ")"; +} + +.clickable:hover { + text-decoration: underline; +} + +.clickable:hover { + font-weight: bold; +} + +.comma-sep-list > * { + padding-right: 1ex; +} + +.comma-sep-list > *:after { + content: ","; +} + +.comma-sep-list > *:last-child:after { + content: ""; +} + +.comma-sep-list > *:last-child { + padding-right: 0ex; }
\ No newline at end of file diff --git a/deps/v8/tools/turbolizer/turbo-visualizer.js b/deps/v8/tools/turbolizer/turbo-visualizer.js index 0c720b22a4..31add283c2 100644 --- a/deps/v8/tools/turbolizer/turbo-visualizer.js +++ b/deps/v8/tools/turbolizer/turbo-visualizer.js @@ -12,22 +12,22 @@ class Snapper { snapper.disassemblyExpand = d3.select("#" + DISASSEMBLY_EXPAND_ID); snapper.disassemblyCollapse = d3.select("#" + DISASSEMBLY_COLLAPSE_ID); - d3.select("#source-collapse").on("click", function(){ + d3.select("#source-collapse").on("click", function () { resizer.snapper.toggleSourceExpanded(); }); - d3.select("#disassembly-collapse").on("click", function(){ + d3.select("#disassembly-collapse").on("click", function () { resizer.snapper.toggleDisassemblyExpanded(); }); } getLastExpandedState(type, default_state) { - var state = window.sessionStorage.getItem("expandedState-"+type); + var state = window.sessionStorage.getItem("expandedState-" + type); if (state === null) return default_state; return state === 'true'; } setLastExpandedState(type, state) { - window.sessionStorage.setItem("expandedState-"+type, state); + window.sessionStorage.setItem("expandedState-" + type, state); } toggleSourceExpanded() { @@ -97,51 +97,50 @@ class Resizer { resizer.right = d3.select("#" + GENERATED_PANE_ID); resizer.resizer_left = d3.select('.resizer-left'); resizer.resizer_right = d3.select('.resizer-right'); - resizer.sep_left = resizer.client_width/3; - resizer.sep_right = resizer.client_width/3*2; + resizer.sep_left = resizer.client_width / 3; + resizer.sep_right = resizer.client_width / 3 * 2; resizer.sep_left_snap = 0; resizer.sep_right_snap = 0; // Offset to prevent resizers from sliding slightly over one another. resizer.sep_width_offset = 7; let dragResizeLeft = d3.behavior.drag() - .on('drag', function() { + .on('drag', function () { let x = d3.mouse(this.parentElement)[0]; - resizer.sep_left = Math.min(Math.max(0,x), resizer.sep_right-resizer.sep_width_offset); + resizer.sep_left = Math.min(Math.max(0, x), resizer.sep_right - resizer.sep_width_offset); resizer.updatePanes(); }) - .on('dragstart', function() { + .on('dragstart', function () { resizer.resizer_left.classed("dragged", true); let x = d3.mouse(this.parentElement)[0]; if (x > dead_width) { resizer.sep_left_snap = resizer.sep_left; } }) - .on('dragend', function() { + .on('dragend', function () { resizer.resizer_left.classed("dragged", false); }); resizer.resizer_left.call(dragResizeLeft); let dragResizeRight = d3.behavior.drag() - .on('drag', function() { + .on('drag', function () { let x = d3.mouse(this.parentElement)[0]; - resizer.sep_right = Math.max(resizer.sep_left+resizer.sep_width_offset, Math.min(x, resizer.client_width)); + resizer.sep_right = Math.max(resizer.sep_left + resizer.sep_width_offset, Math.min(x, resizer.client_width)); resizer.updatePanes(); }) - .on('dragstart', function() { + .on('dragstart', function () { resizer.resizer_right.classed("dragged", true); let x = d3.mouse(this.parentElement)[0]; - if (x < (resizer.client_width-dead_width)) { + if (x < (resizer.client_width - dead_width)) { resizer.sep_right_snap = resizer.sep_right; } }) - .on('dragend', function() { + .on('dragend', function () { resizer.resizer_right.classed("dragged", false); });; resizer.resizer_right.call(dragResizeRight); - window.onresize = function(){ + window.onresize = function () { resizer.updateWidths(); - /*fitPanesToParents();*/ resizer.updatePanes(); }; } @@ -152,7 +151,7 @@ class Resizer { this.resizer_left.classed("snapped", left_snapped); this.resizer_right.classed("snapped", right_snapped); this.left.style('width', this.sep_left + 'px'); - this.middle.style('width', (this.sep_right-this.sep_left) + 'px'); + this.middle.style('width', (this.sep_right - this.sep_left) + 'px'); this.right.style('width', (this.client_width - this.sep_right) + 'px'); this.resizer_left.style('left', this.sep_left + 'px'); this.resizer_right.style('right', (this.client_width - this.sep_right - 1) + 'px'); @@ -168,21 +167,20 @@ class Resizer { } } -document.onload = (function(d3){ +document.onload = (function (d3) { "use strict"; - var jsonObj; - var svg = null; + var svg = null; var graph = null; var schedule = null; - var empty = null; var currentPhaseView = null; var disassemblyView = null; - var sourceView = null; + var sourceViews = []; var selectionBroker = null; + var sourceResolver = null; let resizer = new Resizer(panesUpdatedCallback, 100); function panesUpdatedCallback() { - graph.fitGraphViewToWindow(); + if (graph) graph.fitGraphViewToWindow(); } function hideCurrentPhase() { @@ -206,115 +204,132 @@ document.onload = (function(d3){ if (phase.type == 'graph') { displayPhaseView(graph, phase.data); } else if (phase.type == 'schedule') { - displayPhaseView(schedule, phase.data); - } else { - displayPhaseView(empty, null); + displayPhaseView(schedule, phase); } } - function fitPanesToParents() { - d3.select("#left").classed("scrollable", false) - d3.select("#right").classed("scrollable", false); + function loadFile(txtRes) { + // If the JSON isn't properly terminated, assume compiler crashed and + // add best-guess empty termination + if (txtRes[txtRes.length - 2] == ',') { + txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}'; + } + try { + sourceViews.forEach((sv) => sv.hide()); + hideCurrentPhase(); + graph = null; + if (disassemblyView) disassemblyView.hide(); + sourceViews = []; + sourceResolver = new SourceResolver(); + selectionBroker = new SelectionBroker(sourceResolver); + + const jsonObj = JSON.parse(txtRes); + + let fnc = jsonObj.function; + // Backwards compatibility. + if (typeof fnc == 'string') { + fnc = { + functionName: fnc, + sourceId: -1, + startPosition: jsonObj.sourcePosition, + endPosition: jsonObj.sourcePosition + jsonObj.source.length, + sourceText: jsonObj.source + }; + } + + sourceResolver.setInlinings(jsonObj.inlinings); + sourceResolver.setSources(jsonObj.sources, fnc) + sourceResolver.setNodePositionMap(jsonObj.nodePositions); + sourceResolver.parsePhases(jsonObj.phases); - graph.fitGraphViewToWindow(); + let sourceView = new CodeView(SOURCE_PANE_ID, selectionBroker, sourceResolver, fnc, CodeView.MAIN_SOURCE); + sourceView.show(null, null); + sourceViews.push(sourceView); - d3.select("#left").classed("scrollable", true); - d3.select("#right").classed("scrollable", true); - } + sourceResolver.forEachSource((source) => { + let sourceView = new CodeView(SOURCE_PANE_ID, selectionBroker, sourceResolver, source, CodeView.INLINED_SOURCE); + sourceView.show(null, null); + sourceViews.push(sourceView); + }); + + disassemblyView = new DisassemblyView(GENERATED_PANE_ID, selectionBroker); + disassemblyView.initializeCode(fnc.sourceText); + if (sourceResolver.disassemblyPhase) { + disassemblyView.initializePerfProfile(jsonObj.eventCounts); + disassemblyView.show(sourceResolver.disassemblyPhase.data, null); + } + + var selectMenu = document.getElementById('display-selector'); + selectMenu.innerHTML = ''; + sourceResolver.forEachPhase((phase) => { + var optionElement = document.createElement("option"); + optionElement.text = phase.name; + selectMenu.add(optionElement, null); + }); + selectMenu.onchange = function (item) { + window.sessionStorage.setItem("lastSelectedPhase", selectMenu.selectedIndex); + displayPhase(sourceResolver.getPhase(selectMenu.selectedIndex)); + } - selectionBroker = new SelectionBroker(); + const initialPhaseIndex = sourceResolver.repairPhaseId(+window.sessionStorage.getItem("lastSelectedPhase")); + selectMenu.selectedIndex = initialPhaseIndex; - function initializeHandlers(g) { - d3.select("#hidden-file-upload").on("change", function() { + function displayPhaseByName(phaseName) { + const phaseId = sourceResolver.getPhaseIdByName(phaseName); + selectMenu.selectedIndex = phaseId - 1; + displayPhase(sourceResolver.getPhase(phaseId)); + } + + graph = new GraphView(d3, INTERMEDIATE_PANE_ID, selectionBroker, displayPhaseByName); + schedule = new ScheduleView(INTERMEDIATE_PANE_ID, selectionBroker); + + displayPhase(sourceResolver.getPhase(initialPhaseIndex)); + + d3.select("#search-input").attr("value", window.sessionStorage.getItem("lastSearch") || ""); + } catch (err) { + if (window.confirm("Error: Exception during load of TurboFan JSON file:\n" + + "error: " + err.message + "\nDo you want to clear session storage?")) { + window.sessionStorage.clear(); + } + return; + } + } + + function initializeUploadHandlers() { + // The <input> form #upload-helper with type file can't be a picture. + // We hence keep it hidden, and forward the click from the picture + // button #upload. + d3.select("#upload").on("click", + () => document.getElementById("upload-helper").click()); + d3.select("#upload-helper").on("change", function () { if (window.File && window.FileReader && window.FileList) { - var uploadFile = this.files[0]; + var uploadFile = this.files && this.files[0]; var filereader = new window.FileReader(); - var consts = Node.consts; - filereader.onload = function(){ - var txtRes = filereader.result; - // If the JSON isn't properly terminated, assume compiler crashed and - // add best-guess empty termination - if (txtRes[txtRes.length-2] == ',') { - txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}'; - } - try{ - jsonObj = JSON.parse(txtRes); - - hideCurrentPhase(); - - selectionBroker.setNodePositionMap(jsonObj.nodePositions); - - sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition); - disassemblyView.initializeCode(jsonObj.source); - - var selectMenu = document.getElementById('display-selector'); - var disassemblyPhase = null; - selectMenu.innerHTML = ''; - for (var i = 0; i < jsonObj.phases.length; ++i) { - var optionElement = document.createElement("option"); - optionElement.text = jsonObj.phases[i].name; - if (optionElement.text == 'disassembly') { - disassemblyPhase = jsonObj.phases[i]; - } else { - selectMenu.add(optionElement, null); - } - } - - disassemblyView.initializePerfProfile(jsonObj.eventCounts); - disassemblyView.show(disassemblyPhase.data, null); - - var initialPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase"); - if (!(initialPhaseIndex in jsonObj.phases)) { - initialPhaseIndex = 0; - } - - // We wish to show the remembered phase {lastSelectedPhase}, but - // this will crash if the first view we switch to is a - // ScheduleView. So we first switch to the first phase, which - // should never be a ScheduleView. - displayPhase(jsonObj.phases[0]); - displayPhase(jsonObj.phases[initialPhaseIndex]); - selectMenu.selectedIndex = initialPhaseIndex; - - selectMenu.onchange = function(item) { - window.sessionStorage.setItem("lastSelectedPhase", selectMenu.selectedIndex); - displayPhase(jsonObj.phases[selectMenu.selectedIndex]); - } - - fitPanesToParents(); - - d3.select("#search-input").attr("value", window.sessionStorage.getItem("lastSearch") || ""); - - } - catch(err) { - window.console.log("caught exception, clearing session storage just in case"); - window.sessionStorage.clear(); // just in case - window.console.log("showing error"); - window.alert("Invalid TurboFan JSON file\n" + - "error: " + err.message); - return; - } + filereader.onload = function (e) { + var txtRes = e.target.result; + loadFile(txtRes); }; - filereader.readAsText(uploadFile); + if (uploadFile) + filereader.readAsText(uploadFile); } else { alert("Can't load graph"); } }); } - sourceView = new CodeView(SOURCE_PANE_ID, PR, "", 0, selectionBroker); - disassemblyView = new DisassemblyView(DISASSEMBLY_PANE_ID, selectionBroker); - graph = new GraphView(d3, GRAPH_PANE_ID, [], [], selectionBroker); - schedule = new ScheduleView(SCHEDULE_PANE_ID, selectionBroker); - empty = new EmptyView(EMPTY_PANE_ID, selectionBroker); + initializeUploadHandlers(); + + function handleSearch(e) { + if (currentPhaseView) { + currentPhaseView.searchInputAction(currentPhaseView, this) + } + } - initializeHandlers(graph); + d3.select("#search-input").on("keyup", handleSearch); resizer.snapper.setSourceExpanded(resizer.snapper.getLastExpandedState("source", true)); resizer.snapper.setDisassemblyExpanded(resizer.snapper.getLastExpandedState("disassembly", false)); - displayPhaseView(empty, null); - fitPanesToParents(); resizer.updatePanes(); })(window.d3); diff --git a/deps/v8/tools/turbolizer/turbolizer.png b/deps/v8/tools/turbolizer/turbolizer.png Binary files differnew file mode 100644 index 0000000000..1af1a49b95 --- /dev/null +++ b/deps/v8/tools/turbolizer/turbolizer.png diff --git a/deps/v8/tools/turbolizer/util.js b/deps/v8/tools/turbolizer/util.js index 282221af48..9fcd200f07 100644 --- a/deps/v8/tools/turbolizer/util.js +++ b/deps/v8/tools/turbolizer/util.js @@ -4,19 +4,41 @@ "use strict"; -function makeContainerPosVisible(container, pos) { - var height = container.offsetHeight; - var margin = Math.floor(height / 4); - if (pos < container.scrollTop + margin) { - pos -= margin; - if (pos < 0) pos = 0; - container.scrollTop = pos; - return; +function computeScrollTop(container, element) { + const height = container.offsetHeight; + const margin = Math.floor(height / 4); + const pos = element.offsetTop; + const currentScrollTop = container.scrollTop; + if (pos < currentScrollTop + margin) { + return Math.max(0, pos - margin); + } else if (pos > (currentScrollTop + 3 * margin)) { + return Math.max(0, pos - 3 * margin); } - if (pos > (container.scrollTop + 3 * margin)) { - pos = pos - 3 * margin; - if (pos < 0) pos = 0; - container.scrollTop = pos; + return pos; +} + +class ViewElements { + constructor(container) { + this.container = container; + this.scrollTop = undefined; + } + + consider(element, doConsider) { + if (!doConsider) return; + const newScrollTop = computeScrollTop(this.container, element); + if (isNaN(newScrollTop)) { + console.log("NOO") + } + if (this.scrollTop === undefined) { + this.scrollTop = newScrollTop; + } else { + this.scrollTop = Math.min(this.scrollTop, newScrollTop); + } + } + + apply(doApply) { + if (!doApply || this.scrollTop === undefined) return; + this.container.scrollTop = this.scrollTop; } } @@ -59,11 +81,12 @@ function upperBound(a, value, compare, lookup) { } -function sortUnique(arr, f) { +function sortUnique(arr, f, equal) { + if (arr.length == 0) return arr; arr = arr.sort(f); let ret = [arr[0]]; for (var i = 1; i < arr.length; i++) { - if (arr[i-1] !== arr[i]) { + if (!equal(arr[i-1], arr[i])) { ret.push(arr[i]); } } @@ -78,3 +101,8 @@ function partial(f) { f.apply(this, arguments1.concat(arguments2)); } } + +function isIterable(obj) { + return obj != null && obj != undefined + && typeof obj != 'string' && typeof obj[Symbol.iterator] === 'function'; +} diff --git a/deps/v8/tools/turbolizer/view.js b/deps/v8/tools/turbolizer/view.js index a7c1f1e417..12712618a5 100644 --- a/deps/v8/tools/turbolizer/view.js +++ b/deps/v8/tools/turbolizer/view.js @@ -6,9 +6,9 @@ class View { constructor(id, broker) { - this.divElement = d3.select("#" + id); - this.divNode = this.divElement[0][0]; - this.parentNode = this.divNode.parentNode; + this.container = document.getElementById(id); + this.divNode = this.createViewElement(); + this.divElement = d3.select(this.divNode); } isScrollable() { @@ -16,7 +16,7 @@ class View { } show(data, rememberedSelection) { - this.parentNode.appendChild(this.divElement[0][0]); + this.container.appendChild(this.divElement.node()); this.initializeContent(data, rememberedSelection); this.divElement.attr(VISIBILITY, 'visible'); } @@ -24,7 +24,7 @@ class View { hide() { this.divElement.attr(VISIBILITY, 'hidden'); this.deleteContent(); - this.parentNode.removeChild(this.divNode); + this.container.removeChild(this.divNode); } detachSelection() { diff --git a/deps/v8/tools/v8heapconst.py b/deps/v8/tools/v8heapconst.py index e3b29f8204..68818c66f5 100644 --- a/deps/v8/tools/v8heapconst.py +++ b/deps/v8/tools/v8heapconst.py @@ -61,23 +61,23 @@ INSTANCE_TYPES = { 157: "ALLOCATION_MEMENTO_TYPE", 158: "ALLOCATION_SITE_TYPE", 159: "ASYNC_GENERATOR_REQUEST_TYPE", - 160: "CONTEXT_EXTENSION_TYPE", - 161: "DEBUG_INFO_TYPE", - 162: "FUNCTION_TEMPLATE_INFO_TYPE", - 163: "INTERCEPTOR_INFO_TYPE", - 164: "INTERPRETER_DATA_TYPE", - 165: "MODULE_INFO_ENTRY_TYPE", - 166: "MODULE_TYPE", - 167: "OBJECT_TEMPLATE_INFO_TYPE", - 168: "PROMISE_CAPABILITY_TYPE", - 169: "PROMISE_REACTION_TYPE", - 170: "PROTOTYPE_INFO_TYPE", - 171: "SCRIPT_TYPE", - 172: "STACK_FRAME_INFO_TYPE", - 173: "TUPLE2_TYPE", - 174: "TUPLE3_TYPE", - 175: "WASM_COMPILED_MODULE_TYPE", - 176: "WASM_DEBUG_INFO_TYPE", + 160: "DEBUG_INFO_TYPE", + 161: "FUNCTION_TEMPLATE_INFO_TYPE", + 162: "INTERCEPTOR_INFO_TYPE", + 163: "INTERPRETER_DATA_TYPE", + 164: "MODULE_INFO_ENTRY_TYPE", + 165: "MODULE_TYPE", + 166: "OBJECT_TEMPLATE_INFO_TYPE", + 167: "PROMISE_CAPABILITY_TYPE", + 168: "PROMISE_REACTION_TYPE", + 169: "PROTOTYPE_INFO_TYPE", + 170: "SCRIPT_TYPE", + 171: "STACK_FRAME_INFO_TYPE", + 172: "TUPLE2_TYPE", + 173: "TUPLE3_TYPE", + 174: "WASM_COMPILED_MODULE_TYPE", + 175: "WASM_DEBUG_INFO_TYPE", + 176: "WASM_EXPORTED_FUNCTION_DATA_TYPE", 177: "WASM_SHARED_MODULE_DATA_TYPE", 178: "CALLABLE_TASK_TYPE", 179: "CALLBACK_TASK_TYPE", @@ -89,30 +89,31 @@ INSTANCE_TYPES = { 185: "DESCRIPTOR_ARRAY_TYPE", 186: "HASH_TABLE_TYPE", 187: "SCOPE_INFO_TYPE", - 188: "TRANSITION_ARRAY_TYPE", - 189: "BLOCK_CONTEXT_TYPE", - 190: "CATCH_CONTEXT_TYPE", - 191: "DEBUG_EVALUATE_CONTEXT_TYPE", - 192: "EVAL_CONTEXT_TYPE", - 193: "FUNCTION_CONTEXT_TYPE", - 194: "MODULE_CONTEXT_TYPE", - 195: "NATIVE_CONTEXT_TYPE", - 196: "SCRIPT_CONTEXT_TYPE", - 197: "WITH_CONTEXT_TYPE", - 198: "CALL_HANDLER_INFO_TYPE", - 199: "CELL_TYPE", - 200: "CODE_DATA_CONTAINER_TYPE", - 201: "FEEDBACK_CELL_TYPE", - 202: "FEEDBACK_VECTOR_TYPE", - 203: "LOAD_HANDLER_TYPE", - 204: "PROPERTY_ARRAY_TYPE", - 205: "PROPERTY_CELL_TYPE", - 206: "SHARED_FUNCTION_INFO_TYPE", - 207: "SMALL_ORDERED_HASH_MAP_TYPE", - 208: "SMALL_ORDERED_HASH_SET_TYPE", - 209: "STORE_HANDLER_TYPE", - 210: "WEAK_CELL_TYPE", - 211: "WEAK_FIXED_ARRAY_TYPE", + 188: "BLOCK_CONTEXT_TYPE", + 189: "CATCH_CONTEXT_TYPE", + 190: "DEBUG_EVALUATE_CONTEXT_TYPE", + 191: "EVAL_CONTEXT_TYPE", + 192: "FUNCTION_CONTEXT_TYPE", + 193: "MODULE_CONTEXT_TYPE", + 194: "NATIVE_CONTEXT_TYPE", + 195: "SCRIPT_CONTEXT_TYPE", + 196: "WITH_CONTEXT_TYPE", + 197: "WEAK_FIXED_ARRAY_TYPE", + 198: "TRANSITION_ARRAY_TYPE", + 199: "CALL_HANDLER_INFO_TYPE", + 200: "CELL_TYPE", + 201: "CODE_DATA_CONTAINER_TYPE", + 202: "FEEDBACK_CELL_TYPE", + 203: "FEEDBACK_VECTOR_TYPE", + 204: "LOAD_HANDLER_TYPE", + 205: "PROPERTY_ARRAY_TYPE", + 206: "PROPERTY_CELL_TYPE", + 207: "SHARED_FUNCTION_INFO_TYPE", + 208: "SMALL_ORDERED_HASH_MAP_TYPE", + 209: "SMALL_ORDERED_HASH_SET_TYPE", + 210: "STORE_HANDLER_TYPE", + 211: "WEAK_CELL_TYPE", + 212: "WEAK_ARRAY_LIST_TYPE", 1024: "JS_PROXY_TYPE", 1025: "JS_GLOBAL_OBJECT_TYPE", 1026: "JS_GLOBAL_PROXY_TYPE", @@ -147,199 +148,204 @@ INSTANCE_TYPES = { 1081: "JS_WEAK_SET_TYPE", 1082: "JS_TYPED_ARRAY_TYPE", 1083: "JS_DATA_VIEW_TYPE", - 1084: "WASM_GLOBAL_TYPE", - 1085: "WASM_INSTANCE_TYPE", - 1086: "WASM_MEMORY_TYPE", - 1087: "WASM_MODULE_TYPE", - 1088: "WASM_TABLE_TYPE", - 1089: "JS_BOUND_FUNCTION_TYPE", - 1090: "JS_FUNCTION_TYPE", + 1084: "JS_INTL_LOCALE_TYPE", + 1085: "WASM_GLOBAL_TYPE", + 1086: "WASM_INSTANCE_TYPE", + 1087: "WASM_MEMORY_TYPE", + 1088: "WASM_MODULE_TYPE", + 1089: "WASM_TABLE_TYPE", + 1090: "JS_BOUND_FUNCTION_TYPE", + 1091: "JS_FUNCTION_TYPE", } # List of known V8 maps. KNOWN_MAPS = { - ("MAP_SPACE", 0x02201): (138, "FreeSpaceMap"), - ("MAP_SPACE", 0x02259): (132, "MetaMap"), - ("MAP_SPACE", 0x022b1): (131, "NullMap"), - ("MAP_SPACE", 0x02309): (185, "DescriptorArrayMap"), - ("MAP_SPACE", 0x02361): (183, "FixedArrayMap"), - ("MAP_SPACE", 0x023b9): (152, "OnePointerFillerMap"), - ("MAP_SPACE", 0x02411): (152, "TwoPointerFillerMap"), - ("MAP_SPACE", 0x02469): (131, "UninitializedMap"), - ("MAP_SPACE", 0x024c1): (8, "OneByteInternalizedStringMap"), - ("MAP_SPACE", 0x02519): (131, "UndefinedMap"), - ("MAP_SPACE", 0x02571): (129, "HeapNumberMap"), - ("MAP_SPACE", 0x025c9): (131, "TheHoleMap"), - ("MAP_SPACE", 0x02621): (131, "BooleanMap"), - ("MAP_SPACE", 0x02679): (136, "ByteArrayMap"), - ("MAP_SPACE", 0x026d1): (183, "FixedCOWArrayMap"), - ("MAP_SPACE", 0x02729): (186, "HashTableMap"), - ("MAP_SPACE", 0x02781): (128, "SymbolMap"), - ("MAP_SPACE", 0x027d9): (72, "OneByteStringMap"), - ("MAP_SPACE", 0x02831): (187, "ScopeInfoMap"), - ("MAP_SPACE", 0x02889): (206, "SharedFunctionInfoMap"), - ("MAP_SPACE", 0x028e1): (133, "CodeMap"), - ("MAP_SPACE", 0x02939): (193, "FunctionContextMap"), - ("MAP_SPACE", 0x02991): (199, "CellMap"), - ("MAP_SPACE", 0x029e9): (210, "WeakCellMap"), - ("MAP_SPACE", 0x02a41): (205, "GlobalPropertyCellMap"), - ("MAP_SPACE", 0x02a99): (135, "ForeignMap"), - ("MAP_SPACE", 0x02af1): (188, "TransitionArrayMap"), - ("MAP_SPACE", 0x02b49): (202, "FeedbackVectorMap"), - ("MAP_SPACE", 0x02ba1): (131, "ArgumentsMarkerMap"), - ("MAP_SPACE", 0x02bf9): (131, "ExceptionMap"), - ("MAP_SPACE", 0x02c51): (131, "TerminationExceptionMap"), - ("MAP_SPACE", 0x02ca9): (131, "OptimizedOutMap"), - ("MAP_SPACE", 0x02d01): (131, "StaleRegisterMap"), - ("MAP_SPACE", 0x02d59): (195, "NativeContextMap"), - ("MAP_SPACE", 0x02db1): (194, "ModuleContextMap"), - ("MAP_SPACE", 0x02e09): (192, "EvalContextMap"), - ("MAP_SPACE", 0x02e61): (196, "ScriptContextMap"), - ("MAP_SPACE", 0x02eb9): (189, "BlockContextMap"), - ("MAP_SPACE", 0x02f11): (190, "CatchContextMap"), - ("MAP_SPACE", 0x02f69): (197, "WithContextMap"), - ("MAP_SPACE", 0x02fc1): (191, "DebugEvaluateContextMap"), - ("MAP_SPACE", 0x03019): (183, "ScriptContextTableMap"), - ("MAP_SPACE", 0x03071): (151, "FeedbackMetadataArrayMap"), - ("MAP_SPACE", 0x030c9): (183, "ArrayListMap"), - ("MAP_SPACE", 0x03121): (130, "BigIntMap"), - ("MAP_SPACE", 0x03179): (184, "BoilerplateDescriptionMap"), - ("MAP_SPACE", 0x031d1): (137, "BytecodeArrayMap"), - ("MAP_SPACE", 0x03229): (200, "CodeDataContainerMap"), - ("MAP_SPACE", 0x03281): (1057, "ExternalMap"), - ("MAP_SPACE", 0x032d9): (150, "FixedDoubleArrayMap"), - ("MAP_SPACE", 0x03331): (186, "GlobalDictionaryMap"), - ("MAP_SPACE", 0x03389): (201, "ManyClosuresCellMap"), - ("MAP_SPACE", 0x033e1): (1072, "JSMessageObjectMap"), - ("MAP_SPACE", 0x03439): (183, "ModuleInfoMap"), - ("MAP_SPACE", 0x03491): (134, "MutableHeapNumberMap"), - ("MAP_SPACE", 0x034e9): (186, "NameDictionaryMap"), - ("MAP_SPACE", 0x03541): (201, "NoClosuresCellMap"), - ("MAP_SPACE", 0x03599): (186, "NumberDictionaryMap"), - ("MAP_SPACE", 0x035f1): (201, "OneClosureCellMap"), - ("MAP_SPACE", 0x03649): (186, "OrderedHashMapMap"), - ("MAP_SPACE", 0x036a1): (186, "OrderedHashSetMap"), - ("MAP_SPACE", 0x036f9): (204, "PropertyArrayMap"), - ("MAP_SPACE", 0x03751): (198, "SideEffectCallHandlerInfoMap"), - ("MAP_SPACE", 0x037a9): (198, "SideEffectFreeCallHandlerInfoMap"), - ("MAP_SPACE", 0x03801): (186, "SimpleNumberDictionaryMap"), - ("MAP_SPACE", 0x03859): (183, "SloppyArgumentsElementsMap"), - ("MAP_SPACE", 0x038b1): (207, "SmallOrderedHashMapMap"), - ("MAP_SPACE", 0x03909): (208, "SmallOrderedHashSetMap"), - ("MAP_SPACE", 0x03961): (186, "StringTableMap"), - ("MAP_SPACE", 0x039b9): (211, "WeakFixedArrayMap"), - ("MAP_SPACE", 0x03a11): (106, "NativeSourceStringMap"), - ("MAP_SPACE", 0x03a69): (64, "StringMap"), - ("MAP_SPACE", 0x03ac1): (73, "ConsOneByteStringMap"), - ("MAP_SPACE", 0x03b19): (65, "ConsStringMap"), - ("MAP_SPACE", 0x03b71): (77, "ThinOneByteStringMap"), - ("MAP_SPACE", 0x03bc9): (69, "ThinStringMap"), - ("MAP_SPACE", 0x03c21): (67, "SlicedStringMap"), - ("MAP_SPACE", 0x03c79): (75, "SlicedOneByteStringMap"), - ("MAP_SPACE", 0x03cd1): (66, "ExternalStringMap"), - ("MAP_SPACE", 0x03d29): (82, "ExternalStringWithOneByteDataMap"), - ("MAP_SPACE", 0x03d81): (74, "ExternalOneByteStringMap"), - ("MAP_SPACE", 0x03dd9): (98, "ShortExternalStringMap"), - ("MAP_SPACE", 0x03e31): (114, "ShortExternalStringWithOneByteDataMap"), - ("MAP_SPACE", 0x03e89): (0, "InternalizedStringMap"), - ("MAP_SPACE", 0x03ee1): (2, "ExternalInternalizedStringMap"), - ("MAP_SPACE", 0x03f39): (18, "ExternalInternalizedStringWithOneByteDataMap"), - ("MAP_SPACE", 0x03f91): (10, "ExternalOneByteInternalizedStringMap"), - ("MAP_SPACE", 0x03fe9): (34, "ShortExternalInternalizedStringMap"), - ("MAP_SPACE", 0x04041): (50, "ShortExternalInternalizedStringWithOneByteDataMap"), - ("MAP_SPACE", 0x04099): (42, "ShortExternalOneByteInternalizedStringMap"), - ("MAP_SPACE", 0x040f1): (106, "ShortExternalOneByteStringMap"), - ("MAP_SPACE", 0x04149): (140, "FixedUint8ArrayMap"), - ("MAP_SPACE", 0x041a1): (139, "FixedInt8ArrayMap"), - ("MAP_SPACE", 0x041f9): (142, "FixedUint16ArrayMap"), - ("MAP_SPACE", 0x04251): (141, "FixedInt16ArrayMap"), - ("MAP_SPACE", 0x042a9): (144, "FixedUint32ArrayMap"), - ("MAP_SPACE", 0x04301): (143, "FixedInt32ArrayMap"), - ("MAP_SPACE", 0x04359): (145, "FixedFloat32ArrayMap"), - ("MAP_SPACE", 0x043b1): (146, "FixedFloat64ArrayMap"), - ("MAP_SPACE", 0x04409): (147, "FixedUint8ClampedArrayMap"), - ("MAP_SPACE", 0x04461): (149, "FixedBigUint64ArrayMap"), - ("MAP_SPACE", 0x044b9): (148, "FixedBigInt64ArrayMap"), - ("MAP_SPACE", 0x04511): (173, "Tuple2Map"), - ("MAP_SPACE", 0x04569): (171, "ScriptMap"), - ("MAP_SPACE", 0x045c1): (163, "InterceptorInfoMap"), - ("MAP_SPACE", 0x04619): (158, "AllocationSiteMap"), - ("MAP_SPACE", 0x04671): (154, "AccessorInfoMap"), - ("MAP_SPACE", 0x046c9): (153, "AccessCheckInfoMap"), - ("MAP_SPACE", 0x04721): (155, "AccessorPairMap"), - ("MAP_SPACE", 0x04779): (156, "AliasedArgumentsEntryMap"), - ("MAP_SPACE", 0x047d1): (157, "AllocationMementoMap"), - ("MAP_SPACE", 0x04829): (159, "AsyncGeneratorRequestMap"), - ("MAP_SPACE", 0x04881): (160, "ContextExtensionMap"), - ("MAP_SPACE", 0x048d9): (161, "DebugInfoMap"), - ("MAP_SPACE", 0x04931): (162, "FunctionTemplateInfoMap"), - ("MAP_SPACE", 0x04989): (164, "InterpreterDataMap"), - ("MAP_SPACE", 0x049e1): (165, "ModuleInfoEntryMap"), - ("MAP_SPACE", 0x04a39): (166, "ModuleMap"), - ("MAP_SPACE", 0x04a91): (167, "ObjectTemplateInfoMap"), - ("MAP_SPACE", 0x04ae9): (168, "PromiseCapabilityMap"), - ("MAP_SPACE", 0x04b41): (169, "PromiseReactionMap"), - ("MAP_SPACE", 0x04b99): (170, "PrototypeInfoMap"), - ("MAP_SPACE", 0x04bf1): (172, "StackFrameInfoMap"), - ("MAP_SPACE", 0x04c49): (174, "Tuple3Map"), - ("MAP_SPACE", 0x04ca1): (175, "WasmCompiledModuleMap"), - ("MAP_SPACE", 0x04cf9): (176, "WasmDebugInfoMap"), - ("MAP_SPACE", 0x04d51): (177, "WasmSharedModuleDataMap"), - ("MAP_SPACE", 0x04da9): (178, "CallableTaskMap"), - ("MAP_SPACE", 0x04e01): (179, "CallbackTaskMap"), - ("MAP_SPACE", 0x04e59): (180, "PromiseFulfillReactionJobTaskMap"), - ("MAP_SPACE", 0x04eb1): (181, "PromiseRejectReactionJobTaskMap"), - ("MAP_SPACE", 0x04f09): (182, "PromiseResolveThenableJobTaskMap"), + ("RO_SPACE", 0x02201): (138, "FreeSpaceMap"), + ("RO_SPACE", 0x02259): (132, "MetaMap"), + ("RO_SPACE", 0x022e1): (131, "NullMap"), + ("RO_SPACE", 0x02359): (185, "DescriptorArrayMap"), + ("RO_SPACE", 0x023c1): (183, "FixedArrayMap"), + ("RO_SPACE", 0x02429): (211, "WeakCellMap"), + ("RO_SPACE", 0x024d1): (152, "OnePointerFillerMap"), + ("RO_SPACE", 0x02539): (152, "TwoPointerFillerMap"), + ("RO_SPACE", 0x025d1): (131, "UninitializedMap"), + ("RO_SPACE", 0x02661): (8, "OneByteInternalizedStringMap"), + ("RO_SPACE", 0x02721): (131, "UndefinedMap"), + ("RO_SPACE", 0x02799): (129, "HeapNumberMap"), + ("RO_SPACE", 0x02831): (131, "TheHoleMap"), + ("RO_SPACE", 0x028f9): (131, "BooleanMap"), + ("RO_SPACE", 0x02a09): (136, "ByteArrayMap"), + ("RO_SPACE", 0x02a71): (183, "FixedCOWArrayMap"), + ("RO_SPACE", 0x02ad9): (186, "HashTableMap"), + ("RO_SPACE", 0x02b41): (128, "SymbolMap"), + ("RO_SPACE", 0x02ba9): (72, "OneByteStringMap"), + ("RO_SPACE", 0x02c11): (187, "ScopeInfoMap"), + ("RO_SPACE", 0x02c79): (207, "SharedFunctionInfoMap"), + ("RO_SPACE", 0x02ce1): (133, "CodeMap"), + ("RO_SPACE", 0x02d49): (192, "FunctionContextMap"), + ("RO_SPACE", 0x02db1): (200, "CellMap"), + ("RO_SPACE", 0x02e19): (206, "GlobalPropertyCellMap"), + ("RO_SPACE", 0x02e81): (135, "ForeignMap"), + ("RO_SPACE", 0x02ee9): (198, "TransitionArrayMap"), + ("RO_SPACE", 0x02f51): (203, "FeedbackVectorMap"), + ("RO_SPACE", 0x02ff9): (131, "ArgumentsMarkerMap"), + ("RO_SPACE", 0x030b9): (131, "ExceptionMap"), + ("RO_SPACE", 0x03179): (131, "TerminationExceptionMap"), + ("RO_SPACE", 0x03241): (131, "OptimizedOutMap"), + ("RO_SPACE", 0x03301): (131, "StaleRegisterMap"), + ("RO_SPACE", 0x03391): (194, "NativeContextMap"), + ("RO_SPACE", 0x033f9): (193, "ModuleContextMap"), + ("RO_SPACE", 0x03461): (191, "EvalContextMap"), + ("RO_SPACE", 0x034c9): (195, "ScriptContextMap"), + ("RO_SPACE", 0x03531): (188, "BlockContextMap"), + ("RO_SPACE", 0x03599): (189, "CatchContextMap"), + ("RO_SPACE", 0x03601): (196, "WithContextMap"), + ("RO_SPACE", 0x03669): (190, "DebugEvaluateContextMap"), + ("RO_SPACE", 0x036d1): (183, "ScriptContextTableMap"), + ("RO_SPACE", 0x03739): (151, "FeedbackMetadataArrayMap"), + ("RO_SPACE", 0x037a1): (183, "ArrayListMap"), + ("RO_SPACE", 0x03809): (130, "BigIntMap"), + ("RO_SPACE", 0x03871): (184, "BoilerplateDescriptionMap"), + ("RO_SPACE", 0x038d9): (137, "BytecodeArrayMap"), + ("RO_SPACE", 0x03941): (201, "CodeDataContainerMap"), + ("RO_SPACE", 0x039a9): (150, "FixedDoubleArrayMap"), + ("RO_SPACE", 0x03a11): (186, "GlobalDictionaryMap"), + ("RO_SPACE", 0x03a79): (202, "ManyClosuresCellMap"), + ("RO_SPACE", 0x03ae1): (183, "ModuleInfoMap"), + ("RO_SPACE", 0x03b49): (134, "MutableHeapNumberMap"), + ("RO_SPACE", 0x03bb1): (186, "NameDictionaryMap"), + ("RO_SPACE", 0x03c19): (202, "NoClosuresCellMap"), + ("RO_SPACE", 0x03c81): (186, "NumberDictionaryMap"), + ("RO_SPACE", 0x03ce9): (202, "OneClosureCellMap"), + ("RO_SPACE", 0x03d51): (186, "OrderedHashMapMap"), + ("RO_SPACE", 0x03db9): (186, "OrderedHashSetMap"), + ("RO_SPACE", 0x03e21): (205, "PropertyArrayMap"), + ("RO_SPACE", 0x03e89): (199, "SideEffectCallHandlerInfoMap"), + ("RO_SPACE", 0x03ef1): (199, "SideEffectFreeCallHandlerInfoMap"), + ("RO_SPACE", 0x03f59): (199, "NextCallSideEffectFreeCallHandlerInfoMap"), + ("RO_SPACE", 0x03fc1): (186, "SimpleNumberDictionaryMap"), + ("RO_SPACE", 0x04029): (183, "SloppyArgumentsElementsMap"), + ("RO_SPACE", 0x04091): (208, "SmallOrderedHashMapMap"), + ("RO_SPACE", 0x040f9): (209, "SmallOrderedHashSetMap"), + ("RO_SPACE", 0x04161): (186, "StringTableMap"), + ("RO_SPACE", 0x041c9): (197, "WeakFixedArrayMap"), + ("RO_SPACE", 0x04231): (212, "WeakArrayListMap"), + ("RO_SPACE", 0x04299): (106, "NativeSourceStringMap"), + ("RO_SPACE", 0x04301): (64, "StringMap"), + ("RO_SPACE", 0x04369): (73, "ConsOneByteStringMap"), + ("RO_SPACE", 0x043d1): (65, "ConsStringMap"), + ("RO_SPACE", 0x04439): (77, "ThinOneByteStringMap"), + ("RO_SPACE", 0x044a1): (69, "ThinStringMap"), + ("RO_SPACE", 0x04509): (67, "SlicedStringMap"), + ("RO_SPACE", 0x04571): (75, "SlicedOneByteStringMap"), + ("RO_SPACE", 0x045d9): (66, "ExternalStringMap"), + ("RO_SPACE", 0x04641): (82, "ExternalStringWithOneByteDataMap"), + ("RO_SPACE", 0x046a9): (74, "ExternalOneByteStringMap"), + ("RO_SPACE", 0x04711): (98, "ShortExternalStringMap"), + ("RO_SPACE", 0x04779): (114, "ShortExternalStringWithOneByteDataMap"), + ("RO_SPACE", 0x047e1): (0, "InternalizedStringMap"), + ("RO_SPACE", 0x04849): (2, "ExternalInternalizedStringMap"), + ("RO_SPACE", 0x048b1): (18, "ExternalInternalizedStringWithOneByteDataMap"), + ("RO_SPACE", 0x04919): (10, "ExternalOneByteInternalizedStringMap"), + ("RO_SPACE", 0x04981): (34, "ShortExternalInternalizedStringMap"), + ("RO_SPACE", 0x049e9): (50, "ShortExternalInternalizedStringWithOneByteDataMap"), + ("RO_SPACE", 0x04a51): (42, "ShortExternalOneByteInternalizedStringMap"), + ("RO_SPACE", 0x04ab9): (106, "ShortExternalOneByteStringMap"), + ("RO_SPACE", 0x04b21): (140, "FixedUint8ArrayMap"), + ("RO_SPACE", 0x04b89): (139, "FixedInt8ArrayMap"), + ("RO_SPACE", 0x04bf1): (142, "FixedUint16ArrayMap"), + ("RO_SPACE", 0x04c59): (141, "FixedInt16ArrayMap"), + ("RO_SPACE", 0x04cc1): (144, "FixedUint32ArrayMap"), + ("RO_SPACE", 0x04d29): (143, "FixedInt32ArrayMap"), + ("RO_SPACE", 0x04d91): (145, "FixedFloat32ArrayMap"), + ("RO_SPACE", 0x04df9): (146, "FixedFloat64ArrayMap"), + ("RO_SPACE", 0x04e61): (147, "FixedUint8ClampedArrayMap"), + ("RO_SPACE", 0x04ec9): (149, "FixedBigUint64ArrayMap"), + ("RO_SPACE", 0x04f31): (148, "FixedBigInt64ArrayMap"), + ("RO_SPACE", 0x04f99): (131, "SelfReferenceMarkerMap"), + ("RO_SPACE", 0x05019): (172, "Tuple2Map"), + ("RO_SPACE", 0x05211): (170, "ScriptMap"), + ("RO_SPACE", 0x053d9): (162, "InterceptorInfoMap"), + ("RO_SPACE", 0x07c09): (154, "AccessorInfoMap"), + ("RO_SPACE", 0x07e19): (153, "AccessCheckInfoMap"), + ("RO_SPACE", 0x07e81): (155, "AccessorPairMap"), + ("RO_SPACE", 0x07ee9): (156, "AliasedArgumentsEntryMap"), + ("RO_SPACE", 0x07f51): (157, "AllocationMementoMap"), + ("RO_SPACE", 0x07fb9): (158, "AllocationSiteMap"), + ("RO_SPACE", 0x08021): (159, "AsyncGeneratorRequestMap"), + ("RO_SPACE", 0x08089): (160, "DebugInfoMap"), + ("RO_SPACE", 0x080f1): (161, "FunctionTemplateInfoMap"), + ("RO_SPACE", 0x08159): (163, "InterpreterDataMap"), + ("RO_SPACE", 0x081c1): (164, "ModuleInfoEntryMap"), + ("RO_SPACE", 0x08229): (165, "ModuleMap"), + ("RO_SPACE", 0x08291): (166, "ObjectTemplateInfoMap"), + ("RO_SPACE", 0x082f9): (167, "PromiseCapabilityMap"), + ("RO_SPACE", 0x08361): (168, "PromiseReactionMap"), + ("RO_SPACE", 0x083c9): (169, "PrototypeInfoMap"), + ("RO_SPACE", 0x08431): (171, "StackFrameInfoMap"), + ("RO_SPACE", 0x08499): (173, "Tuple3Map"), + ("RO_SPACE", 0x08501): (174, "WasmCompiledModuleMap"), + ("RO_SPACE", 0x08569): (175, "WasmDebugInfoMap"), + ("RO_SPACE", 0x085d1): (176, "WasmExportedFunctionDataMap"), + ("RO_SPACE", 0x08639): (177, "WasmSharedModuleDataMap"), + ("RO_SPACE", 0x086a1): (178, "CallableTaskMap"), + ("RO_SPACE", 0x08709): (179, "CallbackTaskMap"), + ("RO_SPACE", 0x08771): (180, "PromiseFulfillReactionJobTaskMap"), + ("RO_SPACE", 0x087d9): (181, "PromiseRejectReactionJobTaskMap"), + ("RO_SPACE", 0x08841): (182, "PromiseResolveThenableJobTaskMap"), + ("MAP_SPACE", 0x02201): (1057, "ExternalMap"), + ("MAP_SPACE", 0x02259): (1072, "JSMessageObjectMap"), } # List of known V8 objects. KNOWN_OBJECTS = { - ("OLD_SPACE", 0x02201): "NullValue", - ("OLD_SPACE", 0x02231): "EmptyDescriptorArray", - ("OLD_SPACE", 0x02251): "EmptyFixedArray", - ("OLD_SPACE", 0x02261): "UninitializedValue", - ("OLD_SPACE", 0x022e1): "UndefinedValue", - ("OLD_SPACE", 0x02311): "NanValue", - ("OLD_SPACE", 0x02321): "TheHoleValue", - ("OLD_SPACE", 0x02371): "HoleNanValue", - ("OLD_SPACE", 0x02381): "TrueValue", - ("OLD_SPACE", 0x023f1): "FalseValue", - ("OLD_SPACE", 0x02441): "empty_string", - ("OLD_SPACE", 0x02459): "EmptyScopeInfo", - ("OLD_SPACE", 0x02469): "ArgumentsMarker", - ("OLD_SPACE", 0x024c1): "Exception", - ("OLD_SPACE", 0x02519): "TerminationException", - ("OLD_SPACE", 0x02579): "OptimizedOut", - ("OLD_SPACE", 0x025d1): "StaleRegister", - ("OLD_SPACE", 0x02661): "EmptyByteArray", - ("OLD_SPACE", 0x02681): "EmptyFixedUint8Array", - ("OLD_SPACE", 0x026a1): "EmptyFixedInt8Array", - ("OLD_SPACE", 0x026c1): "EmptyFixedUint16Array", - ("OLD_SPACE", 0x026e1): "EmptyFixedInt16Array", - ("OLD_SPACE", 0x02701): "EmptyFixedUint32Array", - ("OLD_SPACE", 0x02721): "EmptyFixedInt32Array", - ("OLD_SPACE", 0x02741): "EmptyFixedFloat32Array", - ("OLD_SPACE", 0x02761): "EmptyFixedFloat64Array", - ("OLD_SPACE", 0x02781): "EmptyFixedUint8ClampedArray", - ("OLD_SPACE", 0x027e1): "EmptyScript", - ("OLD_SPACE", 0x02879): "ManyClosuresCell", - ("OLD_SPACE", 0x02889): "EmptySloppyArgumentsElements", - ("OLD_SPACE", 0x028a9): "EmptySlowElementDictionary", - ("OLD_SPACE", 0x028f1): "EmptyOrderedHashMap", - ("OLD_SPACE", 0x02919): "EmptyOrderedHashSet", - ("OLD_SPACE", 0x02951): "EmptyPropertyCell", - ("OLD_SPACE", 0x02979): "EmptyWeakCell", - ("OLD_SPACE", 0x029e9): "NoElementsProtector", - ("OLD_SPACE", 0x02a11): "IsConcatSpreadableProtector", - ("OLD_SPACE", 0x02a21): "ArraySpeciesProtector", - ("OLD_SPACE", 0x02a49): "TypedArraySpeciesProtector", - ("OLD_SPACE", 0x02a71): "PromiseSpeciesProtector", - ("OLD_SPACE", 0x02a99): "StringLengthProtector", - ("OLD_SPACE", 0x02aa9): "ArrayIteratorProtector", - ("OLD_SPACE", 0x02ad1): "ArrayBufferNeuteringProtector", - ("OLD_SPACE", 0x02b59): "InfinityValue", - ("OLD_SPACE", 0x02b69): "MinusZeroValue", - ("OLD_SPACE", 0x02b79): "MinusInfinityValue", + ("RO_SPACE", 0x022b1): "NullValue", + ("RO_SPACE", 0x02339): "EmptyDescriptorArray", + ("RO_SPACE", 0x023b1): "EmptyFixedArray", + ("RO_SPACE", 0x025a1): "UninitializedValue", + ("RO_SPACE", 0x026f1): "UndefinedValue", + ("RO_SPACE", 0x02789): "NanValue", + ("RO_SPACE", 0x02801): "TheHoleValue", + ("RO_SPACE", 0x028b9): "HoleNanValue", + ("RO_SPACE", 0x028c9): "TrueValue", + ("RO_SPACE", 0x029a1): "FalseValue", + ("RO_SPACE", 0x029f1): "empty_string", + ("RO_SPACE", 0x02fb9): "EmptyScopeInfo", + ("RO_SPACE", 0x02fc9): "ArgumentsMarker", + ("RO_SPACE", 0x03089): "Exception", + ("RO_SPACE", 0x03149): "TerminationException", + ("RO_SPACE", 0x03211): "OptimizedOut", + ("RO_SPACE", 0x032d1): "StaleRegister", + ("RO_SPACE", 0x05091): "EmptyByteArray", + ("RO_SPACE", 0x050b1): "EmptyFixedUint8Array", + ("RO_SPACE", 0x050d1): "EmptyFixedInt8Array", + ("RO_SPACE", 0x050f1): "EmptyFixedUint16Array", + ("RO_SPACE", 0x05111): "EmptyFixedInt16Array", + ("RO_SPACE", 0x05131): "EmptyFixedUint32Array", + ("RO_SPACE", 0x05151): "EmptyFixedInt32Array", + ("RO_SPACE", 0x05171): "EmptyFixedFloat32Array", + ("RO_SPACE", 0x05191): "EmptyFixedFloat64Array", + ("RO_SPACE", 0x051b1): "EmptyFixedUint8ClampedArray", + ("RO_SPACE", 0x05289): "EmptySloppyArgumentsElements", + ("RO_SPACE", 0x052a9): "EmptySlowElementDictionary", + ("RO_SPACE", 0x052f1): "EmptyOrderedHashMap", + ("RO_SPACE", 0x05319): "EmptyOrderedHashSet", + ("RO_SPACE", 0x05351): "EmptyPropertyCell", + ("RO_SPACE", 0x05379): "EmptyWeakCell", + ("RO_SPACE", 0x05459): "InfinityValue", + ("RO_SPACE", 0x05469): "MinusZeroValue", + ("RO_SPACE", 0x05479): "MinusInfinityValue", + ("RO_SPACE", 0x05489): "SelfReferenceMarker", + ("OLD_SPACE", 0x02211): "EmptyScript", + ("OLD_SPACE", 0x02299): "ManyClosuresCell", + ("OLD_SPACE", 0x022b9): "NoElementsProtector", + ("OLD_SPACE", 0x022e1): "IsConcatSpreadableProtector", + ("OLD_SPACE", 0x022f1): "ArraySpeciesProtector", + ("OLD_SPACE", 0x02319): "TypedArraySpeciesProtector", + ("OLD_SPACE", 0x02341): "PromiseSpeciesProtector", + ("OLD_SPACE", 0x02369): "StringLengthProtector", + ("OLD_SPACE", 0x02379): "ArrayIteratorProtector", + ("OLD_SPACE", 0x023a1): "ArrayBufferNeuteringProtector", } # List of known V8 Frame Markers. @@ -366,4 +372,4 @@ FRAME_MARKERS = ( "NATIVE", ) -# This set of constants is generated from a non-shipping build. +# This set of constants is generated from a shipping build. diff --git a/deps/v8/tools/whitespace.txt b/deps/v8/tools/whitespace.txt index 8a1a4d64c7..99dcf1f898 100644 --- a/deps/v8/tools/whitespace.txt +++ b/deps/v8/tools/whitespace.txt @@ -7,4 +7,4 @@ A Smi balks into a war and says: The doubles heard this and started to unbox. The Smi looked at them when a crazy v8-autoroll account showed up... The autoroller bought a round of Himbeerbrause. Suddenly... -The bartender starts to shake the bottles... +The bartender starts to shake the bottles........................... |