diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-03-12 09:01:49 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-03-14 18:49:21 +0100 |
commit | 7b48713334469818661fe276cf571de9c7899f2d (patch) | |
tree | 4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/tools | |
parent | 8549ac09b256666cf5275224ec58fab9939ff32e (diff) | |
download | android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.gz android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.bz2 android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.zip |
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/tools')
126 files changed, 7126 insertions, 4254 deletions
diff --git a/deps/v8/tools/BUILD.gn b/deps/v8/tools/BUILD.gn index 3ae98078f1..7b019ad0b2 100644 --- a/deps/v8/tools/BUILD.gn +++ b/deps/v8/tools/BUILD.gn @@ -50,6 +50,7 @@ group("v8_testrunner") { data = [ # Also add the num-fuzzer wrapper script in order to be able to run the # num-fuzzer on all existing isolated V8 test suites. + "predictable_wrapper.py", "run-num-fuzzer.py", "run-tests.py", "testrunner/", diff --git a/deps/v8/tools/unittests/PRESUBMIT.py b/deps/v8/tools/PRESUBMIT.py index d428813e13..f719c75eed 100644 --- a/deps/v8/tools/unittests/PRESUBMIT.py +++ b/deps/v8/tools/PRESUBMIT.py @@ -3,7 +3,6 @@ # found in the LICENSE file. def CheckChangeOnCommit(input_api, output_api): - # TODO(machenbach): Run all unittests. tests = input_api.canned_checks.GetUnitTestsInDirectory( - input_api, output_api, '.', whitelist=['run_tests_test.py$']) + input_api, output_api, 'unittests') return input_api.RunTests(tests) diff --git a/deps/v8/tools/blink_tests/TestExpectations b/deps/v8/tools/blink_tests/TestExpectations index e6cc3d274f..e69de29bb2 100644 --- a/deps/v8/tools/blink_tests/TestExpectations +++ b/deps/v8/tools/blink_tests/TestExpectations @@ -1,7 +0,0 @@ -[ Linux ] virtual/pointerevent/fast/events/mouse-cursor-style-change-iframe.html [ Skip ] - -# Turn off Slimming Paint tests on linux. -[ Linux ] virtual/slimmingpaint/ [ Skip ] - -# Several failures since https://crrev.com/c/1196547 -crbug.com/879604 external/wpt/cookies/samesite/ [ Skip ] diff --git a/deps/v8/tools/callstats.html b/deps/v8/tools/callstats.html index 2afd0602d8..1ceca83db0 100644 --- a/deps/v8/tools/callstats.html +++ b/deps/v8/tools/callstats.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <!-- Copyright 2016 the V8 project authors. All rights reserved. Use of this source @@ -5,7 +6,8 @@ code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> - <meta charset="UTF-8"> + <meta charset="utf-8"> + <title>V8 Runtime Stats Komparator</title> <style> body { font-family: arial; @@ -228,8 +230,8 @@ code is governed by a BSD-style license that can be found in the LICENSE file. display: none; } </style> - <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> - <script type="text/javascript"> + <script src="https://www.gstatic.com/charts/loader.js"></script> + <script> "use strict" google.charts.load('current', {packages: ['corechart']}); @@ -957,7 +959,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file. } } </script> - <script type="text/javascript"> + <script> "use strict" // ========================================================================= // Helpers @@ -1058,7 +1060,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file. } </script> - <script type="text/javascript"> + <script> "use strict" // ========================================================================= // EventHandlers @@ -1305,7 +1307,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file. window.open(url,'_blank'); } </script> - <script type="text/javascript"> + <script> "use strict" // ========================================================================= class Versions { diff --git a/deps/v8/tools/callstats.py b/deps/v8/tools/callstats.py index 91f8637acd..709aade30f 100755 --- a/deps/v8/tools/callstats.py +++ b/deps/v8/tools/callstats.py @@ -140,6 +140,8 @@ def get_chrome_flags(js_flags, user_data_dir, arg_delimiter=""): "--no-first-run", "--user-data-dir={}{}{}".format(arg_delimiter, user_data_dir, arg_delimiter), + "--data-path={}{}{}".format(arg_delimiter, + os.path.join(user_data_dir, 'content-shell-data'), arg_delimiter), ] def get_chrome_replay_flags(args, arg_delimiter=""): diff --git a/deps/v8/tools/check-unused-symbols.sh b/deps/v8/tools/check-unused-symbols.sh new file mode 100755 index 0000000000..03489389b5 --- /dev/null +++ b/deps/v8/tools/check-unused-symbols.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# 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. + +v8_root=$(readlink -f $(dirname $BASH_SOURCE)/../) +symbols=$( + grep \ + --only-matching \ + --perl-regexp 'V\(_, \K([^,\)]*)' \ + -- "$v8_root/src/heap-symbols.h") + +# Find symbols which appear exactly once (in heap-symbols.h) +grep \ + --only-matching \ + --no-filename \ + --recursive \ + --fixed-strings "$symbols" \ + -- "$v8_root/src" "$v8_root/test/cctest" \ +| sort \ +| uniq -u \ +| sed -e 's/.*/Heap symbol "&" seems to be unused./' + +echo "Kthxbye." diff --git a/deps/v8/tools/clusterfuzz/v8_mock_archs.js b/deps/v8/tools/clusterfuzz/v8_mock_archs.js index 507f31a3a2..acbaef821f 100644 --- a/deps/v8/tools/clusterfuzz/v8_mock_archs.js +++ b/deps/v8/tools/clusterfuzz/v8_mock_archs.js @@ -15,15 +15,10 @@ var mock = function(arrayType) { var handler = { construct: function(target, args) { - var arrayLength = args[0] - if (args.length > 0 && - Number.isInteger(args[0]) && - args[0] > 1048576) { - args[0] = 1048576 - } else if (args.length > 2 && - Number.isInteger(args[2]) && - args[2] > 1048576) { - args[2] = 1048576 + for (let i = 0; i < args.length; i++) { + if (typeof args[i] != "object") { + args[i] = Math.min(1048576, args[i]); + } } return new ( Function.prototype.bind.apply(arrayType, [null].concat(args))); @@ -40,6 +35,8 @@ Uint16Array = mock(Uint16Array); Int32Array = mock(Int32Array); Uint32Array = mock(Uint32Array); + BigInt64Array = mock(BigInt64Array); + BigUint64Array = mock(BigUint64Array); Float32Array = mock(Float32Array); Float64Array = mock(Float64Array); })(); @@ -54,6 +51,8 @@ Uint16Array, Int32Array, Uint32Array, + BigInt64Array, + BigUint64Array, Float32Array, Float64Array, ]; diff --git a/deps/v8/tools/deprecation_stats.py b/deps/v8/tools/deprecation_stats.py new file mode 100755 index 0000000000..780832e681 --- /dev/null +++ b/deps/v8/tools/deprecation_stats.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# 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. + +import argparse +from datetime import datetime +import re +import subprocess +import sys + +RE_GITHASH = re.compile(r"^[0-9a-f]{40}") +RE_AUTHOR_TIME = re.compile(r"^author-time (\d+)$") +RE_FILENAME = re.compile(r"^filename (.+)$") + +def GetBlame(file_path): + result = subprocess.check_output( + ['git', 'blame', '-t', '--line-porcelain', file_path]) + line_iter = iter(result.splitlines()) + blame_list = list() + current_blame = None + while True: + line = next(line_iter, None) + if line is None: + break + if RE_GITHASH.match(line): + if current_blame is not None: + blame_list.append(current_blame) + current_blame = {'time': 0, 'filename': None, 'content': None} + continue + match = RE_AUTHOR_TIME.match(line) + if match: + current_blame['time'] = datetime.fromtimestamp(int(match.groups()[0])) + continue + match = RE_FILENAME.match(line) + if match: + current_blame['filename'] = match.groups()[0] + current_blame['content'] = next(line_iter).strip() + continue + blame_list.append(current_blame) + return blame_list + +RE_MACRO_END = re.compile(r"\);"); +RE_DEPRECATE_MACRO = re.compile(r"\(.*?,(.*)\);", re.MULTILINE) + +def FilterAndPrint(blame_list, macro, before): + index = 0 + re_macro = re.compile(macro) + deprecated = list() + while index < len(blame_list): + blame = blame_list[index] + match = re_macro.search(blame['content']) + if match and blame['time'] < before: + line = blame['content'] + time = blame['time'] + pos = match.end() + start = -1 + parens = 0 + quotes = 0 + while True: + if pos >= len(line): + # extend to next line + index = index + 1 + blame = blame_list[index] + if line.endswith(','): + # add whitespace when breaking line due to comma + line = line + ' ' + line = line + blame['content'] + if line[pos] == '(': + parens = parens + 1 + elif line[pos] == ')': + parens = parens - 1 + if parens == 0: + break + elif line[pos] == '"': + quotes = quotes + 1 + elif line[pos] == ',' and quotes % 2 == 0 and start == -1: + start = pos + 1 + pos = pos + 1 + deprecated.append([index + 1, time, line[start:pos].strip()]) + index = index + 1 + print("Marked as " + macro + ": " + str(len(deprecated))) + for linenumber, time, content in deprecated: + print(str(linenumber).rjust(8) + " : " + str(time) + " : " + content) + return len(deprecated) + +def ParseOptions(args): + parser = argparse.ArgumentParser(description="Collect deprecation statistics") + parser.add_argument("file_path", help="Path to v8.h") + parser.add_argument("--before", help="Filter by date") + options = parser.parse_args(args) + if options.before: + options.before = datetime.strptime(options.before, '%Y-%m-%d') + else: + options.before = datetime.now() + return options + +def Main(args): + options = ParseOptions(args) + blame_list = GetBlame(options.file_path) + FilterAndPrint(blame_list, "V8_DEPRECATE_SOON", options.before) + FilterAndPrint(blame_list, "V8_DEPRECATED", options.before) + +if __name__ == "__main__": + Main(sys.argv[1:]) diff --git a/deps/v8/tools/dev/gm.py b/deps/v8/tools/dev/gm.py index 178ffdb964..e7a4a239e0 100755 --- a/deps/v8/tools/dev/gm.py +++ b/deps/v8/tools/dev/gm.py @@ -10,10 +10,11 @@ Uses Goma by default if it is detected (at output directory setup time). Expects to be run from the root of a V8 checkout. Usage: - gm.py [<arch>].[<mode>].[<target>] [testname...] + gm.py [<arch>].[<mode>[-<suffix>]].[<target>] [testname...] All arguments are optional. Most combinations should work, e.g.: - gm.py ia32.debug x64.release d8 + gm.py ia32.debug x64.release x64.release-my-custom-opts d8 + gm.py android_arm.release.check gm.py x64 mjsunit/foo cctest/test-bar/* """ # See HELP below for additional documentation. @@ -21,17 +22,20 @@ All arguments are optional. Most combinations should work, e.g.: from __future__ import print_function import errno import os -import pty import re import subprocess import sys +USE_PTY = "linux" in sys.platform +if USE_PTY: + import pty + BUILD_TARGETS_TEST = ["d8", "cctest", "unittests"] BUILD_TARGETS_ALL = ["all"] # All arches that this script understands. ARCHES = ["ia32", "x64", "arm", "arm64", "mipsel", "mips64el", "ppc", "ppc64", - "s390", "s390x"] + "s390", "s390x", "android_arm", "android_arm64"] # Arches that get built/run when you don't specify any. DEFAULT_ARCHES = ["ia32", "x64", "arm", "arm64"] # Modes that this script understands. @@ -202,6 +206,16 @@ def GetPath(arch, mode): subdir = "%s.%s" % (arch, mode) return os.path.join(OUTDIR, subdir) +def PrepareMksnapshotCmdline(orig_cmdline, path): + result = "gdb --args %s/mksnapshot " % path + for w in orig_cmdline.split(" "): + if w.startswith("gen/") or w.startswith("snapshot_blob"): + result += ("%(path)s%(sep)s%(arg)s " % + {"path": path, "sep": os.sep, "arg": w}) + else: + result += "%s " % w + return result + class Config(object): def __init__(self, arch, mode, targets, tests=[]): self.arch = arch @@ -214,51 +228,64 @@ class Config(object): self.tests.update(tests) def GetTargetCpu(self): + if self.arch == "android_arm": return "target_cpu = \"arm\"" + if self.arch == "android_arm64": return "target_cpu = \"arm64\"" cpu = "x86" if "64" in self.arch or self.arch == "s390x": cpu = "x64" return "target_cpu = \"%s\"" % cpu def GetV8TargetCpu(self): + if self.arch == "android_arm": return "\nv8_target_cpu = \"arm\"" + if self.arch == "android_arm64": return "\nv8_target_cpu = \"arm64\"" if self.arch in ("arm", "arm64", "mipsel", "mips64el", "ppc", "ppc64", "s390", "s390x"): return "\nv8_target_cpu = \"%s\"" % self.arch return "" + def GetTargetOS(self): + if self.arch in ("android_arm", "android_arm64"): + return "\ntarget_os = \"android\"" + return "" + def GetGnArgs(self): - template = ARGS_TEMPLATES[self.mode] - arch_specific = self.GetTargetCpu() + self.GetV8TargetCpu() + # Use only substring before first '-' as the actual mode + mode = re.match("([^-]+)", self.mode).group(1) + template = ARGS_TEMPLATES[mode] + arch_specific = (self.GetTargetCpu() + self.GetV8TargetCpu() + + self.GetTargetOS()) return template % arch_specific def Build(self): path = GetPath(self.arch, self.mode) args_gn = os.path.join(path, "args.gn") + build_ninja = os.path.join(path, "build.ninja") if not os.path.exists(path): print("# mkdir -p %s" % path) os.makedirs(path) if not os.path.exists(args_gn): _Write(args_gn, self.GetGnArgs()) + if not os.path.exists(build_ninja): code = _Call("gn gen %s" % path) if code != 0: return code targets = " ".join(self.targets) # The implementation of mksnapshot failure detection relies on # the "pty" module and GDB presence, so skip it on non-Linux. - if "linux" not in sys.platform: + if not USE_PTY: return _Call("autoninja -C %s %s" % (path, targets)) return_code, output = _CallWithOutput("autoninja -C %s %s" % (path, targets)) - if return_code != 0 and "FAILED: snapshot_blob.bin" in output: + if return_code != 0 and "FAILED:" in output and "snapshot_blob" 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 "" + cmdline = re.compile("python ../../tools/run.py ./mksnapshot (.*)") + match = cmdline.search(output) + cmdline = PrepareMksnapshotCmdline(match.group(1), path) + extra_opt _Notify("V8 build requires your attention", "Detected mksnapshot failure, re-running in GDB...") - _Call("gdb -args %(path)s/mksnapshot " - "--startup_src %(path)s/gen/snapshot.cc " - "--random-seed 314159265 " - "--startup-blob %(path)s/snapshot_blob.bin" - "%(extra)s"% {"path": path, "extra": extra_opt}) + _Call(cmdline) return return_code def RunTests(self): @@ -267,8 +294,8 @@ class Config(object): tests = "" else: tests = " ".join(self.tests) - return _Call("tools/run-tests.py --arch=%s --mode=%s %s" % - (self.arch, self.mode, tests)) + return _Call("tools/run-tests.py --outdir=%s %s" % + (GetPath(self.arch, self.mode), tests)) def GetTestBinary(argstring): for suite in TESTSUITES_TARGETS: @@ -336,6 +363,8 @@ class ArgumentParser(object): targets.append(word) elif word in ACTIONS: actions.append(word) + elif any(map(lambda x: word.startswith(x + "-"), MODES)): + modes.append(word) else: print("Didn't understand: %s" % word) sys.exit(1) diff --git a/deps/v8/tools/gdbinit b/deps/v8/tools/gdbinit index cea0f07b1e..5e98d92d6f 100644 --- a/deps/v8/tools/gdbinit +++ b/deps/v8/tools/gdbinit @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# Print HeapObjects. +# Print tagged object. define job call _v8_internal_Print_Object((void*)($arg0)) end @@ -11,7 +11,16 @@ Print a v8 JavaScript object Usage: job tagged_ptr end -# Print v8::Local handle value. +# Print content of v8::internal::Handle. +define jh +call _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).location_)) +end +document jh +Print content of a v8::internal::Handle +Usage: jh internal_handle +end + +# Print content of v8::Local handle. define jlh call _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_)) end @@ -128,17 +137,29 @@ set disable-randomization off # immediately at the line of code that triggered the DCHECK. python def dcheck_stop_handler(event): - orig_frame = gdb.selected_frame() - frame = orig_frame + frame = gdb.selected_frame() select_frame = None - while frame is not None: - if frame.name() in ('V8_Dcheck', 'V8_Fatal'): + message = None + count = 0 + # limit stack scanning since they're usually shallow and otherwise stack + # overflows can be very slow. + while frame is not None and count < 5: + count += 1 + if frame.name() == 'V8_Dcheck': + frame_message = gdb.lookup_symbol('message', frame.block())[0] + if frame_message: + message = frame_message.value(frame).string() + select_frame = frame.older() + break + if frame.name() is not None and frame.name().startswith('V8_Fatal'): select_frame = frame.older() frame = frame.older() if select_frame is not None: select_frame.select() gdb.execute('frame') + if message: + print('DCHECK error: {}'.format(message)) gdb.events.stop.connect(dcheck_stop_handler) end diff --git a/deps/v8/tools/gen-keywords-gen-h.py b/deps/v8/tools/gen-keywords-gen-h.py new file mode 100755 index 0000000000..02750dc109 --- /dev/null +++ b/deps/v8/tools/gen-keywords-gen-h.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python +# 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. + +import os +import sys +import subprocess +import re +import math + +INPUT_PATH = "src/parsing/keywords.txt" +OUTPUT_PATH = "src/parsing/keywords-gen.h" + +# TODO(leszeks): Trimming seems to regress performance, investigate. +TRIM_CHAR_TABLE = False + + +def next_power_of_2(x): + return 1 if x == 0 else 2**int(math.ceil(math.log(x, 2))) + + +def call_with_input(cmd, input_string=""): + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + stdout, _ = p.communicate(input_string) + retcode = p.wait() + if retcode != 0: + raise subprocess.CalledProcessError(retcode, cmd) + return stdout + + +def checked_sub(pattern, sub, out, count=1, flags=0): + out, n = re.subn(pattern, sub, out, flags=flags) + if n != count: + raise Exception("Didn't get exactly %d replacement(s) for pattern: %s" % + (count, pattern)) + return out + + +def change_sizet_to_int(out): + # Literal buffer lengths are given as ints, not size_t + return checked_sub(r'\bsize_t\b', 'int', out, count=4) + + +def drop_line_directives(out): + # #line causes gcov issue, so drop it + return re.sub(r'^#\s*line .*$\n', '', out, flags=re.MULTILINE) + + +def trim_and_dcheck_char_table(out): + # Potential keyword strings are known to be lowercase ascii, so chop off the + # rest of the table and mask out the char + + reads_re = re.compile( + r'asso_values\[static_cast<unsigned char>\(str\[(\d+)\]\)\]') + + dchecks = [] + for str_read in reads_re.finditer(out): + dchecks.append("DCHECK_LT(str[%d], 128);" % int(str_read.group(1))) + + if TRIM_CHAR_TABLE: + out = checked_sub( + r'static const unsigned char asso_values\[\]\s*=\s*\{(\s*\d+\s*,){96}', + "".join(dchecks) + r'static const unsigned char asso_values[32] = {', + out, + flags=re.MULTILINE) + out = checked_sub( + reads_re.pattern, + r'asso_values[static_cast<unsigned char>(str[(\1)]&31)]', + out, + count=len(dchecks), + flags=re.MULTILINE) + else: + out = checked_sub( + r'static const unsigned char asso_values\[\]\s*=\s*\{', + "".join(dchecks) + r'static const unsigned char asso_values[128] = {', + out, + flags=re.MULTILINE) + + return out + + +def use_isinrange(out): + # Our IsInRange method is more efficient than checking for min/max length + return checked_sub(r'if \(len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH\)', + r'if (IsInRange(len, MIN_WORD_LENGTH, MAX_WORD_LENGTH))', + out) + + +def pad_tables(out): + # We don't want to compare against the max hash value, so pad the tables up + # to a power of two and mask the hash. + + # First get the new size + max_hash_value = int(re.search(r'MAX_HASH_VALUE\s*=\s*(\d+)', out).group(1)) + old_table_length = max_hash_value + 1 + new_table_length = next_power_of_2(old_table_length) + table_padding_len = new_table_length - old_table_length + + # Pad the length table. + single_lengthtable_entry = r'\d+' + out = checked_sub( + r""" + static\ const\ unsigned\ char\ kPerfectKeywordLengthTable\[\]\s*=\s*\{ + ( + \s*%(single_lengthtable_entry)s\s* + (?:,\s*%(single_lengthtable_entry)s\s*)* + ) + \} + """ % {'single_lengthtable_entry': single_lengthtable_entry}, + r'static const unsigned char kPerfectKeywordLengthTable[%d] = { \1 %s }' + % (new_table_length, "".join([',0'] * table_padding_len)), + out, + flags=re.MULTILINE | re.VERBOSE) + + # Pad the word list. + single_wordlist_entry = r""" + (?:\#line\ \d+\ ".*"$\s*)? + \{\s*"[a-z]*"\s*,\s*Token::[A-Z_]+\} + """ + out = checked_sub( + r""" + static\ const\ struct\ PerfectKeywordHashTableEntry\ kPerfectKeywordHashTable\[\]\s*=\s*\{ + ( + \s*%(single_wordlist_entry)s\s* + (?:,\s*%(single_wordlist_entry)s\s*)* + ) + \} + """ % {'single_wordlist_entry': single_wordlist_entry}, + r'static const struct PerfectKeywordHashTableEntry kPerfectKeywordHashTable[%d] = {\1 %s }' + % (new_table_length, "".join( + [',{"",Token::IDENTIFIER}'] * table_padding_len)), + out, + flags=re.MULTILINE | re.VERBOSE) + + # Mask the hash and replace the range check with DCHECKs. + out = checked_sub(r'Hash\s*\(\s*str,\s*len\s*\)', + r'Hash(str, len)&0x%x' % (new_table_length - 1), out) + out = checked_sub( + r'if \(key <= MAX_HASH_VALUE\)', + r'DCHECK_LT(key, arraysize(kPerfectKeywordLengthTable));DCHECK_LT(key, arraysize(kPerfectKeywordHashTable));', + out) + + return out + + +def return_token(out): + # We want to return the actual token rather than the table entry. + + # Change the return type of the function. Make it inline too. + out = checked_sub( + r'const\s*struct\s*PerfectKeywordHashTableEntry\s*\*\s*((?:PerfectKeywordHash::)?GetToken)', + r'inline Token::Value \1', + out, + count=2) + + # Change the return value when the keyword is found + out = checked_sub(r'return &kPerfectKeywordHashTable\[key\];', + r'return kPerfectKeywordHashTable[key].value;', out) + + # Change the return value when the keyword is not found + out = checked_sub(r'return 0;', r'return Token::IDENTIFIER;', out) + + return out + + +def memcmp_to_while(out): + # It's faster to loop over the keyword with a while loop than calling memcmp. + # Careful, this replacement is quite flaky, because otherwise the regex is + # unreadable. + return checked_sub( + re.escape("if (*str == *s && !memcmp (str + 1, s + 1, len - 1))") + r"\s*" + + re.escape("return kPerfectKeywordHashTable[key].value;"), + """ + while(*s!=0) { + if (*s++ != *str++) return Token::IDENTIFIER; + } + return kPerfectKeywordHashTable[key].value; + """, + out, + flags=re.MULTILINE) + + +def wrap_namespace(out): + return """// 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. + +// This file is automatically generated by gen-keywords-gen-h.py and should not +// be modified manually. + +#ifndef V8_PARSING_KEYWORDS_GEN_H_ +#define V8_PARSING_KEYWORDS_GEN_H_ + +#include "src/parsing/token.h" + +namespace v8 { +namespace internal { + +%s + +} // namespace internal +} // namespace v8 + +#endif // V8_PARSING_KEYWORDS_GEN_H_ +""" % (out) + + +def trim_character_set_warning(out): + # gperf generates an error message that is too large, trim it + + return out.replace( + '"gperf generated tables don\'t work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."', + '"gperf generated tables don\'t work with this execution character set."\\\n// If you see this error, please report a bug to <bug-gperf@gnu.org>.' + ) + + +def main(): + try: + script_dir = os.path.dirname(sys.argv[0]) + root_dir = os.path.join(script_dir, '..') + + out = subprocess.check_output(["gperf", "-m100", INPUT_PATH], cwd=root_dir) + + # And now some munging of the generated file. + out = change_sizet_to_int(out) + out = drop_line_directives(out) + out = trim_and_dcheck_char_table(out) + out = use_isinrange(out) + out = pad_tables(out) + out = return_token(out) + out = memcmp_to_while(out) + out = wrap_namespace(out) + out = trim_character_set_warning(out) + + # Final formatting. + clang_format_path = os.path.join(root_dir, + 'third_party/depot_tools/clang-format') + out = call_with_input([clang_format_path], out) + + with open(os.path.join(root_dir, OUTPUT_PATH), 'w') as f: + f.write(out) + + return 0 + + except subprocess.CalledProcessError as e: + sys.stderr.write("Error calling '{}'\n".format(" ".join(e.cmd))) + return e.returncode + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py index b98a92d266..af6e2f3cb4 100644 --- a/deps/v8/tools/gen-postmortem-metadata.py +++ b/deps/v8/tools/gen-postmortem-metadata.py @@ -94,8 +94,6 @@ consts_misc = [ { 'name': 'OddballOther', 'value': 'Oddball::kOther' }, { 'name': 'OddballException', 'value': 'Oddball::kException' }, - { 'name': 'prop_idx_first', - 'value': 'DescriptorArray::kFirstIndex' }, { 'name': 'prop_kind_Data', 'value': 'kData' }, { 'name': 'prop_kind_Accessor', @@ -192,10 +190,10 @@ consts_misc = [ { 'name': 'scopeinfo_idx_first_vars', 'value': 'ScopeInfo::kVariablePartIndex' }, - { 'name': 'jsarray_buffer_was_neutered_mask', - 'value': 'JSArrayBuffer::WasNeuteredBit::kMask' }, - { 'name': 'jsarray_buffer_was_neutered_shift', - 'value': 'JSArrayBuffer::WasNeuteredBit::kShift' }, + { 'name': 'jsarray_buffer_was_detached_mask', + 'value': 'JSArrayBuffer::WasDetachedBit::kMask' }, + { 'name': 'jsarray_buffer_was_detached_shift', + 'value': 'JSArrayBuffer::WasDetachedBit::kShift' }, { 'name': 'context_idx_scope_info', 'value': 'Context::SCOPE_INFO_INDEX' }, @@ -207,8 +205,8 @@ consts_misc = [ 'value': 'Context::EXTENSION_INDEX' }, { 'name': 'context_min_slots', 'value': 'Context::MIN_CONTEXT_SLOTS' }, - { 'name': 'context_idx_embedder_data', - 'value': 'Internals::kContextEmbedderDataIndex' }, + { 'name': 'native_context_embedder_data_offset', + 'value': 'Internals::kNativeContextEmbedderDataOffset' }, { 'name': 'namedictionaryshape_prefix_size', @@ -232,6 +230,9 @@ consts_misc = [ 'value': 'SimpleNumberDictionaryShape::kEntrySize' }, { 'name': 'type_JSError__JS_ERROR_TYPE', 'value': 'JS_ERROR_TYPE' }, + + { 'name': 'class_SharedFunctionInfo__function_data__Object', + 'value': 'SharedFunctionInfo::kFunctionDataOffset' }, ]; # @@ -244,6 +245,7 @@ consts_misc = [ # extras_accessors = [ 'JSFunction, context, Context, kContextOffset', + 'JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset', 'HeapObject, map, Map, kMapOffset', 'JSObject, elements, Object, kElementsOffset', 'JSObject, internal_fields, uintptr_t, kHeaderSize', @@ -288,7 +290,7 @@ extras_accessors = [ expected_classes = [ 'ConsString', 'FixedArray', 'HeapNumber', 'JSArray', 'JSFunction', 'JSObject', 'JSRegExp', 'JSValue', 'Map', 'Oddball', 'Script', - 'SeqOneByteString', 'SharedFunctionInfo', 'ScopeInfo' + 'SeqOneByteString', 'SharedFunctionInfo', 'ScopeInfo', 'JSPromise' ]; @@ -311,6 +313,7 @@ header = ''' #include "src/frames-inl.h" /* for architecture-specific frame constants */ #include "src/contexts.h" #include "src/objects.h" +#include "src/objects/js-promise.h" #include "src/objects/js-regexp-string-iterator.h" using namespace v8::internal; @@ -517,7 +520,8 @@ def parse_field(call): consts = []; - if (kind == 'ACCESSORS' or kind == 'ACCESSORS_GCSAFE'): + if (kind == 'ACCESSORS' or kind == 'ACCESSORS2' or + kind == 'ACCESSORS_GCSAFE'): klass = args[0]; field = args[1]; dtype = args[2].replace('<', '_').replace('>', '_') @@ -560,7 +564,7 @@ def load_fields_from_file(filename): # may span multiple lines and may contain nested parentheses. We also # call parse_field() to pick apart the invocation. # - prefixes = [ 'ACCESSORS', 'ACCESSORS_GCSAFE', + prefixes = [ 'ACCESSORS', 'ACCESSORS2', 'ACCESSORS_GCSAFE', 'SMI_ACCESSORS', 'ACCESSORS_TO_SMI' ]; current = ''; opens = 0; diff --git a/deps/v8/tools/generate-header-include-checks.py b/deps/v8/tools/generate-header-include-checks.py index 7ff52dd740..511d03c7ba 100755 --- a/deps/v8/tools/generate-header-include-checks.py +++ b/deps/v8/tools/generate-header-include-checks.py @@ -28,26 +28,14 @@ OUT_DIR = os.path.join(V8_DIR, 'check-header-includes') AUTO_EXCLUDE = [ # flag-definitions.h needs a mode set for being included. 'src/flag-definitions.h', - # blacklist of headers we need to fix (https://crbug.com/v8/7965). - 'src/allocation-site-scopes.h', - 'src/compiler/allocation-builder.h', - 'src/compiler/js-context-specialization.h', - 'src/compiler/raw-machine-assembler.h', - 'src/dateparser-inl.h', - 'src/ic/ic.h', - 'src/lookup.h', - 'src/parsing/parser.h', - 'src/parsing/preparser.h', - 'src/regexp/jsregexp.h', - 'src/snapshot/object-deserializer.h', - 'src/transitions.h', ] AUTO_EXCLUDE_PATTERNS = [ 'src/base/atomicops_internals_.*', ] + [ # platform-specific headers '\\b{}\\b'.format(p) for p in - ('win32', 'ia32', 'x64', 'arm', 'arm64', 'mips', 'mips64', 's390', 'ppc')] + ('win', 'win32', 'ia32', 'x64', 'arm', 'arm64', 'mips', 'mips64', 's390', + 'ppc')] args = None def parse_args(): diff --git a/deps/v8/tools/heap-stats/categories.js b/deps/v8/tools/heap-stats/categories.js index 63b99aae7e..b94a534896 100644 --- a/deps/v8/tools/heap-stats/categories.js +++ b/deps/v8/tools/heap-stats/categories.js @@ -34,6 +34,7 @@ const CATEGORIES = new Map([ 'INTERNALIZED_STRING_TYPE', 'JS_ARGUMENTS_TYPE', 'JS_ARRAY_BUFFER_TYPE', + 'JS_ARRAY_ITERATOR_TYPE', 'JS_ARRAY_TYPE', 'JS_BOUND_FUNCTION_TYPE', 'JS_DATE_TYPE', @@ -49,13 +50,26 @@ const CATEGORIES = new Map([ 'JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE', 'JS_GLOBAL_OBJECT_TYPE', 'JS_GLOBAL_PROXY_TYPE', + 'JS_INTL_COLLATOR_TYPE', + 'JS_INTL_DATE_TIME_FORMAT_TYPE', + 'JS_INTL_LIST_FORMAT_TYPE', + 'JS_INTL_LOCALE_TYPE', + 'JS_INTL_NUMBER_FORMAT_TYPE', + 'JS_INTL_PLURAL_RULES_TYPE', + 'JS_INTL_RELATIVE_TIME_FORMAT_TYPE', + 'JS_INTL_SEGMENT_ITERATOR_TYPE', + 'JS_INTL_SEGMENTER_TYPE', + 'JS_INTL_V8_BREAK_ITERATOR_TYPE', + 'JS_MAP_KEY_ITERATOR_TYPE', 'JS_MAP_KEY_VALUE_ITERATOR_TYPE', 'JS_MAP_TYPE', 'JS_MAP_VALUE_ITERATOR_TYPE', 'JS_MESSAGE_OBJECT_TYPE', 'JS_OBJECT_TYPE', 'JS_PROMISE_TYPE', + 'JS_PROXY_TYPE', 'JS_REGEXP_TYPE', + 'JS_SET_KEY_VALUE_ITERATOR_TYPE', 'JS_SET_TYPE', 'JS_SET_VALUE_ITERATOR_TYPE', 'JS_STRING_ITERATOR_TYPE', @@ -70,10 +84,6 @@ const CATEGORIES = new Map([ 'ONE_BYTE_STRING_TYPE', 'OTHER_CONTEXT_TYPE', 'PROPERTY_ARRAY_TYPE', - 'UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE', - 'UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE', - 'UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE', - 'UNCACHED_EXTERNAL_STRING_TYPE', 'SLICED_ONE_BYTE_STRING_TYPE', 'SLICED_STRING_TYPE', 'STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE', @@ -82,6 +92,10 @@ const CATEGORIES = new Map([ 'SYMBOL_TYPE', 'THIN_ONE_BYTE_STRING_TYPE', 'THIN_STRING_TYPE', + 'UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE', + 'UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE', + 'UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE', + 'UNCACHED_EXTERNAL_STRING_TYPE', 'WASM_INSTANCE_TYPE', 'WASM_MEMORY_TYPE', 'WASM_MODULE_TYPE', @@ -166,7 +180,7 @@ const CATEGORIES = new Map([ 'NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE', 'OPTIMIZED_CODE_LITERALS_TYPE', 'OPTIMIZED_FUNCTION', - 'PRE_PARSED_SCOPE_DATA_TYPE', + 'PREPARSE_DATA_TYPE', 'REGEXP', 'RELOC_INFO_TYPE', 'SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE', @@ -179,8 +193,8 @@ const CATEGORIES = new Map([ 'SOURCE_POSITION_TABLE_TYPE', 'STORE_HANDLER_TYPE', 'STUB', - 'UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE', - 'UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE', + 'UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE', + 'UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE', 'UNCOMPILED_JS_FUNCTION_TYPE', 'UNCOMPILED_SHARED_FUNCTION_INFO_TYPE' ]) diff --git a/deps/v8/tools/heap-stats/index.html b/deps/v8/tools/heap-stats/index.html index 648a38c798..11fac21a3d 100644 --- a/deps/v8/tools/heap-stats/index.html +++ b/deps/v8/tools/heap-stats/index.html @@ -32,7 +32,6 @@ body { </style> <script> - 'use strict'; google.charts.load('current', {'packages':['line', 'corechart', 'bar']}); diff --git a/deps/v8/tools/heap-stats/trace-file-reader.html b/deps/v8/tools/heap-stats/trace-file-reader.html index 649d32bb40..c5e5c6f04a 100644 --- a/deps/v8/tools/heap-stats/trace-file-reader.html +++ b/deps/v8/tools/heap-stats/trace-file-reader.html @@ -60,12 +60,12 @@ found in the LICENSE file. --> } @keyframes spin { - 0% { + 0% { transform: rotate(0deg); - }; - 100% { + } + 100% { transform: rotate(360deg); - }; + } } </style> diff --git a/deps/v8/tools/heap-stats/trace-file-reader.js b/deps/v8/tools/heap-stats/trace-file-reader.js index 5c244a5e92..4fec9a1cb9 100644 --- a/deps/v8/tools/heap-stats/trace-file-reader.js +++ b/deps/v8/tools/heap-stats/trace-file-reader.js @@ -78,7 +78,7 @@ class TraceFileReader extends HTMLElement { } }; // Delay the loading a bit to allow for CSS animations to happen. - setTimeout(() => reader.readAsArrayBuffer(file), 10); + setTimeout(() => reader.readAsArrayBuffer(file), 0); } else { reader.onload = (e) => { try { @@ -90,7 +90,8 @@ class TraceFileReader extends HTMLElement { this.section.className = 'failure'; } }; - setTimeout(() => reader.readAsText(file), 10); + // Delay the loading a bit to allow for CSS animations to happen. + setTimeout(() => reader.readAsText(file), 0); } } diff --git a/deps/v8/tools/ic-explorer.html b/deps/v8/tools/ic-explorer.html index f60a356dd4..aede91e0d0 100644 --- a/deps/v8/tools/ic-explorer.html +++ b/deps/v8/tools/ic-explorer.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <!-- Copyright 2016 the V8 project authors. All rights reserved. Use of this source @@ -5,6 +6,8 @@ code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> + <meta charset="utf-8"> + <title>V8 IC explorer</title> <style> html { font-family: monospace; @@ -46,16 +49,16 @@ code is governed by a BSD-style license that can be found in the LICENSE file. padding: 0.5em 0 0.2em 0; } </style> - <script src="./splaytree.js" type="text/javascript"></script> - <script src="./codemap.js" type="text/javascript"></script> - <script src="./csvparser.js" type="text/javascript"></script> - <script src="./consarray.js" type="text/javascript"></script> - <script src="./profile.js" type="text/javascript"></script> - <script src="./profile_view.js" type="text/javascript"></script> - <script src="./logreader.js" type="text/javascript"></script> - <script src="./arguments.js" type="text/javascript"></script> - <script src="./ic-processor.js" type="text/javascript"></script> - <script src="./SourceMap.js" type="text/javascript"></script> + <script src="./splaytree.js"></script> + <script src="./codemap.js"></script> + <script src="./csvparser.js"></script> + <script src="./consarray.js"></script> + <script src="./profile.js"></script> + <script src="./profile_view.js"></script> + <script src="./logreader.js"></script> + <script src="./arguments.js"></script> + <script src="./ic-processor.js"></script> + <script src="./SourceMap.js"></script> <script> "use strict" diff --git a/deps/v8/tools/ic-processor.js b/deps/v8/tools/ic-processor.js index db1eef4295..a97fe0efff 100644 --- a/deps/v8/tools/ic-processor.js +++ b/deps/v8/tools/ic-processor.js @@ -45,6 +45,12 @@ function IcProcessor() { processor: this.processCodeDelete }, 'sfi-move': { parsers: [parseInt, parseInt], processor: this.processFunctionMove }, + 'LoadGlobalIC': { + parsers : propertyICParser, + processor: this.processPropertyIC.bind(this, "LoadGlobalIC") }, + 'StoreGlobalIC': { + parsers : propertyICParser, + processor: this.processPropertyIC.bind(this, "StoreGlobalIC") }, 'LoadIC': { parsers : propertyICParser, processor: this.processPropertyIC.bind(this, "LoadIC") }, @@ -63,6 +69,8 @@ function IcProcessor() { }); this.profile_ = new Profile(); + this.LoadGlobalIC = 0; + this.StoreGlobalIC = 0; this.LoadIC = 0; this.StoreIC = 0; this.KeyedLoadIC = 0; @@ -104,6 +112,8 @@ IcProcessor.prototype.processLogFile = function(fileName) { } print(); print("====================="); + print("LoadGlobal: " + this.LoadGlobalIC); + print("StoreGlobal: " + this.StoreGlobalIC); print("Load: " + this.LoadIC); print("Store: " + this.StoreIC); print("KeyedLoad: " + this.KeyedLoadIC); diff --git a/deps/v8/tools/js2c.py b/deps/v8/tools/js2c.py index 0107436df6..d03151805d 100755 --- a/deps/v8/tools/js2c.py +++ b/deps/v8/tools/js2c.py @@ -33,7 +33,6 @@ import os, re import optparse -import jsmin import textwrap @@ -96,161 +95,6 @@ def ExpandConstants(lines, constants): return lines -def ExpandMacroDefinition(lines, pos, name_pattern, macro, expander): - pattern_match = name_pattern.search(lines, pos) - while pattern_match is not None: - # Scan over the arguments - height = 1 - start = pattern_match.start() - end = pattern_match.end() - assert lines[end - 1] == '(' - last_match = end - arg_index = [0] # Wrap state into array, to work around Python "scoping" - mapping = { } - def add_arg(str): - # Remember to expand recursively in the arguments - if arg_index[0] >= len(macro.args): - lineno = lines.count(os.linesep, 0, start) + 1 - raise Error('line %s: Too many arguments for macro "%s"' % (lineno, name_pattern.pattern)) - replacement = expander(str.strip()) - mapping[macro.args[arg_index[0]]] = replacement - arg_index[0] += 1 - while end < len(lines) and height > 0: - # We don't count commas at higher nesting levels. - if lines[end] == ',' and height == 1: - add_arg(lines[last_match:end]) - last_match = end + 1 - elif lines[end] in ['(', '{', '[']: - height = height + 1 - elif lines[end] in [')', '}', ']']: - height = height - 1 - end = end + 1 - # Remember to add the last match. - add_arg(lines[last_match:end-1]) - if arg_index[0] < len(macro.args) -1: - lineno = lines.count(os.linesep, 0, start) + 1 - raise Error('line %s: Too few arguments for macro "%s"' % (lineno, name_pattern.pattern)) - result = macro.expand(mapping) - # Replace the occurrence of the macro with the expansion - lines = lines[:start] + result + lines[end:] - pattern_match = name_pattern.search(lines, start + len(result)) - return lines - -def ExpandMacros(lines, macros): - # We allow macros to depend on the previously declared macros, but - # we don't allow self-dependecies or recursion. - for name_pattern, macro in reversed(macros): - def expander(s): - return ExpandMacros(s, macros) - lines = ExpandMacroDefinition(lines, 0, name_pattern, macro, expander) - return lines - -class TextMacro: - def __init__(self, args, body): - self.args = args - self.body = body - def expand(self, mapping): - # Keys could be substrings of earlier values. To avoid unintended - # clobbering, apply all replacements simultaneously. - any_key_pattern = "|".join(re.escape(k) for k in mapping.iterkeys()) - def replace(match): - return mapping[match.group(0)] - return re.sub(any_key_pattern, replace, self.body) - -CONST_PATTERN = re.compile(r'^define\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') -MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$') - - -def ReadMacros(lines): - constants = [] - macros = [] - for line in lines.split('\n'): - hash = line.find('#') - if hash != -1: line = line[:hash] - line = line.strip() - if len(line) is 0: continue - const_match = CONST_PATTERN.match(line) - if const_match: - name = const_match.group(1) - value = const_match.group(2).strip() - constants.append((re.compile("\\b%s\\b" % name), value)) - else: - macro_match = MACRO_PATTERN.match(line) - if macro_match: - name = macro_match.group(1) - args = [match.strip() for match in macro_match.group(2).split(',')] - body = macro_match.group(3).strip() - macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body))) - else: - raise Error("Illegal line: " + line) - return (constants, macros) - - -TEMPLATE_PATTERN = re.compile(r'^\s+T\(([A-Z][a-zA-Z0-9]*),') - -def ReadMessageTemplates(lines): - templates = [] - index = 0 - for line in lines.split('\n'): - template_match = TEMPLATE_PATTERN.match(line) - if template_match: - name = "k%s" % template_match.group(1) - value = index - index = index + 1 - templates.append((re.compile("\\b%s\\b" % name), value)) - return templates - -INLINE_MACRO_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n') -INLINE_MACRO_END_PATTERN = re.compile(r'endmacro\s*\n') - -def ExpandInlineMacros(lines): - pos = 0 - while True: - macro_match = INLINE_MACRO_PATTERN.search(lines, pos) - if macro_match is None: - # no more macros - return lines - name = macro_match.group(1) - args = [match.strip() for match in macro_match.group(2).split(',')] - end_macro_match = INLINE_MACRO_END_PATTERN.search(lines, macro_match.end()); - if end_macro_match is None: - raise Error("Macro %s unclosed" % name) - body = lines[macro_match.end():end_macro_match.start()] - - # remove macro definition - lines = lines[:macro_match.start()] + lines[end_macro_match.end():] - name_pattern = re.compile("\\b%s\\(" % name) - macro = TextMacro(args, body) - - # advance position to where the macro definition was - pos = macro_match.start() - - def non_expander(s): - return s - lines = ExpandMacroDefinition(lines, pos, name_pattern, macro, non_expander) - - -INLINE_CONSTANT_PATTERN = re.compile(r'define\s+([a-zA-Z0-9_]+)\s*=\s*([^;\n]+);\n') - -def ExpandInlineConstants(lines): - pos = 0 - while True: - const_match = INLINE_CONSTANT_PATTERN.search(lines, pos) - if const_match is None: - # no more constants - return lines - name = const_match.group(1) - replacement = const_match.group(2) - name_pattern = re.compile("\\b%s\\b" % name) - - # remove constant definition and replace - lines = (lines[:const_match.start()] + - re.sub(name_pattern, replacement, lines[const_match.end():])) - - # advance position to where the constant definition was - pos = const_match.start() - - HEADER_TEMPLATE = """\ // Copyright 2011 Google Inc. All Rights Reserved. @@ -273,11 +117,6 @@ namespace internal { } template <> - int NativesCollection<%(type)s>::GetDebuggerCount() { - return %(debugger_count)i; - } - - template <> int NativesCollection<%(type)s>::GetIndex(const char* name) { %(get_index_cases)s\ return -1; @@ -323,33 +162,16 @@ GET_SCRIPT_NAME_CASE = """\ """ -def BuildFilterChain(macro_filename, message_template_file): +def BuildFilterChain(): """Build the chain of filter functions to be applied to the sources. - Args: - macro_filename: Name of the macro file, if any. - Returns: A function (string -> string) that processes a source file. """ - filter_chain = [] - - if macro_filename: - (consts, macros) = ReadMacros(ReadFile(macro_filename)) - filter_chain.append(lambda l: ExpandMacros(l, macros)) - filter_chain.append(lambda l: ExpandConstants(l, consts)) - - if message_template_file: - message_templates = ReadMessageTemplates(ReadFile(message_template_file)) - filter_chain.append(lambda l: ExpandConstants(l, message_templates)) - - filter_chain.extend([ + filter_chain = [ RemoveCommentsEmptyLinesAndWhitespace, - ExpandInlineMacros, - ExpandInlineConstants, Validate, - jsmin.JavaScriptMinifier().JSMinify - ]) + ] def chain(f1, f2): return lambda x: f2(f1(x)) @@ -363,25 +185,12 @@ class Sources: def __init__(self): self.names = [] self.modules = [] - self.is_debugger_id = [] - - -def IsDebuggerFile(filename): - return os.path.basename(os.path.dirname(filename)) == "debug" - -def IsMacroFile(filename): - return filename.endswith("macros.py") - -def IsMessageTemplateFile(filename): - return filename.endswith("messages.h") - def PrepareSources(source_files, native_type, emit_js): """Read, prepare and assemble the list of source files. Args: - source_files: List of JavaScript-ish source files. A file named macros.py - will be treated as a list of macros. + source_files: List of JavaScript-ish source files. native_type: String corresponding to a NativeType enum value, allowing us to treat different types of sources differently. emit_js: True if we should skip the byte conversion and just leave the @@ -390,29 +199,7 @@ def PrepareSources(source_files, native_type, emit_js): Returns: An instance of Sources. """ - macro_file = None - macro_files = filter(IsMacroFile, source_files) - assert len(macro_files) in [0, 1] - if macro_files: - source_files.remove(macro_files[0]) - macro_file = macro_files[0] - - message_template_file = None - message_template_files = filter(IsMessageTemplateFile, source_files) - assert len(message_template_files) in [0, 1] - if message_template_files: - source_files.remove(message_template_files[0]) - message_template_file = message_template_files[0] - - filters = None - if native_type in ("EXTRAS", "EXPERIMENTAL_EXTRAS"): - filters = BuildExtraFilterChain() - else: - filters = BuildFilterChain(macro_file, message_template_file) - - # Sort 'debugger' sources first. - source_files = sorted(source_files, - lambda l,r: IsDebuggerFile(r) - IsDebuggerFile(l)) + filters = BuildFilterChain() source_files_and_contents = [(f, ReadFile(f)) for f in source_files] @@ -433,9 +220,6 @@ def PrepareSources(source_files, native_type, emit_js): result.modules.append(lines) - is_debugger = IsDebuggerFile(source) - result.is_debugger_id.append(is_debugger) - name = os.path.basename(source)[:-3] result.names.append(name) @@ -483,7 +267,6 @@ def BuildMetadata(sources, source_bytes, native_type): metadata = { "builtin_count": len(sources.modules), - "debugger_count": sum(sources.is_debugger_id), "sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes), "total_length": total_length, "get_index_cases": "".join(get_index_cases), @@ -528,14 +311,8 @@ def WriteStartupBlob(sources, startup_blob): """ output = open(startup_blob, "wb") - debug_sources = sum(sources.is_debugger_id); - PutInt(output, debug_sources) - for i in xrange(debug_sources): - PutStr(output, sources.names[i]); - PutStr(output, sources.modules[i]); - - PutInt(output, len(sources.names) - debug_sources) - for i in xrange(debug_sources, len(sources.names)): + PutInt(output, len(sources.names)) + for i in xrange(len(sources.names)): PutStr(output, sources.names[i]); PutStr(output, sources.modules[i]); @@ -578,7 +355,7 @@ def main(): parser.set_usage("""js2c out.cc type sources.js ... out.cc: C code to be generated. type: type parameter for NativesCollection template. - sources.js: JS internal sources or macros.py.""") + sources.js: JS internal sources.""") (options, args) = parser.parse_args() JS2C(args[2:], args[0], diff --git a/deps/v8/tools/jsfunfuzz/fuzz-harness.sh b/deps/v8/tools/jsfunfuzz/fuzz-harness.sh index 8d064b286e..fa4f9d9127 100755 --- a/deps/v8/tools/jsfunfuzz/fuzz-harness.sh +++ b/deps/v8/tools/jsfunfuzz/fuzz-harness.sh @@ -51,8 +51,17 @@ if [ "$3" == "--download" ]; then cat << EOF | patch -s -p0 -d "$v8_root" --- tools/jsfunfuzz/jsfunfuzz/multi_timed_run.py~ +++ tools/jsfunfuzz/jsfunfuzz/multi_timed_run.py -@@ -125,7 +125,7 @@ - +@@ -118,19 +118,19 @@ +-def showtail(logfilename): ++def showtail(logfilename, method="tail"): +- cmd = "tail -n 20 %s" % logfilename ++ cmd = "%s -n 20 %s" % (method, logfilename) + print cmd + print "" + os.system(cmd) + print "" + print "" + def many_timed_runs(): iteration = 0 - while True: @@ -60,6 +69,12 @@ if [ "$3" == "--download" ]; then iteration += 1 logfilename = "w%d" % iteration one_timed_run(logfilename) + if not succeeded(logfilename): + showtail(logfilename) +- showtail("err-" + logfilename) ++ showtail("err-" + logfilename, method="head") + + many_timed_runs() EOF fi diff --git a/deps/v8/tools/jsfunfuzz/jsfunfuzz.tar.gz.sha1 b/deps/v8/tools/jsfunfuzz/jsfunfuzz.tar.gz.sha1 index 449996007d..d12877e3b8 100644 --- a/deps/v8/tools/jsfunfuzz/jsfunfuzz.tar.gz.sha1 +++ b/deps/v8/tools/jsfunfuzz/jsfunfuzz.tar.gz.sha1 @@ -1 +1 @@ -d92e66273ea2a0da89456a977edd0224a8e837e9
\ No newline at end of file +936f3baf5a24313da5eb98195d5e01d76fe602fb
\ No newline at end of file diff --git a/deps/v8/tools/jsmin.py b/deps/v8/tools/jsmin.py deleted file mode 100644 index 236f511d44..0000000000 --- a/deps/v8/tools/jsmin.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/python2.4 - -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""A JavaScript minifier. - -It is far from being a complete JS parser, so there are many valid -JavaScript programs that will be ruined by it. Another strangeness is that -it accepts $ and % as parts of identifiers. It doesn't merge lines or strip -out blank lines in order to ease debugging. Variables at the top scope are -properties of the global object so we can't rename them. It is assumed that -you introduce variables with var as if JavaScript followed C++ scope rules -around curly braces, so the declaration must be above the first use. - -Use as: -import jsmin -minifier = JavaScriptMinifier() -program1 = minifier.JSMinify(program1) -program2 = minifier.JSMinify(program2) -""" - -import re - - -class JavaScriptMinifier(object): - """An object that you can feed code snippets to to get them minified.""" - - def __init__(self): - # We prepopulate the list of identifiers that shouldn't be used. These - # short language keywords could otherwise be used by the script as variable - # names. - self.seen_identifiers = {"do": True, "in": True} - self.identifier_counter = 0 - self.in_comment = False - self.map = {} - self.nesting = 0 - - def LookAtIdentifier(self, m): - """Records identifiers or keywords that we see in use. - - (So we can avoid renaming variables to these strings.) - Args: - m: The match object returned by re.search. - - Returns: - Nothing. - """ - identifier = m.group(1) - self.seen_identifiers[identifier] = True - - def Push(self): - """Called when we encounter a '{'.""" - self.nesting += 1 - - def Pop(self): - """Called when we encounter a '}'.""" - self.nesting -= 1 - # We treat each top-level opening brace as a single scope that can span - # several sets of nested braces. - if self.nesting == 0: - self.map = {} - self.identifier_counter = 0 - - def Declaration(self, m): - """Rewrites bits of the program selected by a regexp. - - These can be curly braces, literal strings, function declarations and var - declarations. (These last two must be on one line including the opening - curly brace of the function for their variables to be renamed). - - Args: - m: The match object returned by re.search. - - Returns: - The string that should replace the match in the rewritten program. - """ - matched_text = m.group(0) - - if matched_text.startswith("`") and matched_text.endswith("`"): - return re.sub(r"\$\{([\w$%]+)\}", - lambda m: '${' + self.FindNewName(m.group(1)) + '}', - matched_text) - - if matched_text == "{": - self.Push() - return matched_text - if matched_text == "}": - self.Pop() - return matched_text - if re.match("[\"'/]", matched_text): - return matched_text - m = re.match(r"var ", matched_text) - if m: - var_names = matched_text[m.end():] - var_names = re.split(r",", var_names) - return "var " + ",".join(map(self.FindNewName, var_names)) - m = re.match(r"(function\b[^(]*)\((.*)\)\{$", matched_text) - if m: - up_to_args = m.group(1) - args = m.group(2) - args = re.split(r",", args) - self.Push() - return up_to_args + "(" + ",".join(map(self.FindNewName, args)) + "){" - - if matched_text in self.map: - return self.map[matched_text] - - return matched_text - - def CharFromNumber(self, number): - """A single-digit base-52 encoding using a-zA-Z.""" - if number < 26: - return chr(number + 97) - number -= 26 - return chr(number + 65) - - def FindNewName(self, var_name): - """Finds a new 1-character or 2-character name for a variable. - - Enters it into the mapping table for this scope. - - Args: - var_name: The name of the variable before renaming. - - Returns: - The new name of the variable. - """ - new_identifier = "" - # Variable names that end in _ are member variables of the global object, - # so they can be visible from code in a different scope. We leave them - # alone. - if var_name in self.map: - return self.map[var_name] - if self.nesting == 0: - return var_name - # Do not rename arguments object. - if var_name == 'arguments': - return 'arguments' - while True: - identifier_first_char = self.identifier_counter % 52 - identifier_second_char = self.identifier_counter // 52 - new_identifier = self.CharFromNumber(identifier_first_char) - if identifier_second_char != 0: - new_identifier = ( - self.CharFromNumber(identifier_second_char - 1) + new_identifier) - self.identifier_counter += 1 - if not new_identifier in self.seen_identifiers: - break - - self.map[var_name] = new_identifier - return new_identifier - - def RemoveSpaces(self, m): - """Returns literal strings unchanged, replaces other inputs with group 2. - - Other inputs are replaced with the contents of capture 1. This is either - a single space or an empty string. - - Args: - m: The match object returned by re.search. - - Returns: - The string that should be inserted instead of the matched text. - """ - entire_match = m.group(0) - replacement = m.group(1) - if re.match(r"'.*'$", entire_match): - return entire_match - if re.match(r'".*"$', entire_match): - return entire_match - if re.match(r"`.*`$", entire_match): - return entire_match - if re.match(r"/.+/$", entire_match): - return entire_match - return replacement - - def JSMinify(self, text): - """The main entry point. Takes a text and returns a compressed version. - - The compressed version hopefully does the same thing. Line breaks are - preserved. - - Args: - text: The text of the code snippet as a multiline string. - - Returns: - The compressed text of the code snippet as a multiline string. - """ - new_lines = [] - for line in re.split(r"\n", text): - line = line.replace("\t", " ") - if self.in_comment: - m = re.search(r"\*/", line) - if m: - line = line[m.end():] - self.in_comment = False - else: - new_lines.append("") - continue - - if not self.in_comment: - line = re.sub(r"/\*.*?\*/", " ", line) - line = re.sub(r"//.*", "", line) - m = re.search(r"/\*", line) - if m: - line = line[:m.start()] - self.in_comment = True - - # Strip leading and trailing spaces. - line = re.sub(r"^ +", "", line) - line = re.sub(r" +$", "", line) - # A regexp that matches a literal string surrounded by "double quotes". - # This regexp can handle embedded backslash-escaped characters including - # embedded backslash-escaped double quotes. - double_quoted_string = r'"(?:[^"\\]|\\.)*"' - # A regexp that matches a literal string surrounded by 'single quotes'. - single_quoted_string = r"'(?:[^'\\]|\\.)*'" - # A regexp that matches a template string - template_string = r"`(?:[^`\\]|\\.)*`" - # A regexp that matches a regexp literal surrounded by /slashes/. - # Don't allow a regexp to have a ) before the first ( since that's a - # syntax error and it's probably just two unrelated slashes. - # Also don't allow it to come after anything that can only be the - # end of a primary expression. - slash_quoted_regexp = r"(?<![\w$'\")\]])/(?:(?=\()|(?:[^()/\\]|\\.)+)(?:\([^/\\]|\\.)*/" - # Replace multiple spaces with a single space. - line = re.sub("|".join([double_quoted_string, - single_quoted_string, - template_string, - slash_quoted_regexp, - "( )+"]), - self.RemoveSpaces, - line) - # Strip single spaces unless they have an identifier character both before - # and after the space. % and $ are counted as identifier characters. - line = re.sub("|".join([double_quoted_string, - single_quoted_string, - template_string, - slash_quoted_regexp, - r"(?<![a-zA-Z_0-9$%]) | (?![a-zA-Z_0-9$%])()"]), - self.RemoveSpaces, - line) - # Collect keywords and identifiers that are already in use. - if self.nesting == 0: - re.sub(r"([a-zA-Z0-9_$%]+)", self.LookAtIdentifier, line) - function_declaration_regexp = ( - r"\bfunction" # Function definition keyword... - r"( [\w$%]+)?" # ...optional function name... - r"\([\w$%,]+\)\{") # ...argument declarations. - # Unfortunately the keyword-value syntax { key:value } makes the key look - # like a variable where in fact it is a literal string. We use the - # presence or absence of a question mark to try to distinguish between - # this case and the ternary operator: "condition ? iftrue : iffalse". - if re.search(r"\?", line): - block_trailing_colon = r"" - else: - block_trailing_colon = r"(?![:\w$%])" - # Variable use. Cannot follow a period precede a colon. - variable_use_regexp = r"(?<![.\w$%])[\w$%]+" + block_trailing_colon - line = re.sub("|".join([double_quoted_string, - single_quoted_string, - template_string, - slash_quoted_regexp, - r"\{", # Curly braces. - r"\}", - r"\bvar [\w$%,]+", # var declarations. - function_declaration_regexp, - variable_use_regexp]), - self.Declaration, - line) - new_lines.append(line) - - return "\n".join(new_lines) + "\n" diff --git a/deps/v8/tools/linux-tick-processor b/deps/v8/tools/linux-tick-processor index 705e07d514..8b856caa9c 100755 --- a/deps/v8/tools/linux-tick-processor +++ b/deps/v8/tools/linux-tick-processor @@ -27,8 +27,8 @@ if [ ! -x "$d8_exec" ]; then fi if [ ! -x "$d8_exec" ]; then - echo "d8 shell not found in $D8_PATH" - echo "To build, execute 'make native' from the V8 directory" + echo "d8 shell not found in $D8_PATH" >&2 + echo "Please provide path to d8 as env var in D8_PATH" >&2 exit 1 fi diff --git a/deps/v8/tools/locs.py b/deps/v8/tools/locs.py new file mode 100755 index 0000000000..6773d1a76a --- /dev/null +++ b/deps/v8/tools/locs.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python3 +# 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. + +""" locs.py - Count lines of code before and after preprocessor expansion + Consult --help for more information. +""" + +import argparse +import json +import os +import re +import subprocess +import sys +import tempfile +import time +from pathlib import Path + +ARGPARSE = argparse.ArgumentParser( + description=("A script that computes LoC for a build dir or from a" + "compile_commands.json file"), + epilog="""Examples: + Count with default settings for build in out/Default: + locs.py --build-dir out/Default + Count with default settings according to given compile_commands file: + locs.py --compile-commands compile_commands.json + Count only a custom group of files settings for build in out/Default: + tools/locs.py --build-dir out/Default + --group src-compiler '\.\./\.\./src/compiler' + --only src-compiler + Report the 10 files with the worst expansion: + tools/locs.py --build-dir out/Default --worst 10 + Report the 10 files with the worst expansion in src/compiler: + tools/locs.py --build-dir out/Default --worst 10 + --group src-compiler '\.\./\.\./src/compiler' + --only src-compiler + Report the 10 largest files after preprocessing: + tools/locs.py --build-dir out/Default --largest 10 + Report the 10 smallest input files: + tools/locs.py --build-dir out/Default --smallest 10""", + formatter_class=argparse.RawTextHelpFormatter +) + +ARGPARSE.add_argument( + '--json', + action='store_true', + default=False, + help="output json instead of short summary") +ARGPARSE.add_argument( + '--build-dir', + type=str, + default="", + help="Use specified build dir and generate necessary files") +ARGPARSE.add_argument( + '--echocmd', + action='store_true', + default=False, + help="output command used to compute LoC") +ARGPARSE.add_argument( + '--compile-commands', + type=str, + default='compile_commands.json', + help="Use specified compile_commands.json file") +ARGPARSE.add_argument( + '--only', + action='append', + default=[], + help="Restrict counting to report group (can be passed multiple times)") +ARGPARSE.add_argument( + '--not', + action='append', + default=[], + help="Exclude specific group (can be passed multiple times)") +ARGPARSE.add_argument( + '--list-groups', + action='store_true', + default=False, + help="List groups and associated regular expressions") +ARGPARSE.add_argument( + '--group', + nargs=2, + action='append', + default=[], + help="Add a report group (can be passed multiple times)") +ARGPARSE.add_argument( + '--largest', + type=int, + nargs='?', + default=0, + const=3, + help="Output the n largest files after preprocessing") +ARGPARSE.add_argument( + '--worst', + type=int, + nargs='?', + default=0, + const=3, + help="Output the n files with worst expansion by preprocessing") +ARGPARSE.add_argument( + '--smallest', + type=int, + nargs='?', + default=0, + const=3, + help="Output the n smallest input files") +ARGPARSE.add_argument( + '--files', + type=int, + nargs='?', + default=0, + const=3, + help="Output results for each file separately") + +ARGS = vars(ARGPARSE.parse_args()) + + +def MaxWidth(strings): + max_width = 0 + for s in strings: + max_width = max(max_width, len(s)) + return max_width + + +def GenerateCompileCommandsAndBuild(build_dir, compile_commands_file, out): + if not os.path.isdir(build_dir): + print("Error: Specified build dir {} is not a directory.".format( + build_dir), file=sys.stderr) + exit(1) + compile_commands_file = "{}/compile_commands.json".format(build_dir) + + print("Generating compile commands in {}.".format( + compile_commands_file), file=out) + + ninja = "ninja -C {} -t compdb cxx cc > {}".format( + build_dir, compile_commands_file) + if subprocess.call(ninja, shell=True, stdout=out) != 0: + print("Error: Cound not generate {} for {}.".format( + compile_commands_file, build_dir), file=sys.stderr) + exit(1) + + autoninja = "autoninja -C {} v8_generated_cc_files".format(build_dir) + if subprocess.call(autoninja, shell=True, stdout=out) != 0: + print("Error: Building target 'v8_generated_cc_files'" + " failed for {}.".format(build_dir), file=sys.stderr) + exit(1) + + return compile_commands_file + + +class CompilationData: + def __init__(self, loc, expanded): + self.loc = loc + self.expanded = expanded + + def ratio(self): + return self.expanded / (self.loc+1) + + def to_string(self): + return "{:>9,} to {:>12,} ({:>5.0f}x)".format( + self.loc, self.expanded, self.ratio()) + + +class File(CompilationData): + def __init__(self, file, loc, expanded): + super().__init__(loc, expanded) + self.file = file + + def to_string(self): + return "{} {}".format(super().to_string(), self.file) + + +class Group(CompilationData): + def __init__(self, name, regexp_string): + super().__init__(0, 0) + self.name = name + self.count = 0 + self.regexp = re.compile(regexp_string) + + def account(self, unit): + if (self.regexp.match(unit.file)): + self.loc += unit.loc + self.expanded += unit.expanded + self.count += 1 + + def to_string(self, name_width): + return "{:<{}} ({:>5} files): {}".format( + self.name, name_width, self.count, super().to_string()) + + +def SetupReportGroups(): + default_report_groups = {"total": '.*', + "src": '\\.\\./\\.\\./src', + "test": '\\.\\./\\.\\./test', + "third_party": '\\.\\./\\.\\./third_party', + "gen": 'gen'} + + report_groups = {**default_report_groups, **dict(ARGS['group'])} + + if ARGS['only']: + for only_arg in ARGS['only']: + if not only_arg in report_groups.keys(): + print("Error: specified report group '{}' is not defined.".format( + ARGS['only'])) + exit(1) + else: + report_groups = { + k: v for (k, v) in report_groups.items() if k in ARGS['only']} + + if ARGS['not']: + report_groups = { + k: v for (k, v) in report_groups.items() if k not in ARGS['not']} + + if ARGS['list_groups']: + print_cat_max_width = MaxWidth(list(report_groups.keys()) + ["Category"]) + print(" {:<{}} {}".format("Category", + print_cat_max_width, "Regular expression")) + for cat, regexp_string in report_groups.items(): + print(" {:<{}}: {}".format( + cat, print_cat_max_width, regexp_string)) + + report_groups = {k: Group(k, v) for (k, v) in report_groups.items()} + + return report_groups + + +class Results: + def __init__(self): + self.groups = SetupReportGroups() + self.units = {} + + def track(self, filename): + is_tracked = False + for group in self.groups.values(): + if group.regexp.match(filename): + is_tracked = True + return is_tracked + + def recordFile(self, filename, loc, expanded): + unit = File(filename, loc, expanded) + self.units[filename] = unit + for group in self.groups.values(): + group.account(unit) + + def maxGroupWidth(self): + return MaxWidth([v.name for v in self.groups.values()]) + + def printGroupResults(self, file): + for key in sorted(self.groups.keys()): + print(self.groups[key].to_string(self.maxGroupWidth()), file=file) + + def printSorted(self, key, count, reverse, out): + for unit in sorted(list(self.units.values()), key=key, reverse=reverse)[:count]: + print(unit.to_string(), file=out) + + +class LocsEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, File): + return {"file": o.file, "loc": o.loc, "expanded": o.expanded} + if isinstance(o, Group): + return {"name": o.name, "loc": o.loc, "expanded": o.expanded} + if isinstance(o, Results): + return {"groups": o.groups, "units": o.units} + return json.JSONEncoder.default(self, o) + + +class StatusLine: + def __init__(self): + self.max_width = 0 + + def print(self, statusline, end="\r", file=sys.stdout): + self.max_width = max(self.max_width, len(statusline)) + print("{0:<{1}}".format(statusline, self.max_width), end=end, file=file, flush=True) + + +class CommandSplitter: + def __init__(self): + self.cmd_pattern = re.compile( + "([^\\s]*\\s+)?(?P<clangcmd>[^\\s]*clang.*)" + " -c (?P<infile>.*) -o (?P<outfile>.*)") + + def process(self, compilation_unit, temp_file_name): + cmd = self.cmd_pattern.match(compilation_unit['command']) + outfilename = cmd.group('outfile') + ".cc" + infilename = cmd.group('infile') + infile = Path(compilation_unit['directory']).joinpath(infilename) + outfile = Path(str(temp_file_name)).joinpath(outfilename) + return [cmd.group('clangcmd'), infilename, infile, outfile] + + +def Main(): + compile_commands_file = ARGS['compile_commands'] + out = sys.stdout + if ARGS['json']: + out = sys.stderr + + if ARGS['build_dir']: + compile_commands_file = GenerateCompileCommandsAndBuild( + ARGS['build_dir'], compile_commands_file, out) + + try: + with open(compile_commands_file) as file: + data = json.load(file) + except FileNotFoundError: + print("Error: Cannot read '{}'. Consult --help to get started.") + exit(1) + + result = Results() + status = StatusLine() + + with tempfile.TemporaryDirectory(dir='/tmp/', prefix="locs.") as temp: + processes = [] + start = time.time() + cmd_splitter = CommandSplitter() + + for i, key in enumerate(data): + if not result.track(key['file']): + continue + if not ARGS['json']: + status.print( + "[{}/{}] Counting LoCs of {}".format(i, len(data), key['file'])) + clangcmd, infilename, infile, outfile = cmd_splitter.process(key, temp) + outfile.parent.mkdir(parents=True, exist_ok=True) + if infile.is_file(): + clangcmd = clangcmd + " -E -P " + \ + str(infile) + " -o /dev/stdout | sed '/^\\s*$/d' | wc -l" + loccmd = ("cat {} | sed '\\;^\\s*//;d' | sed '\\;^/\\*;d'" + " | sed '/^\\*/d' | sed '/^\\s*$/d' | wc -l").format( + infile) + runcmd = " {} ; {}".format(clangcmd, loccmd) + if ARGS['echocmd']: + print(runcmd) + p = subprocess.Popen( + runcmd, shell=True, cwd=key['directory'], stdout=subprocess.PIPE) + processes.append({'process': p, 'infile': infilename}) + + for i, p in enumerate(processes): + status.print("[{}/{}] Summing up {}".format( + i, len(processes), p['infile']), file=out) + output, err = p['process'].communicate() + expanded, loc = list(map(int, output.split())) + result.recordFile(p['infile'], loc, expanded) + + end = time.time() + if ARGS['json']: + print(json.dumps(result, ensure_ascii=False, cls=LocsEncoder)) + status.print("Processed {:,} files in {:,.2f} sec.".format( + len(processes), end-start), end="\n", file=out) + result.printGroupResults(file=out) + + if ARGS['largest']: + print("Largest {} files after expansion:".format(ARGS['largest'])) + result.printSorted( + lambda v: v.expanded, ARGS['largest'], reverse=True, out=out) + + if ARGS['worst']: + print("Worst expansion ({} files):".format(ARGS['worst'])) + result.printSorted( + lambda v: v.ratio(), ARGS['worst'], reverse=True, out=out) + + if ARGS['smallest']: + print("Smallest {} input files:".format(ARGS['smallest'])) + result.printSorted( + lambda v: v.loc, ARGS['smallest'], reverse=False, out=out) + + if ARGS['files']: + print("List of input files:") + result.printSorted( + lambda v: v.file, ARGS['files'], reverse=False, out=out) + + return 0 + + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/deps/v8/tools/map-processor b/deps/v8/tools/map-processor index c0713bdf13..cf18c31a8e 100755 --- a/deps/v8/tools/map-processor +++ b/deps/v8/tools/map-processor @@ -28,7 +28,7 @@ fi if [ ! -x "$d8_exec" ]; then echo "d8 shell not found in $D8_PATH" - echo "To build, execute 'make native' from the V8 directory" + echo "Please provide path to d8 as env var in D8_PATH" exit 1 fi diff --git a/deps/v8/tools/map-processor.html b/deps/v8/tools/map-processor.html index 4029e96343..70c205c771 100644 --- a/deps/v8/tools/map-processor.html +++ b/deps/v8/tools/map-processor.html @@ -5,7 +5,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> -<meta charset="UTF-8"> +<meta charset="utf-8"> <style> html, body { font-family: sans-serif; @@ -15,10 +15,100 @@ html, body { h1, h2, h3, section { padding-left: 15px; } + +#content { + opacity: 0.0; + height: 0px; + transition: all 0.5s ease-in-out; +} + +.success #content { + height: auto; + opacity: 1.0; +} + +#fileReader { + width: 100%; + height: 100px; + line-height: 100px; + text-align: center; + border: solid 1px #000000; + border-radius: 5px; + cursor: pointer; + transition: all 0.5s ease-in-out; +} + +.failure #fileReader { + background-color: #FFAAAA; +} + +.success #fileReader { + height: 20px; + line-height: 20px; +} + +#fileReader:hover { + background-color: #e0edfe; +} + +.loading #fileReader { + cursor: wait; +} + +#fileReader > input { + display: none; +} + + +#loader { + display: none; +} + +.loading #loader { + display: block; + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.5); +} + +#spinner { + position: absolute; + width: 100px; + height: 100px; + top: 40%; + left: 50%; + margin-left: -50px; + border: 30px solid #000; + border-top: 30px solid #36E; + border-radius: 50%; + animation: spin 1s ease-in-out infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.colorbox { + width: 10px; + height: 10px; + border: 1px black solid; +} + #stats table { display: inline-block; padding-right: 50px; } +#stats table td { + cursor: pointer; +} #stats .transitionTable { max-height: 200px; overflow-y: scroll; @@ -30,6 +120,16 @@ h1, h2, h3, section { overflow-x: scroll; user-select: none; } +#timelineLabel { + transform: rotate(90deg); + transform-origin: left bottom 0; + position: absolute; + left: 0; + width: 250px; + text-align: center; + font-size: 10px; + opacity: 0.5; +} #timelineChunks { height: 250px; position: absolute; @@ -179,6 +279,9 @@ h1, h2, h3, section { word-break: break-all; background-color: rgba(255,255,255,0.5); } +.black{ + background-color: black; +} .red { background-color: red; } @@ -308,7 +411,7 @@ function selectOption(select, match) { function div(classes) { let node = document.createElement('div'); if (classes !== void 0) { - if (typeof classes == "string") { + if (typeof classes === "string") { node.classList.add(classes); } else { classes.forEach(cls => node.classList.add(cls)); @@ -322,11 +425,17 @@ function table(className) { if (className) node.classList.add(className) return node; } -function td(text) { + +function td(textOrNode) { let node = document.createElement("td"); - node.innerText = text; + if (typeof textOrNode === "object") { + node.appendChild(textOrNode); + } else { + node.innerText = textOrNode; + } return node; } + function tr() { let node = document.createElement("tr"); return node; @@ -369,9 +478,14 @@ define(Array.prototype, "last", function() { return this[this.length - 1] }); // ========================================================================= // EventHandlers function handleBodyLoad() { - let upload = $('uploadInput'); - upload.onclick = (e) => { e.target.value = null }; - upload.onchange = (e) => { handleLoadFile(e.target) }; + let upload = $('fileReader'); + upload.onclick = (e) => $("file").click(); + upload.ondragover = (e) => e.preventDefault(); + upload.ondrop = (e) => handleLoadFile(e); + $('file').onchange = (e) => handleLoadFile(e); + upload.onkeydown = (e) => { + if (event.key == "Enter") $("file").click(); + }; upload.focus(); document.state = new State(); @@ -381,21 +495,32 @@ function handleBodyLoad() { tooltip.style.top = e.pageY + "px"; let map = e.target.map; if (map) { - $("tooltipContents").innerText = map.description.join("\n"); + $("tooltipContents").innerText = map.description; } }); -} -function handleLoadFile(upload) { - let files = upload.files; - let file = files[0]; - let reader = new FileReader(); - reader.onload = function(evt) { - handleLoadText(this.result); + function handleLoadFile(event) { + // Used for drop and file change. + event.preventDefault(); + let host = event.dataTransfer ? event.dataTransfer : event.target; + let file = host.files[0]; + let reader = new FileReader(); + document.body.className = 'loading'; + reader.onload = function(evt) { + try { + handleLoadText(this.result); + document.body.className = 'success'; + } catch(e) { + document.body.className = 'failure'; + console.error(e); + } + } + // Defer the reading to allow spinner CSS animation. + setTimeout(() => reader.readAsText(file), 0); } - reader.readAsText(file); } + function handleLoadText(text) { let mapProcessor = new MapProcessor(); document.state.timeline = mapProcessor.processString(text); @@ -540,6 +665,7 @@ class View { let details = ""; if (this.map) { details += "ID: " + this.map.id; + details += "\nSource location: " + this.map.filePosition; details += "\n" + this.map.description; } $("mapDetails").innerText = details; @@ -591,7 +717,6 @@ class View { time += interval; } this.drawOverview(); - this.drawHistograms(); this.redraw(); } @@ -686,47 +811,6 @@ class View { $("timelineOverview").style.backgroundImage = "url(" + imageData + ")"; } - drawHistograms() { - $("mapsDepthHistogram").histogram = this.timeline.depthHistogram(); - $("mapsFanOutHistogram").histogram = this.timeline.fanOutHistogram(); - } - - drawMapsDepthHistogram() { - let canvas = $("mapsDepthCanvas"); - let histogram = this.timeline.depthHistogram(); - this.drawHistogram(canvas, histogram, true); - } - - drawMapsFanOutHistogram() { - let canvas = $("mapsFanOutCanvas"); - let histogram = this.timeline.fanOutHistogram(); - this.drawHistogram(canvas, histogram, true, true); - } - - drawHistogram(canvas, histogram, logScaleX=false, logScaleY=false) { - let ctx = canvas.getContext("2d"); - let yMax = histogram.max(each => each.length); - if (logScaleY) yMax = Math.log(yMax); - let xMax = histogram.length; - if (logScaleX) xMax = Math.log(xMax); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.beginPath(); - ctx.moveTo(0,canvas.height); - for (let i = 0; i < histogram.length; i++) { - let x = i; - if (logScaleX) x = Math.log(x); - x = x / xMax * canvas.width; - let bucketLength = histogram[i].length; - if (logScaleY) bucketLength = Math.log(bucketLength); - let y = (1 - bucketLength / yMax) * canvas.height; - ctx.lineTo(x, y); - } - ctx.lineTo(canvas.width, canvas.height); - ctx.closePath; - ctx.stroke(); - ctx.fill(); - } - redraw() { let canvas= $("timelineCanvas"); canvas.width = (this.chunks.length+1) * kChunkWidth; @@ -1006,26 +1090,32 @@ class StatsView { } updateGeneralStats() { let pairs = [ - ["Maps", e => true], - ["Transitions", e => e.edge && e.edge.isTransition()], - ["Fast to Slow", e => e.edge && e.edge.isFastToSlow()], - ["Slow to Fast", e => e.edge && e.edge.isSlowToFast()], - ["Initial Map", e => e.edge && e.edge.isInitial()], - ["Replace Descriptors", e => e.edge && e.edge.isReplaceDescriptors()], - ["Copy as Prototype", e => e.edge && e.edge.isCopyAsPrototype()], - ["Optimize as Prototype", e => e.edge && e.edge.isOptimizeAsPrototype()], - ["Deprecated", e => e.isDeprecated()], + ["Maps", null, e => true], + ["Transitions", 'black', e => e.edge && e.edge.isTransition()], + ["Fast to Slow", 'violet', e => e.edge && e.edge.isFastToSlow()], + ["Slow to Fast", 'orange', e => e.edge && e.edge.isSlowToFast()], + ["Initial Map", 'yellow', e => e.edge && e.edge.isInitial()], + ["Replace Descriptors", 'red', e => e.edge && e.edge.isReplaceDescriptors()], + ["Copy as Prototype", 'red', e => e.edge && e.edge.isCopyAsPrototype()], + ["Optimize as Prototype", null, e => e.edge && e.edge.isOptimizeAsPrototype()], + ["Deprecated", null, e => e.isDeprecated()], + ["Bootstrapped", 'green', e => e.isBootstrapped()], ]; let text = ""; let tableNode = table(); let name, filter; let total = this.timeline.size(); - pairs.forEach(([name, filter]) => { + pairs.forEach(([name, color, filter]) => { let row = tr(); + if (color !== null) { + row.appendChild(td(div(['colorbox', color]))); + } else { + row.appendChild(td("")); + } row.maps = this.timeline.filterUniqueTransitions(filter); - row.addEventListener("click", - e => this.transitionView.showMaps(e.target.parentNode.maps)); + row.onclick = + (e) => this.transitionView.showMaps(e.target.parentNode.maps); row.appendChild(td(name)); let count = this.timeline.count(filter); row.appendChild(td(count)); @@ -1060,7 +1150,7 @@ function transitionTypeToColor(type) { switch(type) { case "new": return "green"; case "Normalize": return "violet"; - case "map=SlowToFast": return "orange"; + case "SlowToFast": return "orange"; case "InitialMap": return "yellow"; case "Transition": return "black"; case "ReplaceDescriptors": return "red"; @@ -1069,183 +1159,53 @@ function transitionTypeToColor(type) { } // ShadowDom elements ========================================================= -customElements.define('x-histogram', class extends HTMLElement { - constructor() { - super(); - let shadowRoot = this.attachShadow({mode: 'open'}); - const t = document.querySelector('#x-histogram-template'); - const instance = t.content.cloneNode(true); - shadowRoot.appendChild(instance); - this._histogram = undefined; - this.mouseX = 0; - this.mouseY = 0; - this.canvas.addEventListener('mousemove', event => this.handleCanvasMove(event)); - } - setBoolAttribute(name, value) { - if (value) { - this.setAttribute(name, ""); - } else { - this.deleteAttribute(name); - } - } - static get observedAttributes() { - return ['title', 'xlog', 'ylog', 'xlabel', 'ylabel']; - } - $(query) { return this.shadowRoot.querySelector(query) } - get h1() { return this.$("h2") } - get canvas() { return this.$("canvas") } - get xLabelDiv() { return this.$("#xLabel") } - get yLabelDiv() { return this.$("#yLabel") } - - get histogram() { - return this._histogram; - } - set histogram(array) { - this._histogram = array; - if (this._histogram) { - this.yMax = this._histogram.max(each => each.length); - this.xMax = this._histogram.length; - } - this.draw(); - } - - get title() { return this.getAttribute("title") } - set title(string) { this.setAttribute("title", string) } - get xLabel() { return this.getAttribute("xlabel") } - set xLabel(string) { this.setAttribute("xlabel", string)} - get yLabel() { return this.getAttribute("ylabel") } - set yLabel(string) { this.setAttribute("ylabel", string)} - get xLog() { return this.hasAttribute("xlog") } - set xLog(value) { this.setBoolAttribute("xlog", value) } - get yLog() { return this.hasAttribute("ylog") } - set yLog(value) { this.setBoolAttribute("ylog", value) } - - attributeChangedCallback(name, oldValue, newValue) { - if (name == "title") { - this.h1.innerText = newValue; - return; - } - if (name == "ylabel") { - this.yLabelDiv.innerText = newValue; - return; - } - if (name == "xlabel") { - this.xLabelDiv.innerText = newValue; - return; - } - this.draw(); - } - - handleCanvasMove(event) { - this.mouseX = event.offsetX; - this.mouseY = event.offsetY; - this.draw(); - } - xPosition(i) { - let x = i; - if (this.xLog) x = Math.log(x); - return x / this.xMax * this.canvas.width; - } - yPosition(i) { - let bucketLength = this.histogram[i].length; - if (this.yLog) { - return (1 - Math.log(bucketLength) / Math.log(this.yMax)) * this.drawHeight + 10; - } else { - return (1 - bucketLength / this.yMax) * this.drawHeight + 10; - } - } - - get drawHeight() { return this.canvas.height - 10 } - - draw() { - if (!this.histogram) return; - let width = this.canvas.width; - let height = this.drawHeight; - let ctx = this.canvas.getContext("2d"); - if (this.xLog) yMax = Math.log(yMax); - let xMax = this.histogram.length; - if (this.yLog) xMax = Math.log(xMax); - ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - ctx.beginPath(); - ctx.moveTo(0, height); - for (let i = 0; i < this.histogram.length; i++) { - ctx.lineTo(this.xPosition(i), this.yPosition(i)); - } - ctx.lineTo(width, height); - ctx.closePath; - ctx.stroke(); - ctx.fill(); - if (!this.mouseX) return; - ctx.beginPath(); - let index = Math.round(this.mouseX); - let yBucket = this.histogram[index]; - let y = this.yPosition(index); - if (this.yLog) y = Math.log(y); - ctx.moveTo(0, y); - ctx.lineTo(width-40, y); - ctx.moveTo(this.mouseX, 0); - ctx.lineTo(this.mouseX, height); - ctx.stroke(); - ctx.textAlign = "left"; - ctx.fillText(yBucket.length, width-30, y); - } -}); </script> </head> -<template id="x-histogram-template"> - <style> - #yLabel { - transform: rotate(90deg); - } - canvas, #yLabel, #info { float: left; } - #xLabel { clear: both } - </style> - <h2></h2> - <div id="yLabel"></div> - <canvas height=50></canvas> - <div id="info"> - </div> - <div id="xLabel"></div> -</template> - <body onload="handleBodyLoad(event)" onkeypress="handleKeyDown(event)"> - <h2>Data</h2> + <h1>V8 Map Explorer</h1> <section> - <form name="fileForm"> - <p> - <input id="uploadInput" type="file" name="files"> - </p> - </form> + <div id="fileReader" tabindex=1 > + <span id="label"> + Drag and drop a v8.log file into this area, or click to choose from disk. + </span> + <input id="file" type="file" name="files"> + </div> + <div id="loader"> + <div id="spinner"></div> + </div> </section> - <h2>Stats</h2> - <section id="stats"></section> + <div id="content"> + <h2>Stats</h2> + <section id="stats"></section> - <h2>Timeline</h2> - <div id="timeline"> - <div id=timelineChunks></div> - <canvas id="timelineCanvas" ></canvas> - </div> - <div id="timelineOverview" - onmousemove="handleTimelineIndicatorMove(event)" > - <div id="timelineOverviewIndicator"> - <div class="leftMask"></div> - <div class="rightMask"></div> + <h2>Timeline</h2> + <div id="timeline"> + <div id="timelineLabel">Frequency</div> + <div id="timelineChunks"></div> + <canvas id="timelineCanvas"></canvas> + </div> + <div id="timelineOverview" + onmousemove="handleTimelineIndicatorMove(event)" > + <div id="timelineOverviewIndicator"> + <div class="leftMask"></div> + <div class="rightMask"></div> + </div> </div> - </div> - <h2>Transitions</h2> - <section id="transitionView"></section> - <br/> + <h2>Transitions</h2> + <section id="transitionView"></section> + <br/> - <h2>Selected Map</h2> - <section id="mapDetails"></section> + <h2>Selected Map</h2> + <section id="mapDetails"></section> + </div> - <x-histogram id="mapsDepthHistogram" - title="Maps Depth" xlabel="depth" ylabel="nof"></x-histogram> - <x-histogram id="mapsFanOutHistogram" xlabel="fan-out" - title="Maps Fan-out" ylabel="nof"></x-histogram> + <h2>Instructions</h2> + <section> + <p>Visualize Map trees that have been gathere using <code>--trace-maps</code>.</p> + </section> <div id="tooltip"> <div id="tooltipContents"></div> diff --git a/deps/v8/tools/map-processor.js b/deps/v8/tools/map-processor.js index c0731e8555..7e8572af8c 100644 --- a/deps/v8/tools/map-processor.js +++ b/deps/v8/tools/map-processor.js @@ -151,7 +151,7 @@ class MapProcessor extends LogReader { from = this.getExistingMap(from, time); to = this.getExistingMap(to, time); let edge = new Edge(type, name, reason, time, from, to); - edge.filePosition = this.formatPC(pc, line, column); + to.filePosition = this.formatPC(pc, line, column); edge.finishSetup(); } @@ -209,6 +209,7 @@ class V8Map { V8Map.set(id, this); this.leftId = 0; this.rightId = 0; + this.filePosition = ""; } finalize(id) { @@ -284,6 +285,10 @@ class V8Map { return this.edge === void 0 ? "new" : this.edge.type; } + isBootstrapped() { + return this.edge === void 0; + } + getParents() { let parents = []; let current = this.parent(); @@ -315,7 +320,6 @@ class Edge { this.time = time; this.from = from; this.to = to; - this.filePosition = ""; } finishSetup() { @@ -363,31 +367,35 @@ class Edge { } isTransition() { - return this.type == "Transition" + return this.type === "Transition" } isFastToSlow() { - return this.type == "Normalize" + return this.type === "Normalize" } isSlowToFast() { - return this.type == "SlowToFast" + return this.type === "SlowToFast" } isInitial() { - return this.type == "InitialMap" + return this.type === "InitialMap" + } + + isBootstrapped() { + return this.type === "new" } isReplaceDescriptors() { - return this.type == "ReplaceDescriptors" + return this.type === "ReplaceDescriptors" } isCopyAsPrototype() { - return this.reason == "CopyAsPrototype" + return this.reason === "CopyAsPrototype" } isOptimizeAsPrototype() { - return this.reason == "OptimizeAsPrototype" + return this.reason === "OptimizeAsPrototype" } symbol() { diff --git a/deps/v8/tools/mb/docs/design_spec.md b/deps/v8/tools/mb/docs/design_spec.md index fb202da74e..c119e65e90 100644 --- a/deps/v8/tools/mb/docs/design_spec.md +++ b/deps/v8/tools/mb/docs/design_spec.md @@ -169,7 +169,7 @@ We can then return two lists as output: * `compile_targets`, which is a list of pruned targets to be passed to Ninja to build. It is acceptable to replace a list of pruned targets by a meta target if it turns out that all of the - dependendencies of the target are affected by the patch (i.e., + dependencies of the target are affected by the patch (i.e., all ten binaries that blink_tests depends on), but doing so is not required. * `test_targets`, which is a list of unpruned targets to be mapped diff --git a/deps/v8/tools/mb/docs/user_guide.md b/deps/v8/tools/mb/docs/user_guide.md index a7d72c8839..75c195a949 100644 --- a/deps/v8/tools/mb/docs/user_guide.md +++ b/deps/v8/tools/mb/docs/user_guide.md @@ -20,7 +20,7 @@ For more discussion of MB, see also [the design spec](design_spec.md). ### `mb analyze` -`mb analyze` is reponsible for determining what targets are affected by +`mb analyze` is responsible for determining what targets are affected by a list of files (e.g., the list of files in a patch on a trybot): ``` @@ -229,7 +229,7 @@ The `configs` key points to a dictionary of named build configurations. There should be an key in this dict for every supported configuration of Chromium, meaning every configuration we have a bot for, and every -configuration commonly used by develpers but that we may not have a bot +configuration commonly used by developers but that we may not have a bot for. The value of each key is a list of "mixins" that will define what that diff --git a/deps/v8/tools/node/README.md b/deps/v8/tools/node/README.md new file mode 100644 index 0000000000..dc16c914fd --- /dev/null +++ b/deps/v8/tools/node/README.md @@ -0,0 +1,12 @@ +# Node.js Backports + +We no longer maintain our own backport script. + +For backporting V8 changes to Node.js, there is a useful script in +[node-core-utils][1]. You can use the `git node v8 backport` command, which will +bump the necessary V8 version numbers depending on the specific branch. + +See the [Node.js documentation][2] on V8 backports for a guide. + +[1]: https://github.com/nodejs/node-core-utils +[2]: https://github.com/nodejs/node/blob/master/doc/guides/maintaining-V8.md diff --git a/deps/v8/tools/node/backport_node.py b/deps/v8/tools/node/backport_node.py deleted file mode 100755 index 50b0b077fa..0000000000 --- a/deps/v8/tools/node/backport_node.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python -# Copyright 2017 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 this script to cherry-pick a V8 commit to backport to a Node.js checkout. - -Requirements: - - Node.js checkout to backport to. - - V8 checkout that contains the commit to cherry-pick. - -Usage: - $ backport_node.py <path_to_v8> <path_to_node> <commit-hash> - - This will apply the commit to <path_to_node>/deps/v8 and create a commit in - the Node.js checkout, increment patch level, and copy over the original - commit message. - -Optional flags: - --no-review Run `gclient sync` on the V8 checkout before updating. -""" - -import argparse -import os -import subprocess -import re -import sys - -TARGET_SUBDIR = os.path.join("deps", "v8") -VERSION_FILE = os.path.join("include", "v8-version.h") -VERSION_PATTERN = r'(?<=#define V8_PATCH_LEVEL )\d+' - -def FileToText(file_name): - with open(file_name) as f: - return f.read() - -def TextToFile(text, file_name): - with open(file_name, "w") as f: - f.write(text) - - -def Clean(options): - print ">> Cleaning target directory." - subprocess.check_call(["git", "clean", "-fd"], - cwd = os.path.join(options.node_path, TARGET_SUBDIR)) - -def CherryPick(options): - print ">> Apply patch." - patch = subprocess.Popen(["git", "diff-tree", "-p", options.commit], - stdout=subprocess.PIPE, cwd=options.v8_path) - patch.wait() - try: - subprocess.check_output(["git", "apply", "-3", "--directory=%s" % TARGET_SUBDIR], - stdin=patch.stdout, cwd=options.node_path) - except: - print ">> In another shell, please resolve patch conflicts" - print ">> and `git add` affected files." - print ">> Finally continue by entering RESOLVED." - while raw_input("[RESOLVED]") != "RESOLVED": - print ">> You need to type RESOLVED" - -def UpdateVersion(options): - print ">> Increment patch level." - version_file = os.path.join(options.node_path, TARGET_SUBDIR, VERSION_FILE) - text = FileToText(version_file) - def increment(match): - patch = int(match.group(0)) - return str(patch + 1) - text = re.sub(VERSION_PATTERN, increment, text, flags=re.MULTILINE) - TextToFile(text, version_file) - -def CreateCommit(options): - print ">> Creating commit." - # Find short hash from source. - shorthash = subprocess.check_output( - ["git", "rev-parse", "--short", options.commit], - cwd=options.v8_path).strip() - - # Commit message - title = "deps: backport %s from upstream V8" % shorthash - body = subprocess.check_output( - ["git", "log", options.commit, "-1", "--format=%B"], - cwd=options.v8_path).strip() - body = '\n'.join(" " + line for line in body.splitlines()) - - message = title + "\n\nOriginal commit message:\n\n" + body - - # Create commit at target. - review_message = "--no-edit" if options.no_review else "--edit" - git_commands = [ - ["git", "checkout", "-b", "backport_%s" % shorthash], # new branch - ["git", "add", TARGET_SUBDIR], # add files - ["git", "commit", "-m", message, review_message] # new commit - ] - for command in git_commands: - subprocess.check_call(command, cwd=options.node_path) - -def ParseOptions(args): - parser = argparse.ArgumentParser(description="Backport V8 commit to Node.js") - parser.add_argument("v8_path", help="Path to V8 checkout") - parser.add_argument("node_path", help="Path to Node.js checkout") - parser.add_argument("commit", help="Commit to backport") - parser.add_argument("--no-review", action="store_true", - help="Skip editing commit message") - options = parser.parse_args(args) - options.v8_path = os.path.abspath(options.v8_path) - assert os.path.isdir(options.v8_path) - options.node_path = os.path.abspath(options.node_path) - assert os.path.isdir(options.node_path) - return options - -def Main(args): - options = ParseOptions(args) - Clean(options) - try: - CherryPick(options) - UpdateVersion(options) - CreateCommit(options) - except: - print ">> Failed. Resetting." - subprocess.check_output(["git", "reset", "--hard"], cwd=options.node_path) - raise - -if __name__ == "__main__": - Main(sys.argv[1:]) diff --git a/deps/v8/tools/node/fetch_deps.py b/deps/v8/tools/node/fetch_deps.py index 332c6e2d7d..872263f627 100755 --- a/deps/v8/tools/node/fetch_deps.py +++ b/deps/v8/tools/node/fetch_deps.py @@ -24,8 +24,6 @@ GCLIENT_SOLUTION = [ # These deps are already part of Node.js. "v8/base/trace_event/common" : None, "v8/third_party/googletest/src" : None, - "v8/third_party/jinja2" : None, - "v8/third_party/markupsafe" : None, # These deps are unnecessary for building. "v8/test/benchmarks/data" : None, "v8/testing/gmock" : None, diff --git a/deps/v8/tools/node/test_backport_node.py b/deps/v8/tools/node/test_backport_node.py deleted file mode 100755 index 3c61a402c4..0000000000 --- a/deps/v8/tools/node/test_backport_node.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# Copyright 2017 the V8 project authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import os -import shutil -import subprocess -import sys -import tempfile -import unittest - -import backport_node - -# Base paths. -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -TEST_DATA = os.path.join(BASE_DIR, 'testdata') - -def gitify(path): - files = os.listdir(path) - subprocess.check_call(['git', 'init'], cwd=path) - subprocess.check_call(['git', 'add'] + files, cwd=path) - subprocess.check_call(['git', 'commit', '-m', 'Initial'], cwd=path) - -class TestUpdateNode(unittest.TestCase): - def setUp(self): - self.workdir = tempfile.mkdtemp(prefix='tmp_test_node_') - - def tearDown(self): - shutil.rmtree(self.workdir) - - def testUpdate(self): - v8_cwd = os.path.join(self.workdir, 'v8') - node_cwd = os.path.join(self.workdir, 'node') - - # Set up V8 test fixture. - shutil.copytree(src=os.path.join(TEST_DATA, 'v8'), dst=v8_cwd) - gitify(v8_cwd) - - # Set up node test fixture. - shutil.copytree(src=os.path.join(TEST_DATA, 'node'), dst=node_cwd) - gitify(os.path.join(node_cwd)) - - # Add a patch. - with open(os.path.join(v8_cwd, 'v8_foo'), 'w') as f: - f.write('zonk') - subprocess.check_call(['git', 'add', 'v8_foo'], cwd=v8_cwd) - subprocess.check_call(['git', 'commit', '-m', "Title\n\nBody"], cwd=v8_cwd) - commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=v8_cwd).strip() - - # Run update script. - backport_node.Main([v8_cwd, node_cwd, commit, "--no-review"]) - - # Check message. - message = subprocess.check_output(['git', 'log', '-1', '--format=%B'], cwd=node_cwd) - self.assertIn('Original commit message:\n\n Title\n\n Body', message) - - # Check patch. - gitlog = subprocess.check_output( - ['git', 'diff', 'master', '--cached', '--', 'deps/v8/v8_foo'], - cwd=node_cwd, - ) - self.assertIn('+zonk', gitlog.strip()) - - # Check version. - version_file = os.path.join(node_cwd, "deps", "v8", "include", "v8-version.h") - self.assertIn('#define V8_PATCH_LEVEL 4322', backport_node.FileToText(version_file)) - -if __name__ == "__main__": - unittest.main() diff --git a/deps/v8/tools/node/update_node.py b/deps/v8/tools/node/update_node.py index fb3c2a0aec..c480a69a9b 100755 --- a/deps/v8/tools/node/update_node.py +++ b/deps/v8/tools/node/update_node.py @@ -91,10 +91,11 @@ def UpdateTarget(repository, options, files_to_keep): git_args.append(["add"] + files_to_keep) # add and commit git_args.append(["commit", "-m", "keep files"]) # files we want to keep + git_args.append(["clean", "-fxd"]) # nuke everything else git_args.append(["remote", "add", "source", source]) # point to source repo git_args.append(["fetch", "source", "HEAD"]) # sync to current branch git_args.append(["checkout", "-f", "FETCH_HEAD"]) # switch to that branch - git_args.append(["clean", "-fd"]) # delete removed files + git_args.append(["clean", "-fxd"]) # delete removed files if files_to_keep: git_args.append(["cherry-pick", "master"]) # restore kept files diff --git a/deps/v8/tools/parse-processor b/deps/v8/tools/parse-processor index 85a82d5479..1c7175257d 100755 --- a/deps/v8/tools/parse-processor +++ b/deps/v8/tools/parse-processor @@ -28,7 +28,7 @@ fi if [ ! -x "$d8_exec" ]; then echo "d8 shell not found in $D8_PATH" - echo "To build, execute 'make native' from the V8 directory" + echo "Please provide path to d8 as env var in D8_PATH" exit 1 fi diff --git a/deps/v8/tools/parse-processor.html b/deps/v8/tools/parse-processor.html index 1e67e4a281..0f5818eaf0 100644 --- a/deps/v8/tools/parse-processor.html +++ b/deps/v8/tools/parse-processor.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <!-- Copyright 2016 the V8 project authors. All rights reserved. Use of this source @@ -5,6 +6,8 @@ code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> +<meta charset="utf-8"> +<title>V8 Parse Processor</title> <style> html { font-family: monospace; @@ -100,18 +103,18 @@ code is governed by a BSD-style license that can be found in the LICENSE file. text-align: right; } </style> -<script src="./splaytree.js" type="text/javascript"></script> -<script src="./codemap.js" type="text/javascript"></script> -<script src="./csvparser.js" type="text/javascript"></script> -<script src="./consarray.js" type="text/javascript"></script> -<script src="./profile.js" type="text/javascript"></script> -<script src="./profile_view.js" type="text/javascript"></script> -<script src="./logreader.js" type="text/javascript"></script> -<script src="./arguments.js" type="text/javascript"></script> -<script src="./parse-processor.js" type="text/javascript"></script> -<script src="./SourceMap.js" type="text/javascript"></script> -<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> -<script type="text/javascript"> +<script src="./splaytree.js"></script> +<script src="./codemap.js"></script> +<script src="./csvparser.js"></script> +<script src="./consarray.js"></script> +<script src="./profile.js"></script> +<script src="./profile_view.js"></script> +<script src="./logreader.js"></script> +<script src="./arguments.js"></script> +<script src="./parse-processor.js"></script> +<script src="./SourceMap.js"></script> +<script src="https://www.gstatic.com/charts/loader.js"></script> +<script> "use strict"; google.charts.load('current', {packages: ['corechart']}); diff --git a/deps/v8/tools/plot-timer-events b/deps/v8/tools/plot-timer-events index 3294e85862..02176320a5 100755 --- a/deps/v8/tools/plot-timer-events +++ b/deps/v8/tools/plot-timer-events @@ -32,7 +32,7 @@ fi if test ! -x "$d8_exec"; then echo "d8 shell not found in $D8_PATH" - echo "To build, execute 'make native' from the V8 directory" + echo "Please provide path to d8 as env var in D8_PATH" exit 1 fi diff --git a/deps/v8/tools/profview/profview.js b/deps/v8/tools/profview/profview.js index 5bd64a49bd..210cec7618 100644 --- a/deps/v8/tools/profview/profview.js +++ b/deps/v8/tools/profview/profview.js @@ -55,6 +55,7 @@ function setCallTreeState(state, callTreeState) { let main = { currentState : emptyState(), + renderPending : false, setMode(mode) { if (mode !== main.currentState.mode) { @@ -197,7 +198,11 @@ let main = { }, delayRender() { - Promise.resolve().then(() => { + if (main.renderPending) return; + main.renderPending = true; + + window.requestAnimationFrame(() => { + main.renderPending = false; for (let c of components) { c.render(main.currentState); } @@ -496,7 +501,9 @@ class CallTreeView { nameCell.appendChild(createTypeNode(node.type)); nameCell.appendChild(createFunctionNode(node.name, node.codeId)); if (main.currentState.sourceData && - main.currentState.sourceData.hasSource(node.name)) { + node.codeId >= 0 && + main.currentState.sourceData.hasSource( + this.currentState.file.code[node.codeId].func)) { nameCell.appendChild(createViewSourceNode(node.codeId)); } @@ -1369,7 +1376,7 @@ class SourceData { this.functions = new Map(); for (let codeId = 0; codeId < file.code.length; ++codeId) { let codeBlock = file.code[codeId]; - if (codeBlock.source) { + if (codeBlock.source && codeBlock.func !== undefined) { let data = this.functions.get(codeBlock.func); if (!data) { data = new FunctionSourceData(codeBlock.source.script, @@ -1386,7 +1393,7 @@ class SourceData { for (let i = 0; i < stack.length; i += 2) { let codeId = stack[i]; if (codeId < 0) continue; - let functionid = file.code[codeId].func; + let functionId = file.code[codeId].func; if (this.functions.has(functionId)) { let codeOffset = stack[i + 1]; this.functions.get(functionId).addOffsetSample(codeId, codeOffset); diff --git a/deps/v8/tools/release/auto_roll.py b/deps/v8/tools/release/auto_roll.py index 83c3d343aa..dd60d5dff7 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;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel""") +CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux-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." @@ -155,8 +155,7 @@ class UploadCL(Step): message.append("TBR=%s" % self._options.reviewer) self.GitCommit("\n\n".join(message), author=self._options.author, cwd=cwd) if not self._options.dry_run: - self.GitUpload(author=self._options.author, - force=True, + self.GitUpload(force=True, bypass_hooks=True, cq=self._options.use_commit_queue, cq_dry_run=self._options.use_dry_run, diff --git a/deps/v8/tools/release/common_includes.py b/deps/v8/tools/release/common_includes.py index 0f12d910da..bd28fe3aa7 100644 --- a/deps/v8/tools/release/common_includes.py +++ b/deps/v8/tools/release/common_includes.py @@ -782,7 +782,7 @@ class UploadStep(Step): self.DieNoManualMode("A reviewer must be specified in forced mode.") reviewer = self.ReadLine() - self.GitUpload(reviewer, self._options.author, self._options.force_upload, + self.GitUpload(reviewer, self._options.force_upload, bypass_hooks=self._options.bypass_upload_hooks, cc=self._options.cc, tbr_reviewer=tbr_reviewer) diff --git a/deps/v8/tools/release/create_release.py b/deps/v8/tools/release/create_release.py index ffa5c2a0ca..f030ac804e 100755 --- a/deps/v8/tools/release/create_release.py +++ b/deps/v8/tools/release/create_release.py @@ -207,8 +207,7 @@ class CommitBranch(Step): self["commit_title"] = text.splitlines()[0] TextToFile(text, self.Config("COMMITMSG_FILE")) - self.GitCommit(file_name = self.Config("COMMITMSG_FILE")) - os.remove(self.Config("COMMITMSG_FILE")) + self.GitCommit(file_name=self.Config("COMMITMSG_FILE")) os.remove(self.Config("CHANGELOG_ENTRY_FILE")) @@ -219,16 +218,18 @@ class LandBranch(Step): if self._options.dry_run: print "Dry run - upload CL." else: - self.GitUpload(author=self._options.author, - force=True, + self.GitUpload(force=True, bypass_hooks=True, - no_autocc=True) + no_autocc=True, + message_file=self.Config("COMMITMSG_FILE")) cmd = "cl land --bypass-hooks -f" if self._options.dry_run: print "Dry run. Command:\ngit %s" % cmd else: self.Git(cmd) + os.remove(self.Config("COMMITMSG_FILE")) + class TagRevision(Step): MESSAGE = "Tag the new revision." diff --git a/deps/v8/tools/release/filter_build_files.py b/deps/v8/tools/release/filter_build_files.py index 9cc6607108..032848e3cc 100755 --- a/deps/v8/tools/release/filter_build_files.py +++ b/deps/v8/tools/release/filter_build_files.py @@ -23,6 +23,7 @@ import sys EXECUTABLE_FILES = [ 'd8', + 'cctest', ] SUPPLEMENTARY_FILES = [ diff --git a/deps/v8/tools/release/git_recipes.py b/deps/v8/tools/release/git_recipes.py index a002f4211c..0997e0bb89 100644 --- a/deps/v8/tools/release/git_recipes.py +++ b/deps/v8/tools/release/git_recipes.py @@ -205,12 +205,10 @@ class GitRecipesMixin(object): args.append(Quoted(patch_file)) self.Git(MakeArgs(args), **kwargs) - def GitUpload(self, reviewer="", author="", force=False, cq=False, + def GitUpload(self, reviewer="", force=False, cq=False, cq_dry_run=False, bypass_hooks=False, cc="", tbr_reviewer="", - no_autocc=False, **kwargs): + no_autocc=False, message_file=None, **kwargs): args = ["cl upload --send-mail"] - if author: - args += ["--email", Quoted(author)] if reviewer: args += ["-r", Quoted(reviewer)] if tbr_reviewer: @@ -227,6 +225,8 @@ class GitRecipesMixin(object): args.append("--no-autocc") if cc: args += ["--cc", Quoted(cc)] + if message_file: + args += ["--message-file", Quoted(message_file)] args += ["--gerrit"] # TODO(machenbach): Check output in forced mode. Verify that all required # base files were uploaded, if not retry. diff --git a/deps/v8/tools/release/test_scripts.py b/deps/v8/tools/release/test_scripts.py index f3dc400e58..e454f542ae 100755 --- a/deps/v8/tools/release/test_scripts.py +++ b/deps/v8/tools/release/test_scripts.py @@ -933,8 +933,9 @@ TBR=reviewer@chromium.org""" cb=self.WriteFakeWatchlistsFile), Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "", cb=CheckVersionCommit), - Cmd("git cl upload --send-mail --email \"author@chromium.org\" " - "-f --bypass-hooks --no-autocc --gerrit", ""), + Cmd("git cl upload --send-mail " + "-f --bypass-hooks --no-autocc --message-file " + "\"%s\" --gerrit" % TEST_CONFIG["COMMITMSG_FILE"], ""), Cmd("git cl land --bypass-hooks -f", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=" @@ -1003,7 +1004,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;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:android_optional_gpu_tests_rel +CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux-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""" @@ -1085,7 +1086,7 @@ deps = { "--author \"author@chromium.org <author@chromium.org>\"" % self.ROLL_COMMIT_MSG), "", cwd=chrome_dir), - Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f " + Cmd("git cl upload --send-mail -f " "--cq-dry-run --bypass-hooks --gerrit", "", cwd=chrome_dir), Cmd("git checkout -f master", "", cwd=chrome_dir), diff --git a/deps/v8/tools/run-clang-tidy.py b/deps/v8/tools/run-clang-tidy.py index 11826f19b1..bf08a65fcd 100755 --- a/deps/v8/tools/run-clang-tidy.py +++ b/deps/v8/tools/run-clang-tidy.py @@ -74,6 +74,7 @@ def GenerateCompileCommands(build_folder): line = line.replace('-Wno-ignored-pragma-optimize', '') line = line.replace('-Wno-null-pointer-arithmetic', '') line = line.replace('-Wno-unused-lambda-capture', '') + line = line.replace('-Wno-defaulted-function-deleted', '') cc_file.write(line) @@ -179,7 +180,7 @@ def ClangTidyRunDiff(build_folder, diff_branch, auto_fix): """ The script `clang-tidy-diff` does not provide support to add header- filters. To still analyze headers we use the build path option `-path` to - inject out header-filter option. This works because the script just adds + inject our header-filter option. This works because the script just adds the passed path string to the commandline of clang-tidy. """ modified_build_folder = build_folder diff --git a/deps/v8/tools/run-tests.py.vpython b/deps/v8/tools/run-tests.py.vpython deleted file mode 100644 index 6a12277f6b..0000000000 --- a/deps/v8/tools/run-tests.py.vpython +++ /dev/null @@ -1,32 +0,0 @@ -# This is a vpython "spec" file. -# -# It describes patterns for python wheel dependencies of the python scripts in -# the chromium repo, particularly for dependencies that have compiled components -# (since pure-python dependencies can be easily vendored into third_party). -# -# When vpython is invoked, it finds this file and builds a python VirtualEnv, -# containing all of the dependencies described in this file, fetching them from -# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`, -# this never requires the end-user machine to have a working python extension -# compilation environment. All of these packages are built using: -# https://chromium.googlesource.com/infra/infra/+/master/infra/tools/dockerbuild/ -# -# All python scripts in the repo share this same spec, to avoid dependency -# fragmentation. -# -# If you have depot_tools installed in your $PATH, you can invoke python scripts -# in this repo by running them as you normally would run them, except -# substituting `vpython` instead of `python` on the command line, e.g.: -# vpython path/to/script.py some --arguments -# -# Read more about `vpython` and how to modify this file here: -# https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md - -python_version: "2.7" - -# Used by: -# test/test262 -wheel: < - name: "infra/python/wheels/pyyaml/${vpython_platform}" - version: "version:3.12" -> diff --git a/deps/v8/tools/run_perf.py b/deps/v8/tools/run_perf.py index 67861db3ea..46afbdedce 100755 --- a/deps/v8/tools/run_perf.py +++ b/deps/v8/tools/run_perf.py @@ -108,6 +108,7 @@ import os import re import subprocess import sys +import traceback from testrunner.local import android from testrunner.local import command @@ -125,6 +126,7 @@ GENERIC_RESULTS_RE = re.compile(r"^RESULT ([^:]+): ([^=]+)= ([^ ]+) ([^ ]*)$") RESULT_STDDEV_RE = re.compile(r"^\{([^\}]+)\}$") RESULT_LIST_RE = re.compile(r"^\[([^\]]+)\]$") TOOLS_BASE = os.path.abspath(os.path.dirname(__file__)) +INFRA_FAILURE_RETCODE = 87 def GeometricMean(values): @@ -136,6 +138,11 @@ def GeometricMean(values): return str(math.exp(sum(map(math.log, values)) / len(values))) +class TestFailedError(Exception): + """Error raised when a test has failed due to a non-infra issue.""" + pass + + class Results(object): """Place holder for result traces.""" def __init__(self, traces=None, errors=None): @@ -690,7 +697,7 @@ class DesktopPlatform(Platform): output = cmd.execute() except OSError: # pragma: no cover logging.exception(title % "OSError") - return "" + raise logging.info(title % "Stdout" + "\n%s", output.stdout) if output.stderr: # pragma: no cover @@ -698,6 +705,10 @@ class DesktopPlatform(Platform): logging.info(title % "Stderr" + "\n%s", output.stderr) if output.timed_out: logging.warning(">>> Test timed out after %ss.", runnable.timeout) + raise TestFailedError() + if output.exit_code != 0: + logging.warning(">>> Test crashed.") + raise TestFailedError() if '--prof' in self.extra_flags: os_prefix = {"linux": "linux", "macos": "mac"}.get(utils.GuessOS()) if os_prefix: @@ -779,12 +790,13 @@ class AndroidPlatform(Platform): # pragma: no cover logging.info(title % "Stdout" + "\n%s", stdout) except android.CommandFailedException as e: logging.info(title % "Stdout" + "\n%s", e.output) - raise + logging.warning('>>> Test crashed.') + raise TestFailedError() except android.TimeoutException as e: - if e.output: + if e.output is not None: logging.info(title % "Stdout" + "\n%s", e.output) logging.warning(">>> Test timed out after %ss.", runnable.timeout) - stdout = "" + raise TestFailedError() if runnable.process_size: return stdout + "MaxMemory: Unsupported" return stdout @@ -962,28 +974,24 @@ def Main(args): (options, args) = parser.parse_args(args) - if options.buildbot: - logging.basicConfig( - level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") - else: - logging.basicConfig(level=logging.INFO, format="%(message)s") + logging.basicConfig(level=logging.INFO, format="%(levelname)-8s %(message)s") if len(args) == 0: # pragma: no cover parser.print_help() - return 1 + return INFRA_FAILURE_RETCODE if options.arch in ["auto", "native"]: # pragma: no cover options.arch = ARCH_GUESS if not options.arch in SUPPORTED_ARCHS: # pragma: no cover logging.error("Unknown architecture %s", options.arch) - return 1 + return INFRA_FAILURE_RETCODE if (options.json_test_results_secondary and not options.outdir_secondary): # pragma: no cover logging.error("For writing secondary json test results, a secondary outdir " "patch must be specified.") - return 1 + return INFRA_FAILURE_RETCODE workspace = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) @@ -998,10 +1006,10 @@ def Main(args): else: if not os.path.isfile(options.binary_override_path): logging.error("binary-override-path must be a file name") - return 1 + return INFRA_FAILURE_RETCODE if options.outdir_secondary: logging.error("specify either binary-override-path or outdir-secondary") - return 1 + return INFRA_FAILURE_RETCODE options.shell_dir = os.path.abspath( os.path.dirname(options.binary_override_path)) default_binary_name = os.path.basename(options.binary_override_path) @@ -1029,6 +1037,8 @@ def Main(args): results = Results() results_secondary = Results() + # We use list here to allow modification in nested function below. + have_failed_tests = [False] with CustomMachineConfiguration(governor = options.cpu_governor, disable_aslr = options.noaslr) as conf: for path in args: @@ -1067,7 +1077,10 @@ def Main(args): for i in xrange(0, max(1, total_runs)): # TODO(machenbach): Allow timeout per arch like with run_count per # arch. - yield platform.Run(runnable, i) + try: + yield platform.Run(runnable, i) + except TestFailedError: + have_failed_tests[0] = True # Let runnable iterate over all runs and handle output. result, result_secondary = runnable.Run( @@ -1086,7 +1099,20 @@ def Main(args): else: # pragma: no cover print results_secondary - return min(1, len(results.errors)) + if results.errors or have_failed_tests[0]: + return 1 + + return 0 + + +def MainWrapper(): + try: + return Main(sys.argv[1:]) + except: + # Log uncaptured exceptions and report infra failure to the caller. + traceback.print_exc() + return INFRA_FAILURE_RETCODE + if __name__ == "__main__": # pragma: no cover - sys.exit(Main(sys.argv[1:])) + sys.exit(MainWrapper()) diff --git a/deps/v8/tools/sanitizers/tsan_suppressions.txt b/deps/v8/tools/sanitizers/tsan_suppressions.txt index 839636c8ce..270340e484 100644 --- a/deps/v8/tools/sanitizers/tsan_suppressions.txt +++ b/deps/v8/tools/sanitizers/tsan_suppressions.txt @@ -4,7 +4,3 @@ # Incorrectly detected lock cycles in test-lockers # https://code.google.com/p/thread-sanitizer/issues/detail?id=81 deadlock:LockAndUnlockDifferentIsolatesThread::Run - -# Data race in a third party lib -# https://bugs.chromium.org/p/v8/issues/detail?id=8110 -race:IndianCalendar::fgSystemDefaultCenturyStartYear diff --git a/deps/v8/tools/snapshot/asm_to_inline_asm.py b/deps/v8/tools/snapshot/asm_to_inline_asm.py new file mode 100644 index 0000000000..ad8fdcb0fe --- /dev/null +++ b/deps/v8/tools/snapshot/asm_to_inline_asm.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +# 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. + +''' +Converts a given file in clang assembly syntax to a corresponding +representation in inline assembly. Specifically, this is used to convert +embedded.S to embedded.cc for Windows clang builds. +''' + +import argparse +import sys + +def asm_to_inl_asm(in_filename, out_filename): + with open(in_filename, 'r') as infile, open(out_filename, 'wb') as outfile: + outfile.write('__asm__(\n') + for line in infile: + # Escape " in .S file before outputing it to inline asm file. + line = line.replace('"', '\\"') + outfile.write(' "%s\\n"\n' % line.rstrip()) + outfile.write(');\n') + return 0 + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('input', help='Name of the input assembly file') + parser.add_argument('output', help='Name of the target CC file') + args = parser.parse_args() + sys.exit(asm_to_inl_asm(args.input, args.output)) diff --git a/deps/v8/tools/testrunner/base_runner.py b/deps/v8/tools/testrunner/base_runner.py index fcb2202f8a..8c5f7ad205 100644 --- a/deps/v8/tools/testrunner/base_runner.py +++ b/deps/v8/tools/testrunner/base_runner.py @@ -51,6 +51,7 @@ TEST_MAP = { "inspector", "webkit", "mkgrokdump", + "wasm-js", "fuzzer", "message", "preparser", @@ -65,6 +66,7 @@ TEST_MAP = { "wasm-spec-tests", "inspector", "mkgrokdump", + "wasm-js", "fuzzer", "message", "preparser", @@ -183,6 +185,10 @@ class BuildConfig(object): self.predictable = build_config['v8_enable_verify_predictable'] self.tsan = build_config['is_tsan'] self.ubsan_vptr = build_config['is_ubsan_vptr'] + self.embedded_builtins = build_config['v8_enable_embedded_builtins'] + self.verify_csa = build_config['v8_enable_verify_csa'] + self.lite_mode = build_config['v8_enable_lite_mode'] + self.pointer_compression = build_config['v8_enable_pointer_compression'] # Export only for MIPS target if self.arch in ['mips', 'mipsel', 'mips64', 'mips64el']: self.mips_arch_variant = build_config['mips_arch_variant'] @@ -211,6 +217,14 @@ class BuildConfig(object): detected_options.append('tsan') if self.ubsan_vptr: detected_options.append('ubsan_vptr') + if self.embedded_builtins: + detected_options.append('embedded_builtins') + if self.verify_csa: + detected_options.append('verify_csa') + if self.lite_mode: + detected_options.append('lite_mode') + if self.pointer_compression: + detected_options.append('pointer_compression') return '\n'.join(detected_options) @@ -246,14 +260,10 @@ class BaseTestRunner(object): raise args = self._parse_test_args(args) - suites = self._get_suites(args, options) - self._prepare_suites(suites, options) - + tests = self._load_testsuite_generators(args, options) self._setup_env() - print(">>> Running tests for %s.%s" % (self.build_config.arch, self.mode_name)) - tests = [t for s in suites for t in s.tests] return self._do_execute(tests, args, options) except TestRunnerError: return utils.EXIT_CODE_INTERNAL_ERROR @@ -334,6 +344,8 @@ class BaseTestRunner(object): help="Run without test harness of a given suite") parser.add_option("--random-seed", default=0, type=int, help="Default seed for initializing random generator") + parser.add_option("--run-skipped", help="Also run skipped tests.", + default=False, action="store_true") parser.add_option("-t", "--timeout", default=60, type=int, help="Timeout for single test in seconds") parser.add_option("-v", "--verbose", default=False, action="store_true", @@ -580,10 +592,6 @@ class BaseTestRunner(object): return reduce(list.__add__, map(expand_test_group, args), []) - def _get_suites(self, args, options): - names = self._args_to_suite_names(args, options.test_root) - return self._load_suites(names, options) - def _args_to_suite_names(self, args, test_root): # Use default tests if no test configuration was provided at the cmd line. all_names = set(utils.GetSuitePaths(test_root)) @@ -593,26 +601,34 @@ class BaseTestRunner(object): def _get_default_suite_names(self): return [] - def _load_suites(self, names, options): + def _load_testsuite_generators(self, args, options): + names = self._args_to_suite_names(args, options.test_root) test_config = self._create_test_config(options) - def load_suite(name): + variables = self._get_statusfile_variables(options) + slow_chain, fast_chain = [], [] + for name in names: if options.verbose: print '>>> Loading test suite: %s' % name - return testsuite.TestSuite.LoadTestSuite( - os.path.join(options.test_root, name), - test_config) - return map(load_suite, names) - - def _prepare_suites(self, suites, options): - self._load_status_files(suites, options) - for s in suites: - s.ReadTestCases() - - def _load_status_files(self, suites, options): - # simd_mips is true if SIMD is fully supported on MIPS - variables = self._get_statusfile_variables(options) - for s in suites: - s.ReadStatusFile(variables) + suite = testsuite.TestSuite.Load( + os.path.join(options.test_root, name), test_config) + + if self._is_testsuite_supported(suite, options): + slow_tests, fast_tests = suite.load_tests_from_disk(variables) + slow_chain.append(slow_tests) + fast_chain.append(fast_tests) + + for tests in slow_chain: + for test in tests: + yield test + + for tests in fast_chain: + for test in tests: + yield test + + def _is_testsuite_supported(self, suite, options): + """A predicate that can be overridden to filter out unsupported TestSuite + instances (see NumFuzzer for usage).""" + return True def _get_statusfile_variables(self, options): simd_mips = ( @@ -624,7 +640,6 @@ class BaseTestRunner(object): self.build_config.arch in ['mipsel', 'mips', 'mips64', 'mips64el'] and self.build_config.mips_arch_variant) - # TODO(all): Combine "simulator" and "simulator_run". # TODO(machenbach): In GN we can derive simulator run from # target_arch != v8_target_arch in the dumped build config. return { @@ -639,19 +654,25 @@ class BaseTestRunner(object): "gcov_coverage": self.build_config.gcov_coverage, "isolates": options.isolates, "mips_arch_variant": mips_arch_variant, - "mode": self.mode_options.status_mode, + "mode": self.mode_options.status_mode + if not self.build_config.dcheck_always_on + else "debug", "msan": self.build_config.msan, "no_harness": options.no_harness, "no_i18n": self.build_config.no_i18n, "no_snap": self.build_config.no_snap, "novfp3": False, + "optimize_for_size": "--optimize-for-size" in options.extra_flags, "predictable": self.build_config.predictable, "simd_mips": simd_mips, - "simulator": utils.UseSimulator(self.build_config.arch), "simulator_run": False, "system": self.target_os, "tsan": self.build_config.tsan, "ubsan_vptr": self.build_config.ubsan_vptr, + "embedded_builtins": self.build_config.embedded_builtins, + "verify_csa": self.build_config.verify_csa, + "lite_mode": self.build_config.lite_mode, + "pointer_compression": self.build_config.pointer_compression, } def _create_test_config(self, options): @@ -664,6 +685,7 @@ class BaseTestRunner(object): no_harness=options.no_harness, noi18n=self.build_config.no_i18n, random_seed=options.random_seed, + run_skipped=options.run_skipped, shell_dir=self.outdir, timeout=timeout, verbose=options.verbose, diff --git a/deps/v8/tools/testrunner/local/android.py b/deps/v8/tools/testrunner/local/android.py index 707614f095..5724f9ee2a 100644 --- a/deps/v8/tools/testrunner/local/android.py +++ b/deps/v8/tools/testrunner/local/android.py @@ -42,21 +42,16 @@ class _Driver(object): from devil.android import device_utils # pylint: disable=import-error from devil.android.perf import cache_control # pylint: disable=import-error from devil.android.perf import perf_control # pylint: disable=import-error - from devil.android.sdk import adb_wrapper # pylint: disable=import-error global cache_control global device_errors global perf_control devil_chromium.Initialize() - if not device: - # Detect attached device if not specified. - devices = adb_wrapper.AdbWrapper.Devices() - assert devices, 'No devices detected' - assert len(devices) == 1, 'Multiple devices detected.' - device = str(devices[0]) - self.adb_wrapper = adb_wrapper.AdbWrapper(device) - self.device = device_utils.DeviceUtils(self.adb_wrapper) + # Find specified device or a single attached device if none was specified. + # In case none or multiple devices are attached, this raises an exception. + self.device = device_utils.DeviceUtils.HealthyDevices( + retries=5, enable_usb_resets=True, device_arg=device)[0] # This remembers what we have already pushed to the device. self.pushed = set() @@ -77,6 +72,8 @@ class _Driver(object): skip_if_missing: Keeps silent about missing files when set. Otherwise logs error. """ + # TODO(sergiyb): Implement this method using self.device.PushChangedFiles to + # avoid accessing low-level self.device.adb. file_on_host = os.path.join(host_dir, file_name) # Only push files not yet pushed in one execution. @@ -95,13 +92,13 @@ class _Driver(object): # Work-around for 'text file busy' errors. Push the files to a temporary # location and then copy them with a shell command. - output = self.adb_wrapper.Push(file_on_host, file_on_device_tmp) + output = self.device.adb.Push(file_on_host, file_on_device_tmp) # Success looks like this: '3035 KB/s (12512056 bytes in 4.025s)'. # Errors look like this: 'failed to copy ... '. if output and not re.search('^[0-9]', output.splitlines()[-1]): logging.critical('PUSH FAILED: ' + output) - self.adb_wrapper.Shell('mkdir -p %s' % folder_on_device) - self.adb_wrapper.Shell('cp %s %s' % (file_on_device_tmp, file_on_device)) + self.device.adb.Shell('mkdir -p %s' % folder_on_device) + self.device.adb.Shell('cp %s %s' % (file_on_device_tmp, file_on_device)) self.pushed.add(file_on_host) def push_executable(self, shell_dir, target_dir, binary): diff --git a/deps/v8/tools/testrunner/local/fake_testsuite/fake_testsuite.status b/deps/v8/tools/testrunner/local/fake_testsuite/fake_testsuite.status new file mode 100644 index 0000000000..b5ebc84474 --- /dev/null +++ b/deps/v8/tools/testrunner/local/fake_testsuite/fake_testsuite.status @@ -0,0 +1,5 @@ +# Copyright 2019 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. + +[] diff --git a/deps/v8/tools/testrunner/local/fake_testsuite/testcfg.py b/deps/v8/tools/testrunner/local/fake_testsuite/testcfg.py new file mode 100644 index 0000000000..61d75fb991 --- /dev/null +++ b/deps/v8/tools/testrunner/local/fake_testsuite/testcfg.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# Copyright 2019 the V8 project authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +from testrunner.local import testsuite, statusfile + + +class TestSuite(testsuite.TestSuite): + def _test_class(self): + return testsuite.TestCase + + def ListTests(self): + fast = self._create_test("fast") + slow = self._create_test("slow") + slow._statusfile_outcomes.append(statusfile.SLOW) + yield fast + yield slow + +def GetSuite(*args, **kwargs): + return TestSuite(*args, **kwargs) diff --git a/deps/v8/tools/testrunner/local/statusfile.py b/deps/v8/tools/testrunner/local/statusfile.py index 4742e84caf..5d05e23cc3 100644 --- a/deps/v8/tools/testrunner/local/statusfile.py +++ b/deps/v8/tools/testrunner/local/statusfile.py @@ -45,12 +45,13 @@ FAIL_SLOPPY = "FAIL_SLOPPY" SKIP = "SKIP" SLOW = "SLOW" NO_VARIANTS = "NO_VARIANTS" +FAIL_PHASE_ONLY = "FAIL_PHASE_ONLY" ALWAYS = "ALWAYS" KEYWORDS = {} for key in [SKIP, FAIL, PASS, CRASH, SLOW, FAIL_OK, NO_VARIANTS, FAIL_SLOPPY, - ALWAYS]: + ALWAYS, FAIL_PHASE_ONLY]: KEYWORDS[key] = key # Support arches, modes to be written as keywords instead of strings. diff --git a/deps/v8/tools/testrunner/local/testsuite.py b/deps/v8/tools/testrunner/local/testsuite.py index 4bdfd008fe..9d00d7bc12 100644 --- a/deps/v8/tools/testrunner/local/testsuite.py +++ b/deps/v8/tools/testrunner/local/testsuite.py @@ -29,6 +29,7 @@ import fnmatch import imp import os +from contextlib import contextmanager from . import command from . import statusfile @@ -77,19 +78,22 @@ class TestCombiner(object): def _combined_test_class(self): raise NotImplementedError() +@contextmanager +def _load_testsuite_module(name, root): + f = None + try: + (f, pathname, description) = imp.find_module("testcfg", [root]) + yield imp.load_module(name + "_testcfg", f, pathname, description) + finally: + if f: + f.close() class TestSuite(object): @staticmethod - def LoadTestSuite(root, test_config): + def Load(root, test_config): name = root.split(os.path.sep)[-1] - f = None - try: - (f, pathname, description) = imp.find_module("testcfg", [root]) - module = imp.load_module(name + "_testcfg", f, pathname, description) + with _load_testsuite_module(name, root) as module: return module.GetSuite(name, root, test_config) - finally: - if f: - f.close() def __init__(self, name, root, test_config): self.name = name # string @@ -97,22 +101,22 @@ class TestSuite(object): self.test_config = test_config self.tests = None # list of TestCase objects self.statusfile = None - self.suppress_internals = False def status_file(self): return "%s/%s.status" % (self.root, self.name) - def do_suppress_internals(self): - """Specifies if this test suite should suppress asserts based on internals. - - Internals are e.g. testing against the outcome of native runtime functions. - This is switched off on some fuzzers that violate these contracts. - """ - self.suppress_internals = True - def ListTests(self): raise NotImplementedError + def load_tests_from_disk(self, statusfile_variables): + self.statusfile = statusfile.StatusFile( + self.status_file(), statusfile_variables) + + slow_tests = (test for test in self.ListTests() if test.is_slow) + fast_tests = (test for test in self.ListTests() if not test.is_slow) + + return slow_tests, fast_tests + def get_variants_gen(self, variants): return self._variants_gen_class()(variants) @@ -134,90 +138,11 @@ class TestSuite(object): """ return None - def ReadStatusFile(self, variables): - self.statusfile = statusfile.StatusFile(self.status_file(), variables) - - def ReadTestCases(self): - self.tests = self.ListTests() - - - def FilterTestCasesByStatus(self, - slow_tests_mode=None, - pass_fail_tests_mode=None): - """Filters tests by outcomes from status file. - - Status file has to be loaded before using this function. - - Args: - slow_tests_mode: What to do with slow tests. - pass_fail_tests_mode: What to do with pass or fail tests. - - Mode options: - None (default) - don't skip - "skip" - skip if slow/pass_fail - "run" - skip if not slow/pass_fail - """ - def _skip_slow(is_slow, mode): - return ( - (mode == 'run' and not is_slow) or - (mode == 'skip' and is_slow)) - - def _skip_pass_fail(pass_fail, mode): - return ( - (mode == 'run' and not pass_fail) or - (mode == 'skip' and pass_fail)) - - def _compliant(test): - if test.do_skip: - return False - if _skip_slow(test.is_slow, slow_tests_mode): - return False - if _skip_pass_fail(test.is_pass_or_fail, pass_fail_tests_mode): - return False - return True - - self.tests = filter(_compliant, self.tests) - - def FilterTestCasesByArgs(self, args): - """Filter test cases based on command-line arguments. - - args can be a glob: asterisks in any position of the argument - represent zero or more characters. Without asterisks, only exact matches - will be used with the exeption of the test-suite name as argument. - """ - filtered = [] - globs = [] - for a in args: - argpath = a.split('/') - if argpath[0] != self.name: - continue - if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'): - return # Don't filter, run all tests in this suite. - path = '/'.join(argpath[1:]) - globs.append(path) - - for t in self.tests: - for g in globs: - if fnmatch.fnmatch(t.path, g): - filtered.append(t) - break - self.tests = filtered - def _create_test(self, path, **kwargs): - if self.suppress_internals: - test_class = self._suppressed_test_class() - else: - test_class = self._test_class() + test_class = self._test_class() return test_class(self, path, self._path_to_name(path), self.test_config, **kwargs) - def _suppressed_test_class(self): - """Optional testcase that suppresses assertions. Used by fuzzers that are - only interested in dchecks or tsan and that might violate the assertions - through fuzzing. - """ - return self._test_class() - def _test_class(self): raise NotImplementedError diff --git a/deps/v8/tools/testrunner/local/testsuite_unittest.py b/deps/v8/tools/testrunner/local/testsuite_unittest.py index efefe4c533..efc9fdacf0 100755 --- a/deps/v8/tools/testrunner/local/testsuite_unittest.py +++ b/deps/v8/tools/testrunner/local/testsuite_unittest.py @@ -5,6 +5,7 @@ import os import sys +import tempfile import unittest # Needed because the test runner contains relative imports. @@ -14,107 +15,52 @@ sys.path.append(TOOLS_PATH) from testrunner.local.testsuite import TestSuite from testrunner.objects.testcase import TestCase +from testrunner.test_config import TestConfig class TestSuiteTest(unittest.TestCase): - def test_filter_testcases_by_status_first_pass(self): - suite = TestSuite('foo', 'bar') - suite.rules = { - '': { - 'foo/bar': set(['PASS', 'SKIP']), - 'baz/bar': set(['PASS', 'FAIL']), - }, - } - suite.prefix_rules = { - '': { - 'baz/': set(['PASS', 'SLOW']), - }, - } - suite.tests = [ - TestCase(suite, 'foo/bar', 'foo/bar'), - TestCase(suite, 'baz/bar', 'baz/bar'), - ] - suite.FilterTestCasesByStatus() - self.assertEquals( - [TestCase(suite, 'baz/bar', 'baz/bar')], - suite.tests, + def setUp(self): + test_dir = os.path.dirname(__file__) + self.test_root = os.path.join(test_dir, "fake_testsuite") + self.test_config = TestConfig( + command_prefix=[], + extra_flags=[], + isolates=False, + mode_flags=[], + no_harness=False, + noi18n=False, + random_seed=0, + run_skipped=False, + shell_dir='fake_testsuite/fake_d8', + timeout=10, + verbose=False, ) - outcomes = suite.GetStatusFileOutcomes(suite.tests[0].name, - suite.tests[0].variant) - self.assertEquals(set(['PASS', 'FAIL', 'SLOW']), outcomes) - def test_filter_testcases_by_status_second_pass(self): - suite = TestSuite('foo', 'bar') + self.suite = TestSuite.Load(self.test_root, self.test_config) - suite.rules = { - '': { - 'foo/bar': set(['PREV']), - }, - 'default': { - 'foo/bar': set(['PASS', 'SKIP']), - 'baz/bar': set(['PASS', 'FAIL']), - }, - 'stress': { - 'baz/bar': set(['SKIP']), - }, - } - suite.prefix_rules = { - '': { - 'baz/': set(['PREV']), - }, - 'default': { - 'baz/': set(['PASS', 'SLOW']), - }, - 'stress': { - 'foo/': set(['PASS', 'SLOW']), - }, - } + def testLoadingTestSuites(self): + self.assertEquals(self.suite.name, "fake_testsuite") + self.assertEquals(self.suite.test_config, self.test_config) - test1 = TestCase(suite, 'foo/bar', 'foo/bar') - test2 = TestCase(suite, 'baz/bar', 'baz/bar') - suite.tests = [ - test1.create_variant(variant='default', flags=[]), - test1.create_variant(variant='stress', flags=['-v']), - test2.create_variant(variant='default', flags=[]), - test2.create_variant(variant='stress', flags=['-v']), - ] + # Verify that the components of the TestSuite aren't loaded yet. + self.assertIsNone(self.suite.tests) + self.assertIsNone(self.suite.statusfile) - suite.FilterTestCasesByStatus() - self.assertEquals( - [ - TestCase(suite, 'foo/bar', 'foo/bar').create_variant(None, ['-v']), - TestCase(suite, 'baz/bar', 'baz/bar'), - ], - suite.tests, - ) - - self.assertEquals( - set(['PREV', 'PASS', 'SLOW']), - suite.GetStatusFileOutcomes(suite.tests[0].name, - suite.tests[0].variant), - ) - self.assertEquals( - set(['PREV', 'PASS', 'FAIL', 'SLOW']), - suite.GetStatusFileOutcomes(suite.tests[1].name, - suite.tests[1].variant), - ) + def testLoadingTestsFromDisk(self): + slow_tests, fast_tests = self.suite.load_tests_from_disk( + statusfile_variables={}) + def is_generator(iterator): + return iterator == iter(iterator) - def test_fail_ok_outcome(self): - suite = TestSuite('foo', 'bar') - suite.rules = { - '': { - 'foo/bar': set(['FAIL_OK']), - 'baz/bar': set(['FAIL']), - }, - } - suite.prefix_rules = {} - suite.tests = [ - TestCase(suite, 'foo/bar', 'foo/bar'), - TestCase(suite, 'baz/bar', 'baz/bar'), - ] + self.assertTrue(is_generator(slow_tests)) + self.assertTrue(is_generator(fast_tests)) - for t in suite.tests: - self.assertEquals(['FAIL'], t.expected_outcomes) + slow_tests, fast_tests = list(slow_tests), list(fast_tests) + # Verify that the components of the TestSuite are loaded. + self.assertTrue(len(slow_tests) == len(fast_tests) == 1) + self.assertTrue(all(test.is_slow for test in slow_tests)) + self.assertFalse(any(test.is_slow for test in fast_tests)) + self.assertIsNotNone(self.suite.statusfile) if __name__ == '__main__': diff --git a/deps/v8/tools/testrunner/num_fuzzer.py b/deps/v8/tools/testrunner/num_fuzzer.py index 3b76541604..d5e399626c 100755 --- a/deps/v8/tools/testrunner/num_fuzzer.py +++ b/deps/v8/tools/testrunner/num_fuzzer.py @@ -20,7 +20,7 @@ from testrunner.testproc.execution import ExecutionProc from testrunner.testproc.expectation import ForgiveTimeoutProc from testrunner.testproc.filter import StatusFileFilterProc, NameFilterProc from testrunner.testproc.loader import LoadProc -from testrunner.testproc.progress import ResultsTracker, TestsCounter +from testrunner.testproc.progress import ResultsTracker from testrunner.utils import random_utils @@ -55,6 +55,11 @@ class NumFuzzer(base_runner.BaseTestRunner): parser.add_option("--stress-gc", default=0, type="int", help="probability [0-10] of adding --random-gc-interval " "flag to the test") + + # Stress tasks + parser.add_option("--stress-delay-tasks", default=0, type="int", + help="probability [0-10] of adding --stress-delay-tasks " + "flag to the test") parser.add_option("--stress-thread-pool-size", default=0, type="int", help="probability [0-10] of adding --thread-pool-size " "flag to the test") @@ -67,11 +72,6 @@ class NumFuzzer(base_runner.BaseTestRunner): help="extends --stress-deopt to have minimum interval " "between deopt points") - # Stress interrupt budget - parser.add_option("--stress-interrupt-budget", default=0, type="int", - help="probability [0-10] of adding --interrupt-budget " - "flag to the test") - # Combine multiple tests parser.add_option("--combine-tests", default=False, action="store_true", help="Combine multiple tests as one and run with " @@ -110,14 +110,6 @@ class NumFuzzer(base_runner.BaseTestRunner): def _get_default_suite_names(self): return DEFAULT_SUITES - def _timeout_scalefactor(self, options): - factor = super(NumFuzzer, self)._timeout_scalefactor(options) - if options.stress_interrupt_budget: - # TODO(machenbach): This should be moved to a more generic config. - # Fuzzers have too much timeout in debug mode. - factor = max(int(factor * 0.25), 1) - return factor - def _get_statusfile_variables(self, options): variables = ( super(NumFuzzer, self)._get_statusfile_variables(options)) @@ -129,6 +121,7 @@ class NumFuzzer(base_runner.BaseTestRunner): options.stress_scavenge, options.stress_compaction, options.stress_gc, + options.stress_delay_tasks, options.stress_thread_pool_size])), }) return variables @@ -180,15 +173,8 @@ class NumFuzzer(base_runner.BaseTestRunner): # Indicate if a SIGINT or SIGTERM happened. return sigproc.exit_code - def _load_suites(self, names, options): - suites = super(NumFuzzer, self)._load_suites(names, options) - if options.combine_tests: - suites = [s for s in suites if s.test_combiner_available()] - if options.stress_interrupt_budget: - # Changing interrupt budget forces us to suppress certain test assertions. - for suite in suites: - suite.do_suppress_internals() - return suites + def _is_testsuite_supported(self, suite, options): + return not options.combine_tests or suite.test_combiner_available() def _create_combiner(self, rng, options): if not options.combine_tests: @@ -211,7 +197,7 @@ class NumFuzzer(base_runner.BaseTestRunner): def _disable_analysis(self, options): """Disable analysis phase when options are used that don't support it.""" - return options.combine_tests or options.stress_interrupt_budget + return options.combine_tests def _create_fuzzer_configs(self, options): fuzzers = [] @@ -224,7 +210,7 @@ class NumFuzzer(base_runner.BaseTestRunner): add('scavenge', options.stress_scavenge) add('gc_interval', options.stress_gc) add('threads', options.stress_thread_pool_size) - add('interrupt_budget', options.stress_interrupt_budget) + add('delay', options.stress_delay_tasks) add('deopt', options.stress_deopt, options.stress_deopt_min) return fuzzers diff --git a/deps/v8/tools/testrunner/objects/testcase.py b/deps/v8/tools/testrunner/objects/testcase.py index de8bc561eb..c8f7bdbfb0 100644 --- a/deps/v8/tools/testrunner/objects/testcase.py +++ b/deps/v8/tools/testrunner/objects/testcase.py @@ -43,15 +43,15 @@ RESOURCES_PATTERN = re.compile(r"//\s+Resources:(.*)") # Pattern to auto-detect files to push on Android for statements like: # load("path/to/file.js") LOAD_PATTERN = re.compile( - r"(?:load|readbuffer|read)\((?:'|\")([^'\"]*)(?:'|\")\)") + r"(?:load|readbuffer|read)\((?:'|\")([^'\"]+)(?:'|\")\)") # Pattern to auto-detect files to push on Android for statements like: # import "path/to/file.js" MODULE_RESOURCES_PATTERN_1 = re.compile( - r"(?:import|export)(?:\(| )(?:'|\")([^'\"]*)(?:'|\")") + r"(?:import|export)(?:\(| )(?:'|\")([^'\"]+)(?:'|\")") # Pattern to auto-detect files to push on Android for statements like: # import foobar from "path/to/file.js" MODULE_RESOURCES_PATTERN_2 = re.compile( - r"(?:import|export).*from (?:'|\")([^'\"]*)(?:'|\")") + r"(?:import|export).*from (?:'|\")([^'\"]+)(?:'|\")") class TestCase(object): @@ -135,7 +135,8 @@ class TestCase(object): @property def do_skip(self): - return statusfile.SKIP in self._statusfile_outcomes + return (statusfile.SKIP in self._statusfile_outcomes and + not self.suite.test_config.run_skipped) @property def is_slow(self): diff --git a/deps/v8/tools/testrunner/outproc/test262.py b/deps/v8/tools/testrunner/outproc/test262.py index b5eb5547c3..bf3bc05809 100644 --- a/deps/v8/tools/testrunner/outproc/test262.py +++ b/deps/v8/tools/testrunner/outproc/test262.py @@ -7,18 +7,29 @@ import re from . import base +def _is_failure_output(output): + return ( + output.exit_code != 0 or + 'FAILED!' in output.stdout + ) + + class ExceptionOutProc(base.OutProc): """Output processor for tests with expected exception.""" - def __init__(self, expected_outcomes, expected_exception=None): + def __init__( + self, expected_outcomes, expected_exception=None, negative=False): super(ExceptionOutProc, self).__init__(expected_outcomes) self._expected_exception = expected_exception + self._negative = negative + + @property + def negative(self): + return self._negative def _is_failure_output(self, output): - if output.exit_code != 0: - return True if self._expected_exception != self._parse_exception(output.stdout): return True - return 'FAILED!' in output.stdout + return _is_failure_output(output) def _parse_exception(self, string): # somefile:somelinenumber: someerror[: sometext] @@ -31,16 +42,13 @@ class ExceptionOutProc(base.OutProc): return None -def _is_failure_output(self, output): - return ( - output.exit_code != 0 or - 'FAILED!' in output.stdout - ) - - class NoExceptionOutProc(base.OutProc): """Output processor optimized for tests without expected exception.""" -NoExceptionOutProc._is_failure_output = _is_failure_output + def __init__(self, expected_outcomes): + super(NoExceptionOutProc, self).__init__(expected_outcomes) + + def _is_failure_output(self, output): + return _is_failure_output(output) class PassNoExceptionOutProc(base.PassOutProc): @@ -48,7 +56,8 @@ class PassNoExceptionOutProc(base.PassOutProc): Output processor optimized for tests expected to PASS without expected exception. """ -PassNoExceptionOutProc._is_failure_output = _is_failure_output + def _is_failure_output(self, output): + return _is_failure_output(output) PASS_NO_EXCEPTION = PassNoExceptionOutProc() diff --git a/deps/v8/tools/testrunner/standard_runner.py b/deps/v8/tools/testrunner/standard_runner.py index bf7d3f133d..c84260c0a6 100755 --- a/deps/v8/tools/testrunner/standard_runner.py +++ b/deps/v8/tools/testrunner/standard_runner.py @@ -18,7 +18,7 @@ from testrunner.objects import predictable from testrunner.testproc.execution import ExecutionProc from testrunner.testproc.filter import StatusFileFilterProc, NameFilterProc from testrunner.testproc.loader import LoadProc -from testrunner.testproc.progress import ResultsTracker, TestsCounter +from testrunner.testproc.progress import ResultsTracker from testrunner.testproc.seed import SeedProc from testrunner.testproc.variant import VariantProc from testrunner.utils import random_utils @@ -49,7 +49,8 @@ VARIANT_ALIASES = { GC_STRESS_FLAGS = ["--gc-interval=500", "--stress-compaction", "--concurrent-recompilation-queue-length=64", "--concurrent-recompilation-delay=500", - "--concurrent-recompilation"] + "--concurrent-recompilation", + "--stress-flush-bytecode"] RANDOM_GC_STRESS_FLAGS = ["--random-gc-interval=5000", "--stress-compaction-random"] @@ -281,7 +282,6 @@ class StandardTestRunner(base_runner.BaseTestRunner): print '>>> Running with test processors' loader = LoadProc() - tests_counter = TestsCounter() results = self._create_result_tracker(options) indicators = self._create_progress_indicators(options) @@ -296,7 +296,6 @@ class StandardTestRunner(base_runner.BaseTestRunner): NameFilterProc(args) if args else None, StatusFileFilterProc(options.slow_tests, options.pass_fail_tests), self._create_shard_proc(options), - tests_counter, VariantProc(self._variants), StatusFileFilterProc(options.slow_tests, options.pass_fail_tests), self._create_predictable_filter(), @@ -310,13 +309,9 @@ class StandardTestRunner(base_runner.BaseTestRunner): ] self._prepare_procs(procs) - tests.sort(key=lambda t: t.is_slow, reverse=True) loader.load_tests(tests) - print '>>> Running %d base tests' % tests_counter.total - tests_counter.remove_from_chain() - # This starts up worker processes and blocks until all tests are # processed. execproc.run() diff --git a/deps/v8/tools/testrunner/test_config.py b/deps/v8/tools/testrunner/test_config.py index d9418fe9ac..27ac72bf6c 100644 --- a/deps/v8/tools/testrunner/test_config.py +++ b/deps/v8/tools/testrunner/test_config.py @@ -16,6 +16,7 @@ class TestConfig(object): no_harness, noi18n, random_seed, + run_skipped, shell_dir, timeout, verbose): @@ -27,6 +28,7 @@ class TestConfig(object): self.noi18n = noi18n # random_seed is always not None. self.random_seed = random_seed or random_utils.random_seed() + self.run_skipped = run_skipped self.shell_dir = shell_dir self.timeout = timeout self.verbose = verbose diff --git a/deps/v8/tools/testrunner/testproc/fuzzer.py b/deps/v8/tools/testrunner/testproc/fuzzer.py index 624b9aac04..799b4bfb5e 100644 --- a/deps/v8/tools/testrunner/testproc/fuzzer.py +++ b/deps/v8/tools/testrunner/testproc/fuzzer.py @@ -217,17 +217,16 @@ class CompactionFuzzer(Fuzzer): yield ['--stress-compaction-random'] -class ThreadPoolSizeFuzzer(Fuzzer): +class TaskDelayFuzzer(Fuzzer): def create_flags_generator(self, rng, test, analysis_value): while True: - yield ['--thread-pool-size=%d' % rng.randint(1, 8)] + yield ['--stress-delay-tasks'] -class InterruptBudgetFuzzer(Fuzzer): +class ThreadPoolSizeFuzzer(Fuzzer): def create_flags_generator(self, rng, test, analysis_value): while True: - limit = 1 + int(rng.random() * 144) - yield ['--interrupt-budget=%d' % rng.randint(1, limit * 1024)] + yield ['--thread-pool-size=%d' % rng.randint(1, 8)] class DeoptAnalyzer(Analyzer): @@ -269,9 +268,9 @@ class DeoptFuzzer(Fuzzer): FUZZERS = { 'compaction': (None, CompactionFuzzer), + 'delay': (None, TaskDelayFuzzer), 'deopt': (DeoptAnalyzer, DeoptFuzzer), 'gc_interval': (GcIntervalAnalyzer, GcIntervalFuzzer), - 'interrupt_budget': (None, InterruptBudgetFuzzer), 'marking': (MarkingAnalyzer, MarkingFuzzer), 'scavenge': (ScavengeAnalyzer, ScavengeFuzzer), 'threads': (None, ThreadPoolSizeFuzzer), diff --git a/deps/v8/tools/testrunner/testproc/progress.py b/deps/v8/tools/testrunner/testproc/progress.py index 50b7307e1c..096228dc35 100644 --- a/deps/v8/tools/testrunner/testproc/progress.py +++ b/deps/v8/tools/testrunner/testproc/progress.py @@ -22,15 +22,6 @@ def print_failure_header(test): } -class TestsCounter(base.TestProcObserver): - def __init__(self): - super(TestsCounter, self).__init__() - self.total = 0 - - def _on_next_test(self, test): - self.total += 1 - - class ResultsTracker(base.TestProcObserver): """Tracks number of results and stops to run tests if max_failures reached.""" def __init__(self, max_failures): @@ -66,10 +57,6 @@ class SimpleProgressIndicator(ProgressIndicator): self._requirement = base.DROP_PASS_OUTPUT self._failed = [] - self._total = 0 - - def _on_next_test(self, test): - self._total += 1 def _on_result_for(self, test, result): # TODO(majeski): Support for dummy/grouped results @@ -170,13 +157,9 @@ class CompactProgressIndicator(ProgressIndicator): self._last_status_length = 0 self._start_time = time.time() - self._total = 0 self._passed = 0 self._failed = 0 - def _on_next_test(self, test): - self._total += 1 - def _on_result_for(self, test, result): # TODO(majeski): Support for dummy/grouped results if result.has_unexpected_output: @@ -210,13 +193,8 @@ class CompactProgressIndicator(ProgressIndicator): def _print_progress(self, name): self._clear_line(self._last_status_length) elapsed = time.time() - self._start_time - if not self._total: - progress = 0 - else: - progress = (self._passed + self._failed) * 100 // self._total status = self._templates['status_line'] % { 'passed': self._passed, - 'progress': progress, 'failed': self._failed, 'test': name, 'mins': int(elapsed) / 60, @@ -241,7 +219,6 @@ class ColorProgressIndicator(CompactProgressIndicator): def __init__(self): templates = { 'status_line': ("[%(mins)02i:%(secs)02i|" - "\033[34m%%%(progress) 4d\033[0m|" "\033[32m+%(passed) 4d\033[0m|" "\033[31m-%(failed) 4d\033[0m]: %(test)s"), 'stdout': "\033[1m%s\033[0m", @@ -256,7 +233,7 @@ class ColorProgressIndicator(CompactProgressIndicator): class MonochromeProgressIndicator(CompactProgressIndicator): def __init__(self): templates = { - 'status_line': ("[%(mins)02i:%(secs)02i|%%%(progress) 4d|" + 'status_line': ("[%(mins)02i:%(secs)02i|" "+%(passed) 4d|-%(failed) 4d]: %(test)s"), 'stdout': '%s', 'stderr': '%s', diff --git a/deps/v8/tools/tick-processor.html b/deps/v8/tools/tick-processor.html index b841cc0bd3..bfebfc9e6a 100644 --- a/deps/v8/tools/tick-processor.html +++ b/deps/v8/tools/tick-processor.html @@ -27,10 +27,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> <html lang="en"> <head> - <meta charset="utf-8"/> + <meta charset="utf-8"> <title>V8 Tick Processor</title> - <style type="text/css"> + <style> body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; @@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> <script src="arguments.js"></script> <script src="tickprocessor.js"></script> - <script type="text/javascript"> + <script> var v8log_content; var textout; diff --git a/deps/v8/tools/torque/format-torque.py b/deps/v8/tools/torque/format-torque.py index aac432ef41..148e9af4c5 100755 --- a/deps/v8/tools/torque/format-torque.py +++ b/deps/v8/tools/torque/format-torque.py @@ -13,17 +13,31 @@ from subprocess import Popen, PIPE def preprocess(input): input = re.sub(r'(if\s+)constexpr(\s*\()', r'\1/*COxp*/\2', input) - input = re.sub(r'(\)\s*\:\s*\S+\s+)labels\s+', - r'\1,\n/*_LABELS_HOLD_*/ ', input) input = re.sub(r'(\s+)operator\s*(\'[^\']+\')', r'\1/*_OPE \2*/', input) + + # Mangle typeswitches to look like switch statements with the extra type + # information and syntax encoded in comments. input = re.sub(r'(\s+)typeswitch\s*\(', r'\1/*_TYPE*/switch (', input) - input = re.sub(r'(\s+)case\s*\(([^\s]+)\s+\:\s*([^\:]+)\)(\s*)\:', - r'\1case \3: /*_TSV\2:*/', input) - input = re.sub(r'(\s+)case\s*\(([^\:]+)\)(\s*)\:', + input = re.sub(r'(\s+)case\s*\(\s*([^\:]+)\s*\)(\s*)\:\s*deferred', + r'\1case \2: /*_TSXDEFERRED_*/', input) + input = re.sub(r'(\s+)case\s*\(\s*([^\:]+)\s*\)(\s*)\:', r'\1case \2: /*_TSX*/', input) - input = re.sub(r'\sgenerates\s+\'([^\']+)\'\s*', + input = re.sub(r'(\s+)case\s*\(\s*([^\s]+)\s*\:\s*([^\:]+)\s*\)(\s*)\:\s*deferred', + r'\1case \3: /*_TSVDEFERRED_\2:*/', input) + input = re.sub(r'(\s+)case\s*\(\s*([^\s]+)\s*\:\s*([^\:]+)\s*\)(\s*)\:', + r'\1case \3: /*_TSV\2:*/', input) + + # Add extra space around | operators to fix union types later. + while True: + old = input + input = re.sub(r'(\w+\s*)\|(\s*\w+)', + r'\1|/**/\2', input) + if old == input: + break; + + input = re.sub(r'\bgenerates\s+\'([^\']+)\'\s*', r' _GeNeRaTeS00_/*\1@*/', input) - input = re.sub(r'\sconstexpr\s+\'([^\']+)\'\s*', + input = re.sub(r'\bconstexpr\s+\'([^\']+)\'\s*', r' _CoNsExP_/*\1@*/', input) input = re.sub(r'\notherwise', r'\n otherwise', input) @@ -32,14 +46,23 @@ def preprocess(input): return input def postprocess(output): + output = re.sub(r'% RawObjectCast', r'%RawObjectCast', output) + output = re.sub(r'% RawPointerCast', r'%RawPointerCast', output) + output = re.sub(r'% RawConstexprCast', r'%RawConstexprCast', output) + output = re.sub(r'% FromConstexpr', r'%FromConstexpr', output) + output = re.sub(r'% Allocate', r'%Allocate', output) output = re.sub(r'\/\*COxp\*\/', r'constexpr', output) output = re.sub(r'(\S+)\s*: type([,>])', r'\1: type\2', output) - output = re.sub(r',([\n ]*)\/\*_LABELS_HOLD_\*\/', r'\1labels', output) + output = re.sub(r'(\n\s*)labels( [A-Z])', r'\1 labels\2', output) output = re.sub(r'\/\*_OPE \'([^\']+)\'\*\/', r"operator '\1'", output) output = re.sub(r'\/\*_TYPE\*\/(\s*)switch', r'typeswitch', output) - output = re.sub(r'case ([^\:]+)\:\s*\/\*_TSX\*\/', + output = re.sub(r'case (\w+)\:\s*\/\*_TSXDEFERRED_\*\/', + r'case (\1): deferred', output) + output = re.sub(r'case (\w+)\:\s*\/\*_TSX\*\/', r'case (\1):', output) - output = re.sub(r'case ([^\:]+)\:\s*\/\*_TSV([^\:]+)\:\*\/', + output = re.sub(r'case (\w+)\:\s*\/\*_TSVDEFERRED_([^\:]+)\:\*\/', + r'case (\2: \1): deferred', output) + output = re.sub(r'case (\w+)\:\s*\/\*_TSV([^\:]+)\:\*\/', r'case (\2: \1):', output) output = re.sub(r'\n_GeNeRaTeS00_\s*\/\*([^@]+)@\*\/', r"\n generates '\1'", output) @@ -53,37 +76,68 @@ def postprocess(output): r"\n\1otherwise", output) output = re.sub(r'_OtheSaLi', r"otherwise", output) + + while True: + old = output + output = re.sub(r'(\w+)\s{0,1}\|\s{0,1}/\*\*/(\s*\w+)', + r'\1 |\2', output) + if old == output: + break; + return output -if len(sys.argv) < 2 or len(sys.argv) > 3: - print "invalid number of arguments" - sys.exit(-1) +def process(filename, only_lint, use_stdout): + with open(filename, 'r') as content_file: + content = content_file.read() + + original_input = content + + p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE) + output, err = p.communicate(preprocess(content)) + output = postprocess(output) + rc = p.returncode + if (rc <> 0): + print "error code " + str(rc) + " running clang-format. Exiting..." + sys.exit(rc); + + if only_lint: + if (output != original_input): + print >>sys.stderr, filename + ' requires formatting' + elif use_stdout: + print output + else: + output_file = open(filename, 'w') + output_file.write(output); + output_file.close() + +def print_usage(): + print 'format-torque -i file1[, file2[, ...]]' + print ' format and overwrite input files' + print 'format-torque -l file1[, file2[, ...]]' + print ' merely indicate which files need formatting' + +def Main(): + if len(sys.argv) < 3: + print "error: at least 2 arguments required" + print_usage(); + sys.exit(-1) + + use_stdout = True + lint = False -use_stdout = True -lint = False -if len(sys.argv) == 3: if sys.argv[1] == '-i': use_stdout = False - if sys.argv[1] == '-l': + elif sys.argv[1] == '-l': lint = True + else: + print "error: -i or -l must be specified as the first argument" + print_usage(); + sys.exit(-1); + + for filename in sys.argv[2:]: + process(filename, lint, use_stdout) + + return 0 -filename = sys.argv[len(sys.argv) - 1] - -with open(filename, 'r') as content_file: - content = content_file.read() -original_input = content -p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE) -output, err = p.communicate(preprocess(content)) -output = postprocess(output) -rc = p.returncode -if (rc <> 0): - sys.exit(rc); -if lint: - if (output != original_input): - print >>sys.stderr, filename + ' requires formatting' -elif use_stdout: - print output -else: - output_file = open(filename, 'w') - output_file.write(output); - output_file.close() +if __name__ == '__main__': + sys.exit(Main()); diff --git a/deps/v8/tools/torque/vim-torque/syntax/torque.vim b/deps/v8/tools/torque/vim-torque/syntax/torque.vim index 17713c7213..c2e4ba0f7a 100644 --- a/deps/v8/tools/torque/vim-torque/syntax/torque.vim +++ b/deps/v8/tools/torque/vim-torque/syntax/torque.vim @@ -26,18 +26,18 @@ syn keyword torqueBranch break continue goto syn keyword torqueConditional if else typeswitch otherwise syn match torqueConstant /\v<[A-Z][A-Z0-9_]+>/ syn match torqueConstant /\v<k[A-Z][A-Za-z0-9]*>/ -syn keyword torqueFunction macro builtin runtime +syn keyword torqueFunction macro builtin runtime intrinsic syn keyword torqueKeyword cast convert from_constexpr min max unsafe_cast syn keyword torqueLabel case -syn keyword torqueMatching try label -syn keyword torqueModifier extern javascript constexpr +syn keyword torqueMatching try label catch +syn keyword torqueModifier extern javascript constexpr transitioning transient weak syn match torqueNumber /\v<[0-9]+(\.[0-9]*)?>/ syn match torqueNumber /\v<0x[0-9a-fA-F]+>/ syn keyword torqueOperator operator syn keyword torqueRel extends generates labels syn keyword torqueRepeat while for of syn keyword torqueStatement return tail -syn keyword torqueStructure module struct type +syn keyword torqueStructure module struct type class syn keyword torqueVariable const let syn match torqueType /\v(\<)@<=([A-Za-z][0-9A-Za-z_]*)(>)@=/ diff --git a/deps/v8/tools/torque/vscode-torque/syntaxes/torque.tmLanguage.json b/deps/v8/tools/torque/vscode-torque/syntaxes/torque.tmLanguage.json index d1d43e5dcb..39b994ec25 100644 --- a/deps/v8/tools/torque/vscode-torque/syntaxes/torque.tmLanguage.json +++ b/deps/v8/tools/torque/vscode-torque/syntaxes/torque.tmLanguage.json @@ -61,11 +61,11 @@ "keywords": { "patterns": [{ "name": "keyword.control.torque", - "match": "\\b(if|else|while|for|return|continue|break|goto|otherwise|try|catch)\\b" + "match": "\\b(if|else|while|for|return|continue|break|goto|otherwise|try|label|catch)\\b" }, { "name": "keyword.other.torque", - "match": "\\b(constexpr|module|macro|builtin|runtime|javascript|implicit|deferred|label|labels|tail|let|generates|type|extends|extern|const|typeswitch|case)\\b" + "match": "\\b(constexpr|module|macro|builtin|runtime|intrinsic|javascript|implicit|deferred|label|labels|tail|let|generates|type|struct|class|weak|extends|extern|const|typeswitch|case|transient|transitioning)\\b" }, { "name": "keyword.operator.torque", diff --git a/deps/v8/tools/try_perf.py b/deps/v8/tools/try_perf.py index c6dc394389..a0a98ee752 100755 --- a/deps/v8/tools/try_perf.py +++ b/deps/v8/tools/try_perf.py @@ -9,38 +9,28 @@ import subprocess import sys BOTS = { - '--arm32': 'v8_arm32_perf_try', + '--chromebook': 'v8_chromebook_perf_try', '--linux32': 'v8_linux32_perf_try', '--linux64': 'v8_linux64_perf_try', '--linux64_atom': 'v8_linux64_atom_perf_try', - '--linux64_haswell': 'v8_linux64_haswell_perf_try', '--nexus5': 'v8_nexus5_perf_try', '--nexus7': 'v8_nexus7_perf_try', - '--nexus10': 'v8_nexus10_perf_try', - '--pixel2': 'v8_pixel2_perf_try', '--nokia1': 'v8_nokia1_perf_try', + '--odroid32': 'v8_odroid32_perf_try', + '--pixel2': 'v8_pixel2_perf_try', } -# This list will contain builder names that should be triggered on an internal -# swarming bucket instead of internal Buildbot master. -SWARMING_BOTS = [ - 'v8_linux64_perf_try', - 'v8_pixel2_perf_try', - 'v8_nokia1_perf_try', -] - DEFAULT_BOTS = [ - 'v8_arm32_perf_try', + 'v8_chromebook_perf_try', 'v8_linux32_perf_try', - 'v8_linux64_haswell_perf_try', - 'v8_nexus10_perf_try', + 'v8_linux64_perf_try', ] PUBLIC_BENCHMARKS = [ 'arewefastyet', + 'compile', 'embenchen', 'emscripten', - 'compile', 'jetstream', 'jsbench', 'jstests', @@ -60,17 +50,6 @@ PUBLIC_BENCHMARKS = [ V8_BASE = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -def _trigger_bots(bucket, bots, options): - cmd = ['git cl try'] - cmd += ['-B', bucket] - cmd += ['-b %s' % bot for bot in bots] - if options.revision: cmd += ['-r %s' % options.revision] - benchmarks = ['"%s"' % benchmark for benchmark in options.benchmarks] - cmd += ['-p \'testfilter=[%s]\'' % ','.join(benchmarks)] - if options.extra_flags: - cmd += ['-p \'extra_flags="%s"\'' % options.extra_flags] - subprocess.check_call(' '.join(cmd), shell=True, cwd=V8_BASE) - def main(): parser = argparse.ArgumentParser(description='') parser.add_argument('benchmarks', nargs='+', help='The benchmarks to run.') @@ -80,6 +59,8 @@ def main(): help='Revision (use full hash!) to use for the try job; ' 'default: the revision will be determined by the ' 'try server; see its waterfall for more info') + parser.add_argument('-v', '--verbose', action='store_true', + help='Print debug information') for option in sorted(BOTS): parser.add_argument( option, dest='bots', action='append_const', const=BOTS[option], @@ -110,14 +91,17 @@ def main(): subprocess.check_output( 'update_depot_tools', shell=True, stderr=subprocess.STDOUT, cwd=V8_BASE) - buildbot_bots = [bot for bot in options.bots if bot not in SWARMING_BOTS] - if buildbot_bots: - _trigger_bots('master.internal.client.v8', buildbot_bots, options) - - swarming_bots = [bot for bot in options.bots if bot in SWARMING_BOTS] - if swarming_bots: - _trigger_bots('luci.v8-internal.try', swarming_bots, options) - + cmd = ['git cl try', '-B', 'luci.v8-internal.try'] + cmd += ['-b %s' % bot for bot in options.bots] + if options.revision: cmd += ['-r %s' % options.revision] + benchmarks = ['"%s"' % benchmark for benchmark in options.benchmarks] + cmd += ['-p \'testfilter=[%s]\'' % ','.join(benchmarks)] + if options.extra_flags: + cmd += ['-p \'extra_flags="%s"\'' % options.extra_flags] + if options.verbose: + cmd.append('-vv') + print 'Running %s' % ' '.join(cmd) + subprocess.check_call(' '.join(cmd), shell=True, cwd=V8_BASE) if __name__ == '__main__': # pragma: no cover sys.exit(main()) diff --git a/deps/v8/tools/turbolizer/README.md b/deps/v8/tools/turbolizer/README.md index 293f4a20a6..c5ee729d64 100644 --- a/deps/v8/tools/turbolizer/README.md +++ b/deps/v8/tools/turbolizer/README.md @@ -10,15 +10,20 @@ the '--trace-turbo' command-line flag. Turbolizer is build using npm: + cd tools/turbolizer npm i npm run-script build Afterwards, turbolizer can be hosted locally by starting a web server that serve the contents of the turbolizer directory, e.g.: - cd src/tools/turbolizer python -m SimpleHTTPServer 8000 +To deploy to a directory that can be hosted the script `deploy` can be used. The +following command will deploy to the directory /www/turbolizer: + + npm run deploy -- /www/turbolizer + Optionally, profiling data generated by the perf tools in linux can be merged with the .json files using the turbolizer-perf.py file included. The following command is an example of using the perf script: diff --git a/deps/v8/tools/turbolizer/deploy.sh b/deps/v8/tools/turbolizer/deploy.sh index db76dca490..ae069762d9 100755 --- a/deps/v8/tools/turbolizer/deploy.sh +++ b/deps/v8/tools/turbolizer/deploy.sh @@ -7,12 +7,18 @@ if [ ! -d "$DEST" ]; then exit 1 fi -echo "Deploying..." +function copy() { + echo -n "." + cp "$@" +} -cp *.jpg $DEST/ -cp *.png $DEST/ -cp *.css $DEST/ -cp index.html $DEST/ -cp -R build $DEST/ +echo -n "Deploying..." +copy *.jpg $DEST/ +copy *.png $DEST/ +copy *.css $DEST/ +copy index.html $DEST/ +copy info-view.html $DEST/ +copy -R build $DEST/ +echo "done!" echo "Deployed to $DEST/." diff --git a/deps/v8/tools/turbolizer/expand-all.jpg b/deps/v8/tools/turbolizer/expand-all.jpg Binary files differdeleted file mode 100644 index df64a2c4aa..0000000000 --- a/deps/v8/tools/turbolizer/expand-all.jpg +++ /dev/null diff --git a/deps/v8/tools/turbolizer/hide-selected.png b/deps/v8/tools/turbolizer/img/hide-selected-icon.png Binary files differindex 207cdbb89a..207cdbb89a 100644 --- a/deps/v8/tools/turbolizer/hide-selected.png +++ b/deps/v8/tools/turbolizer/img/hide-selected-icon.png diff --git a/deps/v8/tools/turbolizer/hide-unselected.png b/deps/v8/tools/turbolizer/img/hide-unselected-icon.png Binary files differindex 15617b0939..15617b0939 100644 --- a/deps/v8/tools/turbolizer/hide-unselected.png +++ b/deps/v8/tools/turbolizer/img/hide-unselected-icon.png diff --git a/deps/v8/tools/turbolizer/layout-icon.png b/deps/v8/tools/turbolizer/img/layout-icon.png Binary files differindex 95a517afa6..95a517afa6 100644 --- a/deps/v8/tools/turbolizer/layout-icon.png +++ b/deps/v8/tools/turbolizer/img/layout-icon.png diff --git a/deps/v8/tools/turbolizer/img/show-all-icon.png b/deps/v8/tools/turbolizer/img/show-all-icon.png Binary files differnew file mode 100644 index 0000000000..50fc845f01 --- /dev/null +++ b/deps/v8/tools/turbolizer/img/show-all-icon.png diff --git a/deps/v8/tools/turbolizer/img/show-control-icon.png b/deps/v8/tools/turbolizer/img/show-control-icon.png Binary files differnew file mode 100644 index 0000000000..4238bee9cc --- /dev/null +++ b/deps/v8/tools/turbolizer/img/show-control-icon.png diff --git a/deps/v8/tools/turbolizer/live.png b/deps/v8/tools/turbolizer/img/toggle-hide-dead-icon.png Binary files differindex ac72bb93e8..ac72bb93e8 100644 --- a/deps/v8/tools/turbolizer/live.png +++ b/deps/v8/tools/turbolizer/img/toggle-hide-dead-icon.png diff --git a/deps/v8/tools/turbolizer/types.png b/deps/v8/tools/turbolizer/img/toggle-types-icon.png Binary files differindex 8fead8f079..8fead8f079 100644 --- a/deps/v8/tools/turbolizer/types.png +++ b/deps/v8/tools/turbolizer/img/toggle-types-icon.png diff --git a/deps/v8/tools/turbolizer/search.png b/deps/v8/tools/turbolizer/img/zoom-selection-icon.png Binary files differindex 12dc3e3469..12dc3e3469 100644 --- a/deps/v8/tools/turbolizer/search.png +++ b/deps/v8/tools/turbolizer/img/zoom-selection-icon.png diff --git a/deps/v8/tools/turbolizer/index.html b/deps/v8/tools/turbolizer/index.html index ea89a61261..f970a6df04 100644 --- a/deps/v8/tools/turbolizer/index.html +++ b/deps/v8/tools/turbolizer/index.html @@ -1,63 +1,46 @@ -<!DOCTYPE HTML> +<!DOCTYPE html> <html> - <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 scrollable"></div> - <div class="resizer-left"></div> - <div id="middle" class="viewpane"> - <div id="graph-toolbox-anchor"> - <span id="graph-toolbox"> - <input id="layout" type="image" title="layout graph" src="layout-icon.png" - 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="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"> - <input id="hide-selected" type="image" title="hide selected nodes" - src="hide-selected.png" alt="hide selected nodes" class="button-input"> - <input id="zoom-selection" type="image" title="zoom to selection" - src="search.png" alt="zoom to selection" class="button-input"> - <input id="toggle-types" type="image" title="show/hide types" - src="types.png" alt="show/hide types" class="button-input"> - <input id="search-input" type="text" title="search nodes for regex" - alt="search node for regex" class="search-input" - placeholder="find with regexp…"> - <select id="display-selector"> - <option disabled selected>(please open a file)</option> - </select> - </span> - </div> - <div id="load-file"> - <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='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> +<!-- +Copyright 2019 the V8 project authors. All rights reserved. Use of this source +code is governed by a BSD-style license that can be found in the LICENSE file. +--> +<head> + <meta charset="utf-8"> + <title>V8 Turbolizer</title> + <link rel="stylesheet" href="turbo-visualizer.css"> + <link rel="stylesheet" href="tabs.css"> + <link rel="stylesheet" href="prettify.css"> + <link rel="icon" type="image/png" href="turbolizer.png"> +</head> + +<body> + <div id="left" class="content"></div> + <div id="resizer-left" class="resizer"></div> + <div id="middle"> + + <div id="load-file"> + <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 class="resizer-right"></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"> - <input id="source-shrink" type="image" title="hide source" - src="left-arrow.png" class="button-input"> - </div> - <div id="disassembly-collapse" class="collapse-pane"> - <input id="disassembly-expand" type="image" title="show disassembly" - src="left-arrow.png" class="button-input invisible"> - <input id="disassembly-shrink" type="image" title="hide disassembly" - 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="build/turbolizer.js"></script> - </body> + </div> + <div id="resizer-right" class="resizer"></div> + <div id="right" class="content"></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"> + <input id="source-shrink" type="image" title="hide source" src="left-arrow.png" class="button-input"> + </div> + <div id="disassembly-collapse" class="collapse-pane"> + <input id="disassembly-expand" type="image" title="show disassembly" src="left-arrow.png" class="button-input invisible"> + <input id="disassembly-shrink" type="image" title="hide disassembly" src="right-arrow.png" class="button-input"> + </div> + <div id="text-placeholder" width="0" height="0" style="position: absolute; top:100000px;"> + <svg> + <text text-anchor="right"> + <tspan white-space="inherit" id="text-measure"> + </text> + </svg> + </div> + <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> + <script src="build/turbolizer.js"></script> +</body> </html> diff --git a/deps/v8/tools/turbolizer/info-view.html b/deps/v8/tools/turbolizer/info-view.html new file mode 100644 index 0000000000..7c714c3f9f --- /dev/null +++ b/deps/v8/tools/turbolizer/info-view.html @@ -0,0 +1,119 @@ +<div>This is view contains hints about available keyboard shortcuts.</div> +<div class="info-topic" id="info-global"> + <div class="info-topic-header">Global shortcuts</div> + <div class="info-topic-content"> + <table> + <tr> + <td>CTRL+L</td> + <td>Open load file dialog.</td> + </tr> + <tr> + <td>CTRL+R</td> + <td>Reload turbolizer (Chrome shortcut)</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-view"> + <div class="info-topic-header">Graph view</div> + <div class="info-topic-content"> + <table> + <tr> + <td>r</td> + <td>Relayout graph</td> + </tr> + <tr> + <td>a</td> + <td>Select all nodes</td> + </tr> + <tr> + <td>/</td> + <td>Select search box</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-nodes"> + <div class="info-topic-header">TurboFan graph nodes</div> + <div class="info-topic-content"> + <div>The following commands transform node selections, i.e. each operation will be applied + to each node in the current selection and the union of the resulting nodes will become the + new selection.</div> + <table> + <tr> + <td>UP</td> + <td>Select all input nodes</td> + </tr> + <tr> + <td>DOWN</td> + <td>Select all output nodes</td> + </tr> + <tr> + <td>1-9</td> + <td>Select input node 1-9</td> + </tr> + <tr> + <td>CTRL+1-9</td> + <td>Toggle input edge 1-9</td> + </tr> + <tr> + <td>c</td> + <td>Select control output node</td> + </tr> + <tr> + <td>e</td> + <td>Select effect output node</td> + </tr> + <tr> + <td>o</td> + <td>Reveal node's input nodes</td> + </tr> + <tr> + <td>i</td> + <td>Reveal node's output nodes</td> + </tr> + <tr> + <td>s</td> + <td>Select node's origin node</td> + </tr> + <tr> + <td>/</td> + <td>Select search box</td> + </tr> + </table> + </div> +</div> +<div class="info-topic" id="info-graph-search"> + <div class="info-topic-header">Graph search</div> + <div class="info-topic-content"> + <table> + <tr> + <td>ENTER</td> + <td>Select nodes according to regular expression. Invisible nodes are included depending on the state of the + checkbox "only visible".</td> + </tr> + <tr> + <td>CTRL+ENTER</td> + <td>Select nodes according to regular expression, always including invisible nodes regardless of checkbox.</td> + </tr> + </table> + <div style="font-weight: bold"> + Useful patterns + </div> + <table> + <tr> + <td>IfTrue</td> + <td>Select nodes which have 'IfTrue' in title or description.</td> + </tr> + <tr> + <td>^42:</td> + <td>Select exactly the node with id 14.</td> + </tr> + <tr> + <td>Origin: #42 </td> + <td>Select nodes which were created while node with id 42 was reduced. This is inaccurate if the node was + changed in-place.</td> + </tr> + </table> + </div> +</div> diff --git a/deps/v8/tools/turbolizer/package-lock.json b/deps/v8/tools/turbolizer/package-lock.json index fc9557f76d..34dea91004 100644 --- a/deps/v8/tools/turbolizer/package-lock.json +++ b/deps/v8/tools/turbolizer/package-lock.json @@ -4,19 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", - "dev": true, - "requires": { - "commander": "*" - } + "@koa/cors": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-2.2.2.tgz", + "integrity": "sha512-Ollvsy3wB8+7R9w6hPVzlj3wekF6nK+IHpHj7faSPVXCkahqCwNEPp9+0C4b51RDkdpHjevLEGLOKuVjqtXgSQ==", + "dev": true }, "@types/d3": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.0.0.tgz", - "integrity": "sha512-BVfPw7ha+UgsG24v6ymerMY4+pJgQ/6p+hJA4loCeaaqV9snGS/G6ReVaQEn8Himn67dWn/Je9WhRbnDO7MzLw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.5.0.tgz", + "integrity": "sha512-Bz9EAhWnaO93jLYSAT13blgzwP5Z0grO5THBOXSMeWHIIFHA7ntJSLpHSCr1kDtQunEZKCYT9OfE+4lYY/PwlA==", "requires": { "@types/d3-array": "*", "@types/d3-axis": "*", @@ -52,30 +49,30 @@ } }, "@types/d3-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-YBaAfimGdWE4nDuoGVKsH89/dkz2hWZ0i8qC+xxqmqi+XJ/aXiRF0jPtzXmN7VdkpVjy1xuDmM5/m1FNuB6VWA==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-3r1fOAAb+SGfcOGXty/LGvoP0ovMec4UtGNUyHOSzYyvSGpmt+eNMxLowol/3HryusevznSfcHZebEShXMwsZA==" }, "@types/d3-axis": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.10.tgz", - "integrity": "sha512-5YF0wfdQMPKw01VAAupLIlg/T4pn5M3/vL9u0KZjiemnVnnKBEWE24na4X1iW+TfZiYJ8j+BgK2KFYnAAT54Ug==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.11.tgz", + "integrity": "sha512-cuigApCyCwYJxaQPghj+BqaxzbdRdT/lpZBMtF7EuEIJ61NMQ8yvGnqFvHCIgJEmUu2Wb2wiZqy9kiHi3Ddftg==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-brush": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.0.8.tgz", - "integrity": "sha512-9Thv09jvolu9T1BE3fHmIeYSgbwSpdxtF6/A5HZEDjSTfgtA0mtaXRk5AiWOo0KjuLsI+/7ggD3ZGN5Ye8KXPQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.0.9.tgz", + "integrity": "sha512-mAx8IVc0luUHfk51pl0UN1vzybnAzLMUsvIwLt3fbsqqPkSXr+Pu1AxOPPeyNc27LhHJnfH/LCV7Jlv+Yzqu1A==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-chord": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.7.tgz", - "integrity": "sha512-WbCN7SxhZMpQQw46oSjAovAmvl3IdjhLuQ4r7AXCzNKyxtXXBWuihSPZ4bVwFQF3+S2z37i9d4hfUBatcSJpog==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.8.tgz", + "integrity": "sha512-F0ftYOo7FenAIxsRjXLt8vbij0NLDuVcL+xaGY7R9jUmF2Mrpj1T5XukBI9Cad+Ei7YSxEWREIO+CYcaKCl2qQ==" }, "@types/d3-collection": { "version": "1.0.7", @@ -88,9 +85,9 @@ "integrity": "sha512-xwb1tqvYNWllbHuhMFhiXk63Imf+QNq/dJdmbXmr2wQVnwGenCuj3/0IWJ9hdIFQIqzvhT7T37cvx93jtAsDbQ==" }, "@types/d3-contour": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-1.2.1.tgz", - "integrity": "sha512-p8iC4KeVFyT3qRTGQRj0Jf5QDdPsDUevBEnma7gEsY1yDolVSLanG2eFAiLV+xj8/5DK7oU7Ey8z0drs3pbsug==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-1.3.0.tgz", + "integrity": "sha512-AUCUIjEnC5lCGBM9hS+MryRaFLIrPls4Rbv6ktqbd+TK/RXZPwOy9rtBWmGpbeXcSOYCJTUDwNJuEnmYPJRxHQ==", "requires": { "@types/d3-array": "*", "@types/geojson": "*" @@ -102,17 +99,17 @@ "integrity": "sha512-xyWJQMr832vqhu6fD/YqX+MSFBWnkxasNhcStvlhqygXxj0cKqPft0wuGoH5TIq5ADXgP83qeNVa4R7bEYN3uA==" }, "@types/d3-drag": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-J9liJ4NNeV0oN40MzPiqwWjqNi3YHCRtHNfNMZ1d3uL9yh1+vDuo346LBEr8yyBm30WHvrHssAkExVZrGCswtA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.2.tgz", + "integrity": "sha512-+UKFeaMVTfSQvMO0PTzOyLXSr7OZbF2Rx1iNVwo2XsyiOsd4MSuLyJKUwRmGn67044QpbNzr+VD6/8iBBLExWw==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-dsv": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.0.33.tgz", - "integrity": "sha512-jx5YvaVC3Wfh6LobaiWTeU1NkvL2wPmmpmajk618bD+xVz98yNWzmZMvmlPHGK0HXbMeHmW/6oVX48V9AH1bRQ==" + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.0.34.tgz", + "integrity": "sha512-/grhPLPFJ17GxH18EB8OSOlqcsLahz1xlKb08cVUu3OP83wBPxfoX2otVvLJDTL6BEP0kyTNsA2SdGrRhWwSBQ==" }, "@types/d3-ease": { "version": "1.0.7", @@ -120,9 +117,9 @@ "integrity": "sha1-k6MBhovp4VBh89RDQ7GrP4rLbwk=" }, "@types/d3-fetch": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.1.2.tgz", - "integrity": "sha512-w6ANZv/mUh+6IV3drT22zgPWMRobzuGXhzOZC8JPD+ygce0/Vx6vTci3m3dizkocnQQCOwNbrWWWPYqpWiKzRQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.1.4.tgz", + "integrity": "sha512-POR6AHGEjUk8VjHhU2HfcKxVKnZUIhhHjU65greJs34NlfmWfaDxE+6+ABeMsRCAWa/DRTRNe+1ExuMPBwb7/Q==", "requires": { "@types/d3-dsv": "*" } @@ -146,14 +143,14 @@ } }, "@types/d3-hierarchy": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.2.tgz", - "integrity": "sha512-L+Ht4doqlCIH8jYN2AC1mYIOj13OxlRhdWNWXv2pc3o5A9i3YmQ0kz6A7w8c+Ujylfusi/FO+zVlVnQoOHc2Qw==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", + "integrity": "sha512-DKhqURrURt2c7MsF9sHiF2wrWf2+yZR4Q9oIG026t/ZY4VWoM0Yd7UonaR+rygyReWcFSEjKC/+5A27TgD8R8g==" }, "@types/d3-interpolate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.2.0.tgz", - "integrity": "sha512-qM9KlUrqbwIhBRtw9OtAEbkis1AxsOJEun2uxaX/vEsBp3vyNBmhPz9boXXEqic9ZRi7fCpUNRwyZvxa0PioIw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.3.0.tgz", + "integrity": "sha512-Ng4ds7kPSvP/c3W3J5PPUQlgewif1tGBqCeh5lgY+UG82Y7H9zQ8c2gILsEFDLg7wRGOwnuKZ940Q/LSN14w9w==", "requires": { "@types/d3-color": "*" } @@ -169,9 +166,9 @@ "integrity": "sha512-E6Kyodn9JThgLq20nxSbEce9ow5/ePgm9PX2EO6W1INIL4DayM7cFaiG10DStuamjYAd0X4rntW2q+GRjiIktw==" }, "@types/d3-quadtree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.5.tgz", - "integrity": "sha1-HOHmWerkUw3wyxJ/KX8XQaNnqC4=" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.6.tgz", + "integrity": "sha512-sphVuDdiSIaxLt9kQgebJW98pTktQ/xuN7Ysd8X68Rnjeg/q8+c36/ShlqU52qoKg9nob/JEHH1uQMdxURZidQ==" }, "@types/d3-random": { "version": "1.1.1", @@ -179,35 +176,35 @@ "integrity": "sha512-jUPeBq1XKK9/5XasTvy5QAUwFeMsjma2yt/nP02yC2Tijovx7i/W5776U/HZugxc5SSmtpx4Z3g9KFVon0QrjQ==" }, "@types/d3-scale": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.0.1.tgz", - "integrity": "sha512-D5ZWv8ToLvqacE7XkdMNHMiiVDULdDxT7FMMGU0YJC3/nVzBmApjyTyxracUWOQyY3KK7YhZ05on8pOcNi0dfQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.1.0.tgz", + "integrity": "sha512-vLzRDF5lRxZdCLUOvmw90pkiuSsZdgroBQaat0Ov7Z7OnO9iJsPSm/TZw3wW6m2z/NhIn1E4N0RLNfEi1k4kAA==", "requires": { "@types/d3-time": "*" } }, "@types/d3-scale-chromatic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.2.0.tgz", - "integrity": "sha512-bhS2SVzUzRtrxp1REhGCfHmj8pyDv9oDmsonYiPvBl8KCxPJTxnfXBF39PzAJrYnRKM41TR0kQzsJvL+NmcDtg==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.3.0.tgz", + "integrity": "sha512-JqQH5uu1kmdQEa6XSu7NYzQM71lL1YreBPS5o8SnmEDcBRKL6ooykXa8iFPPOEUiTah25ydi+cTrbsogBSMNSQ==" }, "@types/d3-selection": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.3.1.tgz", - "integrity": "sha512-G+eO+2G1iW3GNrROxhoU+ar+bIJbQq1QkxcfhwjQ19xA20n3T31j5pSJqAOWvPSoFTz4Ets/DQgYhmgT4jepDg==" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.3.4.tgz", + "integrity": "sha512-WQ6Ivy7VuUlZ/Grqc8493ZxC+y/fpvZLy5+8ELvmCr2hll8eJPUqC05l6fgRRA7kjqlpbH7lbmvY6pRKf6yzxw==" }, "@types/d3-shape": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.2.3.tgz", - "integrity": "sha512-iP9TcX0EVi+LlX+jK9ceS+yhEz5abTitF+JaO2ugpRE/J+bccaYLe/0/3LETMmdaEkYarIyboZW8OF67Mpnj1w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.2.7.tgz", + "integrity": "sha512-b2jpGcddOseeNxchaR1SNLqA5xZAbgKix3cXiFeuGeYIEAEUu91UbtelCxOHIUTbNURFnjcbkf4plRbejNzVaQ==", "requires": { "@types/d3-path": "*" } }, "@types/d3-time": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-/UCphyyw97YAq4zKsuXH33R3UNB4jDSza0fLvMubWr/ONh9IePi1NbgFP222blhiCe724ebJs8U87+aDuAq/jA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.9.tgz", + "integrity": "sha512-m+D4NbQdDlTVaO7QgXAnatR3IDxQYDMBtRhgSCi5rs9R1LPq1y7/2aqa1FJ2IWjFm1mOV63swDxonnCDlHgHMA==" }, "@types/d3-time-format": { "version": "2.1.0", @@ -215,27 +212,27 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==" }, "@types/d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-830pT+aYZrgbA91AuynP3KldfB1A1s60d0gKiV+L7JcSKSJapUzUffAm8VZod7RQOxF5SzoItV6cvrTzjbmrJQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.8.tgz", + "integrity": "sha512-AKUgQ/nljUFcUO2P3gK24weVI5XwUTdJvjoh8gJ0yxT4aJ+d7t2Or3TB+k9dEYl14BAjoj32D0ky+YzQSVszfg==" }, "@types/d3-transition": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-GHTghl0YYB8gGgbyKxVLHyAp9Na0HqsX2U7M0u0lGw4IdfEaslooykweZ8fDHW13T+KZeZAuzhbmqBZVFO+6kg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.3.tgz", + "integrity": "sha512-1EukXNuVu/z2G1GZpZagzFJnie9C5zze17ox/vhTgGXNy46rYAm4UkhLLlUeeZ1ndq88k95SOeC8898RpKMLOQ==", "requires": { "@types/d3-selection": "*" } }, "@types/d3-voronoi": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.7.tgz", - "integrity": "sha512-/dHFLK5jhXTb/W4XEQcFydVk8qlIAo85G3r7+N2fkBFw190l0R1GQ8C1VPeXBb2GfSU5GbT2hjlnE7i7UY5Gvg==" + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.8.tgz", + "integrity": "sha512-zqNhW7QsYQGlfOdrwPNPG3Wk64zUa4epKRurkJ/dVc6oeXrB+iTDt8sRZ0KZKOOXvvfa1dcdB0e45TZeLBiodQ==" }, "@types/d3-zoom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-Ofjwz6Pt53tRef9TAwwayN+JThNVYC/vFOepa/H4KtwjhsqkmEseHvc2jpJM7vye5PQ5XHtTSOpdY4Y/6xZWEg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-Tz7+z4+Id0MxERw/ozinC5QHJmGLARs9Mpi/7VVfiR+9AHcFGe9q+fjQa30/oPNY8WPuCh5p5uuXmBYAJ3y91Q==", "requires": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -247,21 +244,91 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "@types/geojson": { - "version": "7946.0.3", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.3.tgz", - "integrity": "sha512-BYHiG1vQJ7T93uswzuXZ0OBPWqj5tsAPtaMDQADV8sn2InllXarwg9llr6uaW22q1QCwBZ81gVajOpYWzjesug==" + "version": "7946.0.4", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.4.tgz", + "integrity": "sha512-MHmwBtCb7OCv1DSivz2UNJXPGU/1btAWRKlqJ2saEhVJkpkvqHMMaOpKg0v4sAbDWSQekHGvPVMM8nQ+Jen03Q==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "optional": true }, "@types/node": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz", - "integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==" + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } }, - "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "ansi-escape-sequences": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", + "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "argv-tools": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/argv-tools/-/argv-tools-0.1.1.tgz", + "integrity": "sha512-Cc0dBvx4dvrjjKpyDA6w8RlNAw8Su30NvZbWl/Tv9ZALEVlLVkWQiHMi84Q0xNfpVuSaiQbYkdmWK8g1PLGhKw==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "find-replace": "^2.0.1" + } + }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", @@ -275,11 +342,112 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "basic-auth": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", @@ -290,26 +458,233 @@ "repeat-element": "^1.1.2" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, "builtin-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz", - "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz", + "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==" + }, + "byte-size": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-4.0.4.tgz", + "integrity": "sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw==", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "requires": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + } + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cli-commands": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cli-commands/-/cli-commands-0.4.0.tgz", + "integrity": "sha512-zAvJlR7roeMgpUIhMDYATYL90vz+9ffuyPr0+qq4LzcZ0Jq+gM+H1KdYKxerc6U2nhitiDEx79YiJlXdrooEOA==", + "dev": true, + "requires": { + "command-line-args": "^5.0.2", + "command-line-commands": "^2.0.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "co-body": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.0.0.tgz", + "integrity": "sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw==", + "dev": true, + "requires": { + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "command-line-args": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.2.tgz", + "integrity": "sha512-/qPcbL8zpqg53x4rAaqMFlRV4opN3pbla7I7k9x8kyOBMQoGT6WltjN6sXZuxOXw6DgdK7Ad+ijYS5gjcr7vlA==", + "dev": true, + "requires": { + "argv-tools": "^0.1.1", + "array-back": "^2.0.0", + "find-replace": "^2.0.1", + "lodash.camelcase": "^4.3.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "command-line-commands": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/command-line-commands/-/command-line-commands-2.0.1.tgz", + "integrity": "sha512-m8c2p1DrNd2ruIAggxd/y6DgygQayf6r8RHwchhXryaLF8I6koYjoYroVP+emeROE9DXN5b9sP1Gh+WtvTTdtQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "command-line-usage": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.5.tgz", + "integrity": "sha512-d8NrGylA5oCXSbGoKz05FkehDAzSmIm4K03S5VDh4d5lZAtTWfc3D1RuETtuQCn8129nYfJfDdF7P/lwcz1BlA==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "chalk": "^2.4.1", + "table-layout": "^0.4.3", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, - "commandpost": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.3.0.tgz", - "integrity": "sha512-T62tyrmYTkaRDbV2z1k2yXTyxk0cFptXYwo1cUbnfHtp7ThLgQ9/90jG1Ym5WLZgFhvOTaHA5VSARWJ9URpLDw==", + "common-log-format": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/common-log-format/-/common-log-format-0.1.4.tgz", + "integrity": "sha512-BXcgq+wzr2htmBmnT7cL7YHzPAWketWbr4kozjoM9kWe4sk3+zMgjcH0HO+EddjDlEw2LZysqLpVRwbF318tDw==", + "dev": true + }, + "compressible": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", + "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "dev": true, + "requires": { + "mime-db": ">= 1.36.0 < 2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookies": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.2.tgz", + "integrity": "sha512-J2JjH9T3PUNKPHknprxgCrCaZshIfxW2j49gq1E1CP5Micj1LppWAR2y9EHSQAzEiX84zOsScWNwUZ0b/ChlMw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "keygrip": "~1.0.2" + } + }, + "copy-to": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", + "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "d3": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-5.5.0.tgz", - "integrity": "sha512-HRDSYvT3n7kMvJH7Avp7iR0Xsz97bkCFka9aOg04EdyXyiAP8yQzUpLH3712y9R7ffVo1g94t1OYFHBB0yI9vQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.7.0.tgz", + "integrity": "sha512-8KEIfx+dFm8PlbJN9PI0suazrZ41QcaAufsKE9PRcqYPWLngHIyWJZX96n6IQKePGgeSu0l7rtlueSSNq8Zc3g==", "requires": { "d3-array": "1", "d3-axis": "1", @@ -345,19 +720,19 @@ } }, "d3-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" }, "d3-axis": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", - "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" }, "d3-brush": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", - "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz", + "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==", "requires": { "d3-dispatch": "1", "d3-drag": "1", @@ -367,50 +742,50 @@ } }, "d3-chord": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", - "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", "requires": { "d3-array": "1", "d3-path": "1" } }, "d3-collection": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", - "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" }, "d3-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.0.tgz", - "integrity": "sha512-dmL9Zr/v39aSSMnLOTd58in2RbregCg4UtGyUArvEKTTN6S3HKEy+ziBWVYo9PTzRyVW+pUBHUtRKz0HYX+SQg==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", + "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" }, "d3-contour": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.0.tgz", - "integrity": "sha512-6zccxidQRtcydx0lWqHawdW1UcBzKZTxv0cW90Dlx98pY/L7GjQJmftH1tWopYFDaLCoXU0ECg9x/z2EuFT8tg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", "requires": { "d3-array": "^1.1.1" } }, "d3-dispatch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz", + "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" }, "d3-drag": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", + "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", "requires": { "d3-dispatch": "1", "d3-selection": "1" } }, "d3-dsv": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", - "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.10.tgz", + "integrity": "sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g==", "requires": { "commander": "2", "iconv-lite": "0.4", @@ -418,22 +793,22 @@ } }, "d3-ease": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz", + "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==" }, "d3-fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.0.tgz", - "integrity": "sha512-j+V4vtT6dceQbcKYLtpTueB8Zvc+wb9I93WaFtEQIYNADXl0c1ZJMN3qQo0CssiTsAqK8pePwc7f4qiW+b0WOg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", + "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", "requires": { "d3-dsv": "1" } }, "d3-force": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", - "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.2.tgz", + "integrity": "sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw==", "requires": { "d3-collection": "1", "d3-dispatch": "1", @@ -442,55 +817,55 @@ } }, "d3-format": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.0.tgz", - "integrity": "sha512-ycfLEIzHVZC3rOvuBOKVyQXSiUyCDjeAPIj9n/wugrr+s5AcTQC2Bz6aKkubG7rQaQF0SGW/OV4UEJB9nfioFg==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", + "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" }, "d3-geo": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.10.0.tgz", - "integrity": "sha512-VK/buVGgexthTTqGRNXQ/LSo3EbOFu4p2Pjud5drSIaEnOaF2moc8A3P7WEljEO1JEBEwbpAJjFWMuJiUtoBcw==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz", + "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==", "requires": { "d3-array": "1" } }, "d3-hierarchy": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.6.tgz", - "integrity": "sha512-nn4bhBnwWnMSoZgkBXD7vRyZ0xVUsNMQRKytWYHhP1I4qHw+qzApCTgSQTZqMdf4XXZbTMqA59hFusga+THA/g==" + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", + "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==" }, "d3-interpolate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.2.0.tgz", - "integrity": "sha512-zLvTk8CREPFfc/2XglPQriAsXkzoRDAyBzndtKJWrZmHw7kmOWHNS11e40kPTd/oGk8P5mFJW5uBbcFQ+ybxyA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", + "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", "requires": { "d3-color": "1" } }, "d3-path": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", - "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", + "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" }, "d3-polygon": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", - "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz", + "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==" }, "d3-quadtree": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", - "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.5.tgz", + "integrity": "sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ==" }, "d3-random": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", - "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" }, "d3-scale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.0.tgz", - "integrity": "sha512-Bb2N3ZgzPdKVEoWGkt8lPV6R7YdpSBWI70Xf26NQHOVjs77a6gLUmBOOPt9d9nB8JiQhwXY1RHCa+eSyWCJZIQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz", + "integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==", "requires": { "d3-array": "^1.2.0", "d3-collection": "1", @@ -501,49 +876,49 @@ } }, "d3-scale-chromatic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.0.tgz", - "integrity": "sha512-YwMbiaW2bStWvQFByK8hA6hk7ToWflspIo2TRukCqERd8isiafEMBXmwfh8c7/0Z94mVvIzIveRLVC6RAjhgeA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz", + "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==", "requires": { "d3-color": "1", "d3-interpolate": "1" } }, "d3-selection": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", - "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", + "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" }, "d3-shape": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", - "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", + "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", "requires": { "d3-path": "1" } }, "d3-time": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.10.tgz", + "integrity": "sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g==" }, "d3-time-format": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", - "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz", + "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==", "requires": { "d3-time": "1" } }, "d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz", + "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==" }, "d3-transition": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.3.tgz", + "integrity": "sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA==", "requires": { "d3-color": "1", "d3-dispatch": "1", @@ -554,14 +929,14 @@ } }, "d3-voronoi": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" }, "d3-zoom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==", "requires": { "d3-dispatch": "1", "d3-drag": "1", @@ -570,25 +945,120 @@ "d3-transition": "1" } }, - "editorconfig": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz", - "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "@types/commander": "^2.11.0", - "@types/semver": "^5.4.0", - "commander": "^2.11.0", - "lru-cache": "^4.1.1", - "semver": "^5.4.1", - "sigmund": "^1.0.1" + "ms": "2.0.0" } }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true, + "optional": true + }, + "defer-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defer-promise/-/defer-promise-1.0.1.tgz", + "integrity": "sha1-HKb/7dvO8XFd16riXHYW+a4iky8=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "error-inject": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz", + "integrity": "sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "estree-walker": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==" }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -630,6 +1100,16 @@ "repeat-string": "^1.5.2" } }, + "find-replace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-2.0.1.tgz", + "integrity": "sha512-LzDo3Fpa30FLIBsh6DCDnMN1KW2g4QKkqKmejlImgWY67dDFPX/x9Kh/op/GK522DchQXEvDi/wD48HKW49XOQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "test-value": "^3.0.0" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -643,16 +1123,48 @@ "for-in": "^1.0.1" } }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", + "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -671,9 +1183,59 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "http-assert": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.0.tgz", + "integrity": "sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "http-errors": "~1.7.1" + } + }, + "http-errors": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz", + "integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } }, "iconv-lite": { "version": "0.4.23", @@ -683,6 +1245,28 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "inflation": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", + "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -711,6 +1295,12 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" }, + "is-generator-function": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", + "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==", + "dev": true + }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -742,6 +1332,12 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -755,6 +1351,38 @@ "isarray": "1.0.0" } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.0" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -763,6 +1391,18 @@ "graceful-fs": "^4.1.6" } }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "keygrip": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", + "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -771,21 +1411,554 @@ "is-buffer": "^1.1.5" } }, - "lru-cache": { + "koa": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.6.1.tgz", + "integrity": "sha512-n9R5Eex4y0drUeqFTeCIeXyz8wjr2AxBo2Cq8LvmiXbJl4yDA5KIrecMPkhnmgACZnPXMRyCLbJoyLmpM9aFAw==", + "dev": true, + "requires": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.7.1", + "debug": "~3.1.0", + "delegates": "^1.0.0", + "depd": "^1.1.2", + "destroy": "^1.0.4", + "error-inject": "^1.0.0", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^1.2.0", + "koa-is-json": "^1.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + } + }, + "koa-bodyparser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/koa-bodyparser/-/koa-bodyparser-4.2.1.tgz", + "integrity": "sha512-UIjPAlMZfNYDDe+4zBaOAUKYqkwAGcIU6r2ARf1UOXPAlfennQys5IiShaVeNf7KkVBlf88f2LeLvBFvKylttw==", + "dev": true, + "requires": { + "co-body": "^6.0.0", + "copy-to": "^2.0.1" + } + }, + "koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true + }, + "koa-compress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-compress/-/koa-compress-2.0.0.tgz", + "integrity": "sha1-e36ykhuEd0a14SK6n1zYpnHo6jo=", + "dev": true, + "requires": { + "bytes": "^2.3.0", + "compressible": "^2.0.0", + "koa-is-json": "^1.0.0", + "statuses": "^1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", + "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=", + "dev": true + } + } + }, + "koa-conditional-get": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-conditional-get/-/koa-conditional-get-2.0.0.tgz", + "integrity": "sha1-pD83I8HQFLcwo07Oit8wuTyCM/I=", + "dev": true + }, + "koa-convert": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", + "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", + "dev": true, + "requires": { + "co": "^4.6.0", + "koa-compose": "^3.0.0" + }, + "dependencies": { + "koa-compose": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", + "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "dev": true, + "requires": { + "any-promise": "^1.1.0" + } + } + } + }, + "koa-etag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-3.0.0.tgz", + "integrity": "sha1-nvc4Ld1agqsN6xU0FckVg293HT8=", + "dev": true, + "requires": { + "etag": "^1.3.0", + "mz": "^2.1.0" + } + }, + "koa-is-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", + "integrity": "sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=", + "dev": true + }, + "koa-json": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/koa-json/-/koa-json-2.0.2.tgz", + "integrity": "sha1-Nq8U5uofXWRtfESihXAcb4Wk/eQ=", + "dev": true, + "requires": { + "koa-is-json": "1", + "streaming-json-stringify": "3" + } + }, + "koa-mock-response": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/koa-mock-response/-/koa-mock-response-0.2.0.tgz", + "integrity": "sha512-HmybRN1a3WqcSFvf7tycu2YhBIEHeqzm8bwcsShNWGsTgP86coZOpdI8aqYm/1DFsAQMctnpdWrva4rDr1Pibg==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "path-to-regexp": "^1.7.0", + "typical": "^2.6.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "koa-morgan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/koa-morgan/-/koa-morgan-1.0.1.tgz", + "integrity": "sha1-CAUuDODYOdPEMXi5CluzQkvvH5k=", + "dev": true, + "requires": { + "morgan": "^1.6.1" + } + }, + "koa-range": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/koa-range/-/koa-range-0.3.0.tgz", + "integrity": "sha1-NYjjSWRzqDmhvSZNKkKx2FvX/qw=", + "dev": true, + "requires": { + "stream-slice": "^0.1.2" + } + }, + "koa-rewrite-75lb": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/koa-rewrite-75lb/-/koa-rewrite-75lb-2.1.1.tgz", + "integrity": "sha512-i9ofDKLs0xNCb2PW7wKGFzBFX6+Ce3aKoZzNKPh0fkejeUOTWkkDqnjXrgqrJEP2ifX6WWsHp6VtGuXzSYLSWQ==", + "dev": true, + "requires": { + "path-to-regexp": "1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "koa-route": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/koa-route/-/koa-route-3.2.0.tgz", + "integrity": "sha1-dimLmaa8+p44yrb+XHmocz51i84=", + "dev": true, + "requires": { + "debug": "*", + "methods": "~1.1.0", + "path-to-regexp": "^1.2.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "koa-send": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "resolved": "http://registry.npmjs.org/koa-send/-/koa-send-4.1.3.tgz", + "integrity": "sha512-3UetMBdaXSiw24qM2Mx5mKmxLKw5ZTPRjACjfhK6Haca55RKm9hr/uHDrkrxhSl5/S1CKI/RivZVIopiatZuTA==", + "dev": true, + "requires": { + "debug": "^2.6.3", + "http-errors": "^1.6.1", + "mz": "^2.6.0", + "resolve-path": "^1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "koa-static": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-4.0.3.tgz", + "integrity": "sha512-JGmxTuPWy4bH7bt6gD/OMWkhprawvRmzJSr8TWKmTL4N7+IMv3s0SedeQi5S4ilxM9Bo6ptkCyXj/7wf+VS5tg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "koa-send": "^4.1.3" + } + }, + "load-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-module/-/load-module-1.0.0.tgz", + "integrity": "sha512-FmoAJI/RM4vmvIRk65g/SFCnGQC9BbALY3zy38Z0cMllNnra1+iCdxAf051LVymzE60/FweOo9or9XJiGgFshg==", + "dev": true, + "requires": { + "array-back": "^2.0.0" + } + }, + "local-web-server": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/local-web-server/-/local-web-server-2.6.0.tgz", + "integrity": "sha512-m7Z5zlzZFxMyiK1W8xR5TJMh00Fy9z7Po8vilSQCpeU4LG2VMK667xCkASBUepFR9fPj6heUMBHu9P/TrwDqFw==", + "dev": true, + "requires": { + "lws": "^1.3.0", + "lws-basic-auth": "^0.1.1", + "lws-blacklist": "^0.3.0", + "lws-body-parser": "^0.2.4", + "lws-compress": "^0.2.1", + "lws-conditional-get": "^0.3.4", + "lws-cors": "^1.0.0", + "lws-index": "^0.4.0", + "lws-json": "^0.3.2", + "lws-log": "^0.3.2", + "lws-mime": "^0.2.2", + "lws-mock-response": "^0.5.1", + "lws-range": "^1.1.0", + "lws-request-monitor": "^0.1.5", + "lws-rewrite": "^0.4.1", + "lws-spa": "^0.3.0", + "lws-static": "^0.5.0", + "node-version-matches": "^1.0.0" + } + }, + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "dev": true + }, + "lws": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/lws/-/lws-1.3.0.tgz", + "integrity": "sha512-2gOJzVtgjg4mA1cyWnzkICR/NLuMD24sbRSwQeVZeVkadp0VOKTlpmnjvA1tQpkb1TGrcOS+N+3vKMJST8tt2w==", + "dev": true, + "requires": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "byte-size": "^4.0.3", + "cli-commands": "^0.4.0", + "command-line-args": "^5.0.2", + "command-line-usage": "^5.0.5", + "koa": "^2.5.2", + "load-module": "^1.0.0", + "lodash.assignwith": "^4.2.0", + "node-version-matches": "^1.0.0", + "opn": "^5.3.0", + "reduce-flatten": "^2.0.0", + "typical": "^3.0.0", + "walk-back": "^3.0.0", + "ws": "^5.2.1" + } + }, + "lws-basic-auth": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/lws-basic-auth/-/lws-basic-auth-0.1.1.tgz", + "integrity": "sha512-npPpqkOFzJzB9yJ2pGXmiYOswH+0n86ro75WhromeGuNo0GfE18ZLI/VCOVWmBbeXp2pcnPIMUAdkNSgukpAww==", + "dev": true, + "requires": { + "basic-auth": "^1.1.0" + } + }, + "lws-blacklist": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/lws-blacklist/-/lws-blacklist-0.3.0.tgz", + "integrity": "sha512-ZA8dujYaZwRNMBhgP+oGsZi9tum44Ba6VHsA3JrV1JVrjZ8c65kLaO/41rLBqQDKP3SDPu7dLity4YLwe1FuNQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "path-to-regexp": "^2.2.0" + } + }, + "lws-body-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/lws-body-parser/-/lws-body-parser-0.2.4.tgz", + "integrity": "sha512-XKJzbzK97TUsewIPA5J2RpEk7kRoJcL+/Du6JlwzqIq84tWuXMfiT2a4Ncj12+tRWrdY2avV6d8uLhqlHLz1yg==", + "dev": true, + "requires": { + "koa-bodyparser": "^4.2.0" + } + }, + "lws-compress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lws-compress/-/lws-compress-0.2.1.tgz", + "integrity": "sha512-14++1o6U8upi3DLx9J2O2sFELsijEJF9utoFxSH4Stoo9SdU2Cxw6BtqQTrb9SEA6O6IsApzstdMYnq8floLSg==", + "dev": true, + "requires": { + "koa-compress": "^2.0.0" + } + }, + "lws-conditional-get": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/lws-conditional-get/-/lws-conditional-get-0.3.4.tgz", + "integrity": "sha512-6asZSfM747snhdz4xexRllm09pebz8pjYeg2d5khLR53D/OJznZWHsIqW0JGiScJObri2D7+H4z7yRLBjokT7g==", + "dev": true, + "requires": { + "koa-conditional-get": "^2.0.0", + "koa-etag": "^3.0.0" + } + }, + "lws-cors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lws-cors/-/lws-cors-1.0.0.tgz", + "integrity": "sha512-4C0m4lvYdAnpAa03tr9AqziB4d8SRPh4beQBuzPiefv7N9/tpVdrl9kgXrUe1hLHhISnVJ5MoOZuZ6wFeMiU4g==", + "dev": true, + "requires": { + "@koa/cors": "^2.2.1" + } + }, + "lws-index": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/lws-index/-/lws-index-0.4.0.tgz", + "integrity": "sha512-k+mkqgMSzx1ipzVpaxsAJU4Qe7R1kp1B/u+qC+d1Y3l+auBz+bLcIxL4dYKfaxLqiz0IFwg1dZwGzVm/dd7FFw==", + "dev": true, + "requires": { + "serve-index-75lb": "^2.0.0" + } + }, + "lws-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/lws-json/-/lws-json-0.3.2.tgz", + "integrity": "sha512-ElmCA8hi3GPMfxbtiI015PDHuJovhhcbXX/qTTTifXhopedAzIBzn/rF5dHZHE4k7HQDYfbiaPgPMbmpv9dMvQ==", + "dev": true, + "requires": { + "koa-json": "^2.0.2" + } + }, + "lws-log": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/lws-log/-/lws-log-0.3.2.tgz", + "integrity": "sha512-DRp4bFl4a7hjwR/RjARjhFLEXs8pIeqKbUvojaAl1hhfRBuW2JsDxRSKC+ViQN06CW4Qypg3ZsztMMR8dRO8dA==", + "dev": true, + "requires": { + "koa-morgan": "^1.0.1", + "stream-log-stats": "^2.0.2" + } + }, + "lws-mime": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lws-mime/-/lws-mime-0.2.2.tgz", + "integrity": "sha512-cWBj9CuuSvvaqdYMPiXRid0QhzJmr+5gWAA96pEDOiW8tMCMoxl7CIgTpHXZwhJzCqdI84RZDVm+FswByATS5w==", + "dev": true + }, + "lws-mock-response": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/lws-mock-response/-/lws-mock-response-0.5.1.tgz", + "integrity": "sha512-4R5Q1RmRglC0pqEwywrS5g62aKaLQsteMnShGmWU9aQ/737Bq0/3qbQ3mb8VbMk3lLzo3ZaNZ1DUsPgVvZaXNQ==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "array-back": "^2.0.0", + "koa-mock-response": "0.2.0", + "load-module": "^1.0.0", + "reduce-flatten": "^2.0.0" } }, + "lws-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lws-range/-/lws-range-1.1.0.tgz", + "integrity": "sha512-Mpx6FdO58Z4l6DAXlATsC2zm10QvyGYElQvFd7P1xqUSTPoYG0wAxfjlpqI+Qdb2O7W4Ah21yESVnPEwae3SIw==", + "dev": true, + "requires": { + "koa-range": "^0.3.0" + } + }, + "lws-request-monitor": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/lws-request-monitor/-/lws-request-monitor-0.1.5.tgz", + "integrity": "sha512-u9eczHPowH17ftUjQ8ysutGDADNZdDD6k8wgFMzOB7/rRq1Is12lTYA4u8pfKZ8C2oyoy+HYsDSrOzTwespTlA==", + "dev": true, + "requires": { + "byte-size": "^4.0.2" + } + }, + "lws-rewrite": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/lws-rewrite/-/lws-rewrite-0.4.1.tgz", + "integrity": "sha512-EHUdbqfdwc4Baa7iXOdG2y815WC040Cing1GwhM9VsBL7lHtZ7zl3EHzjWFv3styoO3qNqZ4W0xCey4hoo/aYg==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "koa-rewrite-75lb": "^2.1.1", + "koa-route": "^3.2.0", + "path-to-regexp": "^1.7.0", + "req-then": "^0.6.4", + "stream-read-all": "^0.1.2", + "typical": "^2.6.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "lws-spa": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/lws-spa/-/lws-spa-0.3.0.tgz", + "integrity": "sha512-8wxZl5dOI/CQsJ6oOG8Y7B4khjlQXfB7GlVkjYFPuOYM+JIw/QzMvezKjKweG0qGePmHJVHWa38+CyololV4aw==", + "dev": true, + "requires": { + "koa-route": "^3.2.0", + "koa-send": "^4.1.3" + } + }, + "lws-static": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/lws-static/-/lws-static-0.5.0.tgz", + "integrity": "sha512-r3QIeJfBox/hSJLSL7TPhNSZsTKE0r4mWYHbGZ+DwrBcKbLt1ljsh5NAtmJpsqCcjYpyOuD/DlsZ0yQY9VI8bA==", + "dev": true, + "requires": { + "koa-static": "^4.0.2" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "math-random": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" }, + "media-typer": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -806,6 +1979,137 @@ "regex-cache": "^0.4.2" } }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "dev": true, + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "dependencies": { + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "node-version-matches": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-version-matches/-/node-version-matches-1.0.0.tgz", + "integrity": "sha512-E1OQnAUB+BvEyNTXTWpUUMAWXYCa7yjiS64djOuTJEkm20yaQfNmWTfx/kvN6nC7fc0GQS182IaefOPxQvpxXg==", + "dev": true, + "requires": { + "semver": "^5.5.0" + } + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -814,6 +2118,12 @@ "remove-trailing-separator": "^1.0.1" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -823,6 +2133,45 @@ "is-extendable": "^0.1.1" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=", + "dev": true + }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -834,31 +2183,56 @@ "is-glob": "^2.0.0" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" }, - "pegjs": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=" + "path-to-regexp": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz", + "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "requires": { "is-number": "^4.0.0", "kind-of": "^6.0.0", @@ -877,6 +2251,53 @@ } } }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -891,15 +2312,36 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "req-then": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/req-then/-/req-then-0.6.4.tgz", + "integrity": "sha512-Uf7xsK1qPqPUetESHemNQ7nGtgOxngSFtlcAOOkx0lDAo+XRZpEA9QDrGBdyOfGq4b+a0z/D5gR2VJ+pp/dzBA==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "defer-promise": "^1.0.1", + "lodash.pick": "^4.4.0", + "stream-read-all": "^0.1.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -908,40 +2350,64 @@ "path-parse": "^1.0.5" } }, + "resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=", + "dev": true, + "requires": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, "rollup": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.62.0.tgz", - "integrity": "sha512-mZS0aIGfYzuJySJD78znu9/hCJsNfBzg4lDuZGMj0hFVcYHt2evNRHv8aqiu9/w6z6Qn8AQoVl4iyEjDmisGeA==", + "version": "0.68.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.68.2.tgz", + "integrity": "sha512-WgjNCXYv7ZbtStIap1+tz4pd2zwz0XYN//OILwEY6dINIFLVizK1iWdu+ZtUURL/OKnp8Lv2w8FBds8YihzX7Q==", "requires": { "@types/estree": "0.0.39", "@types/node": "*" } }, "rollup-plugin-node-resolve": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz", - "integrity": "sha512-9zHGr3oUJq6G+X0oRMYlzid9fXicBdiydhwGChdyeNRGPcN/majtegApRKHLR5drboUvEWU+QeUmGTyEZQs3WA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.0.tgz", + "integrity": "sha512-7Ni+/M5RPSUBfUaP9alwYQiIKnKeXCOHiqBpKUl9kwp3jX5ZJtgXAait1cne6pGEVUUztPD6skIKH9Kq9sNtfw==", "requires": { - "builtin-modules": "^2.0.0", + "builtin-modules": "^3.0.0", "is-module": "^1.0.0", - "resolve": "^1.1.6" + "resolve": "^1.8.1" } }, "rollup-plugin-typescript2": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.15.1.tgz", - "integrity": "sha512-lJ/yfIj1fmp0KyfgPmd2QFeRpLgXlc58fS3Ha9Loc7/p3qByDL7CRndcI9MflE/pUSrfUdDjZMR0mHSKvqrZ+g==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.18.1.tgz", + "integrity": "sha512-aR2m5NCCAUV/KpcKgCWX6Giy8rTko9z92b5t0NX9eZyjOftCvcdDFa1C9Ze/9yp590hnRymr5hG0O9SAXi1oUg==", "requires": { - "fs-extra": "^5.0.0", - "resolve": "^1.7.1", - "rollup-pluginutils": "^2.0.1", - "tslib": "1.9.2" + "fs-extra": "7.0.0", + "resolve": "1.8.1", + "rollup-pluginutils": "2.3.3", + "tslib": "1.9.3" } }, "rollup-pluginutils": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.0.tgz", - "integrity": "sha512-xB6hsRsjdJdIYWEyYUJy/3ki5g69wrf0luHPGNK3ZSocV6HLNfio59l3dZ3TL4xUwEKgROhFi9jOCt6c5gfUWw==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz", + "integrity": "sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA==", "requires": { "estree-walker": "^0.5.2", "micromatch": "^2.3.11" @@ -952,6 +2418,12 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -963,42 +2435,444 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "serve-index-75lb": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/serve-index-75lb/-/serve-index-75lb-2.0.1.tgz", + "integrity": "sha512-/d9r8bqJlFQcwy0a0nb1KnWAA+Mno+V+VaoKocdkbW5aXKRQd/+4bfnRhQRQr6uEoYwTRJ4xgztOyCJvWcpBpQ==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.18", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-log-stats": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-log-stats/-/stream-log-stats-2.0.2.tgz", + "integrity": "sha512-b1LccxXhMlOQQrzSqapQHyZ3UI00QTAv+8VecFgsJz//sGB5LFl/+mkFeWBVVI2/E4DlCT4sGgvLExB/VTVFfA==", + "dev": true, + "requires": { + "JSONStream": "^1.3.1", + "ansi-escape-sequences": "^3.0.0", + "byte-size": "^3.0.0", + "common-log-format": "~0.1.3", + "lodash.throttle": "^4.1.1", + "stream-via": "^1.0.3", + "table-layout": "~0.4.0" + }, + "dependencies": { + "ansi-escape-sequences": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-3.0.0.tgz", + "integrity": "sha1-HBg5S2r5t2/5pjUJ+kl2af0s5T4=", + "dev": true, + "requires": { + "array-back": "^1.0.3" + } + }, + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + }, + "byte-size": { + "version": "3.0.0", + "resolved": "http://registry.npmjs.org/byte-size/-/byte-size-3.0.0.tgz", + "integrity": "sha1-QG+eI2aqXav2NnLrKR17sJSV2nU=", + "dev": true + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "stream-read-all": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-0.1.2.tgz", + "integrity": "sha512-KX42xBg853m+KnwRtwCKT95ShopAbY/MNKs2dBQ0WkNeuJdqgQYRtGRbTlxdx0L6t979h3z/wMq2eMSAu7Tygw==", + "dev": true + }, + "stream-slice": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", + "integrity": "sha1-LcT04bk2+xPz6zmi3vGTJ5jQeks=", + "dev": true + }, + "stream-via": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", + "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", + "dev": true + }, + "streaming-json-stringify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/streaming-json-stringify/-/streaming-json-stringify-3.1.0.tgz", + "integrity": "sha1-gCAEN6mTzDnE/gAmO3s7kDrIevU=", + "dev": true, + "requires": { + "json-stringify-safe": "5", + "readable-stream": "2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "optional": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table-layout": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.4.tgz", + "integrity": "sha512-uNaR3SRMJwfdp9OUr36eyEi6LLsbcTqTO/hfTsNviKsNeyMBPICJCC7QXRF3+07bAP6FRwA8rczJPBqXDc0CkQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "deep-extend": "~0.6.0", + "lodash.padend": "^4.6.1", + "typical": "^2.6.1", + "wordwrapjs": "^3.0.0" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "test-value": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", + "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "typical": "^2.6.1" + }, + "dependencies": { + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "ts-mocha": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-2.0.0.tgz", + "integrity": "sha512-Rj6+vvwKtOTs5GsNO1jLl4DIXUGnyAg5HFt2Yb4SHIRN45clTJkHWpNdTxCSL0u+1oeavSYJah6d1PZ++Ju5pw==", + "dev": true, + "requires": { + "ts-node": "7.0.0", + "tsconfig-paths": "^3.5.0" + } + }, + "ts-node": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.0.tgz", + "integrity": "sha512-klJsfswHP0FuOLsvBZ/zzCfUvakOSSxds78mVeK7I+qP76YWtxf16hEZsp3U+b0kIo82R5UatGFeblYMqabb2Q==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + } + }, + "tsconfig-paths": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.6.0.tgz", + "integrity": "sha512-mrqQIP2F4e03aMTCiPdedCIT300//+q0ET53o5WqqtQjmEICxP9yfz/sHTpPqXpssuJEzODsEzJaLRaf5J2X1g==", + "dev": true, + "optional": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, "tslib": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", - "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==" + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "tslint": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.0.tgz", + "integrity": "sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + } + } }, - "typescript": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.1.tgz", - "integrity": "sha512-h6pM2f/GDchCFlldnriOhs1QHuwbnmj6/v7499eMHqPeW4V2G0elua2eIc2nu8v2NdHV0Gm+tzX83Hr6nUFjQA==", + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "typescript-formatter": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz", - "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==", + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "dev": true, "requires": { - "commandpost": "^1.0.0", - "editorconfig": "^0.15.0" + "media-typer": "0.3.0", + "mime-types": "~2.1.18" } }, + "typescript": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", + "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", + "dev": true + }, + "typical": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-3.0.0.tgz", + "integrity": "sha512-2/pGDQD/q1iJWlrj357aEKGIlRvHirm81x04lsg51hreiohy2snAXoFc9dIHFWEx9LsfOVA5K7lUGM9rcUqwlQ==", + "dev": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "walk-back": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.0.tgz", + "integrity": "sha1-I1h4ejXakQMtrV6S+AsSNw2HlcU=", + "dev": true + }, + "wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "dev": true, + "requires": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "dependencies": { + "reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "dev": true + }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "ylru": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", "dev": true } } diff --git a/deps/v8/tools/turbolizer/package.json b/deps/v8/tools/turbolizer/package.json index 1d8efc5286..ae354ba393 100644 --- a/deps/v8/tools/turbolizer/package.json +++ b/deps/v8/tools/turbolizer/package.json @@ -4,26 +4,31 @@ "description": "Visualization tool for V8 TurboFan IR graphs", "scripts": { "build": "rollup -c", - "watch": "tsc --watch", + "watch": "rollup -c -w", "deploy": "./deploy.sh", - "format": "tsfmt -r" + "test": "ts-mocha -p tsconfig.test.json test/**/*-test.ts", + "dev-server": "ws", + "presubmit": "tslint --project ./tslint.json --fix" }, "author": "The V8 team", "license": "MIT", "dependencies": { - "@types/d3": "^5.0.0", - "d3": "^5.5.0", - "pegjs": "^0.10.0", - "rollup": "^0.62.0", - "rollup-plugin-node-resolve": "^3.3.0", - "rollup-plugin-typescript2": "^0.15.1" + "@types/d3": "^5.5.0", + "d3": "^5.7.0", + "rollup": "^0.68.2", + "rollup-plugin-node-resolve": "^4.0.0", + "rollup-plugin-typescript2": "^0.18.1" }, "repository": { "type": "git", "url": "https://github.com/v8/v8.git" }, "devDependencies": { - "typescript": "^2.9.1", - "typescript-formatter": "^7.2.2" + "chai": "^4.2.0", + "local-web-server": "^2.6.0", + "mocha": "^5.2.0", + "ts-mocha": "^2.0.0", + "typescript": "^3.2.2", + "tslint": "^5.12.0" } } diff --git a/deps/v8/tools/turbolizer/rollup.config.js b/deps/v8/tools/turbolizer/rollup.config.js index bb34555a7d..05b69b8515 100644 --- a/deps/v8/tools/turbolizer/rollup.config.js +++ b/deps/v8/tools/turbolizer/rollup.config.js @@ -5,8 +5,28 @@ import typescript from 'rollup-plugin-typescript2'; import node from 'rollup-plugin-node-resolve'; +import path from 'path' + +const onwarn = warning => { + // Silence circular dependency warning for moment package + const node_modules = path.normalize('node_modules/'); + if (warning.code === 'CIRCULAR_DEPENDENCY' && + !warning.importer.indexOf(node_modules)) { + return + } + + console.warn(`(!) ${warning.message}`) +} + export default { input: "src/turbo-visualizer.ts", - plugins: [node(), typescript({abortOnError:false})], - output: {file: "build/turbolizer.js", format: "iife", sourcemap: true} + plugins: [node(), typescript({ + abortOnError: false + })], + output: { + file: "build/turbolizer.js", + format: "iife", + sourcemap: true + }, + onwarn: onwarn }; diff --git a/deps/v8/tools/turbolizer/src/code-view.ts b/deps/v8/tools/turbolizer/src/code-view.ts index 5975ff7a60..298f08b01d 100644 --- a/deps/v8/tools/turbolizer/src/code-view.ts +++ b/deps/v8/tools/turbolizer/src/code-view.ts @@ -2,16 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Source,SourceResolver,sourcePositionToStringKey} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {View} from "./view.js" -import {MySelection} from "./selection.js" -import {anyToString,ViewElements} from "./util.js" +import { Source, SourceResolver, sourcePositionToStringKey } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { View } from "../src/view"; +import { MySelection } from "../src/selection"; +import { ViewElements } from "../src/util"; +import { SelectionHandler } from "./selection-handler"; export enum CodeMode { MAIN_SOURCE = "main function", INLINED_SOURCE = "inlined function" -}; +} export class CodeView extends View { broker: SelectionBroker; @@ -29,11 +30,10 @@ export class CodeView extends View { return sourceContainer; } - constructor(parentId, broker, sourceResolver, sourceFunction, codeMode: CodeMode) { - super(parentId); - let view = this; + constructor(parent: HTMLElement, broker: SelectionBroker, sourceResolver: SourceResolver, sourceFunction: Source, codeMode: CodeMode) { + super(parent); + const view = this; view.broker = broker; - view.source = null; view.sourceResolver = sourceResolver; view.source = sourceFunction; view.codeMode = codeMode; @@ -44,11 +44,11 @@ export class CodeView extends View { clear: function () { view.selection.clear(); view.updateSelection(); - broker.broadcastClear(this) + broker.broadcastClear(this); }, select: function (sourcePositions, selected) { const locations = []; - for (var sourcePosition of sourcePositions) { + for (const sourcePosition of sourcePositions) { locations.push(sourcePosition); sourceResolver.addInliningPositions(sourcePosition, locations); } @@ -62,7 +62,7 @@ export class CodeView extends View { for (const location of locations) { const translated = sourceResolver.translateToSourceId(view.source.sourceId, location); if (!translated) continue; - view.selection.select(translated, selected); + view.selection.select([translated], selected); } view.updateSelection(firstSelect); }, @@ -100,9 +100,6 @@ export class CodeView extends View { mkVisible.apply(scrollIntoView); } - initializeContent(data, rememberedSelection) { - } - getCodeHtmlElementName() { return `source-pre-${this.source.sourceId}`; } @@ -117,7 +114,6 @@ export class CodeView extends View { } onSelectLine(lineNumber: number, doClear: boolean) { - const key = anyToString(lineNumber); if (doClear) { this.selectionHandler.clear(); } @@ -127,7 +123,7 @@ export class CodeView extends View { } } - onSelectSourcePosition(sourcePosition, doClear) { + onSelectSourcePosition(sourcePosition, doClear: boolean) { if (doClear) { this.selectionHandler.clear(); } @@ -135,7 +131,7 @@ export class CodeView extends View { } initializeCode() { - var view = this; + const view = this; const source = this.source; const sourceText = source.sourceText; if (!sourceText) return; @@ -145,14 +141,14 @@ export class CodeView extends View { } else { sourceContainer.classList.add("inlined-source"); } - var codeHeader = document.createElement("div"); + const codeHeader = document.createElement("div"); codeHeader.setAttribute("id", this.getCodeHeaderHtmlElementName()); codeHeader.classList.add("code-header"); - var codeFileFunction = document.createElement("div"); + const codeFileFunction = document.createElement("div"); codeFileFunction.classList.add("code-file-function"); codeFileFunction.innerHTML = `${source.sourceName}:${source.functionName}`; codeHeader.appendChild(codeFileFunction); - var codeModeDiv = document.createElement("div"); + const codeModeDiv = document.createElement("div"); codeModeDiv.classList.add("code-mode"); codeModeDiv.innerHTML = `${this.codeMode}`; codeHeader.appendChild(codeModeDiv); @@ -160,7 +156,7 @@ export class CodeView extends View { clearDiv.style.clear = "both"; codeHeader.appendChild(clearDiv); sourceContainer.appendChild(codeHeader); - var codePre = document.createElement("pre"); + const codePre = document.createElement("pre"); codePre.setAttribute("id", this.getCodeHtmlElementName()); codePre.classList.add("prettyprint"); sourceContainer.appendChild(codePre); @@ -171,7 +167,7 @@ export class CodeView extends View { } else { codePre.style.display = "none"; } - } + }; if (sourceText != "") { codePre.classList.add("linenums"); codePre.textContent = sourceText; @@ -182,9 +178,17 @@ export class CodeView extends View { console.log(e); } - view.divNode.onclick = function (e) { - view.selectionHandler.clear(); - } + view.divNode.onclick = function (e: MouseEvent) { + if (e.target instanceof Element && e.target.tagName == "DIV") { + const targetDiv = e.target as HTMLDivElement; + if (targetDiv.classList.contains("line-number")) { + e.stopPropagation(); + view.onSelectLine(Number(targetDiv.dataset.lineNumber), !e.shiftKey); + } + } else { + view.selectionHandler.clear(); + } + }; const base: number = source.startPosition; let current = 0; @@ -197,13 +201,14 @@ export class CodeView extends View { currentLineElement.id = "li" + i; currentLineElement.dataset.lineNumber = "" + lineNumber; const spans = currentLineElement.childNodes; - for (let j = 0; j < spans.length; ++j) { - const currentSpan = spans[j]; - const pos = base + current; - const end = pos + currentSpan.textContent.length; - current += currentSpan.textContent.length; - this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust); - newlineAdjust = 0; + for (const currentSpan of spans) { + if (currentSpan instanceof HTMLSpanElement) { + const pos = base + current; + const end = pos + currentSpan.textContent.length; + current += currentSpan.textContent.length; + this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust); + newlineAdjust = 0; + } } this.insertLineNumber(currentLineElement, lineNumber); @@ -220,44 +225,44 @@ export class CodeView extends View { insertSourcePositions(currentSpan, lineNumber, pos, end, adjust) { const view = this; const sps = this.sourceResolver.sourcePositionsInRange(this.source.sourceId, pos - adjust, end); + let offset = 0; for (const sourcePosition of sps) { this.sourceResolver.addAnyPositionToLine(lineNumber, sourcePosition); - const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.firstChild : currentSpan; - const replacementNode = textnode.splitText(Math.max(0, sourcePosition.scriptOffset - pos)); + const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.lastChild : currentSpan; + if (!(textnode instanceof Text)) continue; + const splitLength = Math.max(0, sourcePosition.scriptOffset - pos - offset); + offset += splitLength; + const replacementNode = textnode.splitText(splitLength); const span = document.createElement('span'); span.setAttribute("scriptOffset", sourcePosition.scriptOffset); - span.classList.add("source-position") + span.classList.add("source-position"); const marker = document.createElement('span'); - marker.classList.add("marker") + 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`) + 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.onSelectSourcePosition(sourcePosition, !e.shiftKey); }; view.addHtmlElementToSourcePosition(sourcePosition, span); textnode.parentNode.insertBefore(span, replacementNode); } } - insertLineNumber(lineElement, lineNumber) { + insertLineNumber(lineElement: HTMLElement, lineNumber: number) { const view = this; const lineNumberElement = document.createElement("div"); lineNumberElement.classList.add("line-number"); - lineNumberElement.dataset.lineNumber = lineNumber; - lineNumberElement.innerText = lineNumber; - lineNumberElement.onclick = function (e) { - e.stopPropagation(); - view.onSelectLine(lineNumber, !e.shiftKey); - } - lineElement.insertBefore(lineNumberElement, lineElement.firstChild) + lineNumberElement.dataset.lineNumber = `${lineNumber}`; + lineNumberElement.innerText = `${lineNumber}`; + lineElement.insertBefore(lineNumberElement, lineElement.firstChild); // Don't add lines to source positions of not in backwardsCompatibility mode. if (this.source.backwardsCompatibility === true) { for (const sourcePosition of this.sourceResolver.linetoSourcePositions(lineNumber - 1)) { @@ -266,6 +271,4 @@ export class CodeView extends View { } } - deleteContent() { } - detachSelection() { return null; } } diff --git a/deps/v8/tools/turbolizer/src/disassembly-view.ts b/deps/v8/tools/turbolizer/src/disassembly-view.ts index 8142b2aa0d..4b8fc6ea2d 100644 --- a/deps/v8/tools/turbolizer/src/disassembly-view.ts +++ b/deps/v8/tools/turbolizer/src/disassembly-view.ts @@ -2,16 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {PROF_COLS, UNICODE_BLOCK} from "./constants.js" -import {SelectionBroker} from "./selection-broker.js" -import {TextView} from "./text-view.js" +import { PROF_COLS, UNICODE_BLOCK } from "../src/constants"; +import { SelectionBroker } from "../src/selection-broker"; +import { TextView } from "../src/text-view"; +import { MySelection } from "./selection"; +import { anyToString, interpolate } from "./util"; +import { InstructionSelectionHandler } from "./selection-handler"; + +const toolboxHTML = `<div id="disassembly-toolbox"> +<form> + <label><input id="show-instruction-address" type="checkbox" name="instruction-address">Show addresses</label> + <label><input id="show-instruction-binary" type="checkbox" name="instruction-binary">Show binary literal</label> +</form> +</div>`; export class DisassemblyView extends TextView { SOURCE_POSITION_HEADER_REGEX: any; - addr_event_counts: any; - total_event_counts: any; - max_event_counts: any; - pos_lines: Array<any>; + addrEventCounts: any; + totalEventCounts: any; + maxEventCounts: any; + posLines: Array<any>; + instructionSelectionHandler: InstructionSelectionHandler; + offsetSelection: MySelection; + showInstructionAddressHandler: () => void; + showInstructionBinaryHandler: () => void; createViewElement() { const pane = document.createElement('div'); @@ -21,222 +35,310 @@ export class DisassemblyView extends TextView { <ul id='disassembly-list' class='nolinenums noindent'> </ul> </pre>`; + return pane; } constructor(parentId, broker: SelectionBroker) { - super(parentId, broker, null); - let view = this; - const sourceResolver = broker.sourceResolver; - let ADDRESS_STYLE = { - css: 'tag', - linkHandler: function (text, fragment) { - const matches = text.match(/0x[0-9a-f]{8,16}\s*(?<offset>[0-9a-f]+)/); + super(parentId, broker); + const view = this; + const ADDRESS_STYLE = { + associateData: (text, fragment: HTMLElement) => { + const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/); const offset = Number.parseInt(matches.groups["offset"], 16); + const addressElement = document.createElement("SPAN"); + addressElement.className = "instruction-address"; + addressElement.innerText = matches.groups["address"]; + const offsetElement = document.createElement("SPAN"); + offsetElement.innerText = matches.groups["offset"]; + fragment.appendChild(addressElement); + fragment.appendChild(document.createTextNode(matches.groups["addressSpace"])); + fragment.appendChild(offsetElement); + fragment.appendChild(document.createTextNode(matches.groups["offsetSpace"])); + fragment.classList.add('tag'); + if (!Number.isNaN(offset)) { - const [nodes, blockId] = sourceResolver.nodesForPCOffset(offset) - console.log("nodes for", offset, offset.toString(16), " are ", nodes); - if (nodes.length > 0) { - for (const nodeId of nodes) { - view.addHtmlElementForNodeId(nodeId, fragment); - } - return (e) => { - console.log(offset, nodes); - e.stopPropagation(); - if (!e.shiftKey) { - view.selectionHandler.clear(); - } - view.selectionHandler.select(nodes, true); - }; - } + const pcOffset = view.sourceResolver.getKeyPcOffset(offset); + fragment.dataset.pcOffset = `${pcOffset}`; + addressElement.classList.add('linkable-text'); + offsetElement.classList.add('linkable-text'); } - return undefined; } }; - let ADDRESS_LINK_STYLE = { - css: 'tag' - }; - let UNCLASSIFIED_STYLE = { + const UNCLASSIFIED_STYLE = { css: 'com' }; - let NUMBER_STYLE = { - css: 'lit' + const NUMBER_STYLE = { + css: ['instruction-binary', 'lit'] }; - let COMMENT_STYLE = { + const COMMENT_STYLE = { css: 'com' }; - let POSITION_STYLE = { - css: 'com', + const OPCODE_ARGS = { + associateData: function (text, fragment) { + fragment.innerHTML = text; + const replacer = (match, hexOffset) => { + const offset = Number.parseInt(hexOffset, 16); + const keyOffset = view.sourceResolver.getKeyPcOffset(offset); + return `<span class="tag linkable-text" data-pc-offset="${keyOffset}">${match}</span>`; + }; + const html = text.replace(/<.0?x?([0-9a-fA-F]+)>/g, replacer); + fragment.innerHTML = html; + } }; - let OPCODE_STYLE = { - css: 'kwd', + const OPCODE_STYLE = { + css: 'kwd' }; const BLOCK_HEADER_STYLE = { - css: ['com', 'block'], - block_id: null, - blockId: function (text) { - let matches = /\d+/.exec(text); - if (!matches) return undefined; - BLOCK_HEADER_STYLE.block_id = Number(matches[0]); - return BLOCK_HEADER_STYLE.block_id; - }, - linkHandler: function (text) { - let matches = /\d+/.exec(text); - if (!matches) return undefined; + associateData: function (text, fragment) { + const matches = /\d+/.exec(text); + if (!matches) return; const blockId = matches[0]; - return function (e) { - e.stopPropagation(); - if (!e.shiftKey) { - view.selectionHandler.clear(); - } - view.blockSelectionHandler.select([blockId], true); - }; + fragment.dataset.blockId = blockId; + fragment.innerHTML = text; + fragment.className = "com block"; } }; const SOURCE_POSITION_HEADER_STYLE = { css: 'com' }; view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/; - let patterns = [ + const patterns = [ [ - [/^0x[0-9a-f]{8,16}\s*[0-9a-f]+\ /, ADDRESS_STYLE, 1], + [/^0?x?[0-9a-fA-F]{8,16}\s+[0-9a-f]+\s+/, ADDRESS_STYLE, 1], [view.SOURCE_POSITION_HEADER_REGEX, SOURCE_POSITION_HEADER_STYLE, -1], [/^\s+-- B\d+ start.*/, BLOCK_HEADER_STYLE, -1], [/^.*/, UNCLASSIFIED_STYLE, -1] ], [ - [/^\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], - [/^\s+[0-9a-f]+\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], + [/^\s*[0-9a-f]+\s+/, NUMBER_STYLE, 2], + [/^\s*[0-9a-f]+\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], [/^.*/, null, -1] ], [ + [/^REX.W \S+\s+/, OPCODE_STYLE, 3], [/^\S+\s+/, OPCODE_STYLE, 3], [/^\S+$/, OPCODE_STYLE, -1], [/^.*/, null, -1] ], [ [/^\s+/, null], - [/^[^\(;]+$/, null, -1], - [/^[^\(;]+/, null], - [/^\(/, null, 4], + [/^[^;]+$/, OPCODE_ARGS, -1], + [/^[^;]+/, OPCODE_ARGS, 4], [/^;/, COMMENT_STYLE, 5] ], [ - [/^0x[0-9a-f]{8,16}/, ADDRESS_LINK_STYLE], - [/^[^\)]/, null], - [/^\)$/, null, -1], - [/^\)/, null, 3] - ], - [ - [/^; debug\: position /, COMMENT_STYLE, 6], [/^.+$/, COMMENT_STYLE, -1] - ], - [ - [/^\d+$/, POSITION_STYLE, -1], ] ]; view.setPatterns(patterns); + + const linkHandler = (e: MouseEvent) => { + if (!(e.target instanceof HTMLElement)) return; + const offsetAsString = e.target.dataset.pcOffset ? e.target.dataset.pcOffset : e.target.parentElement.dataset.pcOffset; + const offset = Number.parseInt(offsetAsString, 10); + if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) { + view.offsetSelection.select([offset], true); + const nodes = view.sourceResolver.nodesForPCOffset(offset)[0]; + if (nodes.length > 0) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.selectionHandler.select(nodes, true); + } else { + view.updateSelection(); + } + } + return undefined; + }; + view.divNode.addEventListener('click', linkHandler); + + const linkHandlerBlock = e => { + const blockId = e.target.dataset.blockId; + if (typeof blockId != "undefined" && !Number.isNaN(blockId)) { + e.stopPropagation(); + if (!e.shiftKey) { + view.selectionHandler.clear(); + } + view.blockSelectionHandler.select([blockId], true); + } + }; + view.divNode.addEventListener('click', linkHandlerBlock); + + this.offsetSelection = new MySelection(anyToString); + const instructionSelectionHandler = { + clear: function () { + view.offsetSelection.clear(); + view.updateSelection(); + broker.broadcastClear(instructionSelectionHandler); + }, + select: function (instructionIds, selected) { + view.offsetSelection.select(instructionIds, selected); + view.updateSelection(); + broker.broadcastBlockSelect(instructionSelectionHandler, instructionIds, selected); + }, + brokeredInstructionSelect: function (instructionIds, selected) { + const firstSelect = view.offsetSelection.isEmpty(); + const keyPcOffsets = view.sourceResolver.instructionsToKeyPcOffsets(instructionIds); + view.offsetSelection.select(keyPcOffsets, selected); + view.updateSelection(firstSelect); + }, + brokeredClear: function () { + view.offsetSelection.clear(); + view.updateSelection(); + } + }; + this.instructionSelectionHandler = instructionSelectionHandler; + broker.addInstructionHandler(instructionSelectionHandler); + + const toolbox = document.createElement("div"); + toolbox.id = "toolbox-anchor"; + toolbox.innerHTML = toolboxHTML; + view.divNode.insertBefore(toolbox, view.divNode.firstChild); + const instructionAddressInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-address"); + const lastShowInstructionAddress = window.sessionStorage.getItem("show-instruction-address"); + instructionAddressInput.checked = lastShowInstructionAddress == 'true'; + const showInstructionAddressHandler = () => { + window.sessionStorage.setItem("show-instruction-address", `${instructionAddressInput.checked}`); + for (const el of view.divNode.querySelectorAll(".instruction-address")) { + el.classList.toggle("invisible", !instructionAddressInput.checked); + } + }; + instructionAddressInput.addEventListener("change", showInstructionAddressHandler); + this.showInstructionAddressHandler = showInstructionAddressHandler; + + const instructionBinaryInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-binary"); + const lastShowInstructionBinary = window.sessionStorage.getItem("show-instruction-binary"); + instructionBinaryInput.checked = lastShowInstructionBinary == 'true'; + const showInstructionBinaryHandler = () => { + window.sessionStorage.setItem("show-instruction-binary", `${instructionBinaryInput.checked}`); + for (const el of view.divNode.querySelectorAll(".instruction-binary")) { + el.classList.toggle("invisible", !instructionBinaryInput.checked); + } + }; + instructionBinaryInput.addEventListener("change", showInstructionBinaryHandler); + this.showInstructionBinaryHandler = showInstructionBinaryHandler; + } + + updateSelection(scrollIntoView: boolean = false) { + super.updateSelection(scrollIntoView); + const keyPcOffsets = this.sourceResolver.nodesToKeyPcOffsets(this.selection.selectedKeys()); + if (this.offsetSelection) { + for (const key of this.offsetSelection.selectedKeys()) { + keyPcOffsets.push(Number(key)); + } + } + for (const keyPcOffset of keyPcOffsets) { + const elementsToSelect = this.divNode.querySelectorAll(`[data-pc-offset='${keyPcOffset}']`); + for (const el of elementsToSelect) { + el.classList.toggle("selected", true); + } + } } - initializeCode(sourceText, sourcePosition) { - let view = this; - view.addr_event_counts = null; - view.total_event_counts = null; - view.max_event_counts = null; - view.pos_lines = new Array(); + initializeCode(sourceText, sourcePosition: number = 0) { + const view = this; + view.addrEventCounts = null; + view.totalEventCounts = null; + view.maxEventCounts = null; + view.posLines = new Array(); // Comment lines for line 0 include sourcePosition already, only need to // add sourcePosition for lines > 0. - view.pos_lines[0] = sourcePosition; + view.posLines[0] = sourcePosition; if (sourceText && sourceText != "") { - let base = sourcePosition; + const base = sourcePosition; let current = 0; - let source_lines = sourceText.split("\n"); - for (let i = 1; i < source_lines.length; i++) { + const sourceLines = sourceText.split("\n"); + for (let i = 1; i < sourceLines.length; i++) { // Add 1 for newline character that is split off. - current += source_lines[i - 1].length + 1; - view.pos_lines[i] = base + current; + current += sourceLines[i - 1].length + 1; + view.posLines[i] = base + current; } } } initializePerfProfile(eventCounts) { - let view = this; + const view = this; if (eventCounts !== undefined) { - view.addr_event_counts = eventCounts; - - view.total_event_counts = {}; - view.max_event_counts = {}; - for (let ev_name in view.addr_event_counts) { - let keys = Object.keys(view.addr_event_counts[ev_name]); - let values = keys.map(key => view.addr_event_counts[ev_name][key]); - view.total_event_counts[ev_name] = values.reduce((a, b) => a + b); - view.max_event_counts[ev_name] = values.reduce((a, b) => Math.max(a, b)); + view.addrEventCounts = eventCounts; + + view.totalEventCounts = {}; + view.maxEventCounts = {}; + for (const evName in view.addrEventCounts) { + if (view.addrEventCounts.hasOwnProperty(evName)) { + const keys = Object.keys(view.addrEventCounts[evName]); + const values = keys.map(key => view.addrEventCounts[evName][key]); + view.totalEventCounts[evName] = values.reduce((a, b) => a + b); + view.maxEventCounts[evName] = values.reduce((a, b) => Math.max(a, b)); + } } - } - else { - view.addr_event_counts = null; - view.total_event_counts = null; - view.max_event_counts = null; + } else { + view.addrEventCounts = null; + view.totalEventCounts = null; + view.maxEventCounts = null; } } + showContent(data): void { + console.time("disassembly-view"); + super.initializeContent(data, null); + this.showInstructionAddressHandler(); + this.showInstructionBinaryHandler(); + console.timeEnd("disassembly-view"); + } + // Shorten decimals and remove trailing zeroes for readability. humanize(num) { return num.toFixed(3).replace(/\.?0+$/, "") + "%"; } - // Interpolate between the given start and end values by a fraction of val/max. - interpolate(val, max, start, end) { - return start + (end - start) * (val / max); - } - processLine(line) { - let view = this; + const view = this; let fragments = super.processLine(line); // Add profiling data per instruction if available. - if (view.total_event_counts) { - let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); + if (view.totalEventCounts) { + const matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); if (matches) { - let newFragments = []; - for (let event in view.addr_event_counts) { - let count = view.addr_event_counts[event][matches[1]]; + const newFragments = []; + for (const event in view.addrEventCounts) { + if (!view.addrEventCounts.hasOwnProperty(event)) continue; + const count = view.addrEventCounts[event][matches[1]]; let str = " "; - let css_cls = "prof"; + const cssCls = "prof"; if (count !== undefined) { - let perc = count / view.total_event_counts[event] * 100; + const perc = count / view.totalEventCounts[event] * 100; let col = { r: 255, g: 255, b: 255 }; for (let i = 0; i < PROF_COLS.length; i++) { if (perc === PROF_COLS[i].perc) { col = PROF_COLS[i].col; break; - } - else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) { - let col1 = PROF_COLS[i].col; - let col2 = PROF_COLS[i + 1].col; + } else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) { + const col1 = PROF_COLS[i].col; + const col2 = PROF_COLS[i + 1].col; - let val = perc - PROF_COLS[i].perc; - let max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; + const val = perc - PROF_COLS[i].perc; + const max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; - col.r = Math.round(view.interpolate(val, max, col1.r, col2.r)); - col.g = Math.round(view.interpolate(val, max, col1.g, col2.g)); - col.b = Math.round(view.interpolate(val, max, col1.b, col2.b)); + col.r = Math.round(interpolate(val, max, col1.r, col2.r)); + col.g = Math.round(interpolate(val, max, col1.g, col2.g)); + col.b = Math.round(interpolate(val, max, col1.b, col2.b)); break; } } str = UNICODE_BLOCK; - let fragment = view.createFragment(str, css_cls); + const fragment = view.createFragment(str, cssCls); fragment.title = event + ": " + view.humanize(perc) + " (" + count + ")"; fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b + ")"; newFragments.push(fragment); + } else { + newFragments.push(view.createFragment(str, cssCls)); } - else - newFragments.push(view.createFragment(str, css_cls)); - } fragments = newFragments.concat(fragments); } @@ -245,4 +347,8 @@ export class DisassemblyView extends TextView { } detachSelection() { return null; } + + public searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void { + throw new Error("Method not implemented."); + } } diff --git a/deps/v8/tools/turbolizer/src/edge.ts b/deps/v8/tools/turbolizer/src/edge.ts index 7ca6d9dba0..30d265c561 100644 --- a/deps/v8/tools/turbolizer/src/edge.ts +++ b/deps/v8/tools/turbolizer/src/edge.ts @@ -2,19 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {GNode, DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" +import { GNode, DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node"; +import { Graph } from "./graph"; export const MINIMUM_EDGE_SEPARATION = 20; -export function isEdgeInitiallyVisible(target, index, source, type) { - return type == "control" && (target.cfg || source.cfg); -} - export class Edge { target: GNode; source: GNode; index: number; - type: String; + type: string; backEdgeNumber: number; visible: boolean; @@ -24,55 +21,54 @@ export class Edge { this.index = index; this.type = type; this.backEdgeNumber = 0; - this.visible = isEdgeInitiallyVisible(target, index, source, type); + this.visible = false; } - stringID() { return this.source.id + "," + this.index + "," + this.target.id; - }; + } isVisible() { return this.visible && this.source.visible && this.target.visible; - }; + } - getInputHorizontalPosition(graph) { + getInputHorizontalPosition(graph: Graph, showTypes: boolean) { if (this.backEdgeNumber > 0) { return graph.maxGraphNodeX + this.backEdgeNumber * MINIMUM_EDGE_SEPARATION; } - var source = this.source; - var target = this.target; - var index = this.index; - var input_x = target.x + target.getInputX(index); - var inputApproach = target.getInputApproach(this.index); - var outputApproach = source.getOutputApproach(graph); + const source = this.source; + const target = this.target; + const index = this.index; + const inputX = target.x + target.getInputX(index); + const inputApproach = target.getInputApproach(this.index); + const outputApproach = source.getOutputApproach(showTypes); if (inputApproach > outputApproach) { - return input_x; + return inputX; } else { - var inputOffset = MINIMUM_EDGE_SEPARATION * (index + 1); + const inputOffset = MINIMUM_EDGE_SEPARATION * (index + 1); return (target.x < source.x) ? (target.x + target.getTotalNodeWidth() + inputOffset) - : (target.x - inputOffset) + : (target.x - inputOffset); } } - generatePath(graph) { - var target = this.target; - var source = this.source; - var input_x = target.x + target.getInputX(this.index); - var arrowheadHeight = 7; - var input_y = target.y - 2 * DEFAULT_NODE_BUBBLE_RADIUS - arrowheadHeight; - var output_x = source.x + source.getOutputX(); - var output_y = source.y + graph.getNodeHeight(source) + DEFAULT_NODE_BUBBLE_RADIUS; - var inputApproach = target.getInputApproach(this.index); - var outputApproach = source.getOutputApproach(graph); - var horizontalPos = this.getInputHorizontalPosition(graph); - - var result = "M" + output_x + "," + output_y + - "L" + output_x + "," + outputApproach + + generatePath(graph: Graph, showTypes: boolean) { + const target = this.target; + const source = this.source; + const inputX = target.x + target.getInputX(this.index); + const arrowheadHeight = 7; + const inputY = target.y - 2 * DEFAULT_NODE_BUBBLE_RADIUS - arrowheadHeight; + const outputX = source.x + source.getOutputX(); + const outputY = source.y + source.getNodeHeight(showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + let inputApproach = target.getInputApproach(this.index); + const outputApproach = source.getOutputApproach(showTypes); + const horizontalPos = this.getInputHorizontalPosition(graph, showTypes); + + let result = "M" + outputX + "," + outputY + + "L" + outputX + "," + outputApproach + "L" + horizontalPos + "," + outputApproach; - if (horizontalPos != input_x) { + if (horizontalPos != inputX) { result += "L" + horizontalPos + "," + inputApproach; } else { if (inputApproach < outputApproach) { @@ -80,8 +76,8 @@ export class Edge { } } - result += "L" + input_x + "," + inputApproach + - "L" + input_x + "," + input_y; + result += "L" + inputX + "," + inputApproach + + "L" + inputX + "," + inputY; return result; } diff --git a/deps/v8/tools/turbolizer/src/graph-layout.ts b/deps/v8/tools/turbolizer/src/graph-layout.ts index 302a98aacc..3687c28c86 100644 --- a/deps/v8/tools/turbolizer/src/graph-layout.ts +++ b/deps/v8/tools/turbolizer/src/graph-layout.ts @@ -2,23 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import { MAX_RANK_SENTINEL } from "../src/constants"; +import { MINIMUM_EDGE_SEPARATION, Edge } from "../src/edge"; +import { NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH, DEFAULT_NODE_BUBBLE_RADIUS, GNode } from "../src/node"; +import { Graph } from "./graph"; -import {MAX_RANK_SENTINEL} from "./constants.js" -import {MINIMUM_EDGE_SEPARATION} from "./edge.js" -import {NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH, DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" +const DEFAULT_NODE_ROW_SEPARATION = 130; +const traceLayout = false; +function newGraphOccupation(graph: Graph) { + const isSlotFilled = []; + let maxSlot = 0; + let minSlot = 0; + let nodeOccupation: Array<[number, number]> = []; -const DEFAULT_NODE_ROW_SEPARATION = 130 - -var traceLayout = false; - -function newGraphOccupation(graph) { - var isSlotFilled = []; - var maxSlot = 0; - var minSlot = 0; - var nodeOccupation = []; - - function slotToIndex(slot) { + function slotToIndex(slot: number) { if (slot >= 0) { return slot * 2; } else { @@ -26,42 +24,30 @@ function newGraphOccupation(graph) { } } - function indexToSlot(index) { - if ((index % 0) == 0) { - return index / 2; - } else { - return -((index - 1) / 2); - } - } - - function positionToSlot(pos) { + function positionToSlot(pos: number) { return Math.floor(pos / NODE_INPUT_WIDTH); } - function slotToLeftPosition(slot) { - return slot * NODE_INPUT_WIDTH - } - - function slotToRightPosition(slot) { - return (slot + 1) * NODE_INPUT_WIDTH + function slotToLeftPosition(slot: number) { + return slot * NODE_INPUT_WIDTH; } - function findSpace(pos, width, direction) { - var widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) / + function findSpace(pos: number, width: number, direction: number) { + const widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) / NODE_INPUT_WIDTH); - var currentSlot = positionToSlot(pos + width / 2); - var currentScanSlot = currentSlot; - var widthSlotsRemainingLeft = widthSlots; - var widthSlotsRemainingRight = widthSlots; - var slotsChecked = 0; + const currentSlot = positionToSlot(pos + width / 2); + let currentScanSlot = currentSlot; + let widthSlotsRemainingLeft = widthSlots; + let widthSlotsRemainingRight = widthSlots; + let slotsChecked = 0; while (true) { - var mod = slotsChecked++ % 2; + const mod = slotsChecked++ % 2; currentScanSlot = currentSlot + (mod ? -1 : 1) * (slotsChecked >> 1); if (!isSlotFilled[slotToIndex(currentScanSlot)]) { if (mod) { - if (direction <= 0)--widthSlotsRemainingLeft + if (direction <= 0) --widthSlotsRemainingLeft; } else { - if (direction >= 0)--widthSlotsRemainingRight + if (direction >= 0) --widthSlotsRemainingRight; } if (widthSlotsRemainingLeft == 0 || widthSlotsRemainingRight == 0 || @@ -83,7 +69,7 @@ function newGraphOccupation(graph) { } } - function setIndexRange(from, to, value) { + function setIndexRange(from: number, to: number, value: boolean) { if (to < from) { throw ("illegal slot range"); } @@ -98,48 +84,47 @@ function newGraphOccupation(graph) { } } - function occupySlotRange(from, to) { + function occupySlotRange(from: number, to: number) { if (traceLayout) { console.log("Occupied [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); } setIndexRange(from, to, true); } - function clearSlotRange(from, to) { + function clearSlotRange(from: number, to: number) { if (traceLayout) { console.log("Cleared [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); } setIndexRange(from, to, false); } - function occupyPositionRange(from, to) { + function occupyPositionRange(from: number, to: number) { occupySlotRange(positionToSlot(from), positionToSlot(to - 1)); } - function clearPositionRange(from, to) { + function clearPositionRange(from: number, to: number) { clearSlotRange(positionToSlot(from), positionToSlot(to - 1)); } - function occupyPositionRangeWithMargin(from, to, margin) { - var fromMargin = from - Math.floor(margin); - var toMargin = to + Math.floor(margin); + function occupyPositionRangeWithMargin(from: number, to: number, margin: number) { + const fromMargin = from - Math.floor(margin); + const toMargin = to + Math.floor(margin); occupyPositionRange(fromMargin, toMargin); } - function clearPositionRangeWithMargin(from, to, margin) { - var fromMargin = from - Math.floor(margin); - var toMargin = to + Math.floor(margin); + function clearPositionRangeWithMargin(from: number, to: number, margin: number) { + const fromMargin = from - Math.floor(margin); + const toMargin = to + Math.floor(margin); clearPositionRange(fromMargin, toMargin); } - var occupation = { - occupyNodeInputs: function (node) { - for (var i = 0; i < node.inputs.length; ++i) { + const occupation = { + occupyNodeInputs: function (node: GNode, showTypes: boolean) { + for (let i = 0; i < node.inputs.length; ++i) { if (node.inputs[i].isVisible()) { - var edge = node.inputs[i]; + const edge = node.inputs[i]; if (!edge.isBackEdge()) { - var source = edge.source; - var horizontalPos = edge.getInputHorizontalPosition(graph); + const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); if (traceLayout) { console.log("Occupying input " + i + " of " + node.id + " at " + horizontalPos); } @@ -150,19 +135,18 @@ function newGraphOccupation(graph) { } } }, - occupyNode: function (node) { - var getPlacementHint = function (n) { - var pos = 0; - var direction = -1; - var outputEdges = 0; - var inputEdges = 0; - for (var k = 0; k < n.outputs.length; ++k) { - var outputEdge = n.outputs[k]; + occupyNode: function (node: GNode) { + const getPlacementHint = function (n: GNode) { + let pos = 0; + let direction = -1; + let outputEdges = 0; + let inputEdges = 0; + for (const outputEdge of n.outputs) { if (outputEdge.isVisible()) { - var output = n.outputs[k].target; - for (var l = 0; l < output.inputs.length; ++l) { + const output = outputEdge.target; + for (let l = 0; l < output.inputs.length; ++l) { if (output.rank > n.rank) { - var inputEdge = output.inputs[l]; + const inputEdge = output.inputs[l]; if (inputEdge.isVisible()) { ++inputEdges; } @@ -184,19 +168,19 @@ function newGraphOccupation(graph) { direction = 0; } return [direction, pos]; - } - var width = node.getTotalNodeWidth(); - var margin = MINIMUM_EDGE_SEPARATION; - var paddedWidth = width + 2 * margin; - var placementHint = getPlacementHint(node); - var x = placementHint[1] - paddedWidth + margin; + }; + const width = node.getTotalNodeWidth(); + const margin = MINIMUM_EDGE_SEPARATION; + const paddedWidth = width + 2 * margin; + const placementHint = getPlacementHint(node); + const x = placementHint[1] - paddedWidth + margin; if (traceLayout) { console.log("Node " + node.id + " placement hint [" + x + ", " + (x + paddedWidth) + ")"); } - var placement = findSpace(x, paddedWidth, placementHint[0]); - var firstSlot = placement[0]; - var slotWidth = placement[1]; - var endSlotExclusive = firstSlot + slotWidth - 1; + const placement = findSpace(x, paddedWidth, placementHint[0]); + const firstSlot = placement[0]; + const slotWidth = placement[1]; + const endSlotExclusive = firstSlot + slotWidth - 1; occupySlotRange(firstSlot, endSlotExclusive); nodeOccupation.push([firstSlot, endSlotExclusive]); if (placementHint[0] < 0) { @@ -208,18 +192,18 @@ function newGraphOccupation(graph) { } }, clearOccupiedNodes: function () { - nodeOccupation.forEach(function (o) { - clearSlotRange(o[0], o[1]); + nodeOccupation.forEach(([firstSlot, endSlotExclusive]) => { + clearSlotRange(firstSlot, endSlotExclusive); }); nodeOccupation = []; }, - clearNodeOutputs: function (source) { + clearNodeOutputs: function (source: GNode, showTypes: boolean) { source.outputs.forEach(function (edge) { if (edge.isVisible()) { - var target = edge.target; - for (var i = 0; i < target.inputs.length; ++i) { - if (target.inputs[i].source === source) { - var horizontalPos = edge.getInputHorizontalPosition(graph); + const target = edge.target; + for (const inputEdge of target.inputs) { + if (inputEdge.source === source) { + const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); clearPositionRangeWithMargin(horizontalPos, horizontalPos, NODE_INPUT_WIDTH / 2); @@ -229,8 +213,8 @@ function newGraphOccupation(graph) { }); }, print: function () { - var s = ""; - for (var currentSlot = -40; currentSlot < 40; ++currentSlot) { + let s = ""; + for (let currentSlot = -40; currentSlot < 40; ++currentSlot) { if (currentSlot != 0) { s += " "; } else { @@ -239,7 +223,7 @@ function newGraphOccupation(graph) { } console.log(s); s = ""; - for (var currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) { + for (let currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) { if (isSlotFilled[slotToIndex(currentSlot2)]) { s += "*"; } else { @@ -248,30 +232,33 @@ function newGraphOccupation(graph) { } console.log(s); } - } + }; return occupation; } -export function layoutNodeGraph(graph) { +export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { // First determine the set of nodes that have no outputs. Those are the // basis for bottom-up DFS to determine rank and node placement. - var endNodesHasNoOutputs = []; - var startNodesHasNoInputs = []; - graph.nodes.forEach(function (n, i) { + + const start = performance.now(); + + const endNodesHasNoOutputs = []; + const startNodesHasNoInputs = []; + for (const n of graph.nodes()) { endNodesHasNoOutputs[n.id] = true; startNodesHasNoInputs[n.id] = true; - }); - graph.edges.forEach(function (e, i) { + } + graph.forEachEdge((e: Edge) => { endNodesHasNoOutputs[e.source.id] = false; startNodesHasNoInputs[e.target.id] = false; }); // Finialize the list of start and end nodes. - var endNodes = []; - var startNodes = []; - var visited = []; - var rank = []; - graph.nodes.forEach(function (n, i) { + const endNodes: Array<GNode> = []; + const startNodes: Array<GNode> = []; + let visited: Array<boolean> = []; + const rank: Array<number> = []; + for (const n of graph.nodes()) { if (endNodesHasNoOutputs[n.id]) { endNodes.push(n); } @@ -283,40 +270,44 @@ export function layoutNodeGraph(graph) { n.rank = 0; n.visitOrderWithinRank = 0; n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; - }); + } + if (traceLayout) { + console.log(`layoutGraph init ${performance.now() - start}`); + } - var maxRank = 0; - var visited = []; - var dfsStack = []; - var visitOrderWithinRank = 0; + let maxRank = 0; + visited = []; + let visitOrderWithinRank = 0; - var worklist = startNodes.slice(); + const worklist: Array<GNode> = startNodes.slice(); while (worklist.length != 0) { - var n = worklist.pop(); - var changed = false; + const n: GNode = worklist.pop(); + let changed = false; if (n.rank == MAX_RANK_SENTINEL) { n.rank = 1; changed = true; } - var begin = 0; - var end = n.inputs.length; - if (n.opcode == 'Phi' || n.opcode == 'EffectPhi') { + let begin = 0; + let end = n.inputs.length; + if (n.nodeLabel.opcode == 'Phi' || + n.nodeLabel.opcode == 'EffectPhi' || + n.nodeLabel.opcode == 'InductionVariablePhi') { // Keep with merge or loop node begin = n.inputs.length - 1; } else if (n.hasBackEdges()) { end = 1; } - for (var l = begin; l < end; ++l) { - var input = n.inputs[l].source; + for (let l = begin; l < end; ++l) { + const input = n.inputs[l].source; if (input.visible && input.rank >= n.rank) { n.rank = input.rank + 1; changed = true; } } if (changed) { - var hasBackEdges = n.hasBackEdges(); - for (var l = n.outputs.length - 1; l >= 0; --l) { + const hasBackEdges = n.hasBackEdges(); + for (let l = n.outputs.length - 1; l >= 0; --l) { if (hasBackEdges && (l != 0)) { worklist.unshift(n.outputs[l].target); } else { @@ -329,24 +320,28 @@ export function layoutNodeGraph(graph) { } } + if (traceLayout) { + console.log(`layoutGraph worklist ${performance.now() - start}`); + } + visited = []; - function dfsFindRankLate(n) { + function dfsFindRankLate(n: GNode) { if (visited[n.id]) return; visited[n.id] = true; - var originalRank = n.rank; - var newRank = n.rank; - var firstInput = true; - for (var l = 0; l < n.outputs.length; ++l) { - var output = n.outputs[l].target; + const originalRank = n.rank; + let newRank = n.rank; + let isFirstInput = true; + for (const outputEdge of n.outputs) { + const output = outputEdge.target; dfsFindRankLate(output); - var outputRank = output.rank; - if (output.visible && (firstInput || outputRank <= newRank) && + const outputRank = output.rank; + if (output.visible && (isFirstInput || outputRank <= newRank) && (outputRank > originalRank)) { newRank = outputRank - 1; } - firstInput = false; + isFirstInput = false; } - if (n.opcode != "Start" && n.opcode != "Phi" && n.opcode != "EffectPhi") { + if (n.nodeLabel.opcode != "Start" && n.nodeLabel.opcode != "Phi" && n.nodeLabel.opcode != "EffectPhi" && n.nodeLabel.opcode != "InductionVariablePhi") { n.rank = newRank; } } @@ -354,13 +349,12 @@ export function layoutNodeGraph(graph) { startNodes.forEach(dfsFindRankLate); visited = []; - function dfsRankOrder(n) { + function dfsRankOrder(n: GNode) { if (visited[n.id]) return; visited[n.id] = true; - for (var l = 0; l < n.outputs.length; ++l) { - var edge = n.outputs[l]; - if (edge.isVisible()) { - var output = edge.target; + for (const outputEdge of n.outputs) { + if (outputEdge.isVisible()) { + const output = outputEdge.target; dfsRankOrder(output); } } @@ -374,10 +368,10 @@ export function layoutNodeGraph(graph) { n.rank = maxRank + 1; }); - var rankSets = []; + const rankSets: Array<Array<GNode>> = []; // Collect sets for each rank. - graph.nodes.forEach(function (n, i) { - n.y = n.rank * (DEFAULT_NODE_ROW_SEPARATION + graph.getNodeHeight(n) + + for (const n of graph.nodes()) { + n.y = n.rank * (DEFAULT_NODE_ROW_SEPARATION + n.getNodeHeight(showTypes) + 2 * DEFAULT_NODE_BUBBLE_RADIUS); if (n.visible) { if (rankSets[n.rank] === undefined) { @@ -386,18 +380,17 @@ export function layoutNodeGraph(graph) { rankSets[n.rank].push(n); } } - }); + } // Iterate backwards from highest to lowest rank, placing nodes so that they // spread out from the "center" as much as possible while still being // compact and not overlapping live input lines. - var occupation = newGraphOccupation(graph); - var rankCount = 0; + const occupation = newGraphOccupation(graph); - rankSets.reverse().forEach(function (rankSet) { + rankSets.reverse().forEach(function (rankSet: Array<GNode>) { - for (var i = 0; i < rankSet.length; ++i) { - occupation.clearNodeOutputs(rankSet[i]); + for (const node of rankSet) { + occupation.clearNodeOutputs(node, showTypes); } if (traceLayout) { @@ -405,19 +398,25 @@ export function layoutNodeGraph(graph) { occupation.print(); } - var placedCount = 0; - rankSet = rankSet.sort(function (a, b) { - return a.visitOrderWithinRank < b.visitOrderWithinRank; + let placedCount = 0; + rankSet = rankSet.sort((a: GNode, b: GNode) => { + if (a.visitOrderWithinRank < b.visitOrderWithinRank) { + return -1; + } else if (a.visitOrderWithinRank == b.visitOrderWithinRank) { + return 0; + } else { + return 1; + } }); - for (var i = 0; i < rankSet.length; ++i) { - var nodeToPlace = rankSet[i]; + + for (const nodeToPlace of rankSet) { if (nodeToPlace.visible) { nodeToPlace.x = occupation.occupyNode(nodeToPlace); if (traceLayout) { console.log("Node " + nodeToPlace.id + " is placed between [" + nodeToPlace.x + ", " + (nodeToPlace.x + nodeToPlace.getTotalNodeWidth()) + ")"); } - var staggeredFlooredI = Math.floor(placedCount++ % 3); - var delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI + const staggeredFlooredI = Math.floor(placedCount++ % 3); + const delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI; nodeToPlace.outputApproach += delta; } else { nodeToPlace.x = 0; @@ -436,9 +435,8 @@ export function layoutNodeGraph(graph) { occupation.print(); } - for (var i = 0; i < rankSet.length; ++i) { - var node = rankSet[i]; - occupation.occupyNodeInputs(node); + for (const node of rankSet) { + occupation.occupyNodeInputs(node, showTypes); } if (traceLayout) { @@ -453,57 +451,11 @@ export function layoutNodeGraph(graph) { }); graph.maxBackEdgeNumber = 0; - graph.visibleEdges.selectAll("path").each(function (e) { + graph.forEachEdge((e: Edge) => { if (e.isBackEdge()) { e.backEdgeNumber = ++graph.maxBackEdgeNumber; } else { e.backEdgeNumber = 0; } }); - - redetermineGraphBoundingBox(graph); -} - -function redetermineGraphBoundingBox(graph) { - graph.minGraphX = 0; - graph.maxGraphNodeX = 1; - graph.maxGraphX = undefined; // see below - graph.minGraphY = 0; - graph.maxGraphY = 1; - - for (var i = 0; i < graph.nodes.length; ++i) { - var node = graph.nodes[i]; - - if (!node.visible) { - continue; - } - - if (node.x < graph.minGraphX) { - graph.minGraphX = node.x; - } - if ((node.x + node.getTotalNodeWidth()) > graph.maxGraphNodeX) { - graph.maxGraphNodeX = node.x + node.getTotalNodeWidth(); - } - if ((node.y - 50) < graph.minGraphY) { - graph.minGraphY = node.y - 50; - } - if ((node.y + graph.getNodeHeight(node) + 50) > graph.maxGraphY) { - graph.maxGraphY = node.y + graph.getNodeHeight(node) + 50; - } - } - - graph.maxGraphX = graph.maxGraphNodeX + - graph.maxBackEdgeNumber * MINIMUM_EDGE_SEPARATION; - - const width = (graph.maxGraphX - graph.minGraphX); - const height = graph.maxGraphY - graph.minGraphY; - graph.width = width; - graph.height = height; - - const extent = [ - [graph.minGraphX - width / 2, graph.minGraphY - height / 2], - [graph.maxGraphX + width / 2, graph.maxGraphY + height / 2] - ]; - graph.panZoom.translateExtent(extent); - graph.minScale(); } diff --git a/deps/v8/tools/turbolizer/src/graph-view.ts b/deps/v8/tools/turbolizer/src/graph-view.ts index 9e136f8225..c46413c400 100644 --- a/deps/v8/tools/turbolizer/src/graph-view.ts +++ b/deps/v8/tools/turbolizer/src/graph-view.ts @@ -2,18 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import * as d3 from "d3" -import {layoutNodeGraph} from "./graph-layout.js" -import {MAX_RANK_SENTINEL} from "./constants.js" -import {GNode, nodeToStr, isNodeInitiallyVisible} from "./node.js" -import {NODE_INPUT_WIDTH, MINIMUM_NODE_OUTPUT_APPROACH} from "./node.js" -import {DEFAULT_NODE_BUBBLE_RADIUS} from "./node.js" -import {Edge, edgeToStr} from "./edge.js" -import {View, PhaseView} from "./view.js" -import {MySelection} from "./selection.js" -import {partial, alignUp} from "./util.js" - -function nodeToStringKey(n) { +import * as d3 from "d3"; +import { layoutNodeGraph } from "../src/graph-layout"; +import { GNode, nodeToStr } from "../src/node"; +import { NODE_INPUT_WIDTH } from "../src/node"; +import { DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node"; +import { Edge, edgeToStr } from "../src/edge"; +import { PhaseView } from "../src/view"; +import { MySelection } from "../src/selection"; +import { partial } from "../src/util"; +import { NodeSelectionHandler, ClearableHandler } from "./selection-handler"; +import { Graph } from "./graph"; +import { SelectionBroker } from "./selection-broker"; + +function nodeToStringKey(n: GNode) { return "" + n.id; } @@ -21,35 +23,28 @@ interface GraphState { showTypes: boolean; selection: MySelection; mouseDownNode: any; - justDragged: boolean, - justScaleTransGraph: boolean, - lastKeyDown: number, - hideDead: boolean + justDragged: boolean; + justScaleTransGraph: boolean; + hideDead: boolean; } -export class GraphView extends View implements PhaseView { +export class GraphView extends PhaseView { divElement: d3.Selection<any, any, any, any>; svg: d3.Selection<any, any, any, any>; - showPhaseByName: (string) => void; + showPhaseByName: (p: string, s: Set<any>) => void; state: GraphState; - nodes: Array<GNode>; - edges: Array<any>; - selectionHandler: NodeSelectionHandler; + selectionHandler: NodeSelectionHandler & ClearableHandler; graphElement: d3.Selection<any, any, any, any>; visibleNodes: d3.Selection<any, GNode, any, any>; visibleEdges: d3.Selection<any, Edge, any, any>; - minGraphX: number; - maxGraphX: number; - minGraphY: number; - maxGraphY: number; - width: number; - height: number; - maxGraphNodeX: number; drag: d3.DragBehavior<any, GNode, GNode>; panZoom: d3.ZoomBehavior<SVGElement, any>; - nodeMap: Array<any>; visibleBubbles: d3.Selection<any, any, any, any>; transitionTimout: number; + graph: Graph; + broker: SelectionBroker; + phaseName: string; + toolbox: HTMLElement; createViewElement() { const pane = document.createElement('div'); @@ -57,82 +52,88 @@ export class GraphView extends View implements PhaseView { return pane; } - constructor(id, broker, showPhaseByName: (string) => void) { - super(id); - var graph = this; + constructor(idOrContainer: string | HTMLElement, broker: SelectionBroker, + showPhaseByName: (s: string) => void, toolbox: HTMLElement) { + super(idOrContainer); + const view = this; + this.broker = broker; this.showPhaseByName = showPhaseByName; this.divElement = d3.select(this.divNode); - const svg = this.divElement.append("svg").attr('version', '1.1') + this.phaseName = ""; + this.toolbox = toolbox; + const svg = this.divElement.append("svg") + .attr('version', '2.0') .attr("width", "100%") .attr("height", "100%"); svg.on("click", function (d) { - graph.selectionHandler.clear(); + view.selectionHandler.clear(); }); - graph.svg = svg; + // Listen for key events. Note that the focus handler seems + // to be important even if it does nothing. + svg + .attr("focusable", false) + .on("focus", e => { }) + .on("keydown", e => { view.svgKeyDown(); }); - graph.nodes = []; - graph.edges = []; + view.svg = svg; - graph.minGraphX = 0; - graph.maxGraphX = 1; - graph.minGraphY = 0; - graph.maxGraphY = 1; - - graph.state = { + this.state = { selection: null, mouseDownNode: null, justDragged: false, justScaleTransGraph: false, - lastKeyDown: -1, showTypes: false, hideDead: false }; this.selectionHandler = { clear: function () { - graph.state.selection.clear(); + view.state.selection.clear(); broker.broadcastClear(this); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }, - select: function (nodes, selected) { - let locations = []; + select: function (nodes: Array<GNode>, selected: boolean) { + const locations = []; for (const node of nodes) { - if (node.sourcePosition) { - locations.push(node.sourcePosition); + if (node.nodeLabel.sourcePosition) { + locations.push(node.nodeLabel.sourcePosition); } - if (node.origin && node.origin.bytecodePosition) { - locations.push({ bytecodePosition: node.origin.bytecodePosition }); + if (node.nodeLabel.origin && node.nodeLabel.origin.bytecodePosition) { + locations.push({ bytecodePosition: node.nodeLabel.origin.bytecodePosition }); } } - graph.state.selection.select(nodes, selected); + view.state.selection.select(nodes, selected); broker.broadcastSourcePositionSelect(this, locations, selected); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }, - brokeredNodeSelect: function (locations, selected) { - let selection = graph.nodes - .filter(function (n) { - return locations.has(nodeToStringKey(n)) - && (!graph.state.hideDead || n.isLive()); - }); - 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; + brokeredNodeSelect: function (locations, selected: boolean) { + if (!view.graph) return; + const selection = view.graph.nodes(n => { + return locations.has(nodeToStringKey(n)) + && (!view.state.hideDead || n.isLive()); }); - graph.edges.forEach(function (e) { - e.visible = e.visible || - (graph.state.selection.isSelected(e.source) && graph.state.selection.isSelected(e.target)); - }); - graph.updateGraphVisibility(); + view.state.selection.select(selection, selected); + // Update edge visibility based on selection. + for (const n of view.graph.nodes()) { + if (view.state.selection.isSelected(n)) { + n.visible = true; + n.inputs.forEach(e => { + e.visible = e.visible || view.state.selection.isSelected(e.source); + }); + n.outputs.forEach(e => { + e.visible = e.visible || view.state.selection.isSelected(e.target); + }); + } + } + view.updateGraphVisibility(); }, brokeredClear: function () { - graph.state.selection.clear(); - graph.updateGraphVisibility(); + view.state.selection.clear(); + view.updateGraphVisibility(); } }; - broker.addNodeHandler(this.selectionHandler); - graph.state.selection = new MySelection(nodeToStringKey); + view.state.selection = new MySelection(nodeToStringKey); const defs = svg.append('svg:defs'); defs.append('svg:marker') @@ -146,35 +147,20 @@ export class GraphView extends View implements PhaseView { .attr('d', 'M0,-4L8,0L0,4'); this.graphElement = svg.append("g"); - graph.visibleEdges = this.graphElement.append("g"); - graph.visibleNodes = this.graphElement.append("g"); + view.visibleEdges = this.graphElement.append("g"); + view.visibleNodes = this.graphElement.append("g"); - graph.drag = d3.drag<any, GNode, GNode>() + view.drag = d3.drag<any, GNode, GNode>() .on("drag", function (d) { d.x += d3.event.dx; d.y += d3.event.dy; - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); - - d3.select("#layout").on("click", partial(this.layoutAction, graph)); - d3.select("#show-all").on("click", partial(this.showAllAction, 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)); - - // listen for key events - d3.select(window).on("keydown", function (e) { - graph.svgKeyDown.call(graph); - }).on("keyup", function () { - graph.svgKeyUp.call(graph); - }); - function zoomed() { if (d3.event.shiftKey) return false; - graph.graphElement.attr("transform", d3.event.transform); + view.graphElement.attr("transform", d3.event.transform); + return true; } const zoomSvg = d3.zoom<SVGElement, any>() @@ -190,38 +176,17 @@ export class GraphView extends View implements PhaseView { svg.call(zoomSvg).on("dblclick.zoom", null); - graph.panZoom = zoomSvg; - - } - - - static get selectedClass() { - return "selected"; - } - static get rectClass() { - return "nodeStyle"; - } - static get activeEditId() { - return "active-editing"; - } - static get nodeRadius() { - return 50; - } + view.panZoom = zoomSvg; - getNodeHeight(d): number { - if (this.state.showTypes) { - return d.normalheight + d.labelbbox.height; - } else { - return d.normalheight; - } } - getEdgeFrontier(nodes, inEdges, edgeFilter) { - let frontier = new Set(); + getEdgeFrontier(nodes: Iterable<GNode>, inEdges: boolean, + edgeFilter: (e: Edge, i: number) => boolean) { + const frontier: Set<Edge> = new Set(); for (const n of nodes) { - var edges = inEdges ? n.inputs : n.outputs; - var edgeNumber = 0; - edges.forEach(function (edge) { + const edges = inEdges ? n.inputs : n.outputs; + let edgeNumber = 0; + edges.forEach((edge: Edge) => { if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) { frontier.add(edge); } @@ -231,28 +196,29 @@ export class GraphView extends View implements PhaseView { return frontier; } - getNodeFrontier(nodes, inEdges, edgeFilter) { - let graph = this; - var frontier = new Set(); - var newState = true; - var edgeFrontier = graph.getEdgeFrontier(nodes, inEdges, edgeFilter); + getNodeFrontier(nodes: Iterable<GNode>, inEdges: boolean, + edgeFilter: (e: Edge, i: number) => boolean) { + const view = this; + const frontier: Set<GNode> = new Set(); + let newState = true; + const edgeFrontier = view.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: Edge) { if (edge.visible) { newState = false; } }); } - edgeFrontier.forEach(function (edge) { + edgeFrontier.forEach(function (edge: Edge) { edge.visible = newState; if (newState) { - var node = inEdges ? edge.source : edge.target; + const node = inEdges ? edge.source : edge.target; node.visible = true; frontier.add(node); } }); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); if (newState) { return frontier; } else { @@ -261,8 +227,39 @@ export class GraphView extends View implements PhaseView { } initializeContent(data, rememberedSelection) { - this.createGraph(data, rememberedSelection); - if (rememberedSelection != null) { + this.show(); + function createImgInput(id: string, title: string, onClick): HTMLElement { + const input = document.createElement("input"); + input.setAttribute("id", id); + input.setAttribute("type", "image"); + input.setAttribute("title", title); + input.setAttribute("src", `img/${id}-icon.png`); + input.className = "button-input graph-toolbox-item"; + input.addEventListener("click", onClick); + return input; + } + this.toolbox.appendChild(createImgInput("layout", "layout graph", + partial(this.layoutAction, this))); + this.toolbox.appendChild(createImgInput("show-all", "show all nodes", + partial(this.showAllAction, this))); + this.toolbox.appendChild(createImgInput("show-control", "show all nodes", + partial(this.showControlAction, this))); + this.toolbox.appendChild(createImgInput("toggle-hide-dead", "show only live nodes", + partial(this.toggleHideDead, this))); + this.toolbox.appendChild(createImgInput("hide-unselected", "show only live nodes", + partial(this.hideUnselectedAction, this))); + this.toolbox.appendChild(createImgInput("hide-selected", "show only live nodes", + partial(this.hideSelectedAction, this))); + this.toolbox.appendChild(createImgInput("zoom-selection", "show only live nodes", + partial(this.zoomSelectionAction, this))); + this.toolbox.appendChild(createImgInput("toggle-types", "show only live nodes", + partial(this.toggleTypesAction, this))); + + this.phaseName = data.name; + this.createGraph(data.data, rememberedSelection); + this.broker.addNodeHandler(this.selectionHandler); + + if (rememberedSelection != null && rememberedSelection.size > 0) { this.attachSelection(rememberedSelection); this.connectVisibleSelectedNodes(); this.viewSelection(); @@ -272,88 +269,50 @@ export class GraphView extends View implements PhaseView { } deleteContent() { - if (this.visibleNodes) { - this.nodes = []; - this.edges = []; - this.nodeMap = []; - this.updateGraphVisibility(); + for (const item of this.toolbox.querySelectorAll(".graph-toolbox-item")) { + item.parentElement.removeChild(item); } - }; - - measureText(text) { - const textMeasure = document.getElementById('text-measure') as SVGTSpanElement; - textMeasure.textContent = text; - return { - width: textMeasure.getBBox().width, - height: textMeasure.getBBox().height, - }; - } - createGraph(data, rememberedSelection) { - var g = this; - g.nodes = []; - g.nodeMap = []; - data.nodes.forEach(function (n, i) { - n.__proto__ = GNode.prototype; + for (const n of this.graph.nodes()) { 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 = []; - n.rpo = -1; - n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; - n.cfg = n.control; - g.nodeMap[n.id] = n; - n.displayLabel = n.getDisplayLabel(); - n.labelbbox = g.measureText(n.displayLabel); - n.typebbox = g.measureText(n.getDisplayType()); - var innerwidth = Math.max(n.labelbbox.width, n.typebbox.width); - n.width = alignUp(innerwidth + NODE_INPUT_WIDTH * 2, - NODE_INPUT_WIDTH); - var innerheight = Math.max(n.labelbbox.height, n.typebbox.height); - n.normalheight = innerheight + 20; - g.nodes.push(n); - }); - g.edges = []; - 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); - t.inputs.push(newEdge); - s.outputs.push(newEdge); - g.edges.push(newEdge); - if (e.type == 'control') { - s.cfg = true; - } + } + this.graph.forEachEdge((e: Edge) => { + e.visible = false; }); - 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; - } + this.updateGraphVisibility(); + } + + public hide(): void { + super.hide(); + this.deleteContent(); + } + + createGraph(data, rememberedSelection) { + this.graph = new Graph(data); + + this.showControlAction(this); + + if (rememberedSelection != undefined) { + for (const n of this.graph.nodes()) { + n.visible = n.visible || rememberedSelection.has(nodeToStringKey(n)); } - }); - g.updateGraphVisibility(); - g.layoutGraph(); - g.updateGraphVisibility(); - g.viewWholeGraph(); + } + + this.graph.forEachEdge(e => e.visible = e.source.visible && e.target.visible); + + this.layoutGraph(); + this.updateGraphVisibility(); } connectVisibleSelectedNodes() { - var graph = this; - for (const n of graph.state.selection) { - n.inputs.forEach(function (edge) { + const view = this; + for (const n of view.state.selection) { + n.inputs.forEach(function (edge: Edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } }); - n.outputs.forEach(function (edge) { + n.outputs.forEach(function (edge: Edge) { if (edge.source.visible && edge.target.visible) { edge.visible = true; } @@ -362,52 +321,51 @@ export class GraphView extends View implements PhaseView { } updateInputAndOutputBubbles() { - var g = this; - var s = g.visibleBubbles; + const view = this; + const g = this.graph; + const s = this.visibleBubbles; s.classed("filledBubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; + const edge = g.nodeMap[components[3]].inputs[components[2]]; return edge.isVisible(); } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 2; } }).classed("halfFilledBubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; return false; } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 1; } }).classed("bubbleStyle", function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ib") { - var edge = g.nodeMap[components[3]].inputs[components[2]]; + const edge = g.nodeMap[components[3]].inputs[components[2]]; return !edge.isVisible(); } else { return g.nodeMap[components[1]].areAnyOutputsVisible() == 0; } }); s.each(function (c) { - var components = this.id.split(','); + const components = this.id.split(','); if (components[0] == "ob") { - var from = g.nodeMap[components[1]]; - var x = from.getOutputX(); - var y = g.getNodeHeight(from) + DEFAULT_NODE_BUBBLE_RADIUS; - var transform = "translate(" + x + "," + y + ")"; + const from = g.nodeMap[components[1]]; + const x = from.getOutputX(); + const y = from.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + const transform = "translate(" + x + "," + y + ")"; this.setAttribute('transform', transform); } }); } attachSelection(s) { - 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); + this.selectionHandler.clear(); + const selected = [...this.graph.nodes(n => + s.has(this.state.selection.stringKey(n)) && (!this.state.hideDead || n.isLive()))]; + this.selectionHandler.select(selected, true); } detachSelection() { @@ -415,134 +373,135 @@ export class GraphView extends View implements PhaseView { } selectAllNodes() { - var graph = this; if (!d3.event.shiftKey) { - graph.state.selection.clear(); + this.state.selection.clear(); } - const allVisibleNodes = graph.nodes.filter((n) => n.visible); - graph.state.selection.select(allVisibleNodes, true); - graph.updateGraphVisibility(); + const allVisibleNodes = [...this.graph.nodes(n => n.visible)]; + this.state.selection.select(allVisibleNodes, true); + this.updateGraphVisibility(); } - layoutAction(graph) { - graph.updateGraphVisibility(); + layoutAction(graph: GraphView) { graph.layoutGraph(); graph.updateGraphVisibility(); graph.viewWholeGraph(); } - showAllAction(graph) { - graph.nodes.forEach(function (n) { - n.visible = !graph.state.hideDead || n.isLive(); + showAllAction(view: GraphView) { + for (const n of view.graph.nodes()) { + n.visible = !view.state.hideDead || n.isLive(); + } + view.graph.forEachEdge((e: Edge) => { + e.visible = e.source.visible || e.target.visible; }); - graph.edges.forEach(function (e) { - e.visible = !graph.state.hideDead || (e.source.isLive() && e.target.isLive()); + view.updateGraphVisibility(); + view.viewWholeGraph(); + } + + showControlAction(view: GraphView) { + for (const n of view.graph.nodes()) { + n.visible = n.cfg && (!view.state.hideDead || n.isLive()); + } + view.graph.forEachEdge((e: Edge) => { + e.visible = e.type == 'control' && e.source.visible && e.target.visible; }); - graph.updateGraphVisibility(); - graph.viewWholeGraph(); + view.updateGraphVisibility(); + view.viewWholeGraph(); } - 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); + toggleHideDead(view: GraphView) { + view.state.hideDead = !view.state.hideDead; + if (view.state.hideDead) view.hideDead(); + const element = document.getElementById('toggle-hide-dead'); + element.classList.toggle('button-input-toggled', view.state.hideDead); } hideDead() { - const graph = this; - graph.nodes.filter(function (n) { + for (const n of this.graph.nodes()) { if (!n.isLive()) { n.visible = false; - graph.state.selection.select([n], false); + this.state.selection.select([n], false); } - }) - graph.updateGraphVisibility(); + } + this.updateGraphVisibility(); } - hideUnselectedAction(graph) { - graph.nodes.forEach(function (n) { - if (!graph.state.selection.isSelected(n)) { + hideUnselectedAction(view: GraphView) { + for (const n of view.graph.nodes()) { + if (!view.state.selection.isSelected(n)) { n.visible = false; } - }); - graph.updateGraphVisibility(); + } + view.updateGraphVisibility(); } - hideSelectedAction(graph) { - graph.nodes.forEach(function (n) { - if (graph.state.selection.isSelected(n)) { + hideSelectedAction(view: GraphView) { + for (const n of view.graph.nodes()) { + if (view.state.selection.isSelected(n)) { n.visible = false; } - }); - graph.selectionHandler.clear(); + } + view.selectionHandler.clear(); } - zoomSelectionAction(graph) { - graph.viewSelection(); + zoomSelectionAction(view: GraphView) { + view.viewSelection(); } - toggleTypesAction(graph) { - graph.toggleTypes(); + toggleTypesAction(view: GraphView) { + view.toggleTypes(); } - searchInputAction(searchBar, e: KeyboardEvent) { - const graph = this; + searchInputAction(searchBar: HTMLInputElement, e: KeyboardEvent, onlyVisible: boolean) { if (e.keyCode == 13) { - graph.selectionHandler.clear(); - var query = searchBar.value; + this.selectionHandler.clear(); + const query = searchBar.value; window.sessionStorage.setItem("lastSearch", query); if (query.length == 0) return; - var reg = new RegExp(query); - var filterFunction = function (n) { + const reg = new RegExp(query); + const filterFunction = (n: GNode) => { return (reg.exec(n.getDisplayLabel()) != null || - (graph.state.showTypes && reg.exec(n.getDisplayType())) || + (this.state.showTypes && reg.exec(n.getDisplayType())) || (reg.exec(n.getTitle())) || - reg.exec(n.opcode) != null); + reg.exec(n.nodeLabel.opcode) != null); }; - const selection = graph.nodes.filter( - function (n, i) { - if ((e.ctrlKey || n.visible) && filterFunction(n)) { - if (e.ctrlKey) n.visible = true; - return true; - } - return false; - }); + const selection = [...this.graph.nodes(n => { + if ((e.ctrlKey || n.visible || !onlyVisible) && filterFunction(n)) { + if (e.ctrlKey || !onlyVisible) n.visible = true; + return true; + } + return false; + })]; - graph.selectionHandler.select(selection, true); - graph.connectVisibleSelectedNodes(); - graph.updateGraphVisibility(); + this.selectionHandler.select(selection, true); + this.connectVisibleSelectedNodes(); + this.updateGraphVisibility(); searchBar.blur(); - graph.viewSelection(); + this.viewSelection(); } e.stopPropagation(); } svgKeyDown() { - var state = this.state; - var graph = this; - - // Don't handle key press repetition - if (state.lastKeyDown !== -1) return; + const view = this; + const state = this.state; - var showSelectionFrontierNodes = function (inEdges, filter, select) { - var frontier = graph.getNodeFrontier(state.selection, inEdges, filter); + const showSelectionFrontierNodes = (inEdges: boolean, filter: (e: Edge, i: number) => boolean, doSelect: boolean) => { + const frontier = view.getNodeFrontier(state.selection, inEdges, filter); if (frontier != undefined && frontier.size) { - if (select) { + if (doSelect) { if (!d3.event.shiftKey) { state.selection.clear(); } - state.selection.select(frontier, true); + state.selection.select([...frontier], true); } - graph.updateGraphVisibility(); + view.updateGraphVisibility(); } - allowRepetition = false; - } + }; - var allowRepetition = true; - var eventHandled = true; // unless the below switch defaults + let eventHandled = true; // unless the below switch defaults switch (d3.event.keyCode) { case 49: case 50: @@ -555,8 +514,8 @@ export class GraphView extends View implements PhaseView { case 57: // '1'-'9' showSelectionFrontierNodes(true, - (edge, index) => { return index == (d3.event.keyCode - 49); }, - false); + (edge: Edge, index: number) => index == (d3.event.keyCode - 49), + !d3.event.ctrlKey); break; case 97: case 98: @@ -569,19 +528,19 @@ export class GraphView extends View implements PhaseView { case 105: // 'numpad 1'-'numpad 9' showSelectionFrontierNodes(true, - (edge, index) => { return index == (d3.event.keyCode - 97); }, - false); + (edge, index) => index == (d3.event.keyCode - 97), + !d3.event.ctrlKey); break; case 67: // 'c' showSelectionFrontierNodes(d3.event.altKey, - (edge, index) => { return edge.type == 'control'; }, + (edge, index) => edge.type == 'control', true); break; case 69: // 'e' showSelectionFrontierNodes(d3.event.altKey, - (edge, index) => { return edge.type == 'effect'; }, + (edge, index) => edge.type == 'effect', true); break; case 79: @@ -590,21 +549,26 @@ export class GraphView extends View implements PhaseView { break; case 73: // 'i' - showSelectionFrontierNodes(true, undefined, false); + if (!d3.event.ctrlKey && !d3.event.shiftKey) { + showSelectionFrontierNodes(true, undefined, false); + } else { + eventHandled = false; + } break; case 65: // 'a' - graph.selectAllNodes(); - allowRepetition = false; + view.selectAllNodes(); break; case 38: + // UP case 40: { + // DOWN showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true); break; } case 82: // 'r' - if (!d3.event.ctrlKey) { + if (!d3.event.ctrlKey && !d3.event.shiftKey) { this.layoutAction(this); } else { eventHandled = false; @@ -612,11 +576,7 @@ export class GraphView extends View implements PhaseView { break; case 83: // 's' - graph.selectOrigins(); - break; - case 191: - // '/' - document.getElementById("search-input").focus(); + view.selectOrigins(); break; default: eventHandled = false; @@ -625,93 +585,100 @@ export class GraphView extends View implements PhaseView { if (eventHandled) { d3.event.preventDefault(); } - if (!allowRepetition) { - state.lastKeyDown = d3.event.keyCode; - } } - svgKeyUp() { - this.state.lastKeyDown = -1 - }; - layoutGraph() { - layoutNodeGraph(this); + console.time("layoutGraph"); + layoutNodeGraph(this.graph, this.state.showTypes); + const extent = this.graph.redetermineGraphBoundingBox(this.state.showTypes); + this.panZoom.translateExtent(extent); + this.minScale(); + console.timeEnd("layoutGraph"); } selectOrigins() { const state = this.state; const origins = []; - let phase = null; + let phase = this.phaseName; + const selection = new Set<any>(); for (const n of state.selection) { - if (n.origin) { - const node = this.nodeMap[n.origin.nodeId]; - origins.push(node); - phase = n.origin.phase; + const origin = n.nodeLabel.origin; + if (origin) { + phase = origin.phase; + const node = this.graph.nodeMap[origin.nodeId]; + if (phase === this.phaseName && node) { + origins.push(node); + } else { + selection.add(`${origin.nodeId}`); + } } } - if (origins.length) { - state.selection.clear(); - state.selection.select(origins, true); - if (phase) { - this.showPhaseByName(phase); - } + // Only go through phase reselection if we actually need + // to display another phase. + if (selection.size > 0 && phase !== this.phaseName) { + this.showPhaseByName(phase, selection); + } else if (origins.length > 0) { + this.selectionHandler.clear(); + this.selectionHandler.select(origins, true); } } // call to propagate changes to graph updateGraphVisibility() { - let graph = this; - let state = graph.state; + const view = this; + const graph = this.graph; + const state = this.state; + if (!graph) return; - var filteredEdges = graph.edges.filter(function (e) { - return e.isVisible(); - }); - const selEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>("path").data(filteredEdges, edgeToStr); + const filteredEdges = [...graph.filteredEdges(function (e) { + return e.source.visible && e.target.visible; + })]; + const selEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>("path").data(filteredEdges, edgeToStr); // remove old links selEdges.exit().remove(); // add new paths - selEdges.enter() - .append('path') - .style('marker-end', 'url(#end-arrow)') - .classed('hidden', function (e) { - return !e.isVisible(); - }) + const newEdges = selEdges.enter() + .append('path'); + + newEdges.style('marker-end', 'url(#end-arrow)') .attr("id", function (edge) { return "e," + edge.stringID(); }) .on("click", function (edge) { d3.event.stopPropagation(); if (!d3.event.shiftKey) { - graph.selectionHandler.clear(); + view.selectionHandler.clear(); } - graph.selectionHandler.select([edge.source, edge.target], true); + view.selectionHandler.select([edge.source, edge.target], true); }) - .attr("adjacentToHover", "false"); - - // Set the correct styles on all of the paths - selEdges.classed('value', function (e) { - return e.type == 'value' || e.type == 'context'; - }).classed('control', function (e) { - return e.type == 'control'; - }).classed('effect', function (e) { - return e.type == 'effect'; - }).classed('frame-state', function (e) { - return e.type == 'frame-state'; - }).attr('stroke-dasharray', function (e) { - if (e.type == 'frame-state') return "10,10"; - return (e.type == 'effect') ? "5,5" : ""; - }); + .attr("adjacentToHover", "false") + .classed('value', function (e) { + return e.type == 'value' || e.type == 'context'; + }).classed('control', function (e) { + return e.type == 'control'; + }).classed('effect', function (e) { + return e.type == 'effect'; + }).classed('frame-state', function (e) { + return e.type == 'frame-state'; + }).attr('stroke-dasharray', function (e) { + if (e.type == 'frame-state') return "10,10"; + return (e.type == 'effect') ? "5,5" : ""; + }); + + const newAndOldEdges = newEdges.merge(selEdges); + + newAndOldEdges.classed('hidden', e => !e.isVisible()); // select existing nodes - const filteredNodes = graph.nodes.filter(n => n.visible); - const allNodes = graph.visibleNodes.selectAll<SVGGElement, GNode>("g"); + const filteredNodes = [...graph.nodes(n => n.visible)]; + const allNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g"); const selNodes = allNodes.data(filteredNodes, nodeToStr); // remove old nodes selNodes.exit().remove(); // add new nodes - var newGs = selNodes.enter() + const newGs = selNodes.enter() .append("g"); newGs.classed("turbonode", function (n) { return true; }) @@ -723,36 +690,33 @@ export class GraphView extends View implements PhaseView { .classed("simplified", function (n) { return n.isSimplified(); }) .classed("machine", function (n) { return n.isMachine(); }) .on('mouseenter', function (node) { - const visibleEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>('path'); - const adjInputEdges = visibleEdges.filter(e => { return e.target === node; }); - const adjOutputEdges = visibleEdges.filter(e => { return e.source === node; }); + const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path'); + const adjInputEdges = visibleEdges.filter(e => e.target === node); + const adjOutputEdges = visibleEdges.filter(e => e.source === node); adjInputEdges.attr('relToHover', "input"); adjOutputEdges.attr('relToHover', "output"); const adjInputNodes = adjInputEdges.data().map(e => e.source); - const visibleNodes = graph.visibleNodes.selectAll<SVGGElement, GNode>("g"); - const input = visibleNodes.data<GNode>(adjInputNodes, nodeToStr) - .attr('relToHover', "input"); + const visibleNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g"); + visibleNodes.data<GNode>(adjInputNodes, nodeToStr).attr('relToHover', "input"); const adjOutputNodes = adjOutputEdges.data().map(e => e.target); - const output = visibleNodes.data<GNode>(adjOutputNodes, nodeToStr) - .attr('relToHover', "output"); - graph.updateGraphVisibility(); + visibleNodes.data<GNode>(adjOutputNodes, nodeToStr).attr('relToHover', "output"); + view.updateGraphVisibility(); }) .on('mouseleave', function (node) { - const visibleEdges = graph.visibleEdges.selectAll<SVGPathElement, Edge>('path'); - const adjEdges = visibleEdges.filter(e => { return e.target === node || e.source === node; }); + const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path'); + const adjEdges = visibleEdges.filter(e => e.target === node || e.source === node); adjEdges.attr('relToHover', "none"); const adjNodes = adjEdges.data().map(e => e.target).concat(adjEdges.data().map(e => e.source)); - const visibleNodes = graph.visibleNodes.selectAll<SVGPathElement, GNode>("g"); - const nodes = visibleNodes.data(adjNodes, nodeToStr) - .attr('relToHover', "none"); - graph.updateGraphVisibility(); + const visibleNodes = view.visibleNodes.selectAll<SVGPathElement, GNode>("g"); + visibleNodes.data(adjNodes, nodeToStr).attr('relToHover', "none"); + view.updateGraphVisibility(); }) - .on("click", (d) => { - if (!d3.event.shiftKey) graph.selectionHandler.clear(); - graph.selectionHandler.select([d], undefined); + .on("click", d => { + if (!d3.event.shiftKey) view.selectionHandler.clear(); + view.selectionHandler.select([d], undefined); d3.event.stopPropagation(); }) - .call(graph.drag) + .call(view.drag); newGs.append("rect") .attr("rx", 10) @@ -761,14 +725,14 @@ export class GraphView extends View implements PhaseView { return d.getTotalNodeWidth(); }) .attr('height', function (d) { - return graph.getNodeHeight(d); - }) + return d.getNodeHeight(view.state.showTypes); + }); function appendInputAndOutputBubbles(g, d) { - for (var i = 0; i < d.inputs.length; ++i) { - var x = d.getInputX(i); - var y = -DEFAULT_NODE_BUBBLE_RADIUS; - var s = g.append('circle') + for (let i = 0; i < d.inputs.length; ++i) { + const x = d.getInputX(i); + const y = -DEFAULT_NODE_BUBBLE_RADIUS; + g.append('circle') .classed("filledBubbleStyle", function (c) { return d.inputs[i].isVisible(); }) @@ -780,20 +744,20 @@ export class GraphView extends View implements PhaseView { .attr("transform", function (d) { return "translate(" + x + "," + y + ")"; }) - .on("click", function (d) { - var components = this.id.split(','); - var node = graph.nodeMap[components[3]]; - var edge = node.inputs[components[2]]; - var visible = !edge.isVisible(); + .on("click", function (this: SVGCircleElement, d) { + const components = this.id.split(','); + const node = graph.nodeMap[components[3]]; + const edge = node.inputs[components[2]]; + const visible = !edge.isVisible(); node.setInputVisibility(components[2], visible); d3.event.stopPropagation(); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); } if (d.outputs.length != 0) { - var x = d.getOutputX(); - var y = graph.getNodeHeight(d) + DEFAULT_NODE_BUBBLE_RADIUS; - var s = g.append('circle') + const x = d.getOutputX(); + const y = d.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS; + g.append('circle') .classed("filledBubbleStyle", function (c) { return d.areAnyOutputsVisible() == 2; }) @@ -811,7 +775,7 @@ export class GraphView extends View implements PhaseView { .on("click", function (d) { d.setOutputVisibility(d.areAnyOutputsVisible() == 0); d3.event.stopPropagation(); - graph.updateGraphVisibility(); + view.updateGraphVisibility(); }); } } @@ -833,8 +797,8 @@ export class GraphView extends View implements PhaseView { .append("title") .text(function (l) { return d.getTitle(); - }) - if (d.type != undefined) { + }); + if (d.nodeLabel.type != undefined) { d3.select(this).append("text") .classed("label", true) .classed("type", true) @@ -848,14 +812,14 @@ export class GraphView extends View implements PhaseView { .append("title") .text(function (l) { return d.getType(); - }) + }); } }); const newAndOldNodes = newGs.merge(selNodes); newAndOldNodes.select<SVGTextElement>('.type').each(function (d) { - this.setAttribute('visibility', graph.state.showTypes ? 'visible' : 'hidden'); + this.setAttribute('visibility', view.state.showTypes ? 'visible' : 'hidden'); }); newAndOldNodes @@ -865,15 +829,15 @@ export class GraphView extends View implements PhaseView { }) .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }) .select('rect') - .attr('height', function (d) { return graph.getNodeHeight(d); }); + .attr('height', function (d) { return d.getNodeHeight(view.state.showTypes); }); - graph.visibleBubbles = d3.selectAll('circle'); + view.visibleBubbles = d3.selectAll('circle'); - graph.updateInputAndOutputBubbles(); + view.updateInputAndOutputBubbles(); graph.maxGraphX = graph.maxGraphNodeX; - selEdges.attr("d", function (edge) { - return edge.generatePath(graph); + newAndOldEdges.attr("d", function (edge) { + return edge.generatePath(graph, view.state.showTypes); }); } @@ -886,10 +850,9 @@ export class GraphView extends View implements PhaseView { } minScale() { - const graph = this; const dimensions = this.getSvgViewDimensions(); - const minXScale = dimensions[0] / (2 * graph.width); - const minYScale = dimensions[1] / (2 * graph.height); + const minXScale = dimensions[0] / (2 * this.graph.width); + const minYScale = dimensions[1] / (2 * this.graph.height); const minScale = Math.min(minXScale, minYScale); this.panZoom.scaleExtent([minScale, 40]); return minScale; @@ -897,48 +860,49 @@ export class GraphView extends View implements PhaseView { onresize() { const trans = d3.zoomTransform(this.svg.node()); - const ctrans = this.panZoom.constrain()(trans, this.getSvgExtent(), this.panZoom.translateExtent()) - this.panZoom.transform(this.svg, ctrans) + const ctrans = this.panZoom.constrain()(trans, this.getSvgExtent(), this.panZoom.translateExtent()); + this.panZoom.transform(this.svg, ctrans); } toggleTypes() { - var graph = this; - graph.state.showTypes = !graph.state.showTypes; - var element = document.getElementById('toggle-types'); - element.classList.toggle('button-input-toggled', graph.state.showTypes); - graph.updateGraphVisibility(); + const view = this; + view.state.showTypes = !view.state.showTypes; + const element = document.getElementById('toggle-types'); + element.classList.toggle('button-input-toggled', view.state.showTypes); + view.updateGraphVisibility(); } viewSelection() { - var graph = this; - var minX, maxX, minY, maxY; - var hasSelection = false; - graph.visibleNodes.selectAll<SVGGElement, GNode>("g").each(function (n) { - if (graph.state.selection.isSelected(n)) { + const view = this; + let minX; + let maxX; + let minY; + let maxY; + let hasSelection = false; + view.visibleNodes.selectAll<SVGGElement, GNode>("g").each(function (n) { + if (view.state.selection.isSelected(n)) { hasSelection = true; minX = minX ? Math.min(minX, n.x) : n.x; maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) : n.x + n.getTotalNodeWidth(); minY = minY ? Math.min(minY, n.y) : n.y; - maxY = maxY ? Math.max(maxY, n.y + graph.getNodeHeight(n)) : - n.y + graph.getNodeHeight(n); + maxY = maxY ? Math.max(maxY, n.y + n.getNodeHeight(view.state.showTypes)) : + n.y + n.getNodeHeight(view.state.showTypes); } }); if (hasSelection) { - graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, - maxX + NODE_INPUT_WIDTH, maxY + 60, - true); + view.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, + maxX + NODE_INPUT_WIDTH, maxY + 60); } } - viewGraphRegion(minX, minY, maxX, maxY, transition) { + viewGraphRegion(minX, minY, maxX, maxY) { const [width, height] = this.getSvgViewDimensions(); const dx = maxX - minX; const dy = maxY - minY; const x = (minX + maxX) / 2; const y = (minY + maxY) / 2; const scale = Math.min(width / (1.1 * dx), height / (1.1 * dy)); - const transform = d3.zoomIdentity.translate(1500, 100).scale(0.75); this.svg .transition().duration(300).call(this.panZoom.translateTo, x, y) .transition().duration(300).call(this.panZoom.scaleTo, scale) @@ -947,6 +911,8 @@ export class GraphView extends View implements PhaseView { viewWholeGraph() { this.panZoom.scaleTo(this.svg, 0); - this.panZoom.translateTo(this.svg, this.minGraphX + this.width / 2, this.minGraphY + this.height / 2) + this.panZoom.translateTo(this.svg, + this.graph.minGraphX + this.graph.width / 2, + this.graph.minGraphY + this.graph.height / 2); } } diff --git a/deps/v8/tools/turbolizer/src/graph.ts b/deps/v8/tools/turbolizer/src/graph.ts new file mode 100644 index 0000000000..0eb2e3e1e6 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/graph.ts @@ -0,0 +1,107 @@ +import { GNode } from "./node"; +import { Edge, MINIMUM_EDGE_SEPARATION } from "./edge"; + +export class Graph { + nodeMap: Array<GNode>; + minGraphX: number; + maxGraphX: number; + minGraphY: number; + maxGraphY: number; + maxGraphNodeX: number; + maxBackEdgeNumber: number; + width: number; + height: number; + + constructor(data: any) { + this.nodeMap = []; + + this.minGraphX = 0; + this.maxGraphX = 1; + this.minGraphY = 0; + this.maxGraphY = 1; + this.width = 1; + this.height = 1; + + data.nodes.forEach((jsonNode: any) => { + this.nodeMap[jsonNode.id] = new GNode(jsonNode.nodeLabel); + }); + + data.edges.forEach((e: any) => { + const t = this.nodeMap[e.target]; + const s = this.nodeMap[e.source]; + const newEdge = new Edge(t, e.index, s, e.type); + t.inputs.push(newEdge); + s.outputs.push(newEdge); + if (e.type == 'control') { + // Every source of a control edge is a CFG node. + s.cfg = true; + } + }); + + } + + *nodes(p = (n: GNode) => true) { + for (const node of this.nodeMap) { + if (!node || !p(node)) continue; + yield node; + } + } + + *filteredEdges(p: (e: Edge) => boolean) { + for (const node of this.nodes()) { + for (const edge of node.inputs) { + if (p(edge)) yield edge; + } + } + } + + forEachEdge(p: (e: Edge) => void) { + for (const node of this.nodeMap) { + if (!node) continue; + for (const edge of node.inputs) { + p(edge); + } + } + } + + redetermineGraphBoundingBox(showTypes: boolean): [[number, number], [number, number]] { + this.minGraphX = 0; + this.maxGraphNodeX = 1; + this.maxGraphX = undefined; // see below + this.minGraphY = 0; + this.maxGraphY = 1; + + for (const node of this.nodes()) { + if (!node.visible) { + continue; + } + + if (node.x < this.minGraphX) { + this.minGraphX = node.x; + } + if ((node.x + node.getTotalNodeWidth()) > this.maxGraphNodeX) { + this.maxGraphNodeX = node.x + node.getTotalNodeWidth(); + } + if ((node.y - 50) < this.minGraphY) { + this.minGraphY = node.y - 50; + } + if ((node.y + node.getNodeHeight(showTypes) + 50) > this.maxGraphY) { + this.maxGraphY = node.y + node.getNodeHeight(showTypes) + 50; + } + } + + this.maxGraphX = this.maxGraphNodeX + + this.maxBackEdgeNumber * MINIMUM_EDGE_SEPARATION; + + this.width = this.maxGraphX - this.minGraphX; + this.height = this.maxGraphY - this.minGraphY; + + const extent: [[number, number], [number, number]] = [ + [this.minGraphX - this.width / 2, this.minGraphY - this.height / 2], + [this.maxGraphX + this.width / 2, this.maxGraphY + this.height / 2] + ]; + + return extent; + } + +} diff --git a/deps/v8/tools/turbolizer/src/graphmultiview.ts b/deps/v8/tools/turbolizer/src/graphmultiview.ts index f9e7efb58c..43ec418ee0 100644 --- a/deps/v8/tools/turbolizer/src/graphmultiview.ts +++ b/deps/v8/tools/turbolizer/src/graphmultiview.ts @@ -2,12 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {GraphView} from "./graph-view.js" -import {ScheduleView} from "./schedule-view.js" -import {SequenceView} from "./sequence-view.js" -import {SourceResolver} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {View, PhaseView} from "./view.js" +import { GraphView } from "../src/graph-view"; +import { ScheduleView } from "../src/schedule-view"; +import { SequenceView } from "../src/sequence-view"; +import { SourceResolver } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { View, PhaseView } from "../src/view"; + +const multiviewID = "multiview"; + +const toolboxHTML = ` +<div class="graph-toolbox"> + <select id="phase-select"> + <option disabled selected>(please open a file)</option> + </select> + <input id="search-input" type="text" title="search nodes for regex" alt="search node for regex" class="search-input" + placeholder="find with regexp…"> + <label><input id="search-only-visible" type="checkbox" name="instruction-address" alt="Apply search to visible nodes only">only visible</label> +</div>`; export class GraphMultiView extends View { sourceResolver: SourceResolver; @@ -16,11 +28,12 @@ export class GraphMultiView extends View { schedule: ScheduleView; sequence: SequenceView; selectMenu: HTMLSelectElement; - currentPhaseView: View & PhaseView; + currentPhaseView: PhaseView; createViewElement() { - const pane = document.createElement('div'); - pane.setAttribute('id', "multiview"); + const pane = document.createElement("div"); + pane.setAttribute("id", multiviewID); + pane.className = "viewpane"; return pane; } @@ -29,35 +42,50 @@ export class GraphMultiView extends View { const view = this; view.sourceResolver = sourceResolver; view.selectionBroker = selectionBroker; - const searchInput = document.getElementById("search-input") as HTMLInputElement; + const toolbox = document.createElement("div"); + toolbox.className = "toolbox-anchor"; + toolbox.innerHTML = toolboxHTML; + view.divNode.appendChild(toolbox); + const searchInput = toolbox.querySelector("#search-input") as HTMLInputElement; + const onlyVisibleCheckbox = toolbox.querySelector("#search-only-visible") as HTMLInputElement; searchInput.addEventListener("keyup", e => { if (!view.currentPhaseView) return; - view.currentPhaseView.searchInputAction(searchInput, e) + view.currentPhaseView.searchInputAction(searchInput, e, onlyVisibleCheckbox.checked); + }); + view.divNode.addEventListener("keyup", (e: KeyboardEvent) => { + if (e.keyCode == 191) { // keyCode == '/' + searchInput.focus(); + } }); searchInput.setAttribute("value", window.sessionStorage.getItem("lastSearch") || ""); - this.graph = new GraphView(id, selectionBroker, - (phaseName) => view.displayPhaseByName(phaseName)); - this.schedule = new ScheduleView(id, selectionBroker); - this.sequence = new SequenceView(id, selectionBroker); - this.selectMenu = (<HTMLSelectElement>document.getElementById('display-selector')); + this.graph = new GraphView(this.divNode, selectionBroker, view.displayPhaseByName.bind(this), + toolbox.querySelector(".graph-toolbox")); + this.schedule = new ScheduleView(this.divNode, selectionBroker); + this.sequence = new SequenceView(this.divNode, selectionBroker); + this.selectMenu = toolbox.querySelector("#phase-select") as HTMLSelectElement; } initializeSelect() { const view = this; - view.selectMenu.innerHTML = ''; - view.sourceResolver.forEachPhase((phase) => { + view.selectMenu.innerHTML = ""; + view.sourceResolver.forEachPhase(phase => { const optionElement = document.createElement("option"); - optionElement.text = phase.name; + let maxNodeId = ""; + if (phase.type == "graph" && phase.highestNodeId != 0) { + maxNodeId = ` ${phase.highestNodeId}`; + } + optionElement.text = `${phase.name}${maxNodeId}`; view.selectMenu.add(optionElement); }); this.selectMenu.onchange = function (this: HTMLSelectElement) { - window.sessionStorage.setItem("lastSelectedPhase", this.selectedIndex.toString()); - view.displayPhase(view.sourceResolver.getPhase(this.selectedIndex)); - } + const phaseIndex = this.selectedIndex; + window.sessionStorage.setItem("lastSelectedPhase", phaseIndex.toString()); + view.displayPhase(view.sourceResolver.getPhase(phaseIndex)); + }; } - show(data, rememberedSelection) { - super.show(data, rememberedSelection); + show() { + super.show(); this.initializeSelect(); const lastPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase"); const initialPhaseIndex = this.sourceResolver.repairPhaseId(lastPhaseIndex); @@ -65,29 +93,27 @@ export class GraphMultiView extends View { this.displayPhase(this.sourceResolver.getPhase(initialPhaseIndex)); } - initializeContent() { } - - displayPhase(phase) { - if (phase.type == 'graph') { - this.displayPhaseView(this.graph, phase.data); - } else if (phase.type == 'schedule') { - this.displayPhaseView(this.schedule, phase); - } else if (phase.type == 'sequence') { - this.displayPhaseView(this.sequence, phase); + displayPhase(phase, selection?: Set<any>) { + if (phase.type == "graph") { + this.displayPhaseView(this.graph, phase, selection); + } else if (phase.type == "schedule") { + this.displayPhaseView(this.schedule, phase, selection); + } else if (phase.type == "sequence") { + this.displayPhaseView(this.sequence, phase, selection); } } - displayPhaseView(view, data) { - const rememberedSelection = this.hideCurrentPhase(); - view.show(data, rememberedSelection); - document.getElementById("middle").classList.toggle("scrollable", view.isScrollable()); + displayPhaseView(view: PhaseView, data, selection?: Set<any>) { + const rememberedSelection = selection ? selection : this.hideCurrentPhase(); + view.initializeContent(data, rememberedSelection); + this.divNode.classList.toggle("scrollable", view.isScrollable()); this.currentPhaseView = view; } - displayPhaseByName(phaseName) { + displayPhaseByName(phaseName, selection?: Set<any>) { const phaseId = this.sourceResolver.getPhaseIdByName(phaseName); - this.selectMenu.selectedIndex = phaseId - 1; - this.displayPhase(this.sourceResolver.getPhase(phaseId)); + this.selectMenu.selectedIndex = phaseId; + this.displayPhase(this.sourceResolver.getPhase(phaseId), selection); } hideCurrentPhase() { @@ -104,10 +130,6 @@ export class GraphMultiView extends View { if (this.currentPhaseView) this.currentPhaseView.onresize(); } - deleteContent() { - this.hideCurrentPhase(); - } - detachSelection() { return null; } diff --git a/deps/v8/tools/turbolizer/src/info-view.ts b/deps/v8/tools/turbolizer/src/info-view.ts new file mode 100644 index 0000000000..38585365ff --- /dev/null +++ b/deps/v8/tools/turbolizer/src/info-view.ts @@ -0,0 +1,17 @@ +import { View } from "./view"; + +export class InfoView extends View { + + constructor(idOrContainer: HTMLElement | string) { + super(idOrContainer); + fetch("info-view.html") + .then(response => response.text()) + .then(htmlText => this.divNode.innerHTML = htmlText); + } + + createViewElement(): HTMLElement { + const infoContainer = document.createElement("div"); + infoContainer.classList.add("info-container"); + return infoContainer; + } +} diff --git a/deps/v8/tools/turbolizer/src/lang-disassembly.ts b/deps/v8/tools/turbolizer/src/lang-disassembly.ts deleted file mode 100644 index 9312627abd..0000000000 --- a/deps/v8/tools/turbolizer/src/lang-disassembly.ts +++ /dev/null @@ -1,14 +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. - -PR.registerLangHandler( - PR.createSimpleLexer( - [ - [PR.PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$))/, null, '\''], - [PR.PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0'] - ], - [ // fallthroughStylePatterns - [PR.PR_COMMENT, /;; debug: position \d+/, null], - ]), - ['disassembly']); diff --git a/deps/v8/tools/turbolizer/src/node-label.ts b/deps/v8/tools/turbolizer/src/node-label.ts new file mode 100644 index 0000000000..6e7d41d899 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/node-label.ts @@ -0,0 +1,86 @@ +// Copyright 2019 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 formatOrigin(origin) { + if (origin.nodeId) { + return `#${origin.nodeId} in phase ${origin.phase}/${origin.reducer}`; + } + if (origin.bytecodePosition) { + return `Bytecode line ${origin.bytecodePosition} in phase ${origin.phase}/${origin.reducer}`; + } + return "unknown origin"; +} + +export class NodeLabel { + id: number; + label: string; + title: string; + live: boolean; + properties: string; + sourcePosition: any; + origin: any; + opcode: string; + control: boolean; + opinfo: string; + type: string; + inplaceUpdatePhase: string; + + constructor(id: number, label: string, title: string, live: boolean, properties: string, sourcePosition: any, origin: any, opcode: string, control: boolean, opinfo: string, type: string) { + this.id = id; + this.label = label; + this.title = title; + this.live = live; + this.properties = properties; + this.sourcePosition = sourcePosition; + this.origin = origin; + this.opcode = opcode; + this.control = control; + this.opinfo = opinfo; + this.type = type; + this.inplaceUpdatePhase = null; + } + + equals(that?: NodeLabel) { + if (!that) return false; + if (this.id != that.id) return false; + if (this.label != that.label) return false; + if (this.title != that.title) return false; + if (this.live != that.live) return false; + if (this.properties != that.properties) return false; + if (this.opcode != that.opcode) return false; + if (this.control != that.control) return false; + if (this.opinfo != that.opinfo) return false; + if (this.type != that.type) return false; + return true; + } + + getTitle() { + let propsString = ""; + if (this.properties === "") { + propsString = "no properties"; + } else { + propsString = "[" + this.properties + "]"; + } + let title = this.title + "\n" + propsString + "\n" + this.opinfo; + if (this.origin) { + title += `\nOrigin: ${formatOrigin(this.origin)}`; + } + if (this.inplaceUpdatePhase) { + title += `\nInplace update in phase: ${this.inplaceUpdatePhase}`; + } + return title; + } + + getDisplayLabel() { + const result = `${this.id}: ${this.label}`; + if (result.length > 40) { + return `${this.id}: ${this.opcode}`; + } + return result; + } + + setInplaceUpdatePhase(name: string): any { + this.inplaceUpdatePhase = name; + } +} diff --git a/deps/v8/tools/turbolizer/src/node.ts b/deps/v8/tools/turbolizer/src/node.ts index 95c47cab20..02906d1204 100644 --- a/deps/v8/tools/turbolizer/src/node.ts +++ b/deps/v8/tools/turbolizer/src/node.ts @@ -2,120 +2,111 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {NodeOrigin} from "./source-resolver.js" -import {MINIMUM_EDGE_SEPARATION} from "./edge.js" +import { MINIMUM_EDGE_SEPARATION, Edge } from "../src/edge"; +import { NodeLabel } from "./node-label"; +import { MAX_RANK_SENTINEL } from "./constants"; +import { alignUp, measureText } from "./util"; export const DEFAULT_NODE_BUBBLE_RADIUS = 12; export const NODE_INPUT_WIDTH = 50; export const MINIMUM_NODE_OUTPUT_APPROACH = 15; const MINIMUM_NODE_INPUT_APPROACH = 15 + 2 * DEFAULT_NODE_BUBBLE_RADIUS; -export function isNodeInitiallyVisible(node) { - return node.cfg; -} - -function formatOrigin(origin) { - if (origin.nodeId) { - return `#${origin.nodeId} in phase ${origin.phase}/${origin.reducer}`; - } - if (origin.bytecodePosition) { - return `Bytecode line ${origin.bytecodePosition} in phase ${origin.phase}/${origin.reducer}`; - } - return "unknown origin"; -} - export class GNode { - control: boolean; - opcode: string; - live: boolean; - inputs: Array<any>; - width: number; - properties: string; - title: string; - label: string; - origin: NodeOrigin; - outputs: Array<any>; - outputApproach: number; - type: string; id: number; + nodeLabel: NodeLabel; + displayLabel: string; + inputs: Array<Edge>; + outputs: Array<Edge>; + visible: boolean; x: number; y: number; - visible: boolean; rank: number; - opinfo: string; + outputApproach: number; + cfg: boolean; labelbbox: { width: number, height: number }; + width: number; + normalheight: number; + visitOrderWithinRank: number; + + constructor(nodeLabel: NodeLabel) { + this.id = nodeLabel.id; + this.nodeLabel = nodeLabel; + this.displayLabel = nodeLabel.getDisplayLabel(); + this.inputs = []; + this.outputs = []; + this.visible = false; + this.x = 0; + this.y = 0; + this.rank = MAX_RANK_SENTINEL; + this.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; + // Every control node is a CFG node. + this.cfg = nodeLabel.control; + this.labelbbox = measureText(this.displayLabel); + const typebbox = measureText(this.getDisplayType()); + const innerwidth = Math.max(this.labelbbox.width, typebbox.width); + this.width = alignUp(innerwidth + NODE_INPUT_WIDTH * 2, + NODE_INPUT_WIDTH); + const innerheight = Math.max(this.labelbbox.height, typebbox.height); + this.normalheight = innerheight + 20; + this.visitOrderWithinRank = 0; + } isControl() { - return this.control; + return this.nodeLabel.control; } isInput() { - return this.opcode == 'Parameter' || this.opcode.endsWith('Constant'); + return this.nodeLabel.opcode == 'Parameter' || this.nodeLabel.opcode.endsWith('Constant'); } isLive() { - return this.live !== false; + return this.nodeLabel.live !== false; } isJavaScript() { - return this.opcode.startsWith('JS'); + return this.nodeLabel.opcode.startsWith('JS'); } isSimplified() { if (this.isJavaScript()) return false; - return this.opcode.endsWith('Phi') || - this.opcode.startsWith('Boolean') || - this.opcode.startsWith('Number') || - this.opcode.startsWith('String') || - this.opcode.startsWith('Change') || - this.opcode.startsWith('Object') || - this.opcode.startsWith('Reference') || - this.opcode.startsWith('Any') || - this.opcode.endsWith('ToNumber') || - (this.opcode == 'AnyToBoolean') || - (this.opcode.startsWith('Load') && this.opcode.length > 4) || - (this.opcode.startsWith('Store') && this.opcode.length > 5); + const opcode = this.nodeLabel.opcode; + return opcode.endsWith('Phi') || + opcode.startsWith('Boolean') || + opcode.startsWith('Number') || + opcode.startsWith('String') || + opcode.startsWith('Change') || + opcode.startsWith('Object') || + opcode.startsWith('Reference') || + opcode.startsWith('Any') || + opcode.endsWith('ToNumber') || + (opcode == 'AnyToBoolean') || + (opcode.startsWith('Load') && opcode.length > 4) || + (opcode.startsWith('Store') && opcode.length > 5); } isMachine() { return !(this.isControl() || this.isInput() || this.isJavaScript() || this.isSimplified()); } getTotalNodeWidth() { - var inputWidth = this.inputs.length * NODE_INPUT_WIDTH; + const inputWidth = this.inputs.length * NODE_INPUT_WIDTH; return Math.max(inputWidth, this.width); } getTitle() { - var propsString; - if (this.properties === undefined) { - propsString = ""; - } else if (this.properties === "") { - propsString = "no properties"; - } else { - propsString = "[" + this.properties + "]"; - } - let title = this.title + "\n" + propsString + "\n" + this.opinfo; - if (this.origin) { - title += `\nOrigin: ${formatOrigin(this.origin)}`; - } - return title; + return this.nodeLabel.getTitle(); } getDisplayLabel() { - var result = this.id + ":" + this.label; - if (result.length > 40) { - return this.id + ":" + this.opcode; - } else { - return result; - } + return this.nodeLabel.getDisplayLabel(); } getType() { - return this.type; + return this.nodeLabel.type; } getDisplayType() { - var type_string = this.type; - if (type_string == undefined) return ""; - if (type_string.length > 24) { - type_string = type_string.substr(0, 25) + "..."; + let typeString = this.nodeLabel.type; + if (typeString == undefined) return ""; + if (typeString.length > 24) { + typeString = typeString.substr(0, 25) + "..."; } - return type_string; + return typeString; } deepestInputRank() { - var deepestRank = 0; + let deepestRank = 0; this.inputs.forEach(function (e) { if (e.isVisible() && !e.isBackEdge()) { if (e.source.rank > deepestRank) { @@ -126,14 +117,14 @@ export class GNode { return deepestRank; } areAnyOutputsVisible() { - var visibleCount = 0; + let visibleCount = 0; this.outputs.forEach(function (e) { if (e.isVisible())++visibleCount; }); if (this.outputs.length == visibleCount) return 2; if (visibleCount != 0) return 1; return 0; } setOutputVisibility(v) { - var result = false; + let result = false; this.outputs.forEach(function (e) { e.visible = v; if (v) { @@ -146,7 +137,7 @@ export class GNode { return result; } setInputVisibility(i, v) { - var edge = this.inputs[i]; + const edge = this.inputs[i]; edge.visible = v; if (v) { if (!edge.source.visible) { @@ -158,14 +149,21 @@ export class GNode { } getInputApproach(index) { return this.y - MINIMUM_NODE_INPUT_APPROACH - - (index % 4) * MINIMUM_EDGE_SEPARATION - DEFAULT_NODE_BUBBLE_RADIUS + (index % 4) * MINIMUM_EDGE_SEPARATION - DEFAULT_NODE_BUBBLE_RADIUS; } - getOutputApproach(graph) { - return this.y + this.outputApproach + graph.getNodeHeight(this) + + getNodeHeight(showTypes: boolean): number { + if (showTypes) { + return this.normalheight + this.labelbbox.height; + } else { + return this.normalheight; + } + } + getOutputApproach(showTypes: boolean) { + return this.y + this.outputApproach + this.getNodeHeight(showTypes) + + DEFAULT_NODE_BUBBLE_RADIUS; } getInputX(index) { - var result = this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2) + + const result = this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2) + (index - this.inputs.length + 1) * NODE_INPUT_WIDTH; return result; } @@ -173,10 +171,10 @@ export class GNode { return this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2); } hasBackEdges() { - return (this.opcode == "Loop") || - ((this.opcode == "Phi" || this.opcode == "EffectPhi") && - this.inputs[this.inputs.length - 1].source.opcode == "Loop"); + return (this.nodeLabel.opcode == "Loop") || + ((this.nodeLabel.opcode == "Phi" || this.nodeLabel.opcode == "EffectPhi" || this.nodeLabel.opcode == "InductionVariablePhi") && + this.inputs[this.inputs.length - 1].source.nodeLabel.opcode == "Loop"); } -}; +} export const nodeToStr = (n: GNode) => "N" + n.id; diff --git a/deps/v8/tools/turbolizer/src/resizer.ts b/deps/v8/tools/turbolizer/src/resizer.ts new file mode 100644 index 0000000000..ec2d68c0e2 --- /dev/null +++ b/deps/v8/tools/turbolizer/src/resizer.ts @@ -0,0 +1,199 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as d3 from "d3"; +import * as C from "../src/constants"; + +class Snapper { + resizer: Resizer; + sourceExpand: HTMLElement; + sourceCollapse: HTMLElement; + disassemblyExpand: HTMLElement; + disassemblyCollapse: HTMLElement; + + constructor(resizer: Resizer) { + this.resizer = resizer; + this.sourceExpand = document.getElementById(C.SOURCE_EXPAND_ID); + this.sourceCollapse = document.getElementById(C.SOURCE_COLLAPSE_ID); + this.disassemblyExpand = document.getElementById(C.DISASSEMBLY_EXPAND_ID); + this.disassemblyCollapse = document.getElementById(C.DISASSEMBLY_COLLAPSE_ID); + + document.getElementById("source-collapse").addEventListener("click", () => { + this.setSourceExpanded(!this.sourceExpand.classList.contains("invisible")); + this.resizer.updatePanes(); + }); + document.getElementById("disassembly-collapse").addEventListener("click", () => { + this.setDisassemblyExpanded(!this.disassemblyExpand.classList.contains("invisible")); + this.resizer.updatePanes(); + }); + } + + restoreExpandedState(): void { + this.setSourceExpanded(this.getLastExpandedState("source", true)); + this.setDisassemblyExpanded(this.getLastExpandedState("disassembly", false)); + } + + getLastExpandedState(type: string, defaultState: boolean): boolean { + const state = window.sessionStorage.getItem("expandedState-" + type); + if (state === null) return defaultState; + return state === 'true'; + } + + sourceExpandUpdate(newState: boolean): void { + window.sessionStorage.setItem("expandedState-source", `${newState}`); + this.sourceExpand.classList.toggle("invisible", newState); + this.sourceCollapse.classList.toggle("invisible", !newState); + } + + setSourceExpanded(newState: boolean): void { + if (this.sourceExpand.classList.contains("invisible") === newState) return; + const resizer = this.resizer; + this.sourceExpandUpdate(newState); + if (newState) { + resizer.sepLeft = resizer.sepLeftSnap; + resizer.sepLeftSnap = 0; + } else { + resizer.sepLeftSnap = resizer.sepLeft; + resizer.sepLeft = 0; + } + } + + disassemblyExpandUpdate(newState: boolean): void { + window.sessionStorage.setItem("expandedState-disassembly", `${newState}`); + this.disassemblyExpand.classList.toggle("invisible", newState); + this.disassemblyCollapse.classList.toggle("invisible", !newState); + } + + setDisassemblyExpanded(newState: boolean): void { + if (this.disassemblyExpand.classList.contains("invisible") === newState) return; + const resizer = this.resizer; + this.disassemblyExpandUpdate(newState); + if (newState) { + resizer.sepRight = resizer.sepRightSnap; + resizer.sepRightSnap = resizer.clientWidth; + } else { + resizer.sepRightSnap = resizer.sepRight; + resizer.sepRight = resizer.clientWidth; + } + } + + panesUpdated(): void { + this.sourceExpandUpdate(this.resizer.sepLeft > this.resizer.deadWidth); + this.disassemblyExpandUpdate(this.resizer.sepRight < + (this.resizer.clientWidth - this.resizer.deadWidth)); + } +} + +export class Resizer { + snapper: Snapper; + deadWidth: number; + clientWidth: number; + left: HTMLElement; + right: HTMLElement; + middle: HTMLElement; + sepLeft: number; + sepRight: number; + sepLeftSnap: number; + sepRightSnap: number; + sepWidthOffset: number; + panesUpdatedCallback: () => void; + resizerRight: d3.Selection<HTMLDivElement, any, any, any>; + resizerLeft: d3.Selection<HTMLDivElement, any, any, any>; + + constructor(panesUpdatedCallback: () => void, deadWidth: number) { + const resizer = this; + resizer.panesUpdatedCallback = panesUpdatedCallback; + resizer.deadWidth = deadWidth; + resizer.left = document.getElementById(C.SOURCE_PANE_ID); + resizer.middle = document.getElementById(C.INTERMEDIATE_PANE_ID); + resizer.right = document.getElementById(C.GENERATED_PANE_ID); + resizer.resizerLeft = d3.select('#resizer-left'); + resizer.resizerRight = d3.select('#resizer-right'); + resizer.sepLeftSnap = 0; + resizer.sepRightSnap = 0; + // Offset to prevent resizers from sliding slightly over one another. + resizer.sepWidthOffset = 7; + this.updateWidths(); + + const dragResizeLeft = d3.drag() + .on('drag', function () { + const x = d3.mouse(this.parentElement)[0]; + resizer.sepLeft = Math.min(Math.max(0, x), resizer.sepRight - resizer.sepWidthOffset); + resizer.updatePanes(); + }) + .on('start', function () { + resizer.resizerLeft.classed("dragged", true); + const x = d3.mouse(this.parentElement)[0]; + if (x > deadWidth) { + resizer.sepLeftSnap = resizer.sepLeft; + } + }) + .on('end', function () { + if (!resizer.isRightSnapped()) { + window.sessionStorage.setItem("source-pane-width", `${resizer.sepLeft / resizer.clientWidth}`); + } + resizer.resizerLeft.classed("dragged", false); + }); + resizer.resizerLeft.call(dragResizeLeft); + + const dragResizeRight = d3.drag() + .on('drag', function () { + const x = d3.mouse(this.parentElement)[0]; + resizer.sepRight = Math.max(resizer.sepLeft + resizer.sepWidthOffset, Math.min(x, resizer.clientWidth)); + resizer.updatePanes(); + }) + .on('start', function () { + resizer.resizerRight.classed("dragged", true); + const x = d3.mouse(this.parentElement)[0]; + if (x < (resizer.clientWidth - deadWidth)) { + resizer.sepRightSnap = resizer.sepRight; + } + }) + .on('end', function () { + if (!resizer.isRightSnapped()) { + console.log(`disassembly-pane-width ${resizer.sepRight}`); + window.sessionStorage.setItem("disassembly-pane-width", `${resizer.sepRight / resizer.clientWidth}`); + } + resizer.resizerRight.classed("dragged", false); + }); + resizer.resizerRight.call(dragResizeRight); + window.onresize = function () { + resizer.updateWidths(); + resizer.updatePanes(); + }; + resizer.snapper = new Snapper(resizer); + resizer.snapper.restoreExpandedState(); + } + + isLeftSnapped() { + return this.sepLeft === 0; + } + + isRightSnapped() { + return this.sepRight >= this.clientWidth - 1; + } + + updatePanes() { + const leftSnapped = this.isLeftSnapped(); + const rightSnapped = this.isRightSnapped(); + this.resizerLeft.classed("snapped", leftSnapped); + this.resizerRight.classed("snapped", rightSnapped); + this.left.style.width = this.sepLeft + 'px'; + this.middle.style.width = (this.sepRight - this.sepLeft) + 'px'; + this.right.style.width = (this.clientWidth - this.sepRight) + 'px'; + this.resizerLeft.style('left', this.sepLeft + 'px'); + this.resizerRight.style('right', (this.clientWidth - this.sepRight - 1) + 'px'); + + this.snapper.panesUpdated(); + this.panesUpdatedCallback(); + } + + updateWidths() { + this.clientWidth = document.body.getBoundingClientRect().width; + const sepLeft = window.sessionStorage.getItem("source-pane-width"); + this.sepLeft = this.clientWidth * (sepLeft ? Number.parseFloat(sepLeft) : (1 / 3)); + const sepRight = window.sessionStorage.getItem("disassembly-pane-width"); + this.sepRight = this.clientWidth * (sepRight ? Number.parseFloat(sepRight) : (2 / 3)); + } +} diff --git a/deps/v8/tools/turbolizer/src/schedule-view.ts b/deps/v8/tools/turbolizer/src/schedule-view.ts index f62aba0c86..ed36d126fd 100644 --- a/deps/v8/tools/turbolizer/src/schedule-view.ts +++ b/deps/v8/tools/turbolizer/src/schedule-view.ts @@ -2,12 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Schedule,SourceResolver} from "./source-resolver.js" -import {isIterable} from "./util.js" -import {PhaseView} from "./view.js" -import {TextView} from "./text-view.js" +import { Schedule, SourceResolver } from "../src/source-resolver"; +import { TextView } from "../src/text-view"; -export class ScheduleView extends TextView implements PhaseView { +export class ScheduleView extends TextView { schedule: Schedule; sourceResolver: SourceResolver; @@ -18,7 +16,7 @@ export class ScheduleView extends TextView implements PhaseView { } constructor(parentId, broker) { - super(parentId, broker, null); + super(parentId, broker); this.sourceResolver = broker.sourceResolver; } @@ -39,26 +37,23 @@ export class ScheduleView extends TextView implements PhaseView { initializeContent(data, rememberedSelection) { this.divNode.innerHTML = ''; - this.schedule = data.schedule + this.schedule = data.schedule; this.addBlocks(data.schedule.blocks); this.attachSelection(rememberedSelection); + this.show(); } createElementFromString(htmlString) { - var div = document.createElement('div'); + const div = document.createElement('div'); div.innerHTML = htmlString.trim(); return div.firstChild; } elementForBlock(block) { const view = this; - function createElement(tag: string, cls: string | Array<string>, content?: string) { + function createElement(tag: string, cls: string, content?: string) { const el = document.createElement(tag); - if (isIterable(cls)) { - for (const c of cls) el.classList.add(c); - } else { - el.classList.add(cls); - } + el.className = cls; if (content != undefined) el.innerHTML = content; return el; } @@ -76,15 +71,15 @@ export class ScheduleView extends TextView implements PhaseView { function getMarker(start, end) { if (start != end) { return ["⊙", `This node generated instructions in range [${start},${end}). ` + - `This is currently unreliable for constants.`]; + `This is currently unreliable for constants.`]; } if (start != -1) { return ["·", `The instruction selector did not generate instructions ` + - `for this node, but processed the node at instruction ${start}. ` + - `This usually means that this node was folded into another node; ` + - `the highlighted machine code is a guess.`]; + `for this node, but processed the node at instruction ${start}. ` + + `This usually means that this node was folded into another node; ` + + `the highlighted machine code is a guess.`]; } - return ["", `This not is not in the final schedule.`] + return ["", `This not is not in the final schedule.`]; } function createElementForNode(node) { @@ -92,27 +87,26 @@ export class ScheduleView extends TextView implements PhaseView { const [start, end] = view.sourceResolver.getInstruction(node.id); const [marker, tooltip] = getMarker(start, end); - const instrMarker = createElement("div", ["instr-marker", "com"], marker); + const instrMarker = createElement("div", "instr-marker com", marker); instrMarker.setAttribute("title", tooltip); instrMarker.onclick = mkNodeLinkHandler(node.id); nodeEl.appendChild(instrMarker); - - 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); + const nodeId = createElement("div", "node-id tag clickable", node.id); + nodeId.onclick = mkNodeLinkHandler(node.id); + view.addHtmlElementForNodeId(node.id, nodeId); + nodeEl.appendChild(nodeId); + const nodeLabel = createElement("div", "node-label", node.label); + nodeEl.appendChild(nodeLabel); if (node.inputs.length > 0) { - const node_parameters = createElement("div", ["parameter-list", "comma-sep-list"]); + const nodeParameters = 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); + const paramEl = createElement("div", "parameter tag clickable", param); + nodeParameters.appendChild(paramEl); paramEl.onclick = mkNodeLinkHandler(param); view.addHtmlElementForNodeId(param, paramEl); } - nodeEl.appendChild(node_parameters); + nodeEl.appendChild(nodeParameters); } return nodeEl; @@ -128,38 +122,38 @@ export class ScheduleView extends TextView implements PhaseView { }; } - const schedule_block = createElement("div", "schedule-block"); + const scheduleBlock = createElement("div", "schedule-block"); const [start, end] = view.sourceResolver.getInstructionRangeForBlock(block.id); - const instrMarker = createElement("div", ["instr-marker", "com"], "⊙"); - instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`) + const instrMarker = createElement("div", "instr-marker com", "⊙"); + instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`); instrMarker.onclick = mkBlockLinkHandler(block.id); - schedule_block.appendChild(instrMarker); + scheduleBlock.appendChild(instrMarker); - 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"]); + const blockId = createElement("div", "block-id com clickable", block.id); + blockId.onclick = mkBlockLinkHandler(block.id); + scheduleBlock.appendChild(blockId); + const blockPred = createElement("div", "predecessor-list block-list comma-sep-list"); for (const pred of block.pred) { - const predEl = createElement("div", ["block-id", "com", "clickable"], pred); + const predEl = createElement("div", "block-id com clickable", pred); predEl.onclick = mkBlockLinkHandler(pred); - block_pred.appendChild(predEl); + blockPred.appendChild(predEl); } - if (block.pred.length) schedule_block.appendChild(block_pred); + if (block.pred.length) scheduleBlock.appendChild(blockPred); const nodes = createElement("div", "nodes"); for (const node of block.nodes) { nodes.appendChild(createElementForNode(node)); } - schedule_block.appendChild(nodes); - const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); + scheduleBlock.appendChild(nodes); + const blockSucc = createElement("div", "successor-list block-list comma-sep-list"); for (const succ of block.succ) { - const succEl = createElement("div", ["block-id", "com", "clickable"], succ); + const succEl = createElement("div", "block-id com clickable", succ); succEl.onclick = mkBlockLinkHandler(succ); - block_succ.appendChild(succEl); + blockSucc.appendChild(succEl); } - if (block.succ.length) schedule_block.appendChild(block_succ); - this.addHtmlElementForBlockId(block.id, schedule_block); - return schedule_block; + if (block.succ.length) scheduleBlock.appendChild(blockSucc); + this.addHtmlElementForBlockId(block.id, scheduleBlock); + return scheduleBlock; } addBlocks(blocks) { @@ -170,10 +164,10 @@ export class ScheduleView extends TextView implements PhaseView { } lineString(node) { - return `${node.id}: ${node.label}(${node.inputs.join(", ")})` + return `${node.id}: ${node.label}(${node.inputs.join(", ")})`; } - searchInputAction(searchBar, e) { + searchInputAction(searchBar, e, onlyVisible) { e.stopPropagation(); this.selectionHandler.clear(); const query = searchBar.value; @@ -184,11 +178,9 @@ export class ScheduleView extends TextView implements PhaseView { for (const node of this.schedule.nodes) { if (node === undefined) continue; if (reg.exec(this.lineString(node)) != null) { - select.push(node.id) + select.push(node.id); } } this.selectionHandler.select(select, true); } - - onresize() { } } diff --git a/deps/v8/tools/turbolizer/src/selection-broker.ts b/deps/v8/tools/turbolizer/src/selection-broker.ts index e20fd977d2..7e0c0ddee0 100644 --- a/deps/v8/tools/turbolizer/src/selection-broker.ts +++ b/deps/v8/tools/turbolizer/src/selection-broker.ts @@ -2,36 +2,54 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {SourceResolver, sourcePositionValid} from "./source-resolver.js" +import { SourceResolver, sourcePositionValid } from "../src/source-resolver"; +import { ClearableHandler, SelectionHandler, NodeSelectionHandler, BlockSelectionHandler, InstructionSelectionHandler } from "../src/selection-handler"; export class SelectionBroker { sourceResolver: SourceResolver; + allHandlers: Array<ClearableHandler>; sourcePositionHandlers: Array<SelectionHandler>; nodeHandlers: Array<NodeSelectionHandler>; blockHandlers: Array<BlockSelectionHandler>; + instructionHandlers: Array<InstructionSelectionHandler>; constructor(sourceResolver) { + this.allHandlers = []; this.sourcePositionHandlers = []; this.nodeHandlers = []; this.blockHandlers = []; + this.instructionHandlers = []; this.sourceResolver = sourceResolver; - }; + } - addSourcePositionHandler(handler) { + addSourcePositionHandler(handler: SelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.sourcePositionHandlers.push(handler); } - addNodeHandler(handler) { + addNodeHandler(handler: NodeSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.nodeHandlers.push(handler); } - addBlockHandler(handler) { + addBlockHandler(handler: BlockSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); this.blockHandlers.push(handler); } + addInstructionHandler(handler: InstructionSelectionHandler & ClearableHandler) { + this.allHandlers.push(handler); + this.instructionHandlers.push(handler); + } + + broadcastInstructionSelect(from, instructionOffsets, selected) { + for (const b of this.instructionHandlers) { + if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected); + } + } + broadcastSourcePositionSelect(from, sourcePositions, selected) { - let broker = this; - sourcePositions = sourcePositions.filter((l) => { + sourcePositions = sourcePositions.filter(l => { if (!sourcePositionValid(l)) { console.log("Warning: invalid source position"); return false; @@ -48,7 +66,6 @@ export class SelectionBroker { } broadcastNodeSelect(from, nodes, selected) { - let broker = this; for (const b of this.nodeHandlers) { if (b != from) b.brokeredNodeSelect(nodes, selected); } @@ -59,20 +76,13 @@ export class SelectionBroker { } broadcastBlockSelect(from, blocks, selected) { - let broker = this; - for (var b of this.blockHandlers) { + for (const 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) { + this.allHandlers.forEach(function (b) { if (b != from) b.brokeredClear(); }); } diff --git a/deps/v8/tools/turbolizer/src/selection-handler.ts b/deps/v8/tools/turbolizer/src/selection-handler.ts index bf0719c8a6..a605149238 100644 --- a/deps/v8/tools/turbolizer/src/selection-handler.ts +++ b/deps/v8/tools/turbolizer/src/selection-handler.ts @@ -2,23 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -interface SelectionHandler { +export interface ClearableHandler { + brokeredClear(): void; +} + +export interface SelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredSourcePositionSelect(sourcePositions: any, selected: any): void; -}; +} -interface NodeSelectionHandler { +export interface NodeSelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredNodeSelect(nodeIds: any, selected: any): void; -}; +} -interface BlockSelectionHandler { +export interface BlockSelectionHandler { clear(): void; select(nodeIds: any, selected: any): void; - brokeredClear(): void; brokeredBlockSelect(blockIds: any, selected: any): void; -}; +} + +export interface InstructionSelectionHandler { + clear(): void; + select(instructionIds: any, selected: any): void; + brokeredInstructionSelect(instructionIds: any, selected: any): void; +} diff --git a/deps/v8/tools/turbolizer/src/selection.ts b/deps/v8/tools/turbolizer/src/selection.ts index b02a3e9cbb..90fe3bd4bc 100644 --- a/deps/v8/tools/turbolizer/src/selection.ts +++ b/deps/v8/tools/turbolizer/src/selection.ts @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {isIterable} from "./util.js" - export class MySelection { selection: any; stringKey: (o: any) => string; @@ -21,8 +19,7 @@ export class MySelection { this.selection = new Map(); } - select(s, isSelected) { - if (!isIterable(s)) { s = [s]; } + select(s: Iterable<any>, isSelected?: boolean) { for (const i of s) { if (!i) continue; if (isSelected == undefined) { @@ -36,7 +33,7 @@ export class MySelection { } } - isSelected(i): boolean { + isSelected(i: any): boolean { return this.selection.has(this.stringKey(i)); } @@ -45,21 +42,18 @@ export class MySelection { } selectedKeys() { - var result = new Set(); - for (var i of this.selection.keys()) { + const result = new Set(); + for (const i of this.selection.keys()) { result.add(i); } return result; } detachSelection() { - var result = new Set(); - for (var i of this.selection.keys()) { - result.add(i); - } + const result = this.selectedKeys(); this.clear(); return result; } - [Symbol.iterator]() { return this.selection.values() } + [Symbol.iterator]() { return this.selection.values(); } } diff --git a/deps/v8/tools/turbolizer/src/sequence-view.ts b/deps/v8/tools/turbolizer/src/sequence-view.ts index afddb56649..a796707c74 100644 --- a/deps/v8/tools/turbolizer/src/sequence-view.ts +++ b/deps/v8/tools/turbolizer/src/sequence-view.ts @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Sequence} from "./source-resolver.js" -import {isIterable} from "./util.js" -import {PhaseView} from "./view.js" -import {TextView} from "./text-view.js" +import { Sequence } from "../src/source-resolver"; +import { isIterable } from "../src/util"; +import { TextView } from "../src/text-view"; -export class SequenceView extends TextView implements PhaseView { +export class SequenceView extends TextView { sequence: Sequence; - search_info: Array<any>; + searchInfo: Array<any>; createViewElement() { const pane = document.createElement('div'); @@ -18,7 +17,7 @@ export class SequenceView extends TextView implements PhaseView { } constructor(parentId, broker) { - super(parentId, broker, null); + super(parentId, broker); } attachSelection(s) { @@ -39,9 +38,17 @@ export class SequenceView extends TextView implements PhaseView { initializeContent(data, rememberedSelection) { this.divNode.innerHTML = ''; this.sequence = data.sequence; - this.search_info = []; + this.searchInfo = []; + this.divNode.addEventListener('click', (e: MouseEvent) => { + if (!(e.target instanceof HTMLElement)) return; + const instructionId = Number.parseInt(e.target.dataset.instructionId, 10); + if (!instructionId) return; + if (!e.shiftKey) this.broker.broadcastClear(null); + this.broker.broadcastInstructionSelect(null, [instructionId], true); + }); this.addBlocks(this.sequence.blocks); this.attachSelection(rememberedSelection); + this.show(); } elementForBlock(block) { @@ -75,23 +82,25 @@ export class SequenceView extends TextView implements PhaseView { return mkLinkHandler(text, view.selectionHandler); } - function elementForOperand(operand, search_info) { - var text = operand.text; + function elementForOperand(operand, searchInfo) { + const text = operand.text; const operandEl = createElement("div", ["parameter", "tag", "clickable", operand.type], text); if (operand.tooltip) { operandEl.setAttribute("title", operand.tooltip); } operandEl.onclick = mkOperandLinkHandler(text); - search_info.push(text); + searchInfo.push(text); view.addHtmlElementForNodeId(text, operandEl); return operandEl; } - function elementForInstruction(instruction, search_info) { + function elementForInstruction(instruction, searchInfo) { const instNodeEl = createElement("div", "instruction-node"); - const inst_id = createElement("div", "instruction-id", instruction.id); - instNodeEl.appendChild(inst_id); + const instId = createElement("div", "instruction-id", instruction.id); + instId.classList.add("clickable"); + instId.dataset.instructionId = instruction.id; + instNodeEl.appendChild(instId); const instContentsEl = createElement("div", "instruction-contents"); instNodeEl.appendChild(instContentsEl); @@ -103,11 +112,11 @@ export class SequenceView extends TextView implements PhaseView { const moves = createElement("div", ["comma-sep-list", "gap-move"]); for (const move of gap) { const moveEl = createElement("div", "move"); - const destinationEl = elementForOperand(move[0], search_info); + const destinationEl = elementForOperand(move[0], searchInfo); moveEl.appendChild(destinationEl); const assignEl = createElement("div", "assign", "="); moveEl.appendChild(assignEl); - const sourceEl = elementForOperand(move[1], search_info); + const sourceEl = elementForOperand(move[1], searchInfo); moveEl.appendChild(sourceEl); moves.appendChild(moveEl); } @@ -120,7 +129,7 @@ export class SequenceView extends TextView implements PhaseView { if (instruction.outputs.length > 0) { const outputs = createElement("div", ["comma-sep-list", "input-output-list"]); for (const output of instruction.outputs) { - const outputEl = elementForOperand(output, search_info); + const outputEl = elementForOperand(output, searchInfo); outputs.appendChild(outputEl); } instEl.appendChild(outputs); @@ -128,16 +137,16 @@ export class SequenceView extends TextView implements PhaseView { instEl.appendChild(assignEl); } - var text = instruction.opcode + instruction.flags; - const inst_label = createElement("div", "node-label", text); - search_info.push(text); - view.addHtmlElementForNodeId(text, inst_label); - instEl.appendChild(inst_label); + const text = instruction.opcode + instruction.flags; + const instLabel = createElement("div", "node-label", text); + searchInfo.push(text); + view.addHtmlElementForNodeId(text, instLabel); + instEl.appendChild(instLabel); if (instruction.inputs.length > 0) { const inputs = createElement("div", ["comma-sep-list", "input-output-list"]); for (const input of instruction.inputs) { - const inputEl = elementForOperand(input, search_info); + const inputEl = elementForOperand(input, searchInfo); inputs.appendChild(inputEl); } instEl.appendChild(inputs); @@ -146,7 +155,7 @@ export class SequenceView extends TextView implements PhaseView { if (instruction.temps.length > 0) { const temps = createElement("div", ["comma-sep-list", "input-output-list", "temps"]); for (const temp of instruction.temps) { - const tempEl = elementForOperand(temp, search_info); + const tempEl = elementForOperand(temp, searchInfo); temps.appendChild(tempEl); } instEl.appendChild(temps); @@ -155,20 +164,20 @@ export class SequenceView extends TextView implements PhaseView { return instNodeEl; } - const sequence_block = createElement("div", "schedule-block"); + const sequenceBlock = createElement("div", "schedule-block"); - const block_id = createElement("div", ["block-id", "com", "clickable"], block.id); - block_id.onclick = mkBlockLinkHandler(block.id); - sequence_block.appendChild(block_id); - const block_pred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); + const blockId = createElement("div", ["block-id", "com", "clickable"], block.id); + blockId.onclick = mkBlockLinkHandler(block.id); + sequenceBlock.appendChild(blockId); + const blockPred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); for (const pred of block.predecessors) { const predEl = createElement("div", ["block-id", "com", "clickable"], pred); predEl.onclick = mkBlockLinkHandler(pred); - block_pred.appendChild(predEl); + blockPred.appendChild(predEl); } - if (block.predecessors.length > 0) sequence_block.appendChild(block_pred); + if (block.predecessors.length > 0) sequenceBlock.appendChild(blockPred); const phis = createElement("div", "phis"); - sequence_block.appendChild(phis); + sequenceBlock.appendChild(phis); const phiLabel = createElement("div", "phi-label", "phi:"); phis.appendChild(phiLabel); @@ -180,7 +189,7 @@ export class SequenceView extends TextView implements PhaseView { const phiEl = createElement("div", "phi"); phiContents.appendChild(phiEl); - const outputEl = elementForOperand(phi.output, this.search_info); + const outputEl = elementForOperand(phi.output, this.searchInfo); phiEl.appendChild(outputEl); const assignEl = createElement("div", "assign", "="); @@ -194,18 +203,18 @@ export class SequenceView extends TextView implements PhaseView { const instructions = createElement("div", "instructions"); for (const instruction of block.instructions) { - instructions.appendChild(elementForInstruction(instruction, this.search_info)); + instructions.appendChild(elementForInstruction(instruction, this.searchInfo)); } - sequence_block.appendChild(instructions); - const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); + sequenceBlock.appendChild(instructions); + const blockSucc = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); for (const succ of block.successors) { const succEl = createElement("div", ["block-id", "com", "clickable"], succ); succEl.onclick = mkBlockLinkHandler(succ); - block_succ.appendChild(succEl); + blockSucc.appendChild(succEl); } - if (block.successors.length > 0) sequence_block.appendChild(block_succ); - this.addHtmlElementForBlockId(block.id, sequence_block); - return sequence_block; + if (block.successors.length > 0) sequenceBlock.appendChild(blockSucc); + this.addHtmlElementForBlockId(block.id, sequenceBlock); + return sequenceBlock; } addBlocks(blocks) { @@ -223,13 +232,11 @@ export class SequenceView extends TextView implements PhaseView { const select = []; window.sessionStorage.setItem("lastSearch", query); const reg = new RegExp(query); - for (const item of this.search_info) { + for (const item of this.searchInfo) { if (reg.exec(item) != null) { select.push(item); } } this.selectionHandler.select(select, true); } - - onresize() { } } diff --git a/deps/v8/tools/turbolizer/src/source-resolver.ts b/deps/v8/tools/turbolizer/src/source-resolver.ts index 20f1f5070a..67f9c088a2 100644 --- a/deps/v8/tools/turbolizer/src/source-resolver.ts +++ b/deps/v8/tools/turbolizer/src/source-resolver.ts @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {sortUnique, anyToString} from "./util.js" +import { sortUnique, anyToString } from "../src/util"; +import { NodeLabel } from "./node-label"; function sourcePositionLe(a, b) { if (a.inliningId == b.inliningId) { @@ -16,12 +17,14 @@ function sourcePositionEq(a, b) { a.scriptOffset == b.scriptOffset; } -export function sourcePositionToStringKey(sourcePosition): string { +export function sourcePositionToStringKey(sourcePosition: AnyPosition): string { if (!sourcePosition) return "undefined"; - if (sourcePosition.inliningId && sourcePosition.scriptOffset) + if ('inliningId' in sourcePosition && 'scriptOffset' in sourcePosition) { return "SP:" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset; - if (sourcePosition.bytecodePosition) + } + if (sourcePosition.bytecodePosition) { return "BCP:" + sourcePosition.bytecodePosition; + } return "undefined"; } @@ -48,9 +51,9 @@ interface BytecodePosition { bytecodePosition: number; } -type Origin = NodeOrigin | BytecodePosition; -type TurboFanNodeOrigin = NodeOrigin & TurboFanOrigin; -type TurboFanBytecodeOrigin = BytecodePosition & TurboFanOrigin; +export type Origin = NodeOrigin | BytecodePosition; +export type TurboFanNodeOrigin = NodeOrigin & TurboFanOrigin; +export type TurboFanBytecodeOrigin = BytecodePosition & TurboFanOrigin; type AnyPosition = SourcePosition | BytecodePosition; @@ -61,17 +64,37 @@ export interface Source { sourceText: string; sourceId: number; startPosition?: number; + backwardsCompatibility: boolean; } interface Inlining { inliningPosition: SourcePosition; sourceId: number; } -interface Phase { - type: string; +interface OtherPhase { + type: "disassembly" | "sequence" | "schedule"; + name: string; + data: any; +} + +interface InstructionsPhase { + type: "instructions"; + name: string; + data: any; + instructionOffsetToPCOffset?: any; + blockIdtoInstructionRange?: any; + nodeIdToInstructionRange?: any; +} + +interface GraphPhase { + type: "graph"; name: string; data: any; + highestNodeId: number; + nodeLabelMap: Array<NodeLabel>; } +type Phase = GraphPhase | InstructionsPhase | OtherPhase; + export interface Schedule { nodes: Array<any>; } @@ -94,7 +117,7 @@ export class SourceResolver { blockIdToInstructionRange: Array<[number, number]>; instructionToPCOffset: Array<number>; pcOffsetToInstructions: Map<number, Array<number>>; - + pcOffsets: Array<number>; constructor() { // Maps node ids to source positions. @@ -123,11 +146,12 @@ export class SourceResolver { this.instructionToPCOffset = []; // Maps PC offsets to instructions. this.pcOffsetToInstructions = new Map(); + this.pcOffsets = []; } setSources(sources, mainBackup) { if (sources) { - for (let [sourceId, source] of Object.entries(sources)) { + for (const [sourceId, source] of Object.entries(sources)) { this.sources[sourceId] = source; this.sources[sourceId].sourcePositions = []; } @@ -159,7 +183,7 @@ export class SourceResolver { alternativeMap[nodeId] = { scriptOffset: scriptOffset, inliningId: -1 }; } map = alternativeMap; - }; + } for (const [nodeId, sourcePosition] of Object.entries<SourcePosition>(map)) { if (sourcePosition == undefined) { @@ -172,13 +196,13 @@ export class SourceResolver { this.sources[sourceId].sourcePositions.push(sourcePosition); } this.nodePositionMap[nodeId] = sourcePosition; - let key = sourcePositionToStringKey(sourcePosition); + const 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)) { + for (const [, source] of Object.entries(this.sources)) { source.sourcePositions = sortUnique(source.sourcePositions, sourcePositionLe, sourcePositionEq); } @@ -187,8 +211,8 @@ export class SourceResolver { sourcePositionsToNodeIds(sourcePositions) { const nodeIds = new Set(); for (const sp of sourcePositions) { - let key = sourcePositionToStringKey(sp); - let nodeIdsForPosition = this.positionToNodes.get(key); + const key = sourcePositionToStringKey(sp); + const nodeIdsForPosition = this.positionToNodes.get(key); if (!nodeIdsForPosition) continue; for (const nodeId of nodeIdsForPosition) { nodeIds.add(nodeId); @@ -200,8 +224,8 @@ export class SourceResolver { nodeIdsToSourcePositions(nodeIds): Array<AnyPosition> { const sourcePositions = new Map(); for (const nodeId of nodeIds) { - let sp = this.nodePositionMap[nodeId]; - let key = sourcePositionToStringKey(sp); + const sp = this.nodePositionMap[nodeId]; + const key = sourcePositionToStringKey(sp); sourcePositions.set(key, sp); } const sourcePositionArray = []; @@ -211,13 +235,13 @@ export class SourceResolver { return sourcePositionArray; } - forEachSource(f) { + forEachSource(f: (value: Source, index: number, array: Array<Source>) => void) { this.sources.forEach(f); } - translateToSourceId(sourceId, location) { + translateToSourceId(sourceId: number, location?: SourcePosition) { for (const position of this.getInlineStack(location)) { - let inlining = this.inlinings[position.inliningId]; + const inlining = this.inlinings[position.inliningId]; if (!inlining) continue; if (inlining.sourceId == sourceId) { return position; @@ -226,10 +250,10 @@ export class SourceResolver { return location; } - addInliningPositions(sourcePosition, locations) { - let inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); + addInliningPositions(sourcePosition: AnyPosition, locations: Array<SourcePosition>) { + const inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); if (!inlining) return; - let sourceId = inlining.sourceId + const sourceId = inlining.sourceId; const source = this.sources[sourceId]; for (const sp of source.sourcePositions) { locations.push(sp); @@ -237,26 +261,26 @@ export class SourceResolver { } } - getInliningForPosition(sourcePosition) { + getInliningForPosition(sourcePosition: AnyPosition) { return this.inliningsMap.get(sourcePositionToStringKey(sourcePosition)); } - getSource(sourceId) { + getSource(sourceId: number) { return this.sources[sourceId]; } - getSourceName(sourceId) { + getSourceName(sourceId: number) { const source = this.sources[sourceId]; return `${source.sourceName}:${source.functionName}`; } - sourcePositionFor(sourceId, scriptOffset) { + sourcePositionFor(sourceId: number, scriptOffset: number) { 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 sourcePosition = list[i]; const position = sourcePosition.scriptOffset; const nextPosition = list[Math.min(i + 1, list.length - 1)].scriptOffset; if ((position <= scriptOffset && scriptOffset < nextPosition)) { @@ -266,12 +290,11 @@ export class SourceResolver { return null; } - sourcePositionsInRange(sourceId, start, end) { + sourcePositionsInRange(sourceId: number, start: number, end: number) { 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] + for (const sourcePosition of list) { if (start <= sourcePosition.scriptOffset && sourcePosition.scriptOffset < end) { res.push(sourcePosition); } @@ -279,15 +302,14 @@ export class SourceResolver { return res; } - getInlineStack(sourcePosition) { - if (!sourcePosition) { - return []; - } - let inliningStack = []; + getInlineStack(sourcePosition?: SourcePosition) { + if (!sourcePosition) return []; + + const inliningStack = []; let cur = sourcePosition; while (cur && cur.inliningId != -1) { inliningStack.push(cur); - let inlining = this.inlinings[cur.inliningId]; + const inlining = this.inlinings[cur.inliningId]; if (!inlining) { break; } @@ -299,19 +321,25 @@ export class SourceResolver { return inliningStack; } - recordOrigins(phase) { + recordOrigins(phase: GraphPhase) { if (phase.type != "graph") return; for (const node of phase.data.nodes) { + phase.highestNodeId = Math.max(phase.highestNodeId, node.id); if (node.origin != undefined && node.origin.bytecodePosition != undefined) { const position = { bytecodePosition: node.origin.bytecodePosition }; this.nodePositionMap[node.id] = position; - let key = sourcePositionToStringKey(position); + const key = sourcePositionToStringKey(position); if (!this.positionToNodes.has(key)) { this.positionToNodes.set(key, []); } const A = this.positionToNodes.get(key); - if (!A.includes(node.id)) A.push("" + node.id); + if (!A.includes(node.id)) A.push(`${node.id}`); + } + + // Backwards compatibility. + if (typeof node.pos === "number") { + node.sourcePosition = { scriptOffset: node.pos, inliningId: -1 }; } } } @@ -328,13 +356,13 @@ export class SourceResolver { } } - getInstruction(nodeId):[number, number] { + getInstruction(nodeId: number): [number, number] { const X = this.nodeIdToInstructionRange[nodeId]; if (X === undefined) return [-1, -1]; return X; } - getInstructionRangeForBlock(blockId):[number, number] { + getInstructionRangeForBlock(blockId: number): [number, number] { const X = this.blockIdToInstructionRange[blockId]; if (X === undefined) return [-1, -1]; return X; @@ -346,20 +374,51 @@ export class SourceResolver { if (!this.pcOffsetToInstructions.has(offset)) { this.pcOffsetToInstructions.set(offset, []); } - this.pcOffsetToInstructions.get(offset).push(instruction); + this.pcOffsetToInstructions.get(offset).push(Number(instruction)); } - console.log(this.pcOffsetToInstructions); + this.pcOffsets = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a); } hasPCOffsets() { return this.pcOffsetToInstructions.size > 0; } + getKeyPcOffset(offset: number): number { + if (this.pcOffsets.length === 0) return -1; + for (const key of this.pcOffsets) { + if (key <= offset) { + return key; + } + } + return -1; + } + + instructionRangeToKeyPcOffsets([start, end]: [number, number]) { + if (start == end) return [this.instructionToPCOffset[start]]; + return this.instructionToPCOffset.slice(start, end); + } + + instructionsToKeyPcOffsets(instructionIds: Iterable<number>) { + const keyPcOffsets = []; + for (const instructionId of instructionIds) { + keyPcOffsets.push(this.instructionToPCOffset[instructionId]); + } + return keyPcOffsets; + } + + nodesToKeyPcOffsets(nodes) { + let offsets = []; + for (const node of nodes) { + const range = this.nodeIdToInstructionRange[node]; + if (!range) continue; + offsets = offsets.concat(this.instructionRangeToKeyPcOffsets(range)); + } + return offsets; + } - nodesForPCOffset(offset): [Array<String>, Array<String>] { - const keys = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a); - if (keys.length === 0) return [[],[]]; - for (const key of keys) { + nodesForPCOffset(offset: number): [Array<string>, Array<string>] { + if (this.pcOffsets.length === 0) return [[], []]; + for (const key of this.pcOffsets) { if (key <= offset) { const instrs = this.pcOffsetToInstructions.get(key); const nodes = []; @@ -379,54 +438,82 @@ export class SourceResolver { return [nodes, blocks]; } } - return [[],[]]; + return [[], []]; } parsePhases(phases) { - for (const [phaseId, phase] of Object.entries<Phase>(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 if (phase.type == 'sequence') { - this.phases.push(this.parseSequence(phase)); - this.phaseNames.set(phase.name, this.phases.length); - } else if (phase.type == 'instructions') { - if (phase.nodeIdToInstructionRange) { - this.readNodeIdToInstructionRange(phase.nodeIdToInstructionRange); - } - if (phase.blockIdtoInstructionRange) { - this.readBlockIdToInstructionRange(phase.blockIdtoInstructionRange); - } - if (phase.instructionOffsetToPCOffset) { - this.readInstructionOffsetToPCOffset(phase.instructionOffsetToPCOffset); + const nodeLabelMap = []; + for (const [, phase] of Object.entries<Phase>(phases)) { + switch (phase.type) { + case 'disassembly': + this.disassemblyPhase = phase; + break; + case 'schedule': + this.phaseNames.set(phase.name, this.phases.length); + this.phases.push(this.parseSchedule(phase)); + break; + case 'sequence': + this.phaseNames.set(phase.name, this.phases.length); + this.phases.push(this.parseSequence(phase)); + break; + case 'instructions': + if (phase.nodeIdToInstructionRange) { + this.readNodeIdToInstructionRange(phase.nodeIdToInstructionRange); + } + if (phase.blockIdtoInstructionRange) { + this.readBlockIdToInstructionRange(phase.blockIdtoInstructionRange); + } + if (phase.instructionOffsetToPCOffset) { + this.readInstructionOffsetToPCOffset(phase.instructionOffsetToPCOffset); + } + break; + case 'graph': + const graphPhase: GraphPhase = Object.assign(phase, { highestNodeId: 0 }); + this.phaseNames.set(graphPhase.name, this.phases.length); + this.phases.push(graphPhase); + this.recordOrigins(graphPhase); + this.internNodeLabels(graphPhase, nodeLabelMap); + graphPhase.nodeLabelMap = nodeLabelMap.slice(); + break; + default: + throw "Unsupported phase type"; + } + } + } + + internNodeLabels(phase: GraphPhase, nodeLabelMap: Array<NodeLabel>) { + for (const n of phase.data.nodes) { + const label = new NodeLabel(n.id, n.label, n.title, n.live, + n.properties, n.sourcePosition, n.origin, n.opcode, n.control, + n.opinfo, n.type); + const previous = nodeLabelMap[label.id]; + if (!label.equals(previous)) { + if (previous != undefined) { + label.setInplaceUpdatePhase(phase.name); } - } else { - this.phases.push(phase); - this.recordOrigins(phase); - this.phaseNames.set(phase.name, this.phases.length); + nodeLabelMap[label.id] = label; } + n.nodeLabel = nodeLabelMap[label.id]; } } repairPhaseId(anyPhaseId) { - return Math.max(0, Math.min(anyPhaseId, this.phases.length - 1)) + return Math.max(0, Math.min(anyPhaseId | 0, this.phases.length - 1)); } - getPhase(phaseId) { + getPhase(phaseId: number) { return this.phases[phaseId]; } - getPhaseIdByName(phaseName) { + getPhaseIdByName(phaseName: string) { return this.phaseNames.get(phaseName); } - forEachPhase(f) { + forEachPhase(f: (value: Phase, index: number, array: Array<Phase>) => void) { this.phases.forEach(f); } - addAnyPositionToLine(lineNumber: number | String, sourcePosition: AnyPosition) { + addAnyPositionToLine(lineNumber: number | string, sourcePosition: AnyPosition) { const lineNumberString = anyToString(lineNumber); if (!this.lineToSourcePositions.has(lineNumberString)) { this.lineToSourcePositions.set(lineNumberString, []); @@ -442,19 +529,19 @@ export class SourceResolver { }); } - linetoSourcePositions(lineNumber: number | String) { + linetoSourcePositions(lineNumber: number | string) { const positions = this.lineToSourcePositions.get(anyToString(lineNumber)); if (positions === undefined) return []; return positions; } parseSchedule(phase) { - function createNode(state, match) { + function createNode(state: any, 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)); + inputs = nodeIdStrings.map(n => Number.parseInt(n, 10)); } const node = { id: Number.parseInt(match.groups.id, 10), @@ -464,7 +551,7 @@ export class SourceResolver { 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)); + const successors = nodeIdStrings.map(n => Number.parseInt(n, 10)); state.currentBlock.succ = successors; } state.nodes[node.id] = node; @@ -475,7 +562,7 @@ export class SourceResolver { 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)); + predecessors = blockIdStrings.map(n => Number.parseInt(n, 10)); } const block = { id: Number.parseInt(match.groups.id, 10), diff --git a/deps/v8/tools/turbolizer/src/tabs.ts b/deps/v8/tools/turbolizer/src/tabs.ts new file mode 100644 index 0000000000..0416b9ed9d --- /dev/null +++ b/deps/v8/tools/turbolizer/src/tabs.ts @@ -0,0 +1,114 @@ + +export class Tabs { + private container: HTMLElement; + private tabBar: HTMLElement; + private nextTabId: number; + + private mkTabBar(container: HTMLElement) { + container.classList.add("nav-tabs-container"); + this.tabBar = document.createElement("ul"); + this.tabBar.id = `tab-bar-${container.id}`; + this.tabBar.className = "nav-tabs"; + this.tabBar.ondrop = this.tabBarOnDrop.bind(this); + this.tabBar.ondragover = this.tabBarOnDragover.bind(this); + this.tabBar.onclick = this.tabBarOnClick.bind(this); + + const defaultDiv = document.createElement("div"); + defaultDiv.className = "tab-content tab-default"; + defaultDiv.id = `tab-content-${container.id}-default`; + container.insertBefore(defaultDiv, container.firstChild); + container.insertBefore(this.tabBar, container.firstChild); + } + + constructor(container: HTMLElement) { + this.container = container; + this.nextTabId = 0; + this.mkTabBar(container); + } + + activateTab(tab: HTMLLIElement) { + if (typeof tab.dataset.divid !== "string") return; + for (const li of this.tabBar.querySelectorAll<HTMLLIElement>("li.active")) { + li.classList.remove("active"); + this.showTab(li, false); + } + tab.classList.add("active"); + this.showTab(tab, true); + } + + clearTabsAndContent() { + for (const tab of this.tabBar.querySelectorAll(".nav-tabs > li")) { + if (!(tab instanceof HTMLLIElement)) continue; + if (tab.classList.contains("persistent-tab")) continue; + const tabDiv = document.getElementById(tab.dataset.divid); + tabDiv.parentNode.removeChild(tabDiv); + tab.parentNode.removeChild(tab); + } + } + + private showTab(li: HTMLElement, show: boolean = true) { + const tabDiv = document.getElementById(li.dataset.divid); + tabDiv.style.display = show ? "block" : "none"; + } + + public addTab(caption: string): HTMLLIElement { + const newTab = document.createElement("li"); + newTab.innerHTML = caption; + newTab.id = `tab-header-${this.container.id}-${this.nextTabId++}`; + const lastTab = this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(newTab, lastTab); + return newTab; + } + + public addTabAndContent(caption: string): [HTMLLIElement, HTMLDivElement] { + const contentDiv = document.createElement("div"); + contentDiv.className = "tab-content tab-default"; + contentDiv.id = `tab-content-${this.container.id}-${this.nextTabId++}`; + contentDiv.style.display = "none"; + this.container.appendChild(contentDiv); + + const newTab = this.addTab(caption); + newTab.dataset.divid = contentDiv.id; + newTab.draggable = true; + newTab.ondragstart = this.tabOnDragStart.bind(this); + const lastTab = this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(newTab, lastTab); + return [newTab, contentDiv]; + } + + private moveTabDiv(tab: HTMLLIElement) { + const tabDiv = document.getElementById(tab.dataset.divid); + tabDiv.style.display = "none"; + tab.classList.remove("active"); + this.tabBar.parentNode.appendChild(tabDiv); + } + + private tabBarOnDrop(e: DragEvent) { + if (!(e.target instanceof HTMLElement)) return; + e.preventDefault(); + const tabId = e.dataTransfer.getData("text"); + const tab = document.getElementById(tabId) as HTMLLIElement; + if (tab.parentNode != this.tabBar) { + this.moveTabDiv(tab); + } + const dropTab = + e.target.parentNode == this.tabBar + ? e.target : this.tabBar.querySelector("li.last-tab"); + this.tabBar.insertBefore(tab, dropTab); + this.activateTab(tab); + } + + private tabBarOnDragover(e) { + e.preventDefault(); + } + + private tabOnDragStart(e: DragEvent) { + if (!(e.target instanceof HTMLElement)) return; + e.dataTransfer.setData("text", e.target.id); + } + + private tabBarOnClick(e: MouseEvent) { + const li = e.target as HTMLLIElement; + this.activateTab(li); + } +} diff --git a/deps/v8/tools/turbolizer/src/text-view.ts b/deps/v8/tools/turbolizer/src/text-view.ts index a88d31d194..41a06eae77 100644 --- a/deps/v8/tools/turbolizer/src/text-view.ts +++ b/deps/v8/tools/turbolizer/src/text-view.ts @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {View} from "./view.js" -import {anyToString, ViewElements, isIterable} from "./util.js" -import {MySelection} from "./selection.js" - -export abstract class TextView extends View { +import { PhaseView } from "../src/view"; +import { anyToString, ViewElements, isIterable } from "../src/util"; +import { MySelection } from "../src/selection"; +import { SourceResolver } from "./source-resolver"; +import { SelectionBroker } from "./selection-broker"; +import { NodeSelectionHandler, BlockSelectionHandler } from "./selection-handler"; + +export abstract class TextView extends PhaseView { selectionHandler: NodeSelectionHandler; blockSelectionHandler: BlockSelectionHandler; - nodeSelectionHandler: NodeSelectionHandler; selection: MySelection; blockSelection: MySelection; textListNode: HTMLUListElement; @@ -18,18 +20,22 @@ export abstract class TextView extends View { blockIdtoNodeIds: Map<string, Array<string>>; nodeIdToBlockId: Array<string>; patterns: any; + sourceResolver: SourceResolver; + broker: SelectionBroker; - constructor(id, broker, patterns) { + constructor(id, broker) { super(id); - let view = this; + const view = this; view.textListNode = view.divNode.getElementsByTagName('ul')[0]; - view.patterns = patterns; + view.patterns = null; view.nodeIdToHtmlElementsMap = new Map(); view.blockIdToHtmlElementsMap = new Map(); view.blockIdtoNodeIds = new Map(); view.nodeIdToBlockId = []; view.selection = new MySelection(anyToString); view.blockSelection = new MySelection(anyToString); + view.broker = broker; + view.sourceResolver = broker.sourceResolver; const selectionHandler = { clear: function () { view.selection.clear(); @@ -53,11 +59,12 @@ export abstract class TextView extends View { }; this.selectionHandler = selectionHandler; broker.addNodeHandler(selectionHandler); - view.divNode.onmouseup = function (e) { + view.divNode.addEventListener('click', e => { if (!e.shiftKey) { view.selectionHandler.clear(); } - } + e.stopPropagation(); + }); const blockSelectionHandler = { clear: function () { view.blockSelection.clear(); @@ -129,6 +136,10 @@ export abstract class TextView extends View { element.classList.toggle("selected", isSelected); } } + const elementsToSelect = view.divNode.querySelectorAll(`[data-pc-offset]`); + for (const el of elementsToSelect) { + el.classList.toggle("selected", false); + } for (const key of this.nodeIdToHtmlElementsMap.keys()) { for (const element of this.nodeIdToHtmlElementsMap.get(key)) { element.classList.toggle("selected", false); @@ -146,82 +157,47 @@ export abstract class TextView extends View { } setPatterns(patterns) { - let view = this; - view.patterns = patterns; + this.patterns = patterns; } clearText() { - let view = this; - while (view.textListNode.firstChild) { - view.textListNode.removeChild(view.textListNode.firstChild); + while (this.textListNode.firstChild) { + this.textListNode.removeChild(this.textListNode.firstChild); } } createFragment(text, style) { - let view = this; - let fragment = document.createElement("SPAN"); - - if (style.blockId != undefined) { - const blockId = style.blockId(text); - if (blockId != undefined) { - fragment.blockId = blockId; - this.addHtmlElementForBlockId(blockId, fragment); - } - } - - if (typeof style.link == 'function') { - fragment.classList.add('linkable-text'); - fragment.onmouseup = function (e) { - e.stopPropagation(); - style.link(text) - }; - } - - if (typeof style.nodeId == 'function') { - const nodeId = style.nodeId(text); - if (nodeId != undefined) { - fragment.nodeId = nodeId; - this.addHtmlElementForNodeId(nodeId, fragment); - } - } - - if (typeof style.assignBlockId === 'function') { - fragment.blockId = style.assignBlockId(); - this.addNodeIdToBlockId(fragment.nodeId, fragment.blockId); - } - - if (typeof style.linkHandler == 'function') { - const handler = style.linkHandler(text, fragment) - if (handler !== undefined) { - fragment.classList.add('linkable-text'); - fragment.onmouseup = handler; + const fragment = document.createElement("SPAN"); + + if (typeof style.associateData == 'function') { + style.associateData(text, fragment); + } else { + if (style.css != undefined) { + const css = isIterable(style.css) ? style.css : [style.css]; + for (const cls of css) { + fragment.classList.add(cls); + } } + fragment.innerText = text; } - 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) { - let view = this; - let result = []; + const view = this; + const result = []; let patternSet = 0; while (true) { - let beforeLine = line; - for (let pattern of view.patterns[patternSet]) { - let matches = line.match(pattern[0]); + const beforeLine = line; + for (const pattern of view.patterns[patternSet]) { + const matches = line.match(pattern[0]); if (matches != null) { if (matches[0] != '') { - let style = pattern[1] != null ? pattern[1] : {}; - let text = matches[0]; + const style = pattern[1] != null ? pattern[1] : {}; + const text = matches[0]; if (text != '') { - let fragment = view.createFragment(matches[0], style); + const fragment = view.createFragment(matches[0], style); result.push(fragment); } line = line.substr(matches[0].length); @@ -247,15 +223,15 @@ export abstract class TextView extends View { } processText(text) { - let view = this; - let textLines = text.split(/[\n]/); + const view = this; + const textLines = text.split(/[\n]/); let lineNo = 0; - for (let line of textLines) { - let li = document.createElement("LI"); + for (const line of textLines) { + const li = document.createElement("LI"); li.className = "nolinenums"; li.dataset.lineNo = "" + lineNo++; - let fragments = view.processLine(line); - for (let fragment of fragments) { + const fragments = view.processLine(line); + for (const fragment of fragments) { li.appendChild(fragment); } view.textListNode.appendChild(li); @@ -263,13 +239,12 @@ export abstract class TextView extends View { } initializeContent(data, rememberedSelection) { - let view = this; - view.clearText(); - view.processText(data); + this.clearText(); + this.processText(data); + this.show(); } - deleteContent() { - } + public onresize(): void {} isScrollable() { return true; diff --git a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts index 4cab92a197..87924b7b96 100644 --- a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts +++ b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts @@ -2,220 +2,50 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import * as C from "./constants.js" -import {SourceResolver} from "./source-resolver.js" -import {SelectionBroker} from "./selection-broker.js" -import {DisassemblyView} from "./disassembly-view.js" -import {GraphMultiView} from "./graphmultiview.js" -import {CodeMode, CodeView} from "./code-view.js" -import * as d3 from "d3" - -class Snapper { - resizer: Resizer; - sourceExpand: HTMLElement; - sourceCollapse: HTMLElement; - disassemblyExpand: HTMLElement; - disassemblyCollapse: HTMLElement; - - constructor(resizer: Resizer) { - const snapper = this; - snapper.resizer = resizer; - snapper.sourceExpand = document.getElementById(C.SOURCE_EXPAND_ID); - snapper.sourceCollapse = document.getElementById(C.SOURCE_COLLAPSE_ID); - snapper.disassemblyExpand = document.getElementById(C.DISASSEMBLY_EXPAND_ID); - snapper.disassemblyCollapse = document.getElementById(C.DISASSEMBLY_COLLAPSE_ID); - - document.getElementById("source-collapse").addEventListener("click", function () { - resizer.snapper.toggleSourceExpanded(); - }); - document.getElementById("disassembly-collapse").addEventListener("click", function () { - resizer.snapper.toggleDisassemblyExpanded(); - }); - } - - getLastExpandedState(type, default_state) { - 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); - } - - toggleSourceExpanded(): void { - this.setSourceExpanded(!this.sourceExpand.classList.contains("invisible")); - } - - sourceExpandUpdate(newState: boolean) { - this.setLastExpandedState("source", newState); - this.sourceExpand.classList.toggle("invisible", newState); - this.sourceCollapse.classList.toggle("invisible", !newState); - } - - setSourceExpanded(newState) { - if (this.sourceExpand.classList.contains("invisible") === newState) return; - this.sourceExpandUpdate(newState); - let resizer = this.resizer; - if (newState) { - resizer.sep_left = resizer.sep_left_snap; - resizer.sep_left_snap = 0; - } else { - resizer.sep_left_snap = resizer.sep_left; - resizer.sep_left = 0; - } - resizer.updatePanes(); - } - - toggleDisassemblyExpanded() { - this.setDisassemblyExpanded(!this.disassemblyExpand.classList.contains("invisible")); - } - - disassemblyExpandUpdate(newState) { - this.setLastExpandedState("disassembly", newState); - this.disassemblyExpand.classList.toggle("invisible", newState); - this.disassemblyCollapse.classList.toggle("invisible", !newState); - } - - setDisassemblyExpanded(newState) { - if (this.disassemblyExpand.classList.contains("invisible") === newState) return; - this.disassemblyExpandUpdate(newState); - let resizer = this.resizer; - if (newState) { - resizer.sep_right = resizer.sep_right_snap; - resizer.sep_right_snap = resizer.client_width; - } else { - resizer.sep_right_snap = resizer.sep_right; - resizer.sep_right = resizer.client_width; - } - resizer.updatePanes(); - } - - panesUpated() { - this.sourceExpandUpdate(this.resizer.sep_left > this.resizer.dead_width); - this.disassemblyExpandUpdate(this.resizer.sep_right < - (this.resizer.client_width - this.resizer.dead_width)); - } -} - -class Resizer { - snapper: Snapper; - dead_width: number; - client_width: number; - left: HTMLElement; - right: HTMLElement; - middle: HTMLElement; - sep_left: number; - sep_right: number; - sep_left_snap: number; - sep_right_snap: number; - sep_width_offset: number; - panes_updated_callback: () => void; - resizer_right: d3.Selection<HTMLDivElement, any, any, any>; - resizer_left: d3.Selection<HTMLDivElement, any, any, any>; - - constructor(panes_updated_callback: () => void, dead_width: number) { - let resizer = this; - resizer.snapper = new Snapper(resizer) - resizer.panes_updated_callback = panes_updated_callback; - resizer.dead_width = dead_width - resizer.client_width = document.body.getBoundingClientRect().width; - resizer.left = document.getElementById(C.SOURCE_PANE_ID); - resizer.middle = document.getElementById(C.INTERMEDIATE_PANE_ID); - resizer.right = document.getElementById(C.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_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.drag() - .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.updatePanes(); - }) - .on('start', 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('end', function () { - resizer.resizer_left.classed("dragged", false); - }); - resizer.resizer_left.call(dragResizeLeft); - - let dragResizeRight = d3.drag() - .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.updatePanes(); - }) - .on('start', function () { - resizer.resizer_right.classed("dragged", true); - let x = d3.mouse(this.parentElement)[0]; - if (x < (resizer.client_width - dead_width)) { - resizer.sep_right_snap = resizer.sep_right; - } - }) - .on('end', function () { - resizer.resizer_right.classed("dragged", false); - });; - resizer.resizer_right.call(dragResizeRight); - window.onresize = function () { - resizer.updateWidths(); - resizer.updatePanes(); - }; - } - - updatePanes() { - let left_snapped = this.sep_left === 0; - let right_snapped = this.sep_right >= this.client_width - 1; - 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.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'); - - this.snapper.panesUpated(); - this.panes_updated_callback(); - } - - updateWidths() { - this.client_width = document.body.getBoundingClientRect().width; - this.sep_right = Math.min(this.sep_right, this.client_width); - this.sep_left = Math.min(Math.max(0, this.sep_left), this.sep_right); - } -} +import { SourceResolver } from "../src/source-resolver"; +import { SelectionBroker } from "../src/selection-broker"; +import { DisassemblyView } from "../src/disassembly-view"; +import { GraphMultiView } from "../src/graphmultiview"; +import { CodeMode, CodeView } from "../src/code-view"; +import { Tabs } from "../src/tabs"; +import { Resizer } from "../src/resizer"; +import * as C from "../src/constants"; +import { InfoView } from "./info-view"; window.onload = function () { - var svg = null; - var multiview = null; - var disassemblyView = null; - var sourceViews = []; - var selectionBroker = null; - var sourceResolver = null; - let resizer = new Resizer(panesUpdatedCallback, 100); + let multiview: GraphMultiView = null; + let disassemblyView: DisassemblyView = null; + let sourceViews: Array<CodeView> = []; + let selectionBroker: SelectionBroker = null; + let sourceResolver: SourceResolver = null; + const resizer = new Resizer(panesUpdatedCallback, 100); + const sourceTabsContainer = document.getElementById(C.SOURCE_PANE_ID); + const sourceTabs = new Tabs(sourceTabsContainer); + sourceTabs.addTab("+").classList.add("last-tab", "persistent-tab"); + const disassemblyTabsContainer = document.getElementById(C.GENERATED_PANE_ID); + const disassemblyTabs = new Tabs(disassemblyTabsContainer); + disassemblyTabs.addTab("+").classList.add("last-tab", "persistent-tab"); + const [infoTab, infoContainer] = sourceTabs.addTabAndContent("Info"); + infoTab.classList.add("persistent-tab"); + infoContainer.classList.add("viewpane", "scrollable"); + const infoView = new InfoView(infoContainer); + infoView.show(); + sourceTabs.activateTab(infoTab); function panesUpdatedCallback() { if (multiview) multiview.onresize(); } - function loadFile(txtRes) { + function loadFile(txtRes: string) { + sourceTabs.clearTabsAndContent(); + disassemblyTabs.clearTabsAndContent(); // 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()); + sourceViews.forEach(sv => sv.hide()); if (multiview) multiview.hide(); multiview = null; if (disassemblyView) disassemblyView.hide(); @@ -225,9 +55,9 @@ window.onload = function () { const jsonObj = JSON.parse(txtRes); - let fnc = jsonObj.function; + let fnc = null; // Backwards compatibility. - if (typeof fnc == 'string') { + if (typeof jsonObj.function == 'string') { fnc = { functionName: fnc, sourceId: -1, @@ -236,33 +66,42 @@ window.onload = function () { sourceText: jsonObj.source, backwardsCompatibility: true }; + } else { + fnc = Object.assign(jsonObj.function, { backwardsCompatibility: false }); } sourceResolver.setInlinings(jsonObj.inlinings); sourceResolver.setSourceLineToBytecodePosition(jsonObj.sourceLineToBytecodePosition); - sourceResolver.setSources(jsonObj.sources, fnc) + sourceResolver.setSources(jsonObj.sources, fnc); sourceResolver.setNodePositionMap(jsonObj.nodePositions); sourceResolver.parsePhases(jsonObj.phases); - let sourceView = new CodeView(C.SOURCE_PANE_ID, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE); - sourceView.show(null, null); + const [sourceTab, sourceContainer] = sourceTabs.addTabAndContent("Source"); + sourceContainer.classList.add("viewpane", "scrollable"); + sourceTabs.activateTab(sourceTab); + const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE); + sourceView.show(); sourceViews.push(sourceView); - sourceResolver.forEachSource((source) => { - let sourceView = new CodeView(C.SOURCE_PANE_ID, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE); - sourceView.show(null, null); + sourceResolver.forEachSource(source => { + const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE); + sourceView.show(); sourceViews.push(sourceView); }); - disassemblyView = new DisassemblyView(C.GENERATED_PANE_ID, selectionBroker); + const [disassemblyTab, disassemblyContainer] = disassemblyTabs.addTabAndContent("Disassembly"); + disassemblyContainer.classList.add("viewpane", "scrollable"); + disassemblyTabs.activateTab(disassemblyTab); + disassemblyView = new DisassemblyView(disassemblyContainer, selectionBroker); disassemblyView.initializeCode(fnc.sourceText); if (sourceResolver.disassemblyPhase) { disassemblyView.initializePerfProfile(jsonObj.eventCounts); - disassemblyView.show(sourceResolver.disassemblyPhase.data, null); + disassemblyView.showContent(sourceResolver.disassemblyPhase.data); + disassemblyView.show(); } multiview = new GraphMultiView(C.INTERMEDIATE_PANE_ID, selectionBroker, sourceResolver); - multiview.show(jsonObj); + multiview.show(); } catch (err) { if (window.confirm("Error: Exception during load of TurboFan JSON file:\n" + "error: " + err.message + "\nDo you want to clear session storage?")) { @@ -276,26 +115,34 @@ window.onload = function () { // 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 (this: HTMLInputElement) { - var uploadFile = this.files && this.files[0]; - var filereader = new FileReader(); - filereader.onload = function (e) { - var txtRes = e.target.result; - loadFile(txtRes); - }; - if (uploadFile) - filereader.readAsText(uploadFile); + document.getElementById("upload").addEventListener("click", e => { + document.getElementById("upload-helper").click(); + e.stopPropagation(); + }); + document.getElementById("upload-helper").addEventListener("change", + function (this: HTMLInputElement) { + const uploadFile = this.files && this.files[0]; + if (uploadFile) { + const filereader = new FileReader(); + filereader.onload = () => { + const txtRes = filereader.result; + if (typeof txtRes == 'string') { + loadFile(txtRes); + } + }; + filereader.readAsText(uploadFile); + } + } + ); + window.addEventListener("keydown", (e: KeyboardEvent) => { + if (e.keyCode == 76 && e.ctrlKey) { // CTRL + L + document.getElementById("upload-helper").click(); + e.stopPropagation(); + e.preventDefault(); + } }); } initializeUploadHandlers(); - - - resizer.snapper.setSourceExpanded(resizer.snapper.getLastExpandedState("source", true)); - resizer.snapper.setDisassemblyExpanded(resizer.snapper.getLastExpandedState("disassembly", false)); - resizer.updatePanes(); - }; diff --git a/deps/v8/tools/turbolizer/src/util.ts b/deps/v8/tools/turbolizer/src/util.ts index ef877e508c..d9c8dcdce0 100644 --- a/deps/v8/tools/turbolizer/src/util.ts +++ b/deps/v8/tools/turbolizer/src/util.ts @@ -32,7 +32,7 @@ export class ViewElements { if (!doConsider) return; const newScrollTop = computeScrollTop(this.container, element); if (isNaN(newScrollTop)) { - console.log("NOO") + console.log("NOO"); } if (this.scrollTop === undefined) { this.scrollTop = newScrollTop; @@ -47,50 +47,11 @@ export class ViewElements { } } - -function lowerBound(a, value, compare, lookup) { - let first = 0; - let count = a.length; - while (count > 0) { - let step = Math.floor(count / 2); - let middle = first + step; - let middle_value = (lookup === undefined) ? a[middle] : lookup(a, middle); - let result = (compare === undefined) ? (middle_value < value) : compare(middle_value, value); - if (result) { - first = middle + 1; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - - -function upperBound(a, value, compare, lookup) { - let first = 0; - let count = a.length; - while (count > 0) { - let step = Math.floor(count / 2); - let middle = first + step; - let middle_value = (lookup === undefined) ? a[middle] : lookup(a, middle); - let result = (compare === undefined) ? (value < middle_value) : compare(value, middle_value); - if (!result) { - first = middle + 1; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - - export function sortUnique<T>(arr: Array<T>, f: (a: T, b: T) => number, equal: (a: T, b: T) => boolean) { if (arr.length == 0) return arr; arr = arr.sort(f); - let ret = [arr[0]]; - for (var i = 1; i < arr.length; i++) { + const ret = [arr[0]]; + for (let i = 1; i < arr.length; i++) { if (!equal(arr[i - 1], arr[i])) { ret.push(arr[i]); } @@ -99,11 +60,10 @@ export function sortUnique<T>(arr: Array<T>, f: (a: T, b: T) => number, equal: ( } // Partial application without binding the receiver -export function partial(f, ...arguments1) { - return function (...arguments2) { - var arguments2 = Array.from(arguments); +export function partial(f: any, ...arguments1: Array<any>) { + return function (this: any, ...arguments2: Array<any>) { f.apply(this, [...arguments1, ...arguments2]); - } + }; } export function isIterable(obj: any): obj is Iterable<any> { @@ -111,6 +71,23 @@ export function isIterable(obj: any): obj is Iterable<any> { && typeof obj != 'string' && typeof obj[Symbol.iterator] === 'function'; } -export function alignUp(raw:number, multiple:number):number { +export function alignUp(raw: number, multiple: number): number { return Math.floor((raw + multiple - 1) / multiple) * multiple; } + +export function measureText(text: string) { + const textMeasure = document.getElementById('text-measure'); + if (textMeasure instanceof SVGTSpanElement) { + textMeasure.textContent = text; + return { + width: textMeasure.getBBox().width, + height: textMeasure.getBBox().height, + }; + } + return { width: 0, height: 0 }; +} + +// Interpolate between the given start and end values by a fraction of val/max. +export function interpolate(val: number, max: number, start: number, end: number) { + return start + (end - start) * (val / max); +} diff --git a/deps/v8/tools/turbolizer/src/view.ts b/deps/v8/tools/turbolizer/src/view.ts index dbb8514fe2..a8bb125fc4 100644 --- a/deps/v8/tools/turbolizer/src/view.ts +++ b/deps/v8/tools/turbolizer/src/view.ts @@ -3,34 +3,35 @@ // found in the LICENSE file. export abstract class View { - container: HTMLElement; - divNode: HTMLElement; - abstract initializeContent(data: any, rememberedSelection: Selection): void; - abstract createViewElement(): HTMLElement; - abstract deleteContent(): void; - abstract detachSelection(): Set<string>; + protected container: HTMLElement; + protected divNode: HTMLElement; + protected abstract createViewElement(): HTMLElement; - constructor(id) { - this.container = document.getElementById(id); + constructor(idOrContainer: string | HTMLElement) { + this.container = typeof idOrContainer == "string" ? document.getElementById(idOrContainer) : idOrContainer; this.divNode = this.createViewElement(); } - isScrollable(): boolean { - return false; - } - - show(data, rememberedSelection): void { + public show(): void { this.container.appendChild(this.divNode); - this.initializeContent(data, rememberedSelection); } - hide(): void { - this.deleteContent(); + public hide(): void { this.container.removeChild(this.divNode); } } -export interface PhaseView { - onresize(); - searchInputAction(searchInput: HTMLInputElement, e: Event); +export abstract class PhaseView extends View { + public abstract initializeContent(data: any, rememberedSelection: Set<any>): void; + public abstract detachSelection(): Set<string>; + public abstract onresize(): void; + public abstract searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void; + + constructor(idOrContainer: string | HTMLElement) { + super(idOrContainer); + } + + public isScrollable(): boolean { + return false; + } } diff --git a/deps/v8/tools/turbolizer/tabs.css b/deps/v8/tools/turbolizer/tabs.css new file mode 100644 index 0000000000..54dba72b70 --- /dev/null +++ b/deps/v8/tools/turbolizer/tabs.css @@ -0,0 +1,55 @@ +.content { + display: grid; + grid-template-areas: "tabs" "window"; + grid-template-columns: 1fr; + grid-template-rows: auto 1fr; + min-height: calc(100vh); +} + +.nav-tabs-container { + grid-area: tabs; + padding: 0px; + background-color: #999999; + border-bottom: 4px solid #CCCCCC; +} + +.tab-content { + grid-area: window; + background-color: white; + padding: 0px; + display:none; +} + +.tab-content.tab-default { + display: block; +} + +ul.nav-tabs { + padding: 0px; + margin: 0px; + overflow: auto; + display: table-row; + min-height: 2ex; +} + +.nav-tabs li { + display: inline-block; + padding-left: 10px; + padding-right: 10px; + padding-top: 4px; + padding-bottom: 4px; + min-width: 20px; + text-decoration: none; + color: black; + text-align: center; + user-select: none; + cursor: pointer; +} + +.nav-tabs li:hover { + background-color: #EEEEEE; +} + +.nav-tabs li.active { + background-color: #CCCCCC; +}
\ No newline at end of file diff --git a/deps/v8/tools/turbolizer/test/source-resolver-test.ts b/deps/v8/tools/turbolizer/test/source-resolver-test.ts new file mode 100644 index 0000000000..38d674510f --- /dev/null +++ b/deps/v8/tools/turbolizer/test/source-resolver-test.ts @@ -0,0 +1,10 @@ +import { SourceResolver } from '../src/source-resolver'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +describe('SourceResolver', () => { + it('should be constructible', () => { + const a: SourceResolver = new SourceResolver(); + expect(a.sources.length).to.equal(0); + }); +}); diff --git a/deps/v8/tools/turbolizer/tsconfig.json b/deps/v8/tools/turbolizer/tsconfig.json index c54157280f..cd036ac3ab 100644 --- a/deps/v8/tools/turbolizer/tsconfig.json +++ b/deps/v8/tools/turbolizer/tsconfig.json @@ -1,32 +1,39 @@ { - "compilerOptions": { - "outDir": "build/", - "allowJs": false, - "target": "es2017", - "module": "es2015", - "sourceMap": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "moduleResolution": "node" - }, - "files": [ - "src/util.ts", - "src/lang-disassembly.ts", - "src/node.ts", - "src/edge.ts", - "src/source-resolver.ts", - "src/selection.ts", - "src/selection-broker.ts", - "src/selection-handler.ts", - "src/constants.ts", - "src/view.ts", - "src/text-view.ts", - "src/code-view.ts", - "src/graph-layout.ts", - "src/graph-view.ts", - "src/schedule-view.ts", - "src/disassembly-view.ts", - "src/graphmultiview.ts", - "src/turbo-visualizer.ts" - ] + "compilerOptions": { + "outDir": "build/", + "allowJs": false, + "target": "es2018", + "module": "es2015", + "sourceMap": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "moduleResolution": "node", + "noUnusedLocals": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "lib": ["dom", "es6", "dom.iterable", "scripthost", "es2018"] + }, + "files": [ + "src/util.ts", + "src/node.ts", + "src/edge.ts", + "src/graph.ts", + "src/node-label.ts", + "src/source-resolver.ts", + "src/selection.ts", + "src/selection-broker.ts", + "src/selection-handler.ts", + "src/constants.ts", + "src/view.ts", + "src/text-view.ts", + "src/code-view.ts", + "src/graph-layout.ts", + "src/graph-view.ts", + "src/schedule-view.ts", + "src/disassembly-view.ts", + "src/graphmultiview.ts", + "src/turbo-visualizer.ts", + "src/resizer.ts", + "src/info-view.ts" + ] } diff --git a/deps/v8/tools/turbolizer/tsconfig.test.json b/deps/v8/tools/turbolizer/tsconfig.test.json new file mode 100644 index 0000000000..1b7a59159d --- /dev/null +++ b/deps/v8/tools/turbolizer/tsconfig.test.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs" + } +} diff --git a/deps/v8/tools/turbolizer/tslint.json b/deps/v8/tools/turbolizer/tslint.json new file mode 100644 index 0000000000..e07e057a62 --- /dev/null +++ b/deps/v8/tools/turbolizer/tslint.json @@ -0,0 +1,45 @@ +{ + "defaultSeverity": "error", + "extends": "tslint:recommended", + "jsRules": {}, + "rules": { + "curly": [true, "ignore-same-line"], + "quotemark": [false, "double", "avoid-escape", "avoid-template"], + "only-arrow-functions": [false], + "no-var-keyword": true, + "prefer-const": [true], + "max-line-length": [false, { + "limit": 80 + }], + "ordered-imports": false, + "array-type": [true, "generic"], + "semicolon": true, + "member-access": false, + "object-literal-shorthand": false, + "object-literal-key-quotes": [true, "as-needed"], + "object-literal-sort-keys": false, + "space-before-function-paren": [true, { + "anonymous": "always" + }], + "triple-equals": false, + "no-string-throw": false, + "no-empty": [true, "allow-empty-catch", "allow-empty-functions"], + "trailing-comma": false, + "member-ordering": false, + "no-string-literal": false, + "arrow-parens": [true, "ban-single-arg-parens"], + "no-console": false, + "interface-name": false, + "no-bitwise": false, + "no-shadowed-variable": false, + "prefer-for-of": true, + "align": true, + "arrow-return-shorthand": true, + "max-classes-per-file": false, + "variable-name": true, + "forin": false, + "one-variable-per-declaration": true, + "no-consecutive-blank-lines": true + }, + "rulesDirectory": [] +} diff --git a/deps/v8/tools/turbolizer/turbo-visualizer.css b/deps/v8/tools/turbolizer/turbo-visualizer.css index c7d45a7ee2..b37dcc498b 100644 --- a/deps/v8/tools/turbolizer/turbo-visualizer.css +++ b/deps/v8/tools/turbolizer/turbo-visualizer.css @@ -1,58 +1,69 @@ .visible-transition { - transition-delay: 0s; - transition-duration: 1s; - transition-property: all; - transition-timing-function: ease; + transition-delay: 0s; + transition-duration: 1s; + transition-property: all; + transition-timing-function: ease; } .collapse-pane { - background: #A0A0A0; - bottom: 0; - position: absolute; - margin-bottom: 0.5em; - margin-right: 0.5em; - margin-left: 0.5em; - border-radius: 5px; - padding: 0.5em; - z-index: 5; - opacity: 0.7; - cursor: pointer; + background: #A0A0A0; + bottom: 0; + position: absolute; + margin-bottom: 0.5em; + margin-right: 0.5em; + margin-left: 0.5em; + border-radius: 5px; + padding: 0.5em; + z-index: 20; + opacity: 0.7; + cursor: pointer; } .search-input { - vertical-align: middle; - width: 145px; - opacity: 1; + vertical-align: middle; + width: 145px; + opacity: 1; + box-sizing: border-box; + height: 1.5em; +} + +#phase-select { + box-sizing: border-box; + height: 1.5em; +} + +#search-only-visible { + vertical-align: middle; } .button-input { - vertical-align: middle; - width: 24px; - opacity: 0.4; - cursor: pointer; + vertical-align: middle; + width: 24px; + opacity: 0.4; + cursor: pointer; } .button-input-toggled { - border-radius: 5px; - background-color: #505050; + border-radius: 5px; + background-color: #505050; } .button-input:focus { - outline: none; + outline: none; } .invisible { - display: none; + display: none; } .selected { - background-color: #FFFF33; + background-color: #FFFF33; } .selected.block, .selected.block-id, .selected.schedule-block { - background-color: #AAFFAA; + background-color: #AAFFAA; } ol.linenums { @@ -60,120 +71,142 @@ ol.linenums { } .line-number { - display:inline-block; - min-width: 3ex; - text-align: right; - color: #444444; - margin-right: 0.5ex; - padding-right: 0.5ex; - background: #EEEEEE; - /* font-size: 80%; */ - user-select: none; - height: 120%; + display: inline-block; + min-width: 3ex; + text-align: right; + color: #444444; + margin-right: 0.5ex; + padding-right: 0.5ex; + background: #EEEEEE; + /* font-size: 80%; */ + user-select: none; + height: 120%; } .line-number:hover { - background-color: #CCCCCC; + background-color: #CCCCCC; } -.prettyprint ol.linenums > li.selected { - background-color: #FFFF33 !important; +.prettyprint ol.linenums>li.selected { + background-color: #FFFF33 !important; } li.selected .line-number { - background-color: #FFFF33; + background-color: #FFFF33; } -.prettyprint ol.linenums > li { - list-style-type: decimal; - display: block; +.prettyprint ol.linenums>li { + list-style-type: decimal; + display: block; } .source-container { - border-bottom: 2px solid #AAAAAA; + 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; + 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; + border-top: 2px solid #AAAAAA; + font-weight: bold; } .code-header .code-file-function { - font-family: monospace; - float: left; - user-select: text; + font-family: monospace; + float: left; + user-select: text; } .code-header .code-mode { - float: right; - font-family: sans-serif; - font-size: small; + float: right; + font-family: sans-serif; + font-size: small; +} + +.info-container { + font-family: sans-serif; + font-size: small; +} + +.info-topic { + border: 1px solid lightgray; + margin: 2px; } -html, body { - margin: 0; - padding: 0; - /*height: 99vh; +.info-topic-header { + background-color: lightgray; + padding: 1px; +} + +.info-topic-content { + padding: 2px; +} + + +html, +body { + margin: 0; + padding: 0; + /*height: 99vh; width: 99vw;*/ - overflow: hidden; + overflow: hidden; } p { - text-align: center; - overflow: overlay; - position: relative; + text-align: center; + overflow: overlay; + position: relative; } marker { - fill: #080808; + fill: #080808; } g rect { - fill: #F0F0F0; - stroke: #080808; - stroke-width: 2px; + fill: #F0F0F0; + stroke: #080808; + stroke-width: 2px; } g.dead { - opacity: .5; + opacity: .5; } g.unsorted rect { - opacity: 0.5; + opacity: 0.5; } div.scrollable { - overflow-y: auto; overflow-x: hidden; + overflow-y: auto; + overflow-x: hidden; } g.turbonode[relToHover="input"] rect { - stroke: #67e62c; - stroke-width: 16px; + stroke: #67e62c; + stroke-width: 16px; } g.turbonode[relToHover="output"] rect { - stroke: #d23b14; - stroke-width: 16px; + stroke: #d23b14; + stroke-width: 16px; } path[relToHover="input"] { - stroke: #67e62c; - stroke-width: 16px; + stroke: #67e62c; + stroke-width: 16px; } path[relToHover="output"] { - stroke: #d23b14; - stroke-width: 16px; + stroke: #d23b14; + stroke-width: 16px; } @@ -183,82 +216,82 @@ g.turbonode:hover rect { } g.control rect { - fill: #EFCC00; - stroke: #080808; - stroke-width: 5px; + fill: #EFCC00; + stroke: #080808; + stroke-width: 5px; } g.javascript rect { - fill: #DD7E6B; + fill: #DD7E6B; } g.simplified rect { - fill: #3C78D8; + fill: #3C78D8; } g.machine rect { - fill: #6AA84F; + fill: #6AA84F; } g.input rect { - fill: #CFE2F3; + fill: #CFE2F3; } g.selected rect { - fill: #FFFF33; + fill: #FFFF33; } circle.bubbleStyle { - fill: #080808; - fill-opacity: 0.0; - stroke: #080808; - stroke-width: 2px; + fill: #080808; + fill-opacity: 0.0; + stroke: #080808; + stroke-width: 2px; } circle.bubbleStyle:hover { - stroke-width: 3px; + stroke-width: 3px; } circle.filledBubbleStyle { - fill: #080808; - stroke: #080808; - stroke-width: 2px; + fill: #080808; + stroke: #080808; + stroke-width: 2px; } circle.filledBubbleStyle:hover { - fill: #080808; - stroke-width: 3px; + fill: #080808; + stroke-width: 3px; } circle.halfFilledBubbleStyle { - fill: #808080; - stroke: #101010; - stroke-width: 2px; + fill: #808080; + stroke: #101010; + stroke-width: 2px; } circle.halfFilledBubbleStyle:hover { - fill: #808080; - stroke-width: 3px; + fill: #808080; + stroke-width: 3px; } path { - fill: none; - stroke: #080808; - stroke-width: 4px; - cursor: default; + fill: none; + stroke: #080808; + stroke-width: 4px; + cursor: default; } path:hover { - stroke-width: 6px; + stroke-width: 6px; } path.hidden { - fill: none; - stroke-width: 0; + fill: none; + stroke-width: 0; } path.link.selected { - stroke: #FFFF33; + stroke: #FFFF33; } pre.prettyprint { @@ -271,11 +304,11 @@ li.L3, li.L5, li.L7, li.L9 { - background: none !important + background: none !important } li.nolinenums { - list-style-type:none; + list-style-type: none; } ul.noindent { @@ -284,151 +317,142 @@ ul.noindent { -webkit-margin-after: 0px; } -input:hover, .collapse-pane:hover input { - opacity: 1; - cursor: pointer; +input:hover, +.collapse-pane:hover input { + opacity: 1; + cursor: pointer; } -span.linkable-text { - text-decoration: underline; +.linkable-text { + text-decoration: underline; } -span.linkable-text:hover { - cursor: pointer; - font-weight: bold; +.linkable-text:hover { + cursor: pointer; + font-weight: bold; } #left { - float: left; - user-select: none; + float: left; + user-select: none; } #middle { - float:left; - background-color: #F8F8F8; - user-select: none; + float: left; + background-color: #F8F8F8; + user-select: none; } #right { - float: right; + float: right; } .viewpane { - height: 100vh; - background-color: #FFFFFF; + height: 100vh; + background-color: #FFFFFF; +} + +.multiview { + width: 100%; } #disassembly-collapse { - right: 0; + right: 0; } #source-collapse { - left: 0; + left: 0; } #graph { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } -#graph-toolbox-anchor { - height: 0px; +.toolbox-anchor { + height: 0px; } -#graph-toolbox { - position: relative; - top: 1em; - left: 25px; - border: 2px solid #eee8d5; - border-radius: 5px; - padding: 0.7em; - z-index: 5; - background: rgba(100%, 100%, 100%, 0.7); +.graph-toolbox { + position: relative; + border-bottom: 2px solid #eee8d5; + z-index: 5; + background: rgba(100%, 100%, 100%, 0.7); + box-sizing: border-box; + padding: 3px; + margin-left: 4px; + margin-right: 4px; } -#disassembly-toolbox { - position: relative; - top: 1em; - left: 0.7em; - border: 2px solid #eee8d5; - border-radius: 5px; - padding: 0.7em; - z-index: 5; +.disassembly-toolbox { + position: relative; + padding-bottom: 3px; + z-index: 5; + background: rgba(100%, 100%, 100%, 0.7); + padding-top: 3px; + box-sizing: border-box; + margin-left: 4px; + margin-right: 4px; } #load-file { - position: absolute; - top: 0; - right: 0; - margin-top: 0.5em; - margin-right: 0.5em; - z-index: 5; - opacity: 0.7; + position: absolute; + top: 0; + right: 0; + margin-top: 0.5em; + margin-right: 0.5em; + z-index: 20; + opacity: 0.7; } #load-file input { - background: #A0A0A0; - border-radius: 5px; - padding: 0.5em; + background: #A0A0A0; + border-radius: 5px; + padding: 0.5em; } #upload-helper { - display: none; + display: none; } .prof { - cursor: default; + cursor: default; } tspan { - font-size: 500%; - font-family: sans-serif; + font-size: 500%; + font-family: sans-serif; } text { - dominant-baseline: text-before-edge; -} - -.resizer-left { - position:absolute; - width: 4px; - height:100%; - background: #a0a0a0; - cursor: pointer; + dominant-baseline: text-before-edge; } -.resizer-left.snapped { - width: 12px; +.resizer { + position: absolute; + z-index: 10; + width: 4px; + height: 100%; + background: #a0a0a0; + cursor: pointer; } -.resizer-left:hover { - background: orange; +.resizer.snapped { + width: 12px; } -.resizer-left.dragged { - background: orange; +.resizer.snapped:hover { + width: 12px; + margin-left: 0px; } -.resizer-right { - position:absolute; - width: 4px; - height:100%; - background: #a0a0a0; - cursor: pointer; -} - -.resizer-right.snapped { - width: 12px; -} - -.resizer-right:hover { - background: orange; -} - -.resizer-right.dragged { - background: orange; +.resizer:hover, +.resizer.dragged { + width: 10px; + margin-left: -4px; + background: orange; } .source-position { @@ -438,227 +462,233 @@ text { } .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; + 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; + content: ""; + display: inline-block; + bottom: -1ex; + width: 0px; + margin-left: -4px; + margin-right: -4px; + margin-bottom: -1ex; + border-width: 5px; + border-style: solid; + border-color: transparent transparent #555 transparent; } .source-position.selected .marker { - border-color: transparent transparent #F00 transparent; + border-color: transparent transparent #F00 transparent; } .source-position .inlining-marker:hover { - border-color: transparent transparent #AA5 transparent; + 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; + 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; } #sequence { - font-family: monospace; - margin-top: 50px; + font-family: monospace; + margin-top: 50px; } #schedule { - font-family: monospace; - margin-top: 50px; + font-family: monospace; + margin-top: 50px; } .schedule-block { - margin: 5px; - background-color: white; - padding-left: 5px; + margin: 5px; + background-color: white; + padding-left: 5px; } .schedule-block .block-id { - display: inline-block; - font-size:large; - text-decoration: underline; - padding-left: 1ex; + display: inline-block; + font-size: large; + text-decoration: underline; + padding-left: 1ex; } .schedule-block .block-id:hover { - font-weight: bold; + font-weight: bold; } -.schedule-block > .block-id::before { - content: "Block B"; +.schedule-block>.block-id::before { + content: "Block B"; } .schedule-block .block-list { - display: inline-block; + display: inline-block; } .schedule-block .block-list * { - display: inline-block; + display: inline-block; } .schedule-block .block-list .block-id { - padding-left: 1ex; + padding-left: 1ex; } .schedule-block .block-list .block-id:before { - content: "B"; + content: "B"; } .schedule-block .predecessor-list::before { - display: inline-block; - content: " \2B05 "; - padding-left: 1ex; - padding-right: 1ex; + 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; + display: inline-block; + content: " \2B95 "; + padding-left: 1ex; + padding-right: 1ex; } .schedule-block .nodes .node * { - display:inline-block; + display: inline-block; } .schedule-block .nodes .node .node-id { - padding-right: 1ex; - min-width: 5ex; - text-align: right; + padding-right: 1ex; + min-width: 5ex; + text-align: right; } .schedule-block .nodes .node .node-id:after { - content: ":"; + content: ":"; } .schedule-block .nodes .node .node-label { - user-select: text; + user-select: text; } .schedule-block .nodes .node .parameter-list:before { - content: "("; + content: "("; } .schedule-block .nodes .node .parameter-list:after { - content: ")"; + content: ")"; } .schedule-block .instr-marker { - padding-right: .5ex; - padding-left: .5ex; - min-width: 1ex; - background: #EEEEEE; - /* display: none; */ + padding-right: .5ex; + padding-left: .5ex; + min-width: 1em; + background: #EEEEEE; + /* display: none; */ } -.schedule-block > .instr-marker { - display: inline; +.schedule-block>.instr-marker { + display: inline; } .instruction * { - padding-right: .5ex; + padding-right: .5ex; } -.phi-label, .instruction-id { - display: inline-block; - padding-right: .5ex; - padding-left: .5ex; - min-width: 1ex; - vertical-align: top; +.phi-label, +.instruction-id { + display: inline-block; + padding-right: .5ex; + padding-left: .5ex; + min-width: 1ex; + vertical-align: top; } .instruction-id:after { - content: ":"; + content: ":"; } -.instruction-node, .gap, .instruction { - display: block; +.instruction-node, +.gap, +.instruction { + display: block; } -.phi-contents, .instruction-contents, .gap *, .instruction * { - display: inline-block; +.phi-contents, +.instruction-contents, +.gap *, +.instruction * { + display: inline-block; } .phi * { - padding-right: 1ex; - display: inline-block; + padding-right: 1ex; + display: inline-block; } .gap .gap-move { - padding-left: .5ex; - padding-right: .5ex; + padding-left: .5ex; + padding-right: .5ex; } -.gap > *:before { - content: "("; +.gap>*:before { + content: "("; } -.gap > *:after { - content: ")"; +.gap>*:after { + content: ")"; } .parameter.constant { - outline: 1px dotted red; + outline: 1px dotted red; } .clickable:hover { - text-decoration: underline; + text-decoration: underline; } .clickable:hover { - font-weight: bold; + font-weight: bold; } -.comma-sep-list > * { - padding-right: 1ex; +.comma-sep-list>* { + padding-right: 1ex; } -.comma-sep-list > *:after { - content: ","; +.comma-sep-list>*:after { + content: ","; } -.comma-sep-list > *:last-child:after { - content: ""; +.comma-sep-list>*:last-child:after { + content: ""; } -.comma-sep-list > *:last-child { - padding-right: 0ex; +.comma-sep-list>*:last-child { + padding-right: 0ex; } .temps:before { - content: "temps: "; + content: "temps: "; } .temps { - padding-left: .5ex; - outline: 1px dotted grey; + padding-left: .5ex; + outline: 1px dotted grey; } diff --git a/deps/v8/tools/ubsan/blacklist.txt b/deps/v8/tools/ubsan/blacklist.txt index 213f2da600..12504639c5 100644 --- a/deps/v8/tools/ubsan/blacklist.txt +++ b/deps/v8/tools/ubsan/blacklist.txt @@ -1,2 +1,6 @@ ############################################################################# -# UBSan blacklist.
\ No newline at end of file +# UBSan blacklist. + +# UBSan bug, fixed in LLVM r350779. Drop this suppression when that +# revision has rolled into Chromium's bundled Clang. +fun:*v8*internal*NewArray* diff --git a/deps/v8/tools/unittests/run_perf_test.py b/deps/v8/tools/unittests/run_perf_test.py index 6ba18e0b9e..0e22c77c11 100755 --- a/deps/v8/tools/unittests/run_perf_test.py +++ b/deps/v8/tools/unittests/run_perf_test.py @@ -85,7 +85,7 @@ V8_GENERIC_JSON = { "units": "ms", } -Output = namedtuple("Output", "stdout, stderr, timed_out") +Output = namedtuple("Output", "stdout, stderr, timed_out, exit_code") class PerfTest(unittest.TestCase): @classmethod @@ -113,6 +113,7 @@ class PerfTest(unittest.TestCase): os.makedirs(TEST_WORKSPACE) def tearDown(self): + patch.stopall() if path.exists(TEST_WORKSPACE): shutil.rmtree(TEST_WORKSPACE) @@ -125,7 +126,8 @@ class PerfTest(unittest.TestCase): # Fake output for each test run. test_outputs = [Output(stdout=arg, stderr=None, - timed_out=kwargs.get("timed_out", False)) + timed_out=kwargs.get("timed_out", False), + exit_code=kwargs.get("exit_code", 0)) for arg in args[1]] def create_cmd(*args, **kwargs): cmd = MagicMock() @@ -134,7 +136,9 @@ class PerfTest(unittest.TestCase): cmd.execute = MagicMock(side_effect=execute) return cmd - command.Command = MagicMock(side_effect=create_cmd) + patch.object( + run_perf.command, 'PosixCommand', + MagicMock(side_effect=create_cmd)).start() # Check that d8 is called from the correct cwd for each test run. dirs = [path.join(TEST_WORKSPACE, arg) for arg in args[0]] @@ -402,6 +406,18 @@ class PerfTest(unittest.TestCase): self._VerifyErrors(["Found non-numeric in test/Infra/Constant4"]) self._VerifyMock(path.join("out", "x64.release", "cc"), "--flag", "") + def testOneRunCrashed(self): + self._WriteTestInput(V8_JSON) + self._MockCommand( + ["."], ["x\nRichards: 1.234\nDeltaBlue: 10657567\ny\n"], exit_code=1) + self.assertEquals(1, self._CallMain()) + self._VerifyResults("test", "score", [ + {"name": "Richards", "results": [], "stddev": ""}, + {"name": "DeltaBlue", "results": [], "stddev": ""}, + ]) + self._VerifyErrors([]) + self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") + def testOneRunTimingOut(self): test_input = dict(V8_JSON) test_input["timeout"] = 70 @@ -412,10 +428,7 @@ class PerfTest(unittest.TestCase): {"name": "Richards", "results": [], "stddev": ""}, {"name": "DeltaBlue", "results": [], "stddev": ""}, ]) - self._VerifyErrors([ - "Regexp \"^Richards: (.+)$\" didn't match for test test/Richards.", - "Regexp \"^DeltaBlue: (.+)$\" didn't match for test test/DeltaBlue.", - ]) + self._VerifyErrors([]) self._VerifyMock( path.join("out", "x64.release", "d7"), "--flag", "run.js", timeout=70) diff --git a/deps/v8/tools/unittests/run_tests_test.py b/deps/v8/tools/unittests/run_tests_test.py index 4eb9feeac6..e136db6b53 100755 --- a/deps/v8/tools/unittests/run_tests_test.py +++ b/deps/v8/tools/unittests/run_tests_test.py @@ -103,8 +103,7 @@ def run_tests(basedir, *args, **kwargs): sys_args.append('--infra-staging') else: sys_args.append('--no-infra-staging') - code = standard_runner.StandardTestRunner( - basedir=basedir).execute(sys_args) + code = standard_runner.StandardTestRunner(basedir=basedir).execute(sys_args) return Result(stdout.getvalue(), stderr.getvalue(), code) @@ -174,7 +173,6 @@ class SystemTest(unittest.TestCase): 'sweet/bananas', 'sweet/raspberries', ) - self.assertIn('Running 2 base tests', result.stdout, result) self.assertIn('Done running sweet/bananas: pass', result.stdout, result) # TODO(majeski): Implement for test processors # self.assertIn('Total time:', result.stderr, result) @@ -193,10 +191,9 @@ class SystemTest(unittest.TestCase): '--shard-run=%d' % shard, 'sweet/bananas', 'sweet/raspberries', - infra_staging=True, + infra_staging=False, ) # One of the shards gets one variant of each test. - self.assertIn('Running 1 base tests', result.stdout, result) self.assertIn('2 tests ran', result.stdout, result) if shard == 1: self.assertIn('Done running sweet/bananas', result.stdout, result) @@ -225,10 +222,7 @@ class SystemTest(unittest.TestCase): self.assertIn('Done running sweet/raspberries', result.stdout, result) self.assertEqual(0, result.returncode, result) - def testFailProc(self): - self.testFail(infra_staging=True) - - def testFail(self, infra_staging=True): + def testFail(self): """Test running only failing tests in two variants.""" with temp_base() as basedir: result = run_tests( @@ -237,17 +231,13 @@ class SystemTest(unittest.TestCase): '--progress=verbose', '--variants=default,stress', 'sweet/strawberries', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 2 tests', result.stdout, result) - else: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn('2 tests ran', result.stdout, result) self.assertIn('Done running sweet/strawberries: FAIL', result.stdout, result) self.assertEqual(1, result.returncode, result) - def check_cleaned_json_output(self, expected_results_name, actual_json): + def check_cleaned_json_output( + self, expected_results_name, actual_json, basedir): # Check relevant properties of the json output. with open(actual_json) as f: json_output = json.load(f)[0] @@ -260,6 +250,7 @@ class SystemTest(unittest.TestCase): data['duration'] = 1 data['command'] = ' '.join( ['/usr/bin/python'] + data['command'].split()[1:]) + data['command'] = data['command'].replace(basedir + '/', '') for data in json_output['slowest_tests']: replace_variable_data(data) for data in json_output['results']: @@ -272,10 +263,7 @@ class SystemTest(unittest.TestCase): msg = None # Set to pretty_json for bootstrapping. self.assertDictEqual(json_output, expected_test_results, msg) - def testFailWithRerunAndJSONProc(self): - self.testFailWithRerunAndJSON(infra_staging=True) - - def testFailWithRerunAndJSON(self, infra_staging=True): + def testFailWithRerunAndJSON(self): """Test re-running a failing test and output to json.""" with temp_base() as basedir: json_path = os.path.join(basedir, 'out.json') @@ -288,21 +276,12 @@ class SystemTest(unittest.TestCase): '--random-seed=123', '--json-test-results', json_path, 'sweet/strawberries', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 1 tests', result.stdout, result) - else: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn('1 tests ran', result.stdout, result) self.assertIn('Done running sweet/strawberries: FAIL', result.stdout, result) - if not infra_staging: - # We run one test, which fails and gets re-run twice. - self.assertIn('3 tests failed', result.stdout, result) - else: - # With test processors we don't count reruns as separated failures. - # TODO(majeski): fix it? - self.assertIn('1 tests failed', result.stdout, result) + # With test processors we don't count reruns as separated failures. + # TODO(majeski): fix it? + self.assertIn('1 tests failed', result.stdout, result) self.assertEqual(0, result.returncode, result) # TODO(majeski): Previously we only reported the variant flags in the @@ -310,12 +289,10 @@ class SystemTest(unittest.TestCase): # After recent changes we report all flags, including the file names. # This is redundant to the command. Needs investigation. self.maxDiff = None - self.check_cleaned_json_output('expected_test_results1.json', json_path) + self.check_cleaned_json_output( + 'expected_test_results1.json', json_path, basedir) - def testFlakeWithRerunAndJSONProc(self): - self.testFlakeWithRerunAndJSON(infra_staging=True) - - def testFlakeWithRerunAndJSON(self, infra_staging=True): + def testFlakeWithRerunAndJSON(self): """Test re-running a failing test and output to json.""" with temp_base(baseroot='testroot2') as basedir: json_path = os.path.join(basedir, 'out.json') @@ -328,21 +305,15 @@ class SystemTest(unittest.TestCase): '--random-seed=123', '--json-test-results', json_path, 'sweet', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 1 tests', result.stdout, result) - self.assertIn( - 'Done running sweet/bananaflakes: FAIL', result.stdout, result) - self.assertIn('1 tests failed', result.stdout, result) - else: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn( - 'Done running sweet/bananaflakes: pass', result.stdout, result) - self.assertIn('All tests succeeded', result.stdout, result) + self.assertIn( + 'Done running sweet/bananaflakes: pass', result.stdout, result) + self.assertIn('All tests succeeded', result.stdout, result) self.assertEqual(0, result.returncode, result) self.maxDiff = None - self.check_cleaned_json_output('expected_test_results2.json', json_path) + self.check_cleaned_json_output( + 'expected_test_results2.json', json_path, basedir) def testAutoDetect(self): """Fake a build with several auto-detected options. @@ -355,7 +326,9 @@ class SystemTest(unittest.TestCase): basedir, dcheck_always_on=True, is_asan=True, is_cfi=True, is_msan=True, is_tsan=True, is_ubsan_vptr=True, target_cpu='x86', v8_enable_i18n_support=False, v8_target_cpu='x86', - v8_use_snapshot=False) + v8_use_snapshot=False, v8_enable_embedded_builtins=False, + v8_enable_verify_csa=False, v8_enable_lite_mode=False, + v8_enable_pointer_compression=False) result = run_tests( basedir, '--mode=Release', @@ -379,10 +352,7 @@ class SystemTest(unittest.TestCase): # TODO(machenbach): Test some more implications of the auto-detected # options, e.g. that the right env variables are set. - def testSkipsProc(self): - self.testSkips(infra_staging=True) - - def testSkips(self, infra_staging=True): + def testSkips(self): """Test skipping tests in status file for a specific variant.""" with temp_base() as basedir: result = run_tests( @@ -391,19 +361,27 @@ class SystemTest(unittest.TestCase): '--progress=verbose', '--variants=nooptimization', 'sweet/strawberries', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 0 tests', result.stdout, result) - else: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn('0 tests ran', result.stdout, result) + self.assertIn('0 tests ran', result.stdout, result) self.assertEqual(2, result.returncode, result) - def testDefaultProc(self): - self.testDefault(infra_staging=True) + def testRunSkips(self): + """Inverse the above. Test parameter to keep running skipped tests.""" + with temp_base() as basedir: + result = run_tests( + basedir, + '--mode=Release', + '--progress=verbose', + '--variants=nooptimization', + '--run-skipped', + 'sweet/strawberries', + ) + self.assertIn('1 tests failed', result.stdout, result) + self.assertIn('1 tests ran', result.stdout, result) + self.assertEqual(1, result.returncode, result) - def testDefault(self, infra_staging=True): + def testDefault(self): """Test using default test suites, though no tests are run since they don't exist in a test setting. """ @@ -411,13 +389,9 @@ class SystemTest(unittest.TestCase): result = run_tests( basedir, '--mode=Release', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Warning: no tests were run!', result.stdout, result) - else: - self.assertIn('Running 0 base tests', result.stdout, result) - self.assertIn('0 tests ran', result.stdout, result) + self.assertIn('0 tests ran', result.stdout, result) self.assertEqual(2, result.returncode, result) def testNoBuildConfig(self): @@ -514,10 +488,7 @@ class SystemTest(unittest.TestCase): self.assertIn('(no source available)', result.stdout, result) self.assertEqual(0, result.returncode, result) - def testPredictableProc(self): - self.testPredictable(infra_staging=True) - - def testPredictable(self, infra_staging=True): + def testPredictable(self): """Test running a test in verify-predictable mode. The test will fail because of missing allocation output. We verify that and @@ -531,13 +502,9 @@ class SystemTest(unittest.TestCase): '--progress=verbose', '--variants=default', 'sweet/bananas', - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 1 tests', result.stdout, result) - else: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn('1 tests ran', result.stdout, result) + self.assertIn('1 tests ran', result.stdout, result) self.assertIn('Done running sweet/bananas: FAIL', result.stdout, result) self.assertIn('Test had no allocation output', result.stdout, result) self.assertIn('--predictable --verify_predictable', result.stdout, result) @@ -558,10 +525,7 @@ class SystemTest(unittest.TestCase): # timeout was used. self.assertEqual(0, result.returncode, result) - def testRandomSeedStressWithDefaultProc(self): - self.testRandomSeedStressWithDefault(infra_staging=True) - - def testRandomSeedStressWithDefault(self, infra_staging=True): + def testRandomSeedStressWithDefault(self): """Test using random-seed-stress feature has the right number of tests.""" with temp_base() as basedir: result = run_tests( @@ -571,13 +535,9 @@ class SystemTest(unittest.TestCase): '--variants=default', '--random-seed-stress-count=2', 'sweet/bananas', - infra_staging=infra_staging, + infra_staging=False, ) - if infra_staging: - self.assertIn('Running 1 base tests', result.stdout, result) - self.assertIn('2 tests ran', result.stdout, result) - else: - self.assertIn('Running 2 tests', result.stdout, result) + self.assertIn('2 tests ran', result.stdout, result) self.assertEqual(0, result.returncode, result) def testRandomSeedStressWithSeed(self): @@ -592,7 +552,6 @@ class SystemTest(unittest.TestCase): '--random-seed=123', 'sweet/strawberries', ) - self.assertIn('Running 1 base tests', result.stdout, result) self.assertIn('2 tests ran', result.stdout, result) # We use a failing test so that the command is printed and we can verify # that the right random seed was passed. @@ -618,7 +577,6 @@ class SystemTest(unittest.TestCase): ) # Both tests are either marked as running in only default or only # slow variant. - self.assertIn('Running 2 base tests', result.stdout, result) self.assertIn('2 tests ran', result.stdout, result) self.assertEqual(0, result.returncode, result) @@ -629,10 +587,7 @@ class SystemTest(unittest.TestCase): self.assertTrue(statusfile.PresubmitCheck( os.path.join(basedir, 'test', 'sweet', 'sweet.status'))) - def testDotsProgressProc(self): - self.testDotsProgress(infra_staging=True) - - def testDotsProgress(self, infra_staging=True): + def testDotsProgress(self): with temp_base() as basedir: result = run_tests( basedir, @@ -641,29 +596,19 @@ class SystemTest(unittest.TestCase): 'sweet/cherries', 'sweet/bananas', '--no-sorting', '-j1', # make results order deterministic - infra_staging=infra_staging, + infra_staging=False, ) - if not infra_staging: - self.assertIn('Running 2 tests', result.stdout, result) - else: - self.assertIn('Running 2 base tests', result.stdout, result) - self.assertIn('2 tests ran', result.stdout, result) + self.assertIn('2 tests ran', result.stdout, result) self.assertIn('F.', result.stdout, result) self.assertEqual(1, result.returncode, result) - def testMonoProgressProc(self): - self._testCompactProgress('mono', True) - def testMonoProgress(self): - self._testCompactProgress('mono', False) - - def testColorProgressProc(self): - self._testCompactProgress('color', True) + self._testCompactProgress('mono') def testColorProgress(self): - self._testCompactProgress('color', False) + self._testCompactProgress('color') - def _testCompactProgress(self, name, infra_staging): + def _testCompactProgress(self, name): with temp_base() as basedir: result = run_tests( basedir, @@ -671,14 +616,13 @@ class SystemTest(unittest.TestCase): '--progress=%s' % name, 'sweet/cherries', 'sweet/bananas', - infra_staging=infra_staging, + infra_staging=False, ) if name == 'color': - expected = ('\033[34m% 100\033[0m|' - '\033[32m+ 1\033[0m|' + expected = ('\033[32m+ 1\033[0m|' '\033[31m- 1\033[0m]: Done') else: - expected = '% 100|+ 1|- 1]: Done' + expected = '+ 1|- 1]: Done' self.assertIn(expected, result.stdout) self.assertIn('sweet/cherries', result.stdout) self.assertIn('sweet/bananas', result.stdout) @@ -697,7 +641,6 @@ class SystemTest(unittest.TestCase): 'sweet/blackberries', # FAIL 'sweet/raspberries', # should not run ) - self.assertIn('Running 4 base tests', result.stdout, result) self.assertIn('sweet/mangoes: pass', result.stdout, result) self.assertIn('sweet/strawberries: FAIL', result.stdout, result) self.assertIn('Too many failures, exiting...', result.stdout, result) diff --git a/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json b/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json index eb9f7bafdc..79f9856a47 100644 --- a/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json +++ b/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json @@ -15,5 +15,9 @@ "v8_enable_i18n_support": true, "v8_enable_verify_predictable": false, "v8_target_cpu": "x64", - "v8_use_snapshot": true + "v8_use_snapshot": true, + "v8_enable_embedded_builtins": false, + "v8_enable_verify_csa": false, + "v8_enable_lite_mode": false, + "v8_enable_pointer_compression": true } diff --git a/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json b/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json index eb9f7bafdc..e4946321c5 100644 --- a/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json +++ b/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json @@ -15,5 +15,9 @@ "v8_enable_i18n_support": true, "v8_enable_verify_predictable": false, "v8_target_cpu": "x64", - "v8_use_snapshot": true + "v8_use_snapshot": true, + "v8_enable_embedded_builtins": false, + "v8_enable_verify_csa": false, + "v8_enable_lite_mode": false, + "v8_enable_pointer_compression": false } diff --git a/deps/v8/tools/update-object-macros-undef.py b/deps/v8/tools/update-object-macros-undef.py new file mode 100755 index 0000000000..ecec6239ad --- /dev/null +++ b/deps/v8/tools/update-object-macros-undef.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# 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. +# vim:fenc=utf-8:shiftwidth=2:tabstop=2:softtabstop=2:extandtab + +""" +Generate object-macros-undef.h from object-macros.h. +""" + +import os.path +import re +import sys + +INPUT = 'src/objects/object-macros.h' +OUTPUT = 'src/objects/object-macros-undef.h' +HEADER = """// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Generate this file using the {} script. + +// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD + +""".format(os.path.basename(__file__)) + + +def main(): + if not os.path.isfile(INPUT): + sys.exit("Input file {} does not exist; run this script in a v8 checkout." + .format(INPUT)) + if not os.path.isfile(OUTPUT): + sys.exit("Output file {} does not exist; run this script in a v8 checkout." + .format(OUTPUT)) + regexp = re.compile('^#define (\w+)') + seen = set() + with open(INPUT, 'r') as infile, open(OUTPUT, 'w') as outfile: + outfile.write(HEADER) + for line in infile: + match = regexp.match(line) + if match and match.group(1) not in seen: + seen.add(match.group(1)) + outfile.write('#undef {}\n'.format(match.group(1))) + +if __name__ == "__main__": + main() diff --git a/deps/v8/tools/v8_presubmit.py b/deps/v8/tools/v8_presubmit.py index 22d6bf5389..5d775c8cb9 100755 --- a/deps/v8/tools/v8_presubmit.py +++ b/deps/v8/tools/v8_presubmit.py @@ -347,14 +347,15 @@ class CppLintProcessor(CacheableSourceFileProcessor): return None, arguments -class TorqueFormatProcessor(CacheableSourceFileProcessor): +class TorqueLintProcessor(CacheableSourceFileProcessor): """ Check .tq files to verify they follow the Torque style guide. """ def __init__(self, use_cache=True): - super(TorqueFormatProcessor, self).__init__( - use_cache=use_cache, cache_file_path='.torquelint-cache', file_type='Torque') + super(TorqueLintProcessor, self).__init__( + use_cache=use_cache, cache_file_path='.torquelint-cache', + file_type='Torque') def IsRelevant(self, name): return name.endswith('.tq') @@ -438,22 +439,15 @@ class SourceProcessor(SourceFileProcessor): IGNORE_COPYRIGHTS = ['box2d.js', 'cpplint.py', - 'check_injected_script_source.py', 'copy.js', 'corrections.js', 'crypto.js', 'daemon.py', - 'debugger-script.js', 'earley-boyer.js', 'fannkuch.js', 'fasta.js', - 'generate_protocol_externs.py', 'injected-script.cc', 'injected-script.h', - 'injected-script-source.js', - 'java-script-call-frame.cc', - 'java-script-call-frame.h', - 'jsmin.py', 'libraries.cc', 'libraries-empty.cc', 'lua_binarytrees.js', @@ -464,14 +458,11 @@ class SourceProcessor(SourceFileProcessor): 'raytrace.js', 'regexp-pcre.js', 'resources-123.js', - 'rjsmin.py', 'sqlite.js', 'sqlite-change-heap.js', 'sqlite-pointer-masking.js', 'sqlite-safe-heap.js', 'v8-debugger-script.h', - 'v8-function-call.cc', - 'v8-function-call.h', 'v8-inspector-impl.cc', 'v8-inspector-impl.h', 'v8-runtime-agent-impl.cc', @@ -521,7 +512,7 @@ class SourceProcessor(SourceFileProcessor): print "%s does not end with a single new line." % name result = False # Sanitize flags for fuzzer. - if "mjsunit" in name or "debugger" in name: + if ".js" in name and ("mjsunit" in name or "debugger" in name): match = FLAGS_LINE.search(contents) if match: print "%s Flags should use '-' (not '_')" % name @@ -551,7 +542,7 @@ class SourceProcessor(SourceFileProcessor): try: handle = open(file) contents = handle.read() - if not self.ProcessContents(file, contents): + if len(contents) > 0 and not self.ProcessContents(file, contents): success = False violations += 1 finally: @@ -673,8 +664,8 @@ def GetOptions(): result = optparse.OptionParser() result.add_option('--no-lint', help="Do not run cpplint", default=False, action="store_true") - result.add_option('--no-linter-cache', help="Do not cache linter results", default=False, - action="store_true") + result.add_option('--no-linter-cache', help="Do not cache linter results", + default=False, action="store_true") return result @@ -692,7 +683,8 @@ def Main(): success &= CppLintProcessor(use_cache=use_linter_cache).RunOnPath(workspace) print "Running Torque formatting check..." - success &= TorqueFormatProcessor(use_cache=use_linter_cache).RunOnPath(workspace) + success &= TorqueLintProcessor(use_cache=use_linter_cache).RunOnPath( + workspace) print "Running copyright header, trailing whitespaces and " \ "two empty lines between declarations check..." success &= SourceProcessor().RunOnPath(workspace) diff --git a/deps/v8/tools/v8heapconst.py b/deps/v8/tools/v8heapconst.py index f8c8061ff4..fc053b60f7 100644 --- a/deps/v8/tools/v8heapconst.py +++ b/deps/v8/tools/v8heapconst.py @@ -59,73 +59,79 @@ INSTANCE_TYPES = { 155: "ACCESSOR_PAIR_TYPE", 156: "ALIASED_ARGUMENTS_ENTRY_TYPE", 157: "ALLOCATION_MEMENTO_TYPE", - 158: "ASYNC_GENERATOR_REQUEST_TYPE", - 159: "DEBUG_INFO_TYPE", - 160: "FUNCTION_TEMPLATE_INFO_TYPE", - 161: "INTERCEPTOR_INFO_TYPE", - 162: "INTERPRETER_DATA_TYPE", - 163: "MODULE_INFO_ENTRY_TYPE", - 164: "MODULE_TYPE", - 165: "OBJECT_TEMPLATE_INFO_TYPE", - 166: "PROMISE_CAPABILITY_TYPE", - 167: "PROMISE_REACTION_TYPE", - 168: "PROTOTYPE_INFO_TYPE", - 169: "SCRIPT_TYPE", - 170: "STACK_FRAME_INFO_TYPE", - 171: "TUPLE2_TYPE", - 172: "TUPLE3_TYPE", - 173: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE", - 174: "WASM_DEBUG_INFO_TYPE", - 175: "WASM_EXPORTED_FUNCTION_DATA_TYPE", - 176: "CALLABLE_TASK_TYPE", - 177: "CALLBACK_TASK_TYPE", - 178: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE", - 179: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE", - 180: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE", - 181: "MICROTASK_QUEUE_TYPE", - 182: "ALLOCATION_SITE_TYPE", - 183: "FIXED_ARRAY_TYPE", - 184: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", - 185: "HASH_TABLE_TYPE", - 186: "ORDERED_HASH_MAP_TYPE", - 187: "ORDERED_HASH_SET_TYPE", - 188: "NAME_DICTIONARY_TYPE", - 189: "GLOBAL_DICTIONARY_TYPE", - 190: "NUMBER_DICTIONARY_TYPE", - 191: "SIMPLE_NUMBER_DICTIONARY_TYPE", - 192: "STRING_TABLE_TYPE", - 193: "EPHEMERON_HASH_TABLE_TYPE", - 194: "SCOPE_INFO_TYPE", - 195: "SCRIPT_CONTEXT_TABLE_TYPE", - 196: "AWAIT_CONTEXT_TYPE", - 197: "BLOCK_CONTEXT_TYPE", - 198: "CATCH_CONTEXT_TYPE", - 199: "DEBUG_EVALUATE_CONTEXT_TYPE", - 200: "EVAL_CONTEXT_TYPE", - 201: "FUNCTION_CONTEXT_TYPE", - 202: "MODULE_CONTEXT_TYPE", - 203: "NATIVE_CONTEXT_TYPE", - 204: "SCRIPT_CONTEXT_TYPE", - 205: "WITH_CONTEXT_TYPE", - 206: "WEAK_FIXED_ARRAY_TYPE", - 207: "DESCRIPTOR_ARRAY_TYPE", - 208: "TRANSITION_ARRAY_TYPE", - 209: "CALL_HANDLER_INFO_TYPE", - 210: "CELL_TYPE", - 211: "CODE_DATA_CONTAINER_TYPE", - 212: "FEEDBACK_CELL_TYPE", - 213: "FEEDBACK_VECTOR_TYPE", - 214: "LOAD_HANDLER_TYPE", - 215: "PRE_PARSED_SCOPE_DATA_TYPE", - 216: "PROPERTY_ARRAY_TYPE", - 217: "PROPERTY_CELL_TYPE", - 218: "SHARED_FUNCTION_INFO_TYPE", - 219: "SMALL_ORDERED_HASH_MAP_TYPE", - 220: "SMALL_ORDERED_HASH_SET_TYPE", - 221: "STORE_HANDLER_TYPE", - 222: "UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE", - 223: "UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE", - 224: "WEAK_ARRAY_LIST_TYPE", + 158: "ASM_WASM_DATA_TYPE", + 159: "ASYNC_GENERATOR_REQUEST_TYPE", + 160: "DEBUG_INFO_TYPE", + 161: "FUNCTION_TEMPLATE_INFO_TYPE", + 162: "FUNCTION_TEMPLATE_RARE_DATA_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: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE", + 176: "WASM_DEBUG_INFO_TYPE", + 177: "WASM_EXCEPTION_TAG_TYPE", + 178: "WASM_EXPORTED_FUNCTION_DATA_TYPE", + 179: "CALLABLE_TASK_TYPE", + 180: "CALLBACK_TASK_TYPE", + 181: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE", + 182: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE", + 183: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE", + 184: "WEAK_FACTORY_CLEANUP_JOB_TASK_TYPE", + 185: "ALLOCATION_SITE_TYPE", + 186: "EMBEDDER_DATA_ARRAY_TYPE", + 187: "FIXED_ARRAY_TYPE", + 188: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", + 189: "HASH_TABLE_TYPE", + 190: "ORDERED_HASH_MAP_TYPE", + 191: "ORDERED_HASH_SET_TYPE", + 192: "ORDERED_NAME_DICTIONARY_TYPE", + 193: "NAME_DICTIONARY_TYPE", + 194: "GLOBAL_DICTIONARY_TYPE", + 195: "NUMBER_DICTIONARY_TYPE", + 196: "SIMPLE_NUMBER_DICTIONARY_TYPE", + 197: "STRING_TABLE_TYPE", + 198: "EPHEMERON_HASH_TABLE_TYPE", + 199: "SCOPE_INFO_TYPE", + 200: "SCRIPT_CONTEXT_TABLE_TYPE", + 201: "AWAIT_CONTEXT_TYPE", + 202: "BLOCK_CONTEXT_TYPE", + 203: "CATCH_CONTEXT_TYPE", + 204: "DEBUG_EVALUATE_CONTEXT_TYPE", + 205: "EVAL_CONTEXT_TYPE", + 206: "FUNCTION_CONTEXT_TYPE", + 207: "MODULE_CONTEXT_TYPE", + 208: "NATIVE_CONTEXT_TYPE", + 209: "SCRIPT_CONTEXT_TYPE", + 210: "WITH_CONTEXT_TYPE", + 211: "WEAK_FIXED_ARRAY_TYPE", + 212: "TRANSITION_ARRAY_TYPE", + 213: "CALL_HANDLER_INFO_TYPE", + 214: "CELL_TYPE", + 215: "CODE_DATA_CONTAINER_TYPE", + 216: "DESCRIPTOR_ARRAY_TYPE", + 217: "FEEDBACK_CELL_TYPE", + 218: "FEEDBACK_VECTOR_TYPE", + 219: "LOAD_HANDLER_TYPE", + 220: "PREPARSE_DATA_TYPE", + 221: "PROPERTY_ARRAY_TYPE", + 222: "PROPERTY_CELL_TYPE", + 223: "SHARED_FUNCTION_INFO_TYPE", + 224: "SMALL_ORDERED_HASH_MAP_TYPE", + 225: "SMALL_ORDERED_HASH_SET_TYPE", + 226: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", + 227: "STORE_HANDLER_TYPE", + 228: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", + 229: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", + 230: "WEAK_ARRAY_LIST_TYPE", 1024: "JS_PROXY_TYPE", 1025: "JS_GLOBAL_OBJECT_TYPE", 1026: "JS_GLOBAL_PROXY_TYPE", @@ -139,246 +145,296 @@ INSTANCE_TYPES = { 1060: "JS_ARRAY_ITERATOR_TYPE", 1061: "JS_ARRAY_TYPE", 1062: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE", - 1063: "JS_ASYNC_GENERATOR_OBJECT_TYPE", - 1064: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", - 1065: "JS_DATE_TYPE", - 1066: "JS_ERROR_TYPE", - 1067: "JS_GENERATOR_OBJECT_TYPE", - 1068: "JS_MAP_TYPE", - 1069: "JS_MAP_KEY_ITERATOR_TYPE", - 1070: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", - 1071: "JS_MAP_VALUE_ITERATOR_TYPE", - 1072: "JS_MESSAGE_OBJECT_TYPE", - 1073: "JS_PROMISE_TYPE", - 1074: "JS_REGEXP_TYPE", - 1075: "JS_REGEXP_STRING_ITERATOR_TYPE", - 1076: "JS_SET_TYPE", - 1077: "JS_SET_KEY_VALUE_ITERATOR_TYPE", - 1078: "JS_SET_VALUE_ITERATOR_TYPE", - 1079: "JS_STRING_ITERATOR_TYPE", - 1080: "JS_WEAK_MAP_TYPE", - 1081: "JS_WEAK_SET_TYPE", - 1082: "JS_TYPED_ARRAY_TYPE", - 1083: "JS_DATA_VIEW_TYPE", - 1084: "JS_INTL_V8_BREAK_ITERATOR_TYPE", - 1085: "JS_INTL_COLLATOR_TYPE", - 1086: "JS_INTL_DATE_TIME_FORMAT_TYPE", - 1087: "JS_INTL_LIST_FORMAT_TYPE", - 1088: "JS_INTL_LOCALE_TYPE", - 1089: "JS_INTL_NUMBER_FORMAT_TYPE", - 1090: "JS_INTL_PLURAL_RULES_TYPE", - 1091: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE", - 1092: "JS_INTL_SEGMENTER_TYPE", - 1093: "WASM_EXCEPTION_TYPE", - 1094: "WASM_GLOBAL_TYPE", - 1095: "WASM_INSTANCE_TYPE", - 1096: "WASM_MEMORY_TYPE", - 1097: "WASM_MODULE_TYPE", - 1098: "WASM_TABLE_TYPE", - 1099: "JS_BOUND_FUNCTION_TYPE", - 1100: "JS_FUNCTION_TYPE", + 1063: "JS_ASYNC_FUNCTION_OBJECT_TYPE", + 1064: "JS_ASYNC_GENERATOR_OBJECT_TYPE", + 1065: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", + 1066: "JS_DATE_TYPE", + 1067: "JS_ERROR_TYPE", + 1068: "JS_GENERATOR_OBJECT_TYPE", + 1069: "JS_MAP_TYPE", + 1070: "JS_MAP_KEY_ITERATOR_TYPE", + 1071: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", + 1072: "JS_MAP_VALUE_ITERATOR_TYPE", + 1073: "JS_MESSAGE_OBJECT_TYPE", + 1074: "JS_PROMISE_TYPE", + 1075: "JS_REGEXP_TYPE", + 1076: "JS_REGEXP_STRING_ITERATOR_TYPE", + 1077: "JS_SET_TYPE", + 1078: "JS_SET_KEY_VALUE_ITERATOR_TYPE", + 1079: "JS_SET_VALUE_ITERATOR_TYPE", + 1080: "JS_STRING_ITERATOR_TYPE", + 1081: "JS_WEAK_CELL_TYPE", + 1082: "JS_WEAK_REF_TYPE", + 1083: "JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE", + 1084: "JS_WEAK_FACTORY_TYPE", + 1085: "JS_WEAK_MAP_TYPE", + 1086: "JS_WEAK_SET_TYPE", + 1087: "JS_TYPED_ARRAY_TYPE", + 1088: "JS_DATA_VIEW_TYPE", + 1089: "JS_INTL_V8_BREAK_ITERATOR_TYPE", + 1090: "JS_INTL_COLLATOR_TYPE", + 1091: "JS_INTL_DATE_TIME_FORMAT_TYPE", + 1092: "JS_INTL_LIST_FORMAT_TYPE", + 1093: "JS_INTL_LOCALE_TYPE", + 1094: "JS_INTL_NUMBER_FORMAT_TYPE", + 1095: "JS_INTL_PLURAL_RULES_TYPE", + 1096: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE", + 1097: "JS_INTL_SEGMENT_ITERATOR_TYPE", + 1098: "JS_INTL_SEGMENTER_TYPE", + 1099: "WASM_EXCEPTION_TYPE", + 1100: "WASM_GLOBAL_TYPE", + 1101: "WASM_INSTANCE_TYPE", + 1102: "WASM_MEMORY_TYPE", + 1103: "WASM_MODULE_TYPE", + 1104: "WASM_TABLE_TYPE", + 1105: "JS_BOUND_FUNCTION_TYPE", + 1106: "JS_FUNCTION_TYPE", } # List of known V8 maps. KNOWN_MAPS = { - ("RO_SPACE", 0x02201): (138, "FreeSpaceMap"), - ("RO_SPACE", 0x02251): (132, "MetaMap"), - ("RO_SPACE", 0x022d1): (131, "NullMap"), - ("RO_SPACE", 0x02341): (207, "DescriptorArrayMap"), - ("RO_SPACE", 0x023a1): (206, "WeakFixedArrayMap"), - ("RO_SPACE", 0x023f1): (152, "OnePointerFillerMap"), - ("RO_SPACE", 0x02441): (152, "TwoPointerFillerMap"), - ("RO_SPACE", 0x024c1): (131, "UninitializedMap"), - ("RO_SPACE", 0x02531): (8, "OneByteInternalizedStringMap"), - ("RO_SPACE", 0x025d1): (131, "UndefinedMap"), - ("RO_SPACE", 0x02631): (129, "HeapNumberMap"), - ("RO_SPACE", 0x026b1): (131, "TheHoleMap"), - ("RO_SPACE", 0x02759): (131, "BooleanMap"), - ("RO_SPACE", 0x02831): (136, "ByteArrayMap"), - ("RO_SPACE", 0x02881): (183, "FixedArrayMap"), - ("RO_SPACE", 0x028d1): (183, "FixedCOWArrayMap"), - ("RO_SPACE", 0x02921): (185, "HashTableMap"), - ("RO_SPACE", 0x02971): (128, "SymbolMap"), - ("RO_SPACE", 0x029c1): (72, "OneByteStringMap"), - ("RO_SPACE", 0x02a11): (194, "ScopeInfoMap"), - ("RO_SPACE", 0x02a61): (218, "SharedFunctionInfoMap"), - ("RO_SPACE", 0x02ab1): (133, "CodeMap"), - ("RO_SPACE", 0x02b01): (201, "FunctionContextMap"), - ("RO_SPACE", 0x02b51): (210, "CellMap"), - ("RO_SPACE", 0x02ba1): (217, "GlobalPropertyCellMap"), - ("RO_SPACE", 0x02bf1): (135, "ForeignMap"), - ("RO_SPACE", 0x02c41): (208, "TransitionArrayMap"), - ("RO_SPACE", 0x02c91): (213, "FeedbackVectorMap"), - ("RO_SPACE", 0x02d31): (131, "ArgumentsMarkerMap"), - ("RO_SPACE", 0x02dd1): (131, "ExceptionMap"), - ("RO_SPACE", 0x02e71): (131, "TerminationExceptionMap"), - ("RO_SPACE", 0x02f19): (131, "OptimizedOutMap"), - ("RO_SPACE", 0x02fb9): (131, "StaleRegisterMap"), - ("RO_SPACE", 0x03029): (203, "NativeContextMap"), - ("RO_SPACE", 0x03079): (202, "ModuleContextMap"), - ("RO_SPACE", 0x030c9): (200, "EvalContextMap"), - ("RO_SPACE", 0x03119): (204, "ScriptContextMap"), - ("RO_SPACE", 0x03169): (196, "AwaitContextMap"), - ("RO_SPACE", 0x031b9): (197, "BlockContextMap"), - ("RO_SPACE", 0x03209): (198, "CatchContextMap"), - ("RO_SPACE", 0x03259): (205, "WithContextMap"), - ("RO_SPACE", 0x032a9): (199, "DebugEvaluateContextMap"), - ("RO_SPACE", 0x032f9): (195, "ScriptContextTableMap"), - ("RO_SPACE", 0x03349): (151, "FeedbackMetadataArrayMap"), - ("RO_SPACE", 0x03399): (183, "ArrayListMap"), - ("RO_SPACE", 0x033e9): (130, "BigIntMap"), - ("RO_SPACE", 0x03439): (184, "ObjectBoilerplateDescriptionMap"), - ("RO_SPACE", 0x03489): (137, "BytecodeArrayMap"), - ("RO_SPACE", 0x034d9): (211, "CodeDataContainerMap"), - ("RO_SPACE", 0x03529): (150, "FixedDoubleArrayMap"), - ("RO_SPACE", 0x03579): (189, "GlobalDictionaryMap"), - ("RO_SPACE", 0x035c9): (212, "ManyClosuresCellMap"), - ("RO_SPACE", 0x03619): (183, "ModuleInfoMap"), - ("RO_SPACE", 0x03669): (134, "MutableHeapNumberMap"), - ("RO_SPACE", 0x036b9): (188, "NameDictionaryMap"), - ("RO_SPACE", 0x03709): (212, "NoClosuresCellMap"), - ("RO_SPACE", 0x03759): (190, "NumberDictionaryMap"), - ("RO_SPACE", 0x037a9): (212, "OneClosureCellMap"), - ("RO_SPACE", 0x037f9): (186, "OrderedHashMapMap"), - ("RO_SPACE", 0x03849): (187, "OrderedHashSetMap"), - ("RO_SPACE", 0x03899): (215, "PreParsedScopeDataMap"), - ("RO_SPACE", 0x038e9): (216, "PropertyArrayMap"), - ("RO_SPACE", 0x03939): (209, "SideEffectCallHandlerInfoMap"), - ("RO_SPACE", 0x03989): (209, "SideEffectFreeCallHandlerInfoMap"), - ("RO_SPACE", 0x039d9): (209, "NextCallSideEffectFreeCallHandlerInfoMap"), - ("RO_SPACE", 0x03a29): (191, "SimpleNumberDictionaryMap"), - ("RO_SPACE", 0x03a79): (183, "SloppyArgumentsElementsMap"), - ("RO_SPACE", 0x03ac9): (219, "SmallOrderedHashMapMap"), - ("RO_SPACE", 0x03b19): (220, "SmallOrderedHashSetMap"), - ("RO_SPACE", 0x03b69): (192, "StringTableMap"), - ("RO_SPACE", 0x03bb9): (222, "UncompiledDataWithoutPreParsedScopeMap"), - ("RO_SPACE", 0x03c09): (223, "UncompiledDataWithPreParsedScopeMap"), - ("RO_SPACE", 0x03c59): (224, "WeakArrayListMap"), - ("RO_SPACE", 0x03ca9): (193, "EphemeronHashTableMap"), - ("RO_SPACE", 0x03cf9): (106, "NativeSourceStringMap"), - ("RO_SPACE", 0x03d49): (64, "StringMap"), - ("RO_SPACE", 0x03d99): (73, "ConsOneByteStringMap"), - ("RO_SPACE", 0x03de9): (65, "ConsStringMap"), - ("RO_SPACE", 0x03e39): (77, "ThinOneByteStringMap"), - ("RO_SPACE", 0x03e89): (69, "ThinStringMap"), - ("RO_SPACE", 0x03ed9): (67, "SlicedStringMap"), - ("RO_SPACE", 0x03f29): (75, "SlicedOneByteStringMap"), - ("RO_SPACE", 0x03f79): (66, "ExternalStringMap"), - ("RO_SPACE", 0x03fc9): (82, "ExternalStringWithOneByteDataMap"), - ("RO_SPACE", 0x04019): (74, "ExternalOneByteStringMap"), - ("RO_SPACE", 0x04069): (98, "UncachedExternalStringMap"), - ("RO_SPACE", 0x040b9): (114, "UncachedExternalStringWithOneByteDataMap"), - ("RO_SPACE", 0x04109): (0, "InternalizedStringMap"), - ("RO_SPACE", 0x04159): (2, "ExternalInternalizedStringMap"), - ("RO_SPACE", 0x041a9): (18, "ExternalInternalizedStringWithOneByteDataMap"), - ("RO_SPACE", 0x041f9): (10, "ExternalOneByteInternalizedStringMap"), - ("RO_SPACE", 0x04249): (34, "UncachedExternalInternalizedStringMap"), - ("RO_SPACE", 0x04299): (50, "UncachedExternalInternalizedStringWithOneByteDataMap"), - ("RO_SPACE", 0x042e9): (42, "UncachedExternalOneByteInternalizedStringMap"), - ("RO_SPACE", 0x04339): (106, "UncachedExternalOneByteStringMap"), - ("RO_SPACE", 0x04389): (140, "FixedUint8ArrayMap"), - ("RO_SPACE", 0x043d9): (139, "FixedInt8ArrayMap"), - ("RO_SPACE", 0x04429): (142, "FixedUint16ArrayMap"), - ("RO_SPACE", 0x04479): (141, "FixedInt16ArrayMap"), - ("RO_SPACE", 0x044c9): (144, "FixedUint32ArrayMap"), - ("RO_SPACE", 0x04519): (143, "FixedInt32ArrayMap"), - ("RO_SPACE", 0x04569): (145, "FixedFloat32ArrayMap"), - ("RO_SPACE", 0x045b9): (146, "FixedFloat64ArrayMap"), - ("RO_SPACE", 0x04609): (147, "FixedUint8ClampedArrayMap"), - ("RO_SPACE", 0x04659): (149, "FixedBigUint64ArrayMap"), - ("RO_SPACE", 0x046a9): (148, "FixedBigInt64ArrayMap"), - ("RO_SPACE", 0x046f9): (131, "SelfReferenceMarkerMap"), - ("RO_SPACE", 0x04761): (171, "Tuple2Map"), - ("RO_SPACE", 0x04801): (173, "ArrayBoilerplateDescriptionMap"), - ("RO_SPACE", 0x04af1): (161, "InterceptorInfoMap"), - ("RO_SPACE", 0x06ea9): (153, "AccessCheckInfoMap"), - ("RO_SPACE", 0x06ef9): (154, "AccessorInfoMap"), - ("RO_SPACE", 0x06f49): (155, "AccessorPairMap"), - ("RO_SPACE", 0x06f99): (156, "AliasedArgumentsEntryMap"), - ("RO_SPACE", 0x06fe9): (157, "AllocationMementoMap"), - ("RO_SPACE", 0x07039): (158, "AsyncGeneratorRequestMap"), - ("RO_SPACE", 0x07089): (159, "DebugInfoMap"), - ("RO_SPACE", 0x070d9): (160, "FunctionTemplateInfoMap"), - ("RO_SPACE", 0x07129): (162, "InterpreterDataMap"), - ("RO_SPACE", 0x07179): (163, "ModuleInfoEntryMap"), - ("RO_SPACE", 0x071c9): (164, "ModuleMap"), - ("RO_SPACE", 0x07219): (165, "ObjectTemplateInfoMap"), - ("RO_SPACE", 0x07269): (166, "PromiseCapabilityMap"), - ("RO_SPACE", 0x072b9): (167, "PromiseReactionMap"), - ("RO_SPACE", 0x07309): (168, "PrototypeInfoMap"), - ("RO_SPACE", 0x07359): (169, "ScriptMap"), - ("RO_SPACE", 0x073a9): (170, "StackFrameInfoMap"), - ("RO_SPACE", 0x073f9): (172, "Tuple3Map"), - ("RO_SPACE", 0x07449): (174, "WasmDebugInfoMap"), - ("RO_SPACE", 0x07499): (175, "WasmExportedFunctionDataMap"), - ("RO_SPACE", 0x074e9): (176, "CallableTaskMap"), - ("RO_SPACE", 0x07539): (177, "CallbackTaskMap"), - ("RO_SPACE", 0x07589): (178, "PromiseFulfillReactionJobTaskMap"), - ("RO_SPACE", 0x075d9): (179, "PromiseRejectReactionJobTaskMap"), - ("RO_SPACE", 0x07629): (180, "PromiseResolveThenableJobTaskMap"), - ("RO_SPACE", 0x07679): (181, "MicrotaskQueueMap"), - ("RO_SPACE", 0x076c9): (182, "AllocationSiteWithWeakNextMap"), - ("RO_SPACE", 0x07719): (182, "AllocationSiteWithoutWeakNextMap"), - ("RO_SPACE", 0x07769): (214, "LoadHandler1Map"), - ("RO_SPACE", 0x077b9): (214, "LoadHandler2Map"), - ("RO_SPACE", 0x07809): (214, "LoadHandler3Map"), - ("RO_SPACE", 0x07859): (221, "StoreHandler0Map"), - ("RO_SPACE", 0x078a9): (221, "StoreHandler1Map"), - ("RO_SPACE", 0x078f9): (221, "StoreHandler2Map"), - ("RO_SPACE", 0x07949): (221, "StoreHandler3Map"), - ("MAP_SPACE", 0x02201): (1057, "ExternalMap"), - ("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"), + ("RO_SPACE", 0x00139): (138, "FreeSpaceMap"), + ("RO_SPACE", 0x00189): (132, "MetaMap"), + ("RO_SPACE", 0x00209): (131, "NullMap"), + ("RO_SPACE", 0x00271): (216, "DescriptorArrayMap"), + ("RO_SPACE", 0x002d1): (211, "WeakFixedArrayMap"), + ("RO_SPACE", 0x00321): (152, "OnePointerFillerMap"), + ("RO_SPACE", 0x00371): (152, "TwoPointerFillerMap"), + ("RO_SPACE", 0x003f1): (131, "UninitializedMap"), + ("RO_SPACE", 0x00461): (8, "OneByteInternalizedStringMap"), + ("RO_SPACE", 0x00501): (131, "UndefinedMap"), + ("RO_SPACE", 0x00561): (129, "HeapNumberMap"), + ("RO_SPACE", 0x005e1): (131, "TheHoleMap"), + ("RO_SPACE", 0x00689): (131, "BooleanMap"), + ("RO_SPACE", 0x00761): (136, "ByteArrayMap"), + ("RO_SPACE", 0x007b1): (187, "FixedArrayMap"), + ("RO_SPACE", 0x00801): (187, "FixedCOWArrayMap"), + ("RO_SPACE", 0x00851): (189, "HashTableMap"), + ("RO_SPACE", 0x008a1): (128, "SymbolMap"), + ("RO_SPACE", 0x008f1): (72, "OneByteStringMap"), + ("RO_SPACE", 0x00941): (199, "ScopeInfoMap"), + ("RO_SPACE", 0x00991): (223, "SharedFunctionInfoMap"), + ("RO_SPACE", 0x009e1): (133, "CodeMap"), + ("RO_SPACE", 0x00a31): (206, "FunctionContextMap"), + ("RO_SPACE", 0x00a81): (214, "CellMap"), + ("RO_SPACE", 0x00ad1): (222, "GlobalPropertyCellMap"), + ("RO_SPACE", 0x00b21): (135, "ForeignMap"), + ("RO_SPACE", 0x00b71): (212, "TransitionArrayMap"), + ("RO_SPACE", 0x00bc1): (218, "FeedbackVectorMap"), + ("RO_SPACE", 0x00c61): (131, "ArgumentsMarkerMap"), + ("RO_SPACE", 0x00d01): (131, "ExceptionMap"), + ("RO_SPACE", 0x00da1): (131, "TerminationExceptionMap"), + ("RO_SPACE", 0x00e49): (131, "OptimizedOutMap"), + ("RO_SPACE", 0x00ee9): (131, "StaleRegisterMap"), + ("RO_SPACE", 0x00f59): (208, "NativeContextMap"), + ("RO_SPACE", 0x00fa9): (207, "ModuleContextMap"), + ("RO_SPACE", 0x00ff9): (205, "EvalContextMap"), + ("RO_SPACE", 0x01049): (209, "ScriptContextMap"), + ("RO_SPACE", 0x01099): (201, "AwaitContextMap"), + ("RO_SPACE", 0x010e9): (202, "BlockContextMap"), + ("RO_SPACE", 0x01139): (203, "CatchContextMap"), + ("RO_SPACE", 0x01189): (210, "WithContextMap"), + ("RO_SPACE", 0x011d9): (204, "DebugEvaluateContextMap"), + ("RO_SPACE", 0x01229): (200, "ScriptContextTableMap"), + ("RO_SPACE", 0x01279): (151, "FeedbackMetadataArrayMap"), + ("RO_SPACE", 0x012c9): (187, "ArrayListMap"), + ("RO_SPACE", 0x01319): (130, "BigIntMap"), + ("RO_SPACE", 0x01369): (188, "ObjectBoilerplateDescriptionMap"), + ("RO_SPACE", 0x013b9): (137, "BytecodeArrayMap"), + ("RO_SPACE", 0x01409): (215, "CodeDataContainerMap"), + ("RO_SPACE", 0x01459): (150, "FixedDoubleArrayMap"), + ("RO_SPACE", 0x014a9): (194, "GlobalDictionaryMap"), + ("RO_SPACE", 0x014f9): (217, "ManyClosuresCellMap"), + ("RO_SPACE", 0x01549): (187, "ModuleInfoMap"), + ("RO_SPACE", 0x01599): (134, "MutableHeapNumberMap"), + ("RO_SPACE", 0x015e9): (193, "NameDictionaryMap"), + ("RO_SPACE", 0x01639): (217, "NoClosuresCellMap"), + ("RO_SPACE", 0x01689): (217, "NoFeedbackCellMap"), + ("RO_SPACE", 0x016d9): (195, "NumberDictionaryMap"), + ("RO_SPACE", 0x01729): (217, "OneClosureCellMap"), + ("RO_SPACE", 0x01779): (190, "OrderedHashMapMap"), + ("RO_SPACE", 0x017c9): (191, "OrderedHashSetMap"), + ("RO_SPACE", 0x01819): (192, "OrderedNameDictionaryMap"), + ("RO_SPACE", 0x01869): (220, "PreparseDataMap"), + ("RO_SPACE", 0x018b9): (221, "PropertyArrayMap"), + ("RO_SPACE", 0x01909): (213, "SideEffectCallHandlerInfoMap"), + ("RO_SPACE", 0x01959): (213, "SideEffectFreeCallHandlerInfoMap"), + ("RO_SPACE", 0x019a9): (213, "NextCallSideEffectFreeCallHandlerInfoMap"), + ("RO_SPACE", 0x019f9): (196, "SimpleNumberDictionaryMap"), + ("RO_SPACE", 0x01a49): (187, "SloppyArgumentsElementsMap"), + ("RO_SPACE", 0x01a99): (224, "SmallOrderedHashMapMap"), + ("RO_SPACE", 0x01ae9): (225, "SmallOrderedHashSetMap"), + ("RO_SPACE", 0x01b39): (226, "SmallOrderedNameDictionaryMap"), + ("RO_SPACE", 0x01b89): (197, "StringTableMap"), + ("RO_SPACE", 0x01bd9): (228, "UncompiledDataWithoutPreparseDataMap"), + ("RO_SPACE", 0x01c29): (229, "UncompiledDataWithPreparseDataMap"), + ("RO_SPACE", 0x01c79): (230, "WeakArrayListMap"), + ("RO_SPACE", 0x01cc9): (198, "EphemeronHashTableMap"), + ("RO_SPACE", 0x01d19): (186, "EmbedderDataArrayMap"), + ("RO_SPACE", 0x01d69): (106, "NativeSourceStringMap"), + ("RO_SPACE", 0x01db9): (64, "StringMap"), + ("RO_SPACE", 0x01e09): (73, "ConsOneByteStringMap"), + ("RO_SPACE", 0x01e59): (65, "ConsStringMap"), + ("RO_SPACE", 0x01ea9): (77, "ThinOneByteStringMap"), + ("RO_SPACE", 0x01ef9): (69, "ThinStringMap"), + ("RO_SPACE", 0x01f49): (67, "SlicedStringMap"), + ("RO_SPACE", 0x01f99): (75, "SlicedOneByteStringMap"), + ("RO_SPACE", 0x01fe9): (66, "ExternalStringMap"), + ("RO_SPACE", 0x02039): (82, "ExternalStringWithOneByteDataMap"), + ("RO_SPACE", 0x02089): (74, "ExternalOneByteStringMap"), + ("RO_SPACE", 0x020d9): (98, "UncachedExternalStringMap"), + ("RO_SPACE", 0x02129): (114, "UncachedExternalStringWithOneByteDataMap"), + ("RO_SPACE", 0x02179): (0, "InternalizedStringMap"), + ("RO_SPACE", 0x021c9): (2, "ExternalInternalizedStringMap"), + ("RO_SPACE", 0x02219): (18, "ExternalInternalizedStringWithOneByteDataMap"), + ("RO_SPACE", 0x02269): (10, "ExternalOneByteInternalizedStringMap"), + ("RO_SPACE", 0x022b9): (34, "UncachedExternalInternalizedStringMap"), + ("RO_SPACE", 0x02309): (50, "UncachedExternalInternalizedStringWithOneByteDataMap"), + ("RO_SPACE", 0x02359): (42, "UncachedExternalOneByteInternalizedStringMap"), + ("RO_SPACE", 0x023a9): (106, "UncachedExternalOneByteStringMap"), + ("RO_SPACE", 0x023f9): (140, "FixedUint8ArrayMap"), + ("RO_SPACE", 0x02449): (139, "FixedInt8ArrayMap"), + ("RO_SPACE", 0x02499): (142, "FixedUint16ArrayMap"), + ("RO_SPACE", 0x024e9): (141, "FixedInt16ArrayMap"), + ("RO_SPACE", 0x02539): (144, "FixedUint32ArrayMap"), + ("RO_SPACE", 0x02589): (143, "FixedInt32ArrayMap"), + ("RO_SPACE", 0x025d9): (145, "FixedFloat32ArrayMap"), + ("RO_SPACE", 0x02629): (146, "FixedFloat64ArrayMap"), + ("RO_SPACE", 0x02679): (147, "FixedUint8ClampedArrayMap"), + ("RO_SPACE", 0x026c9): (149, "FixedBigUint64ArrayMap"), + ("RO_SPACE", 0x02719): (148, "FixedBigInt64ArrayMap"), + ("RO_SPACE", 0x02769): (131, "SelfReferenceMarkerMap"), + ("RO_SPACE", 0x027d1): (173, "Tuple2Map"), + ("RO_SPACE", 0x02871): (175, "ArrayBoilerplateDescriptionMap"), + ("RO_SPACE", 0x02bb1): (163, "InterceptorInfoMap"), + ("RO_SPACE", 0x05081): (153, "AccessCheckInfoMap"), + ("RO_SPACE", 0x050d1): (154, "AccessorInfoMap"), + ("RO_SPACE", 0x05121): (155, "AccessorPairMap"), + ("RO_SPACE", 0x05171): (156, "AliasedArgumentsEntryMap"), + ("RO_SPACE", 0x051c1): (157, "AllocationMementoMap"), + ("RO_SPACE", 0x05211): (158, "AsmWasmDataMap"), + ("RO_SPACE", 0x05261): (159, "AsyncGeneratorRequestMap"), + ("RO_SPACE", 0x052b1): (160, "DebugInfoMap"), + ("RO_SPACE", 0x05301): (161, "FunctionTemplateInfoMap"), + ("RO_SPACE", 0x05351): (162, "FunctionTemplateRareDataMap"), + ("RO_SPACE", 0x053a1): (164, "InterpreterDataMap"), + ("RO_SPACE", 0x053f1): (165, "ModuleInfoEntryMap"), + ("RO_SPACE", 0x05441): (166, "ModuleMap"), + ("RO_SPACE", 0x05491): (167, "ObjectTemplateInfoMap"), + ("RO_SPACE", 0x054e1): (168, "PromiseCapabilityMap"), + ("RO_SPACE", 0x05531): (169, "PromiseReactionMap"), + ("RO_SPACE", 0x05581): (170, "PrototypeInfoMap"), + ("RO_SPACE", 0x055d1): (171, "ScriptMap"), + ("RO_SPACE", 0x05621): (172, "StackFrameInfoMap"), + ("RO_SPACE", 0x05671): (174, "Tuple3Map"), + ("RO_SPACE", 0x056c1): (176, "WasmDebugInfoMap"), + ("RO_SPACE", 0x05711): (177, "WasmExceptionTagMap"), + ("RO_SPACE", 0x05761): (178, "WasmExportedFunctionDataMap"), + ("RO_SPACE", 0x057b1): (179, "CallableTaskMap"), + ("RO_SPACE", 0x05801): (180, "CallbackTaskMap"), + ("RO_SPACE", 0x05851): (181, "PromiseFulfillReactionJobTaskMap"), + ("RO_SPACE", 0x058a1): (182, "PromiseRejectReactionJobTaskMap"), + ("RO_SPACE", 0x058f1): (183, "PromiseResolveThenableJobTaskMap"), + ("RO_SPACE", 0x05941): (184, "WeakFactoryCleanupJobTaskMap"), + ("RO_SPACE", 0x05991): (185, "AllocationSiteWithWeakNextMap"), + ("RO_SPACE", 0x059e1): (185, "AllocationSiteWithoutWeakNextMap"), + ("RO_SPACE", 0x05a31): (219, "LoadHandler1Map"), + ("RO_SPACE", 0x05a81): (219, "LoadHandler2Map"), + ("RO_SPACE", 0x05ad1): (219, "LoadHandler3Map"), + ("RO_SPACE", 0x05b21): (227, "StoreHandler0Map"), + ("RO_SPACE", 0x05b71): (227, "StoreHandler1Map"), + ("RO_SPACE", 0x05bc1): (227, "StoreHandler2Map"), + ("RO_SPACE", 0x05c11): (227, "StoreHandler3Map"), + ("MAP_SPACE", 0x00139): (1057, "ExternalMap"), + ("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"), } # List of known V8 objects. KNOWN_OBJECTS = { - ("RO_SPACE", 0x022a1): "NullValue", - ("RO_SPACE", 0x02321): "EmptyDescriptorArray", - ("RO_SPACE", 0x02491): "UninitializedValue", - ("RO_SPACE", 0x025a1): "UndefinedValue", - ("RO_SPACE", 0x02621): "NanValue", - ("RO_SPACE", 0x02681): "TheHoleValue", - ("RO_SPACE", 0x02719): "HoleNanValue", - ("RO_SPACE", 0x02729): "TrueValue", - ("RO_SPACE", 0x027d9): "FalseValue", - ("RO_SPACE", 0x02821): "empty_string", - ("RO_SPACE", 0x02ce1): "EmptyScopeInfo", - ("RO_SPACE", 0x02cf1): "EmptyFixedArray", - ("RO_SPACE", 0x02d01): "ArgumentsMarker", - ("RO_SPACE", 0x02da1): "Exception", - ("RO_SPACE", 0x02e41): "TerminationException", - ("RO_SPACE", 0x02ee9): "OptimizedOut", - ("RO_SPACE", 0x02f89): "StaleRegister", - ("RO_SPACE", 0x047c1): "EmptyByteArray", - ("RO_SPACE", 0x04851): "EmptyFixedUint8Array", - ("RO_SPACE", 0x04871): "EmptyFixedInt8Array", - ("RO_SPACE", 0x04891): "EmptyFixedUint16Array", - ("RO_SPACE", 0x048b1): "EmptyFixedInt16Array", - ("RO_SPACE", 0x048d1): "EmptyFixedUint32Array", - ("RO_SPACE", 0x048f1): "EmptyFixedInt32Array", - ("RO_SPACE", 0x04911): "EmptyFixedFloat32Array", - ("RO_SPACE", 0x04931): "EmptyFixedFloat64Array", - ("RO_SPACE", 0x04951): "EmptyFixedUint8ClampedArray", - ("RO_SPACE", 0x049b1): "EmptySloppyArgumentsElements", - ("RO_SPACE", 0x049d1): "EmptySlowElementDictionary", - ("RO_SPACE", 0x04a19): "EmptyOrderedHashMap", - ("RO_SPACE", 0x04a41): "EmptyOrderedHashSet", - ("RO_SPACE", 0x04a79): "EmptyPropertyCell", - ("RO_SPACE", 0x04b59): "InfinityValue", - ("RO_SPACE", 0x04b69): "MinusZeroValue", - ("RO_SPACE", 0x04b79): "MinusInfinityValue", - ("RO_SPACE", 0x04b89): "SelfReferenceMarker", - ("OLD_SPACE", 0x02211): "EmptyScript", - ("OLD_SPACE", 0x02291): "ManyClosuresCell", - ("OLD_SPACE", 0x022b1): "NoElementsProtector", - ("OLD_SPACE", 0x022d9): "IsConcatSpreadableProtector", - ("OLD_SPACE", 0x022e9): "ArraySpeciesProtector", - ("OLD_SPACE", 0x02311): "TypedArraySpeciesProtector", - ("OLD_SPACE", 0x02339): "PromiseSpeciesProtector", - ("OLD_SPACE", 0x02361): "StringLengthProtector", - ("OLD_SPACE", 0x02371): "ArrayIteratorProtector", - ("OLD_SPACE", 0x02399): "ArrayBufferNeuteringProtector", - ("OLD_SPACE", 0x02421): "StringIteratorProtector", + ("RO_SPACE", 0x001d9): "NullValue", + ("RO_SPACE", 0x00259): "EmptyDescriptorArray", + ("RO_SPACE", 0x002c1): "EmptyWeakFixedArray", + ("RO_SPACE", 0x003c1): "UninitializedValue", + ("RO_SPACE", 0x004d1): "UndefinedValue", + ("RO_SPACE", 0x00551): "NanValue", + ("RO_SPACE", 0x005b1): "TheHoleValue", + ("RO_SPACE", 0x00649): "HoleNanValue", + ("RO_SPACE", 0x00659): "TrueValue", + ("RO_SPACE", 0x00709): "FalseValue", + ("RO_SPACE", 0x00751): "empty_string", + ("RO_SPACE", 0x00c11): "EmptyScopeInfo", + ("RO_SPACE", 0x00c21): "EmptyFixedArray", + ("RO_SPACE", 0x00c31): "ArgumentsMarker", + ("RO_SPACE", 0x00cd1): "Exception", + ("RO_SPACE", 0x00d71): "TerminationException", + ("RO_SPACE", 0x00e19): "OptimizedOut", + ("RO_SPACE", 0x00eb9): "StaleRegister", + ("RO_SPACE", 0x027b9): "EmptyEnumCache", + ("RO_SPACE", 0x02821): "EmptyPropertyArray", + ("RO_SPACE", 0x02831): "EmptyByteArray", + ("RO_SPACE", 0x02841): "EmptyObjectBoilerplateDescription", + ("RO_SPACE", 0x02859): "EmptyArrayBoilerplateDescription", + ("RO_SPACE", 0x028c1): "EmptyFixedUint8Array", + ("RO_SPACE", 0x028e1): "EmptyFixedInt8Array", + ("RO_SPACE", 0x02901): "EmptyFixedUint16Array", + ("RO_SPACE", 0x02921): "EmptyFixedInt16Array", + ("RO_SPACE", 0x02941): "EmptyFixedUint32Array", + ("RO_SPACE", 0x02961): "EmptyFixedInt32Array", + ("RO_SPACE", 0x02981): "EmptyFixedFloat32Array", + ("RO_SPACE", 0x029a1): "EmptyFixedFloat64Array", + ("RO_SPACE", 0x029c1): "EmptyFixedUint8ClampedArray", + ("RO_SPACE", 0x029e1): "EmptyFixedBigUint64Array", + ("RO_SPACE", 0x02a01): "EmptyFixedBigInt64Array", + ("RO_SPACE", 0x02a21): "EmptySloppyArgumentsElements", + ("RO_SPACE", 0x02a41): "EmptySlowElementDictionary", + ("RO_SPACE", 0x02a89): "EmptyOrderedHashMap", + ("RO_SPACE", 0x02ab1): "EmptyOrderedHashSet", + ("RO_SPACE", 0x02ad9): "EmptyFeedbackMetadata", + ("RO_SPACE", 0x02ae9): "EmptyPropertyCell", + ("RO_SPACE", 0x02b11): "EmptyPropertyDictionary", + ("RO_SPACE", 0x02b61): "NoOpInterceptorInfo", + ("RO_SPACE", 0x02c01): "EmptyWeakArrayList", + ("RO_SPACE", 0x02c19): "InfinityValue", + ("RO_SPACE", 0x02c29): "MinusZeroValue", + ("RO_SPACE", 0x02c39): "MinusInfinityValue", + ("RO_SPACE", 0x02c49): "SelfReferenceMarker", + ("RO_SPACE", 0x02ca1): "OffHeapTrampolineRelocationInfo", + ("RO_SPACE", 0x02cb9): "HashSeed", + ("OLD_SPACE", 0x00139): "ArgumentsIteratorAccessor", + ("OLD_SPACE", 0x001a9): "ArrayLengthAccessor", + ("OLD_SPACE", 0x00219): "BoundFunctionLengthAccessor", + ("OLD_SPACE", 0x00289): "BoundFunctionNameAccessor", + ("OLD_SPACE", 0x002f9): "ErrorStackAccessor", + ("OLD_SPACE", 0x00369): "FunctionArgumentsAccessor", + ("OLD_SPACE", 0x003d9): "FunctionCallerAccessor", + ("OLD_SPACE", 0x00449): "FunctionNameAccessor", + ("OLD_SPACE", 0x004b9): "FunctionLengthAccessor", + ("OLD_SPACE", 0x00529): "FunctionPrototypeAccessor", + ("OLD_SPACE", 0x00599): "StringLengthAccessor", + ("OLD_SPACE", 0x00609): "InvalidPrototypeValidityCell", + ("OLD_SPACE", 0x00619): "EmptyScript", + ("OLD_SPACE", 0x00699): "ManyClosuresCell", + ("OLD_SPACE", 0x006a9): "NoFeedbackCell", + ("OLD_SPACE", 0x006b9): "ArrayConstructorProtector", + ("OLD_SPACE", 0x006c9): "NoElementsProtector", + ("OLD_SPACE", 0x006f1): "IsConcatSpreadableProtector", + ("OLD_SPACE", 0x00701): "ArraySpeciesProtector", + ("OLD_SPACE", 0x00729): "TypedArraySpeciesProtector", + ("OLD_SPACE", 0x00751): "RegExpSpeciesProtector", + ("OLD_SPACE", 0x00779): "PromiseSpeciesProtector", + ("OLD_SPACE", 0x007a1): "StringLengthProtector", + ("OLD_SPACE", 0x007b1): "ArrayIteratorProtector", + ("OLD_SPACE", 0x007d9): "ArrayBufferDetachingProtector", + ("OLD_SPACE", 0x00801): "PromiseHookProtector", + ("OLD_SPACE", 0x00829): "PromiseResolveProtector", + ("OLD_SPACE", 0x00839): "MapIteratorProtector", + ("OLD_SPACE", 0x00861): "PromiseThenProtector", + ("OLD_SPACE", 0x00889): "SetIteratorProtector", + ("OLD_SPACE", 0x008b1): "StringIteratorProtector", + ("OLD_SPACE", 0x008d9): "SingleCharacterStringCache", + ("OLD_SPACE", 0x010e9): "StringSplitCache", + ("OLD_SPACE", 0x018f9): "RegExpMultipleCache", + ("OLD_SPACE", 0x02109): "BuiltinsConstantsTable", } # List of known V8 Frame Markers. diff --git a/deps/v8/tools/wasm/update-wasm-spec-tests.sh b/deps/v8/tools/wasm/update-wasm-spec-tests.sh index 92aaa8fd3c..9189c814b9 100755 --- a/deps/v8/tools/wasm/update-wasm-spec-tests.sh +++ b/deps/v8/tools/wasm/update-wasm-spec-tests.sh @@ -27,16 +27,16 @@ mkdir ${SPEC_TEST_DIR}/tmp ./tools/dev/gm.py x64.release d8 -cd ${V8_DIR}/test/wasm-js/interpreter +cd ${V8_DIR}/test/wasm-js/data/interpreter # The next step requires that ocaml is installed. See the README.md in -# ${V8_DIR}/test/wasm-js/interpreter/. +# ${V8_DIR}/test/wasm-js/data/interpreter/. make clean all -cd ${V8_DIR}/test/wasm-js/test/core +cd ${V8_DIR}/test/wasm-js/data/test/core -./run.py --wasm ${V8_DIR}/test/wasm-js/interpreter/wasm --js ${V8_DIR}/out/x64.release/d8 --out ${SPEC_TEST_DIR}/tmp +./run.py --wasm ${V8_DIR}/test/wasm-js/data/interpreter/wasm --js ${V8_DIR}/out/x64.release/d8 --out ${SPEC_TEST_DIR}/tmp cp ${SPEC_TEST_DIR}/tmp/*.js ${SPEC_TEST_DIR}/tests/ rm -rf ${SPEC_TEST_DIR}/tmp diff --git a/deps/v8/tools/wasm/wasm-import-profiler-end.js b/deps/v8/tools/wasm/wasm-import-profiler-end.js new file mode 100644 index 0000000000..5b5eedda03 --- /dev/null +++ b/deps/v8/tools/wasm/wasm-import-profiler-end.js @@ -0,0 +1,6 @@ +// 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. + +// Code to run at shutdown: print out the profiles for all instances. +if (typeof WebAssembly.dumpAllProfiles == "function") WebAssembly.dumpAllProfiles(); diff --git a/deps/v8/tools/wasm/wasm-import-profiler.js b/deps/v8/tools/wasm/wasm-import-profiler.js new file mode 100644 index 0000000000..cfbb3fb13b --- /dev/null +++ b/deps/v8/tools/wasm/wasm-import-profiler.js @@ -0,0 +1,131 @@ +// 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. + +(() => { + let all_profiles = []; + let instanceMap = new WeakMap(); + let instanceCounter = 0; + + function instrument(imports, profile) { + let orig_imports = imports; + return new Proxy(imports, { + get: (obj, module_name) => { + let orig_module = orig_imports[module_name]; + return new Proxy(orig_module, { + get: (obj, item_name) => { + let orig_func = orig_module[item_name]; + let item = orig_func; + if (typeof orig_func == "function") { + var full_name = module_name + "." + item_name; + print("instrumented " + full_name); + profile[full_name] = {name: full_name, count: 0, total: 0}; + item = function profiled_func(...args) { + var before = performance.now(); + var result = orig_func(...args); + var delta = performance.now() - before; + var data = profile[full_name]; + data.count++; + data.total += delta; + return result; + } + } + return item; + } + }) + } + }); + } + + function dumpProfile(profile) { + let array = []; + for (let key in profile) { + if (key == "instanceNum") continue; + let data = profile[key]; + if (data.count == 0) continue; + array.push(data); + } + print(`--- Import profile for instance ${profile.instanceNum} ---`); + if (array.length == 0) return; + array.sort((a, b) => b.total - a.total); + for (let data of array) { + print(`${padl(data.name, 30)}: ${padr(data.count, 10)} ${padp(data.total, 10)}ms`); + } + } + + function padl(s, len) { + s = s.toString(); + while (s.length < len) s = s + " "; + return s; + } + function padr(s, len) { + s = s.toString(); + while (s.length < len) s = " " + s; + return s; + } + function padp(s, len) { + s = s.toString(); + var i = s.indexOf("."); + if (i == -1) i = s.length; + while (i++ < len) s = " " + s; + return s; + } + + // patch: WebAssembly.instantiate (async) + let orig_instantiate = WebAssembly.instantiate; + WebAssembly.instantiate = (m, imports, ...args) => { + let profile = {}; + let promise = orig_instantiate(m, instrument(imports, profile), ...args); + promise.then((instance) => { + instanceMap.set(instance, profile); + all_profiles.push(profile); + profile.instanceNum = instanceCounter++; + }); + return promise; + } + + // patch: new WebAssembly.Instance (sync) + let orig_new_instance = WebAssembly.Instance; + WebAssembly.Instance = new Proxy(orig_new_instance, { + construct: (target, args) => { + let profile = {}; + args[1] = instrument(args[1], profile); + let instance = new orig_new_instance(...args); + instanceMap.set(instance, profile); + all_profiles.push(profile); + profile.instanceNum = instanceCounter++; + return instance; + } + }); + + // expose: WebAssembly.dumpProfile(instance) + WebAssembly.dumpProfile = (instance) => { + let profile = instanceMap.get(instance); + if (profile === undefined) return; + dumpProfile(profile); + } + // expose: WebAssembly.clearProfile(instance) + WebAssembly.clearProfile = (instance) => { + let profile = instanceMap.get(instance); + if (profile === undefined) return; + for (let key in profile) { + if (key == "instanceNum") continue; + let data = p[key]; + data.count = 0; + data.total = 0; + } + } + // expose: WebAssembly.dumpAllProfiles() + WebAssembly.dumpAllProfiles = () => { + for (let profile of all_profiles) dumpProfile(profile); + } + // expose: WebAssembly.getProfile(instance) + // returns: { + // func_name1: {name: func_name1, count: <num>, total: <num>} + // func_name2: {name: func_name1, count: <num>, total: <num>} + // ... + // } + WebAssembly.getProfile = (instance) => { + return instanceMap.get(instance); + } +})(); diff --git a/deps/v8/tools/whitespace.txt b/deps/v8/tools/whitespace.txt index 11f5364162..1b70f46680 100644 --- a/deps/v8/tools/whitespace.txt +++ b/deps/v8/tools/whitespace.txt @@ -6,5 +6,5 @@ A Smi balks into a war and says: "I'm so deoptimized today!" The doubles heard this and started to unbox. The Smi looked at them when a crazy v8-autoroll account showed up... -The autoroller bought a round of Himbeerbrause. Suddenly..... -The bartender starts to shake the bottles...... +The autoroller bought a round of Himbeerbrause. Suddenly....... +The bartender starts to shake the bottles! |