diff --git a/deps/v8/.github/mistaken-pull-closer.yml b/deps/v8/.github/mistaken-pull-closer.yml new file mode 100644 index 00000000000000..b78f1f6bfc043c --- /dev/null +++ b/deps/v8/.github/mistaken-pull-closer.yml @@ -0,0 +1,13 @@ +# `true` will close all PRs. +filters: + - true + +# The message to post to the closed PR. +commentBody: | + Thanks for your contribution! Unfortunately, we don't use GitHub pull + requests to manage code contributions to this repository. Instead, please + see https://v8.dev/docs/contribute which provides full instructions on + how to get involved. + +# Whether to add a label to the closed PR. +addLabel: false diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 11c7ae61ddaf53..b340100517a5a4 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -23,6 +23,7 @@ *~ .#* .*.sw? +.cache .ccls-cache .clangd .cpplint-cache @@ -60,7 +61,6 @@ /test/wasm-spec-tests/tests.tar.gz /third_party/* !/third_party/antlr4 -!/third_party/binutils !/third_party/inspector_protocol !/third_party/jsoncpp /third_party/jsoncpp/source @@ -78,6 +78,7 @@ !/third_party/v8 !/third_party/wasm-api /tools/clang +/tools/gcmole/bootstrap /tools/gcmole/gcmole-tools /tools/gcmole/gcmole-tools.tar.gz /tools/jsfunfuzz/jsfunfuzz diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 5dba6abe9b5546..716a23b5bf4058 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -28,7 +28,6 @@ IBM Inc. <*@ibm.com> Red Hat Inc. <*@redhat.com> Samsung <*@*.samsung.com> Samsung <*@samsung.com> -Joyent, Inc <*@joyent.com> RT-RK Computer Based System <*@rt-rk.com> Amazon, Inc <*@amazon.com> ST Microelectronics <*@st.com> @@ -61,7 +60,6 @@ Andreas Anyuru Andrew Paprocki Andrei Kashcha Anna Henningsen -Antoine du Hamel Anton Bikineev Bangfu Tao Daniel Shelton @@ -136,6 +134,7 @@ Kevin Gibbons Kris Selden Kyounga Ra Loo Rong Jie +Lu Yahan Luis Reis Luke Zarko Maciej MaƂecki diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 1dc6c7d5ac51df..f39529a3a953a3 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -45,6 +45,12 @@ declare_args() { # Sets --DV8_LITE_MODE. v8_enable_lite_mode = false + # Sets -DSYSTEM_INSTRUMENTATION. Enables OS-dependent event tracing + v8_enable_system_instrumentation = false + + # Sets the GUID for the ETW provider + v8_etw_guid = "" + # Sets -DVERIFY_HEAP. v8_enable_verify_heap = "" @@ -113,7 +119,8 @@ declare_args() { v8_disable_arguments_adaptor = v8_current_cpu == "x86" || v8_current_cpu == "x64" || v8_current_cpu == "arm" || v8_current_cpu == "arm64" || - v8_current_cpu == "mipsel" || v8_current_cpu == "mips64el" + v8_current_cpu == "mipsel" || v8_current_cpu == "mips64el" || + v8_current_cpu == "ppc64" || v8_current_cpu == "s390x" # Sets -dOBJECT_PRINT. v8_enable_object_print = "" @@ -422,6 +429,7 @@ config("internal_config") { "//build/config/compiler:wexit_time_destructors", ":internal_config_base", ":v8_header_features", + ":cppgc_header_features", ] if (is_component_build) { @@ -459,17 +467,15 @@ config("libbase_config") { } } +# Standalone cppgc cannot be built within chrome or with perfetto. +assert(!cppgc_is_standalone || !build_with_chromium) +assert(!cppgc_is_standalone || !v8_use_perfetto) + # This config should be applied to code using the cppgc_base. config("cppgc_base_config") { defines = [] - if (cppgc_enable_object_names) { - defines += [ "CPPGC_SUPPORTS_OBJECT_NAMES" ] - } - if (cppgc_enable_caged_heap) { - defines += [ "CPPGC_CAGED_HEAP" ] - } - if (cppgc_enable_young_generation) { - defines += [ "CPPGC_YOUNG_GENERATION" ] + if (cppgc_is_standalone) { + defines += [ "CPPGC_IS_STANDALONE" ] } } @@ -482,7 +488,10 @@ config("libsampler_config") { # itself. config("external_config") { defines = [] - configs = [ ":v8_header_features" ] + configs = [ + ":v8_header_features", + ":cppgc_header_features", + ] if (is_component_build) { defines += [ "USING_V8_SHARED" ] } @@ -531,6 +540,25 @@ config("v8_header_features") { if (v8_disable_arguments_adaptor) { defines += [ "V8_NO_ARGUMENTS_ADAPTOR" ] } + if (v8_use_perfetto) { + defines += [ "V8_USE_PERFETTO" ] + } +} + +config("cppgc_header_features") { + visibility = [ ":*" ] + + defines = [] + + if (cppgc_enable_object_names) { + defines += [ "CPPGC_SUPPORTS_OBJECT_NAMES" ] + } + if (cppgc_enable_caged_heap) { + defines += [ "CPPGC_CAGED_HEAP" ] + } + if (cppgc_enable_young_generation) { + defines += [ "CPPGC_YOUNG_GENERATION" ] + } } # Put defines here that are only used in our internal files and NEVER in @@ -541,7 +569,10 @@ config("features") { defines = [] - configs = [ ":v8_header_features" ] + configs = [ + ":v8_header_features", + ":cppgc_header_features", + ] if (v8_embedder_string != "") { defines += [ "V8_EMBEDDER_STRING=\"$v8_embedder_string\"" ] @@ -646,9 +677,6 @@ config("features") { if (v8_enable_shared_ro_heap) { defines += [ "V8_SHARED_RO_HEAP" ] } - if (v8_use_perfetto) { - defines += [ "V8_USE_PERFETTO" ] - } if (v8_win64_unwinding_info) { defines += [ "V8_WIN64_UNWINDING_INFO" ] } @@ -673,6 +701,12 @@ config("features") { if (v8_dict_mode_prototypes) { defines += [ "V8_DICT_MODE_PROTOTYPES" ] } + if (v8_enable_system_instrumentation) { + defines += [ "V8_ENABLE_SYSTEM_INSTRUMENTATION" ] + } + if (v8_etw_guid != "") { + defines += [ "V8_ETW_GUID=\"$v8_etw_guid\"" ] + } } config("toolchain") { @@ -720,6 +754,7 @@ config("toolchain") { # TODO(v8:10026): Enable this in src/build. if (current_cpu == "arm64") { cflags += [ "-mbranch-protection=standard" ] + asmflags = [ "-mmark-bti-property" ] } } } @@ -811,6 +846,7 @@ config("toolchain") { defines += [ "V8_TARGET_ARCH_PPC" ] } else if (v8_current_cpu == "ppc64") { defines += [ "V8_TARGET_ARCH_PPC64" ] + cflags += [ "-ffp-contract=off" ] } if (host_byteorder == "little") { defines += [ "V8_TARGET_ARCH_PPC_LE" ] @@ -1132,6 +1168,7 @@ action("postmortem-metadata") { torque_files = [ "src/builtins/aggregate-error.tq", + "src/builtins/array-at.tq", "src/builtins/array-copywithin.tq", "src/builtins/array-every.tq", "src/builtins/array-filter.tq", @@ -1171,7 +1208,7 @@ torque_files = [ "src/builtins/function.tq", "src/builtins/growable-fixed-array.tq", "src/builtins/ic-callable.tq", - "src/builtins/ic-dynamic-map-checks.tq", + "src/builtins/ic-dynamic-check-maps.tq", "src/builtins/ic.tq", "src/builtins/internal-coverage.tq", "src/builtins/internal.tq", @@ -1214,6 +1251,7 @@ torque_files = [ "src/builtins/regexp-split.tq", "src/builtins/regexp-test.tq", "src/builtins/regexp.tq", + "src/builtins/string-at.tq", "src/builtins/string-endswith.tq", "src/builtins/string-html.tq", "src/builtins/string-iterator.tq", @@ -1227,6 +1265,7 @@ torque_files = [ "src/builtins/string-trim.tq", "src/builtins/symbol.tq", "src/builtins/torque-internal.tq", + "src/builtins/typed-array-at.tq", "src/builtins/typed-array-createtypedarray.tq", "src/builtins/typed-array-every.tq", "src/builtins/typed-array-entries.tq", @@ -1373,8 +1412,6 @@ template("run_torque") { "$target_gen_dir/torque-generated/exported-macros-assembler.h", "$target_gen_dir/torque-generated/csa-types.h", "$target_gen_dir/torque-generated/instance-types.h", - "$target_gen_dir/torque-generated/runtime-macros.cc", - "$target_gen_dir/torque-generated/runtime-macros.h", "$target_gen_dir/torque-generated/class-forward-declarations.h", ] @@ -1495,7 +1532,6 @@ v8_source_set("torque_generated_definitions") { "$target_gen_dir/torque-generated/class-verifiers.h", "$target_gen_dir/torque-generated/factory.cc", "$target_gen_dir/torque-generated/objects-printer.cc", - "$target_gen_dir/torque-generated/runtime-macros.cc", ] foreach(file, torque_files) { filetq = string_replace(file, ".tq", "-tq") @@ -1961,7 +1997,10 @@ v8_header_set("v8_version") { # can depend upon to get basic v8 types. v8_header_set("v8_headers") { configs = [ ":internal_config" ] - public_configs = [ ":v8_header_features" ] + public_configs = [ + ":v8_header_features", + ":cppgc_header_features", + ] sources = [ "include/v8-cppgc.h", @@ -1982,6 +2021,12 @@ v8_header_set("v8_headers") { deps = [ ":v8_version" ] } +v8_source_set("v8_wrappers") { + configs = [ ":internal_config" ] + + sources = [ "src/base/platform/wrappers.h" ] +} + # This is split out to share basic headers with Torque. v8_header_set("v8_shared_internal_headers") { visibility = [ ":*" ] # Only targets in this file can depend on this. @@ -2495,6 +2540,8 @@ v8_source_set("v8_base_without_compiler") { "src/debug/debug-stack-trace-iterator.h", "src/debug/debug-type-profile.cc", "src/debug/debug-type-profile.h", + "src/debug/debug-wasm-support.cc", + "src/debug/debug-wasm-support.h", "src/debug/debug.cc", "src/debug/debug.h", "src/debug/interface-types.h", @@ -2555,6 +2602,7 @@ v8_source_set("v8_base_without_compiler") { "src/execution/protectors.h", "src/execution/runtime-profiler.cc", "src/execution/runtime-profiler.h", + "src/execution/shared-mutex-guard-if-off-thread.h", "src/execution/simulator-base.cc", "src/execution/simulator-base.h", "src/execution/simulator.h", @@ -2709,6 +2757,7 @@ v8_source_set("v8_base_without_compiler") { "src/heap/paged-spaces.cc", "src/heap/paged-spaces.h", "src/heap/parallel-work-item.h", + "src/heap/parked-scope.h", "src/heap/read-only-heap-inl.h", "src/heap/read-only-heap.cc", "src/heap/read-only-heap.h", @@ -3111,6 +3160,8 @@ v8_source_set("v8_base_without_compiler") { "src/parsing/expression-scope.h", "src/parsing/func-name-inferrer.cc", "src/parsing/func-name-inferrer.h", + "src/parsing/import-assertions.cc", + "src/parsing/import-assertions.h", "src/parsing/literal-buffer.cc", "src/parsing/literal-buffer.h", "src/parsing/parse-info.cc", @@ -3307,6 +3358,8 @@ v8_source_set("v8_base_without_compiler") { "src/strings/uri.h", "src/tasks/cancelable-task.cc", "src/tasks/cancelable-task.h", + "src/tasks/operations-barrier.cc", + "src/tasks/operations-barrier.h", "src/tasks/task-utils.cc", "src/tasks/task-utils.h", "src/third_party/siphash/halfsiphash.cc", @@ -3391,8 +3444,6 @@ v8_source_set("v8_base_without_compiler") { "src/wasm/wasm-code-manager.cc", "src/wasm/wasm-code-manager.h", "src/wasm/wasm-constants.h", - "src/wasm/wasm-debug-evaluate.cc", - "src/wasm/wasm-debug-evaluate.h", "src/wasm/wasm-debug.cc", "src/wasm/wasm-engine.cc", "src/wasm/wasm-engine.h", @@ -3808,9 +3859,7 @@ v8_source_set("v8_base_without_compiler") { ":cppgc_base_config", ] - defines = [] deps = [ - ":cppgc_base", ":torque_generated_definitions", ":v8_cppgc_shared", ":v8_headers", @@ -3819,10 +3868,12 @@ v8_source_set("v8_base_without_compiler") { ":v8_shared_internal_headers", ":v8_tracing", ":v8_version", + ":v8_wrappers", "src/inspector:inspector", ] public_deps = [ + ":cppgc_base", ":generate_bytecode_builtins_list", ":run_torque", ":v8_maybe_icu", @@ -3983,7 +4034,10 @@ v8_source_set("torque_base") { deps = [ ":v8_shared_internal_headers" ] - public_deps = [ ":v8_libbase" ] + public_deps = [ + ":v8_libbase", + ":v8_wrappers", + ] # The use of exceptions for Torque in violation of the Chromium style-guide # is justified by the fact that it is only used from the non-essential @@ -4106,8 +4160,6 @@ v8_component("v8_libbase") { "src/base/platform/semaphore.h", "src/base/platform/time.cc", "src/base/platform/time.h", - "src/base/platform/wrappers.h", - "src/base/platform/wrappers_std.cc", "src/base/region-allocator.cc", "src/base/region-allocator.h", "src/base/ring-buffer.h", @@ -4132,7 +4184,7 @@ v8_component("v8_libbase") { deps = [ ":v8_headers" ] - public_deps = [] + public_deps = [ ":v8_wrappers" ] data = [] @@ -4173,10 +4225,7 @@ v8_component("v8_libbase") { "src/base/platform/platform-aix.cc", ] - libs = [ - "dl", - "rt", - ] + libs = [ "dl" ] } else if (is_android) { if (current_toolchain == host_toolchain) { libs = [ @@ -4205,6 +4254,7 @@ v8_component("v8_libbase") { "src/base/debug/stack_trace_fuchsia.cc", "src/base/platform/platform-fuchsia.cc", ] + deps += [ "//third_party/fuchsia-sdk/sdk/pkg/zx" ] } else if (is_mac || is_ios) { sources += [ "src/base/debug/stack_trace_posix.cc", @@ -4226,6 +4276,10 @@ v8_component("v8_libbase") { "ws2_32.lib", ] + if (v8_enable_system_instrumentation) { + libs += [ "advapi32.lib" ] # Needed for TraceLoggingProvider.h + } + data_deps += [ "//build/win:runtime_libs" ] } @@ -4268,6 +4322,8 @@ v8_component("v8_libplatform") { "src/libplatform/delayed-task-queue.h", "src/libplatform/task-queue.cc", "src/libplatform/task-queue.h", + "src/libplatform/tracing/recorder-default.cc", + "src/libplatform/tracing/recorder.h", "src/libplatform/tracing/trace-buffer.cc", "src/libplatform/tracing/trace-buffer.h", "src/libplatform/tracing/trace-config.cc", @@ -4287,15 +4343,19 @@ v8_component("v8_libplatform") { public_configs = [ ":libplatform_config" ] + public_deps = [] + deps = [ ":v8_headers", ":v8_libbase", ":v8_tracing", + ":v8_wrappers", ] if (v8_use_perfetto) { sources -= [ "//base/trace_event/common/trace_event_common.h", + "src/libplatform/tracing/recorder-default.cc", "src/libplatform/tracing/trace-buffer.cc", "src/libplatform/tracing/trace-buffer.h", "src/libplatform/tracing/trace-object.cc", @@ -4310,6 +4370,9 @@ v8_component("v8_libplatform") { # TODO(skyostil): Switch TraceEventListener to protozero. "//third_party/perfetto/protos/perfetto/trace:lite", ] + } else if (is_win) { + sources -= [ "src/libplatform/tracing/recorder-default.cc" ] + sources += [ "src/libplatform/tracing/recorder-win.cc" ] } } @@ -4385,6 +4448,26 @@ v8_source_set("v8_cppgc_shared") { public_deps = [ ":v8_libbase" ] } +# This is split out to be a non-code containing target that the Chromium browser +# can depend upon to get basic cppgc types. +v8_header_set("cppgc_headers") { + configs = [ ":internal_config" ] + public_configs = [ + ":v8_header_features", + ":cppgc_header_features", + ] + + sources = [ + "include/cppgc/garbage-collected.h", + "include/cppgc/member.h", + "include/cppgc/persistent.h", + "include/cppgc/type-traits.h", + "include/cppgc/visitor.h", + ] + + public_deps = [ ":v8_headers" ] +} + v8_source_set("cppgc_base") { visibility = [ ":*" ] @@ -4395,6 +4478,7 @@ v8_source_set("cppgc_base") { "include/cppgc/default-platform.h", "include/cppgc/ephemeron-pair.h", "include/cppgc/garbage-collected.h", + "include/cppgc/heap-consistency.h", "include/cppgc/heap.h", "include/cppgc/internal/api-constants.h", "include/cppgc/internal/atomic-entry-flag.h", @@ -4426,6 +4510,7 @@ v8_source_set("cppgc_base") { "src/heap/cppgc/compactor.h", "src/heap/cppgc/concurrent-marker.cc", "src/heap/cppgc/concurrent-marker.h", + "src/heap/cppgc/default-platform.cc", "src/heap/cppgc/free-list.cc", "src/heap/cppgc/free-list.h", "src/heap/cppgc/garbage-collector.h", @@ -4484,6 +4569,7 @@ v8_source_set("cppgc_base") { "src/heap/cppgc/sweeper.cc", "src/heap/cppgc/sweeper.h", "src/heap/cppgc/task-handle.h", + "src/heap/cppgc/trace-event.h", "src/heap/cppgc/trace-trait.cc", "src/heap/cppgc/virtual-memory.cc", "src/heap/cppgc/virtual-memory.h", @@ -4491,6 +4577,12 @@ v8_source_set("cppgc_base") { "src/heap/cppgc/write-barrier.cc", ] + if (cppgc_is_standalone) { + sources += [ "//base/trace_event/common/trace_event_common.h" ] + } else { + deps = [ ":v8_tracing" ] + } + if (cppgc_enable_caged_heap) { sources += [ "include/cppgc/internal/caged-heap-local-data.h", @@ -4621,6 +4713,7 @@ if (current_toolchain == v8_snapshot_toolchain) { ":v8_libplatform", ":v8_maybe_icu", ":v8_tracing", + ":v8_wrappers", "//build/win:default_exe_manifest", ] } @@ -4765,7 +4858,10 @@ group("v8_python_base") { group("v8_clusterfuzz") { testonly = true - deps = [ ":d8" ] + deps = [ + ":d8", + ":v8_simple_inspector_fuzzer", + ] if (v8_multi_arch_build) { deps += [ @@ -4861,16 +4957,22 @@ if (is_component_build) { configs = [ ":internal_config" ] + if (!cppgc_is_standalone) { + deps = [ ":v8" ] + } + public_configs = [ ":external_config" ] } - v8_component("cppgc_for_testing") { - testonly = true + if (cppgc_is_standalone) { + v8_component("cppgc_for_testing") { + testonly = true - public_deps = [ ":cppgc_base" ] + public_deps = [ ":cppgc_base" ] - configs = [ ":internal_config" ] - public_configs = [ ":external_config" ] + configs = [ ":internal_config" ] + public_configs = [ ":external_config" ] + } } v8_component("v8_cppgc_shared_for_testing") { @@ -4908,15 +5010,21 @@ if (is_component_build) { group("cppgc") { public_deps = [ ":cppgc_base" ] + if (!cppgc_is_standalone) { + deps = [ ":v8" ] + } + public_configs = [ ":external_config" ] } - group("cppgc_for_testing") { - testonly = true + if (cppgc_is_standalone) { + group("cppgc_for_testing") { + testonly = true - public_deps = [ ":cppgc_base" ] + public_deps = [ ":cppgc_base" ] - public_configs = [ ":external_config" ] + public_configs = [ ":external_config" ] + } } group("v8_cppgc_shared_for_testing") { @@ -4961,6 +5069,7 @@ v8_executable("d8") { ":v8_libbase", ":v8_libplatform", ":v8_tracing", + ":v8_wrappers", "//build/win:default_exe_manifest", ] @@ -5037,34 +5146,24 @@ if (want_v8_shell) { } } -v8_executable("cppgc_for_v8_embedders") { - sources = [ "samples/cppgc/cppgc-for-v8-embedders.cc" ] - - configs = [ - # Note: don't use :internal_config here because this target will get - # the :external_config applied to it by virtue of depending on :cppgc, and - # you can't have both applied to the same target. - ":internal_config_base", - ] - - deps = [ - ":cppgc", - ":v8_libplatform", - "//build/win:default_exe_manifest", - ] -} - -v8_executable("cppgc_standalone") { - sources = [ "samples/cppgc/cppgc-standalone.cc" ] +v8_executable("cppgc_sample") { + sources = [ "samples/cppgc/cppgc-sample.cc" ] configs = [ # Note: don't use :internal_config here because this target will get # the :external_config applied to it by virtue of depending on :cppgc, and # you can't have both applied to the same target. ":internal_config_base", + ":cppgc_base_config", ] deps = [ ":cppgc" ] + if (!cppgc_is_standalone) { + deps += [ + ":v8", + "//build/win:default_exe_manifest", + ] + } } template("v8_fuzzer") { @@ -5099,7 +5198,10 @@ v8_fuzzer("json_fuzzer") { v8_source_set("multi_return_fuzzer") { sources = [ "test/fuzzer/multi-return.cc" ] - deps = [ ":fuzzer_support" ] + deps = [ + ":fuzzer_support", + ":v8_wrappers", + ] configs = [ ":external_config", @@ -5113,7 +5215,10 @@ v8_fuzzer("multi_return_fuzzer") { v8_source_set("parser_fuzzer") { sources = [ "test/fuzzer/parser.cc" ] - deps = [ ":fuzzer_support" ] + deps = [ + ":fuzzer_support", + ":v8_wrappers", + ] configs = [ ":external_config", @@ -5130,7 +5235,10 @@ v8_source_set("regexp_builtins_fuzzer") { "test/fuzzer/regexp_builtins/mjsunit.js.h", ] - deps = [ ":fuzzer_support" ] + deps = [ + ":fuzzer_support", + ":v8_wrappers", + ] configs = [ ":external_config", @@ -5144,7 +5252,10 @@ v8_fuzzer("regexp_builtins_fuzzer") { v8_source_set("regexp_fuzzer") { sources = [ "test/fuzzer/regexp.cc" ] - deps = [ ":fuzzer_support" ] + deps = [ + ":fuzzer_support", + ":v8_wrappers", + ] configs = [ ":external_config", @@ -5183,6 +5294,7 @@ v8_source_set("wasm_fuzzer") { deps = [ ":fuzzer_support", ":lib_wasm_fuzzer_common", + ":v8_wrappers", ":wasm_test_common", ] @@ -5201,6 +5313,7 @@ v8_source_set("wasm_async_fuzzer") { deps = [ ":fuzzer_support", ":lib_wasm_fuzzer_common", + ":v8_wrappers", ":wasm_test_common", ] @@ -5222,6 +5335,7 @@ v8_source_set("wasm_code_fuzzer") { deps = [ ":fuzzer_support", ":lib_wasm_fuzzer_common", + ":v8_wrappers", ":wasm_test_common", ] @@ -5263,6 +5377,7 @@ v8_source_set("wasm_compile_fuzzer") { deps = [ ":fuzzer_support", ":lib_wasm_fuzzer_common", + ":v8_wrappers", ":wasm_test_common", ] @@ -5280,6 +5395,7 @@ v8_source_set("inspector_fuzzer") { deps = [ ":fuzzer_support", + ":v8_wrappers", "test/inspector:inspector_test", ] diff --git a/deps/v8/DEPS b/deps/v8/DEPS index 3e3fed387db216..e6c2e762e01392 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -10,7 +10,6 @@ gclient_gn_args = [ # Remove when migration is complete. 'checkout_fuchsia_for_arm64_host', 'checkout_google_benchmark', - 'mac_xcode_version', ] vars = { @@ -47,13 +46,11 @@ vars = { 'checkout_google_benchmark' : False, - 'mac_xcode_version': 'default', - # GN CIPD package version. - 'gn_version': 'git_revision:53d92014bf94c3893886470a1c7c1289f8818db0', + 'gn_version': 'git_revision:595e3be7c8381d4eeefce62a63ec12bae9ce5140', # luci-go CIPD package version. - 'luci_go': 'git_revision:1a022d3a4c50be4207ee93451255d71896416596', + 'luci_go': 'git_revision:67aba6e3373bb0b9e3ef9871362045736cd29b6e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version @@ -91,15 +88,15 @@ vars = { deps = { 'build': - Var('chromium_url') + '/chromium/src/build.git' + '@' + '2101eff1ac4bfd25f2dfa71ad632a600a38c1ed9', + Var('chromium_url') + '/chromium/src/build.git' + '@' + 'd5995537211ebc4d1bc37f215c25fa3781ba9d6e', 'third_party/depot_tools': - Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '982b2a757087c2519e42b82b93cbfe5adf43cdd5', + Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '82b992a1656d7d1cd0ee3cbea8ff609ffdfed380', 'third_party/icu': - Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'c2a4cae149aae7fd30c4cbe3cf1b30df03b386f1', + Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '899e18383fd732b47e6978db2b960a1b2a80179b', 'third_party/instrumented_libraries': - Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + '6ba978ccb754d270b6cd12da58c8269b617e4f6e', + Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + '4d3867052d35b2171f2edbb3466fa8f7e2d11319', 'buildtools': - Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '6302c1175607a436e18947a5abe9df2209e845fc', + Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '235cfe435ca5a9826569ee4ef603e226216bd768', 'buildtools/clang_format/script': Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917', 'buildtools/linux64': { @@ -187,7 +184,7 @@ deps = { 'dep_type': 'cipd', }, 'third_party/catapult': { - 'url': Var('chromium_url') + '/catapult.git' + '@' + '434681c2378b686117c2b003a58c54d78f22185f', + 'url': Var('chromium_url') + '/catapult.git' + '@' + 'd1a3011cd91205aa96b74b5dfc227d391e88108d', 'condition': 'checkout_android', }, 'third_party/colorama/src': { @@ -195,27 +192,27 @@ deps = { 'condition': 'checkout_android', }, 'third_party/fuchsia-sdk': { - 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + 'f8df9ff79b878d1998970cc04a197061069e48ce', + 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + 'efa46583d89ea8c97523281d9f52a0d96472114d', 'condition': 'checkout_fuchsia', }, 'third_party/googletest/src': - Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '4fe018038f87675c083d0cfb6a6b57c274fb1753', + Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '1b0cdaae57c046c87fb99cb4f69c312a7e794adb', 'third_party/google_benchmark/src': { 'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + '7f27afe83b82f3a98baf58ef595814b9d42a5b2b', 'condition': 'checkout_google_benchmark', }, 'third_party/jinja2': - Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'a82a4944a7f2496639f34a89c9923be5908b80aa', + Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + '11b6b3e5971d760bd2d310f77643f55a818a6d25', 'third_party/markupsafe': Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + '0944e71f4b2cb9a871bcbe353f95e889b64a611a', 'tools/swarming_client': - Var('chromium_url') + '/infra/luci/client-py.git' + '@' + 'd46ea7635f2911208268170512cb611412488fd8', + Var('chromium_url') + '/infra/luci/client-py.git' + '@' + '1a072711d4388c62e02480fabc26c68c24494be9', 'test/benchmarks/data': Var('chromium_url') + '/v8/deps/third_party/benchmarks.git' + '@' + '05d7188267b4560491ff9155c5ee13e207ecd65f', 'test/mozilla/data': Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be', 'test/test262/data': - Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '0e7319c015fe935594f8bcafaedb0c94f7fec1df', + Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'b2e9dff2816cceb5ee84c0c226c50a31d01a7297', 'test/test262/harness': Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b', 'third_party/qemu-linux-x64': { @@ -242,7 +239,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'xP4TXh9wWGTG0qr4y6eFcUO_0HOBmt3vorgtVmpwBJsC' + 'version': 'xAHa1IXmKteChkPvba9ezjSnKL7IyDePQRzWVUEAx9UC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -259,7 +256,7 @@ deps = { 'dep_type': 'cipd', }, 'tools/clang': - Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'a37c0858a645506c8e9d3bebab1ed5a5b1f9df61', + Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '2246bee280e908ac1fd27ab75e7d0021b14d875c', 'tools/luci-go': { 'packages': [ { @@ -293,7 +290,7 @@ deps = { 'third_party/protobuf': Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91', 'third_party/zlib': - Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + 'e84c9a3fd75fdc39055b7ae27d6ec508e50bd39e', + Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '2c183c9f93a328bfb3121284da13cf89a0f7e64a', 'third_party/jsoncpp/source': Var('chromium_url') + '/external/github.com/open-source-parsers/jsoncpp.git'+ '@' + '9059f5cad030ba11d37818847443a53918c327b1', 'third_party/ittapi': { @@ -490,20 +487,7 @@ hooks = [ 'name': 'mac_toolchain', 'pattern': '.', 'condition': 'checkout_mac', - 'action': ['python', 'build/mac_toolchain.py', - '--xcode-version', Var('mac_xcode_version')], - }, - # Pull binutils for linux, enabled debug fission for faster linking / - # debugging when used with clang on Ubuntu Precise. - # https://code.google.com/p/chromium/issues/detail?id=352046 - { - 'name': 'binutils', - 'pattern': 'third_party/binutils', - 'condition': 'host_os == "linux"', - 'action': [ - 'python', - 'third_party/binutils/download.py', - ], + 'action': ['python', 'build/mac_toolchain.py'], }, { # Note: On Win, this should run after win_toolchain, as it may use it. diff --git a/deps/v8/MIPS_OWNERS b/deps/v8/MIPS_OWNERS index cab3679d656e6a..6c65e34e9c3bf7 100644 --- a/deps/v8/MIPS_OWNERS +++ b/deps/v8/MIPS_OWNERS @@ -1 +1,2 @@ xwafish@gmail.com +zhaojiazhong-hf@loongson.cn diff --git a/deps/v8/WATCHLISTS b/deps/v8/WATCHLISTS index 54d6bbec1c51ff..fa95f144cb73cb 100644 --- a/deps/v8/WATCHLISTS +++ b/deps/v8/WATCHLISTS @@ -87,6 +87,11 @@ 'tracing': { 'filepath': 'src/tracing/', }, + 'ieee754': { + 'filepath': 'src/base/ieee754\.(cc|h)' \ + '|src/base/overflowing-math.h' \ + '|LICENSE.fdlibm', + } }, 'WATCHLISTS': { @@ -133,5 +138,9 @@ 'lpy+v8tracing@chromium.org', 'fmeawad@chromium.org', ], + 'ieee754': [ + 'rtoy+watch@chromium.org', + 'hongchan+watch@chromium.org' + ], }, } diff --git a/deps/v8/build_overrides/build.gni b/deps/v8/build_overrides/build.gni index dde92c46eaa78d..4e0c284efaeae9 100644 --- a/deps/v8/build_overrides/build.gni +++ b/deps/v8/build_overrides/build.gni @@ -32,9 +32,6 @@ use_perfetto_client_library = false # Some non-Chromium builds don't support building java targets. enable_java_templates = false -# Some non-Chromium builds don't use Chromium's third_party/binutils. -linux_use_bundled_binutils_override = true - # Allows different projects to specify their own suppressions files. asan_suppressions_file = "//build/sanitizers/asan_suppressions.cc" lsan_suppressions_file = "//build/sanitizers/lsan_suppressions.cc" diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni index edc944ef0c7a96..5651a178c283df 100644 --- a/deps/v8/gni/v8.gni +++ b/deps/v8/gni/v8.gni @@ -71,6 +71,8 @@ declare_args() { v8_enable_conservative_stack_scanning = false v8_enable_google_benchmark = checkout_google_benchmark + + cppgc_is_standalone = false } if (v8_use_external_startup_data == "") { diff --git a/deps/v8/include/DEPS b/deps/v8/include/DEPS index 7d60081fb480b7..9f4002059b3051 100644 --- a/deps/v8/include/DEPS +++ b/deps/v8/include/DEPS @@ -2,5 +2,8 @@ include_rules = [ # v8-inspector-protocol.h depends on generated files under include/inspector. "+inspector", "+cppgc/common.h", + # Used by v8-cppgc.h to bridge to cppgc. + "+cppgc/custom-space.h", + "+cppgc/internal/write-barrier.h", "+cppgc/visitor.h", ] diff --git a/deps/v8/include/cppgc/allocation.h b/deps/v8/include/cppgc/allocation.h index 556f313a4ac81c..1164f6925cdcf7 100644 --- a/deps/v8/include/cppgc/allocation.h +++ b/deps/v8/include/cppgc/allocation.h @@ -39,9 +39,8 @@ class V8_EXPORT MakeGarbageCollectedTraitInternal { const_cast(reinterpret_cast( reinterpret_cast(payload) - api_constants::kFullyConstructedBitFieldOffsetFromPayload))); - uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed); - value = value | api_constants::kFullyConstructedBitMask; - atomic_mutable_bitfield->store(value, std::memory_order_release); + atomic_mutable_bitfield->fetch_or(api_constants::kFullyConstructedBitMask, + std::memory_order_release); } static void* Allocate(cppgc::AllocationHandle& handle, size_t size, @@ -113,11 +112,29 @@ class MakeGarbageCollectedTraitBase }; /** - * struct used specify to MakeGarbageCollected how many bytes should be - * appended to the allocated object. + * Passed to MakeGarbageCollected to specify how many bytes should be appended + * to the allocated object. + * + * Example: + * \code + * class InlinedArray final : public GarbageCollected { + * public: + * explicit InlinedArray(size_t bytes) : size(bytes), byte_array(this + 1) {} + * void Trace(Visitor*) const {} + + * size_t size; + * char* byte_array; + * }; + * + * auto* inlined_array = MakeGarbageCollectedbyte_array[i]); + * } + * \endcode */ struct AdditionalBytes { - explicit AdditionalBytes(size_t bytes) : value(bytes) {} + constexpr explicit AdditionalBytes(size_t bytes) : value(bytes) {} const size_t value; }; diff --git a/deps/v8/include/cppgc/common.h b/deps/v8/include/cppgc/common.h index 228b9abb74e763..1fff1a03fe369f 100644 --- a/deps/v8/include/cppgc/common.h +++ b/deps/v8/include/cppgc/common.h @@ -14,11 +14,11 @@ namespace cppgc { enum class EmbedderStackState { kMayContainHeapPointers, kNoHeapPointers, - kUnknown V8_ENUM_DEPRECATE_SOON("Use kMayContainHeapPointers") = + kUnknown V8_ENUM_DEPRECATED("Use kMayContainHeapPointers") = kMayContainHeapPointers, - kNonEmpty V8_ENUM_DEPRECATE_SOON("Use kMayContainHeapPointers") = + kNonEmpty V8_ENUM_DEPRECATED("Use kMayContainHeapPointers") = kMayContainHeapPointers, - kEmpty V8_ENUM_DEPRECATE_SOON("Use kNoHeapPointers") = kNoHeapPointers, + kEmpty V8_ENUM_DEPRECATED("Use kNoHeapPointers") = kNoHeapPointers, }; } // namespace cppgc diff --git a/deps/v8/include/cppgc/default-platform.h b/deps/v8/include/cppgc/default-platform.h index 28990da92e6550..2ccdeddd8376f4 100644 --- a/deps/v8/include/cppgc/default-platform.h +++ b/deps/v8/include/cppgc/default-platform.h @@ -20,12 +20,24 @@ namespace cppgc { */ class V8_EXPORT DefaultPlatform : public Platform { public: + /** + * Use this method instead of 'cppgc::InitializeProcess' when using + * 'cppgc::DefaultPlatform'. 'cppgc::DefaultPlatform::InitializeProcess' + * will initialize cppgc and v8 if needed (for non-standalone builds). + * + * \param platform DefaultPlatform instance used to initialize cppgc/v8. + */ + static void InitializeProcess(DefaultPlatform* platform); + using IdleTaskSupport = v8::platform::IdleTaskSupport; explicit DefaultPlatform( int thread_pool_size = 0, - IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled) - : v8_platform_(v8::platform::NewDefaultPlatform(thread_pool_size, - idle_task_support)) {} + IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, + std::unique_ptr tracing_controller = {}) + : v8_platform_(v8::platform::NewDefaultPlatform( + thread_pool_size, idle_task_support, + v8::platform::InProcessStackDumping::kDisabled, + std::move(tracing_controller))) {} cppgc::PageAllocator* GetPageAllocator() override { return v8_platform_->GetPageAllocator(); @@ -48,6 +60,10 @@ class V8_EXPORT DefaultPlatform : public Platform { return v8_platform_->PostJob(priority, std::move(job_task)); } + TracingController* GetTracingController() override { + return v8_platform_->GetTracingController(); + } + protected: static constexpr v8::Isolate* kNoIsolate = nullptr; diff --git a/deps/v8/include/cppgc/heap-consistency.h b/deps/v8/include/cppgc/heap-consistency.h new file mode 100644 index 00000000000000..4a4eb103817e6e --- /dev/null +++ b/deps/v8/include/cppgc/heap-consistency.h @@ -0,0 +1,137 @@ +// Copyright 2020 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. + +#ifndef INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ +#define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ + +#include + +#include "cppgc/internal/write-barrier.h" +#include "cppgc/trace-trait.h" +#include "v8config.h" // NOLINT(build/include_directory) + +namespace cppgc { + +class HeapHandle; + +namespace subtle { + +/** + * **DO NOT USE: Use the appropriate managed types.** + * + * Consistency helpers that aid in maintaining a consistent internal state of + * the garbage collector. + */ +class HeapConsistency final { + public: + using WriteBarrierParams = internal::WriteBarrier::Params; + using WriteBarrierType = internal::WriteBarrier::Type; + + /** + * Gets the required write barrier type for a specific write. + * + * \param slot Slot containing the pointer to the object. The slot itself + * must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + * \param value The pointer to the object. May be an interior pointer to an + * interface of the actual object. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType GetWriteBarrierType( + const void* slot, const void* value, WriteBarrierParams& params) { + return internal::WriteBarrier::GetWriteBarrierType(slot, value, params); + } + + /** + * Gets the required write barrier type for a specific write. + * + * \param slot Slot containing the pointer to some part of an object object + * that has been allocated using `MakeGarbageCollected()`. Does not consider + * the value of `slot`. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType + GetWriteBarrierType(const void* slot, WriteBarrierParams& params) { + return internal::WriteBarrier::GetWriteBarrierType(slot, params); + } + + /** + * Conservative Dijkstra-style write barrier that processes an object if it + * has not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param object The pointer to the object. May be an interior pointer to a + * an interface of the actual object. + */ + static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params, + const void* object) { + internal::WriteBarrier::DijkstraMarkingBarrier(params, object); + } + + /** + * Conservative Dijkstra-style write barrier that processes a range of + * elements if they have not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param heap The corresponding heap. + * \param first_element Pointer to the first element that should be processed. + * The slot itself must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + * \param element_size Size of the element in bytes. + * \param number_of_elements Number of elements that should be processed, + * starting with `first_element`. + * \param trace_callback The trace callback that should be invoked for each + * element if necessary. + */ + static V8_INLINE void DijkstraWriteBarrierRange( + const WriteBarrierParams& params, HeapHandle& heap, + const void* first_element, size_t element_size, size_t number_of_elements, + TraceCallback trace_callback) { + internal::WriteBarrier::DijkstraMarkingBarrierRange( + params, heap, first_element, element_size, number_of_elements, + trace_callback); + } + + /** + * Steele-style write barrier that re-processes an object if it has already + * been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param object The pointer to the object which must point to an object that + * has been allocated using `MakeGarbageCollected()`. Interior pointers are + * not supported. + */ + static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params, + const void* object) { + internal::WriteBarrier::SteeleMarkingBarrier(params, object); + } + + /** + * Generational barrier for maintaining consistency when running with multiple + * generations. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param slot Slot containing the pointer to the object. The slot itself + * must reside in an object that has been allocated using + * `MakeGarbageCollected()`. + */ + static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, + const void* slot) { + internal::WriteBarrier::GenerationalBarrier(params, slot); + } + + private: + HeapConsistency() = delete; +}; + +} // namespace subtle +} // namespace cppgc + +#endif // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ diff --git a/deps/v8/include/cppgc/heap.h b/deps/v8/include/cppgc/heap.h index 04a55598bd853a..fd0512f1f18e16 100644 --- a/deps/v8/include/cppgc/heap.h +++ b/deps/v8/include/cppgc/heap.h @@ -29,6 +29,11 @@ namespace internal { class Heap; } // namespace internal +/** + * Used for additional heap APIs. + */ +class HeapHandle; + class V8_EXPORT Heap { public: /** @@ -51,6 +56,41 @@ class V8_EXPORT Heap { kNoConservativeStackScan, }; + /** + * Specifies supported marking types + */ + enum class MarkingType : uint8_t { + /** + * Atomic stop-the-world marking. This option does not require any write + * barriers but is the most intrusive in terms of jank. + */ + kAtomic, + /** + * Incremental marking, i.e. interleave marking is the rest of the + * application on the same thread. + */ + kIncremental, + /** + * Incremental and concurrent marking. + */ + kIncrementalAndConcurrent + }; + + /** + * Specifies supported sweeping types + */ + enum class SweepingType : uint8_t { + /** + * Atomic stop-the-world sweeping. All of sweeping is performed at once. + */ + kAtomic, + /** + * Incremental and concurrent sweeping. Sweeping is split and interleaved + * with the rest of the application. + */ + kIncrementalAndConcurrent + }; + /** * Constraints for a Heap setup. */ @@ -93,6 +133,16 @@ class V8_EXPORT Heap { */ StackSupport stack_support = StackSupport::kSupportsConservativeStackScan; + /** + * Specifies which types of marking are supported by the heap. + */ + MarkingType marking_support = MarkingType::kIncrementalAndConcurrent; + + /** + * Specifies which types of sweeping are supported by the heap. + */ + SweepingType sweeping_support = SweepingType::kIncrementalAndConcurrent; + /** * Resource constraints specifying various properties that the internal * GC scheduler follows. @@ -132,6 +182,12 @@ class V8_EXPORT Heap { */ AllocationHandle& GetAllocationHandle(); + /** + * \returns the opaque heap handle which may be used to refer to this heap in + * other APIs. Valid as long as the underlying `Heap` is alive. + */ + HeapHandle& GetHeapHandle(); + private: Heap() = default; diff --git a/deps/v8/include/cppgc/internal/api-constants.h b/deps/v8/include/cppgc/internal/api-constants.h index 1303b8b861f648..a70f00710c8b8a 100644 --- a/deps/v8/include/cppgc/internal/api-constants.h +++ b/deps/v8/include/cppgc/internal/api-constants.h @@ -28,7 +28,7 @@ constexpr size_t kGB = kMB * 1024; static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload = 2 * sizeof(uint16_t); // Mask for in-construction bit. -static constexpr size_t kFullyConstructedBitMask = size_t{1}; +static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1}; static constexpr size_t kPageSize = size_t{1} << 17; diff --git a/deps/v8/include/cppgc/internal/pointer-policies.h b/deps/v8/include/cppgc/internal/pointer-policies.h index 50c5d5768fcf84..58f2515a3d7e1b 100644 --- a/deps/v8/include/cppgc/internal/pointer-policies.h +++ b/deps/v8/include/cppgc/internal/pointer-policies.h @@ -28,7 +28,17 @@ struct DijkstraWriteBarrierPolicy { // barrier doesn't break the tri-color invariant. } static void AssigningBarrier(const void* slot, const void* value) { - WriteBarrier::MarkingBarrier(slot, value); + WriteBarrier::Params params; + switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) { + case WriteBarrier::Type::kGenerational: + WriteBarrier::GenerationalBarrier(params, slot); + break; + case WriteBarrier::Type::kMarking: + WriteBarrier::DijkstraMarkingBarrier(params, value); + break; + case WriteBarrier::Type::kNone: + break; + } } }; diff --git a/deps/v8/include/cppgc/internal/write-barrier.h b/deps/v8/include/cppgc/internal/write-barrier.h index 5bf550b02610dd..e3cc4c989d89dd 100644 --- a/deps/v8/include/cppgc/internal/write-barrier.h +++ b/deps/v8/include/cppgc/internal/write-barrier.h @@ -7,6 +7,7 @@ #include "cppgc/internal/api-constants.h" #include "cppgc/internal/process-heap.h" +#include "cppgc/trace-trait.h" #include "v8config.h" // NOLINT(build/include_directory) #if defined(CPPGC_CAGED_HEAP) @@ -14,64 +15,235 @@ #endif namespace cppgc { + +class HeapHandle; + namespace internal { +class WriteBarrierTypeForCagedHeapPolicy; +class WriteBarrierTypeForNonCagedHeapPolicy; + class V8_EXPORT WriteBarrier final { public: - static V8_INLINE void MarkingBarrier(const void* slot, const void* value) { + enum class Type : uint8_t { + kNone, + kMarking, + kGenerational, + }; + + struct Params { +#if V8_ENABLE_CHECKS + Type type = Type::kNone; +#endif // !V8_ENABLE_CHECKS #if defined(CPPGC_CAGED_HEAP) - const uintptr_t start = - reinterpret_cast(value) & - ~(api_constants::kCagedHeapReservationAlignment - 1); - const uintptr_t slot_offset = reinterpret_cast(slot) - start; - if (slot_offset > api_constants::kCagedHeapReservationSize) { - // Check if slot is on stack or value is sentinel or nullptr. This relies - // on the fact that kSentinelPointer is encoded as 0x1. - return; - } + uintptr_t start; - CagedHeapLocalData* local_data = - reinterpret_cast(start); - if (V8_UNLIKELY(local_data->is_marking_in_progress)) { - MarkingBarrierSlow(value); - return; + CagedHeapLocalData& caged_heap() const { + return *reinterpret_cast(start); } + uintptr_t slot_offset; + uintptr_t value_offset; +#endif // CPPGC_CAGED_HEAP + }; + + enum class ValueMode { + kValuePresent, + kNoValuePresent, + }; + + // Returns the required write barrier for a given `slot` and `value`. + static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value, + Params& params); + // Returns the required write barrier for a given `slot`. + static V8_INLINE Type GetWriteBarrierType(const void* slot, Params& params); + + static V8_INLINE void DijkstraMarkingBarrier(const Params& params, + const void* object); + static V8_INLINE void DijkstraMarkingBarrierRange( + const Params& params, HeapHandle& heap, const void* first_element, + size_t element_size, size_t number_of_elements, + TraceCallback trace_callback); + static V8_INLINE void SteeleMarkingBarrier(const Params& params, + const void* object); #if defined(CPPGC_YOUNG_GENERATION) - GenerationalBarrier(local_data, slot, slot_offset, - reinterpret_cast(value) - start); -#endif -#else - if (V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking())) return; + static V8_INLINE void GenerationalBarrier(const Params& params, + const void* slot); +#else // !CPPGC_YOUNG_GENERATION + static V8_INLINE void GenerationalBarrier(const Params& params, + const void* slot) {} +#endif // CPPGC_YOUNG_GENERATION - MarkingBarrierSlowWithSentinelCheck(value); -#endif // CPPGC_CAGED_HEAP - } +#if V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params); +#else // !V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params) {} +#endif // !V8_ENABLE_CHECKS private: WriteBarrier() = delete; - static void MarkingBarrierSlow(const void* value); - static void MarkingBarrierSlowWithSentinelCheck(const void* value); +#if defined(CPPGC_CAGED_HEAP) + using WriteBarrierTypePolicy = WriteBarrierTypeForCagedHeapPolicy; +#else // !CPPGC_CAGED_HEAP + using WriteBarrierTypePolicy = WriteBarrierTypeForNonCagedHeapPolicy; +#endif // !CPPGC_CAGED_HEAP + + static void DijkstraMarkingBarrierSlow(const void* value); + static void DijkstraMarkingBarrierSlowWithSentinelCheck(const void* value); + static void DijkstraMarkingBarrierRangeSlow(HeapHandle& heap_handle, + const void* first_element, + size_t element_size, + size_t number_of_elements, + TraceCallback trace_callback); + static void SteeleMarkingBarrierSlow(const void* value); + static void SteeleMarkingBarrierSlowWithSentinelCheck(const void* value); #if defined(CPPGC_YOUNG_GENERATION) - static V8_INLINE void GenerationalBarrier(CagedHeapLocalData* local_data, - const void* slot, - uintptr_t slot_offset, - uintptr_t value_offset) { - const AgeTable& age_table = local_data->age_table; + static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data, + const AgeTable& ageTable, + const void* slot, uintptr_t value_offset); +#endif // CPPGC_YOUNG_GENERATION +}; - // Bail out if the slot is in young generation. - if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return; +#if defined(CPPGC_CAGED_HEAP) +class WriteBarrierTypeForCagedHeapPolicy final { + public: + template + static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value, + WriteBarrier::Params& params) { + const bool have_caged_heap = + value_mode == WriteBarrier::ValueMode::kValuePresent + ? TryGetCagedHeap(slot, value, params) + : TryGetCagedHeap(slot, slot, params); + if (!have_caged_heap) { + return WriteBarrier::Type::kNone; + } + if (V8_UNLIKELY(params.caged_heap().is_marking_in_progress)) { +#if V8_ENABLE_CHECKS + params.type = WriteBarrier::Type::kMarking; +#endif // !V8_ENABLE_CHECKS + return WriteBarrier::Type::kMarking; + } +#if defined(CPPGC_YOUNG_GENERATION) + params.slot_offset = reinterpret_cast(slot) - params.start; + if (value_mode == WriteBarrier::ValueMode::kValuePresent) { + params.value_offset = reinterpret_cast(value) - params.start; + } else { + params.value_offset = 0; + } +#if V8_ENABLE_CHECKS + params.type = WriteBarrier::Type::kGenerational; +#endif // !V8_ENABLE_CHECKS + return WriteBarrier::Type::kGenerational; +#else // !CPPGC_YOUNG_GENERATION + return WriteBarrier::Type::kNone; +#endif // !CPPGC_YOUNG_GENERATION + } - GenerationalBarrierSlow(local_data, age_table, slot, value_offset); + private: + WriteBarrierTypeForCagedHeapPolicy() = delete; + + static V8_INLINE bool TryGetCagedHeap(const void* slot, const void* value, + WriteBarrier::Params& params) { + params.start = reinterpret_cast(value) & + ~(api_constants::kCagedHeapReservationAlignment - 1); + const uintptr_t slot_offset = + reinterpret_cast(slot) - params.start; + if (slot_offset > api_constants::kCagedHeapReservationSize) { + // Check if slot is on stack or value is sentinel or nullptr. This relies + // on the fact that kSentinelPointer is encoded as 0x1. + return false; + } + return true; + } +}; +#endif // CPPGC_CAGED_HEAP + +class WriteBarrierTypeForNonCagedHeapPolicy final { + public: + template + static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value, + WriteBarrier::Params& params) { + WriteBarrier::Type type = + V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking()) + ? WriteBarrier::Type::kNone + : WriteBarrier::Type::kMarking; +#if V8_ENABLE_CHECKS + params.type = type; +#endif // !V8_ENABLE_CHECKS + return type; } - static void GenerationalBarrierSlow(CagedHeapLocalData* local_data, - const AgeTable& ageTable, - const void* slot, uintptr_t value_offset); -#endif + private: + WriteBarrierTypeForNonCagedHeapPolicy() = delete; }; +// static +WriteBarrier::Type WriteBarrier::GetWriteBarrierType( + const void* slot, const void* value, WriteBarrier::Params& params) { + return WriteBarrierTypePolicy::Get(slot, value, + params); +} + +// static +WriteBarrier::Type WriteBarrier::GetWriteBarrierType( + const void* slot, WriteBarrier::Params& params) { + return WriteBarrierTypePolicy::Get(slot, nullptr, + params); +} + +// static +void WriteBarrier::DijkstraMarkingBarrier(const Params& params, + const void* object) { + CheckParams(Type::kMarking, params); +#if defined(CPPGC_CAGED_HEAP) + // Caged heap already filters out sentinels. + DijkstraMarkingBarrierSlow(object); +#else // !CPPGC_CAGED_HEAP + DijkstraMarkingBarrierSlowWithSentinelCheck(object); +#endif // !CPPGC_CAGED_HEAP +} + +// static +void WriteBarrier::DijkstraMarkingBarrierRange(const Params& params, + HeapHandle& heap, + const void* first_element, + size_t element_size, + size_t number_of_elements, + TraceCallback trace_callback) { + CheckParams(Type::kMarking, params); + DijkstraMarkingBarrierRangeSlow(heap, first_element, element_size, + number_of_elements, trace_callback); +} + +// static +void WriteBarrier::SteeleMarkingBarrier(const Params& params, + const void* object) { + CheckParams(Type::kMarking, params); +#if defined(CPPGC_CAGED_HEAP) + // Caged heap already filters out sentinels. + SteeleMarkingBarrierSlow(object); +#else // !CPPGC_CAGED_HEAP + SteeleMarkingBarrierSlowWithSentinelCheck(object); +#endif // !CPPGC_CAGED_HEAP +} + +#if defined(CPPGC_YOUNG_GENERATION) +// static +void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) { + CheckParams(Type::kGenerational, params); + + const CagedHeapLocalData& local_data = params.caged_heap(); + const AgeTable& age_table = local_data.age_table; + + // Bail out if the slot is in young generation. + if (V8_LIKELY(age_table[params.slot_offset] == AgeTable::Age::kYoung)) return; + + GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset); +} + +#endif // !CPPGC_YOUNG_GENERATION + } // namespace internal } // namespace cppgc diff --git a/deps/v8/include/cppgc/platform.h b/deps/v8/include/cppgc/platform.h index fb0b6b208275c9..571aa80c3b80f1 100644 --- a/deps/v8/include/cppgc/platform.h +++ b/deps/v8/include/cppgc/platform.h @@ -20,6 +20,7 @@ using PageAllocator = v8::PageAllocator; using Task = v8::Task; using TaskPriority = v8::TaskPriority; using TaskRunner = v8::TaskRunner; +using TracingController = v8::TracingController; /** * Platform interface used by Heap. Contains allocators and executors. @@ -113,6 +114,13 @@ class V8_EXPORT Platform { TaskPriority priority, std::unique_ptr job_task) { return nullptr; } + + /** + * Returns an instance of a `TracingController`. This must be non-nullptr. The + * default implementation returns an empty `TracingController` that consumes + * trace data without effect. + */ + virtual TracingController* GetTracingController(); }; /** diff --git a/deps/v8/include/cppgc/prefinalizer.h b/deps/v8/include/cppgc/prefinalizer.h index bde76429ec95c4..9b7bc0e5943870 100644 --- a/deps/v8/include/cppgc/prefinalizer.h +++ b/deps/v8/include/cppgc/prefinalizer.h @@ -34,7 +34,7 @@ class PrefinalizerRegistration final { public: \ static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \ void* object) { \ - static_assert(cppgc::internal::IsGarbageCollectedTypeV, \ + static_assert(cppgc::IsGarbageCollectedTypeV, \ "Only garbage collected objects can have prefinalizers"); \ Class* self = static_cast(object); \ if (liveness_broker.IsHeapObjectAlive(self)) return false; \ diff --git a/deps/v8/include/cppgc/type-traits.h b/deps/v8/include/cppgc/type-traits.h index 4d8ab809c8d439..c7d02db902389c 100644 --- a/deps/v8/include/cppgc/type-traits.h +++ b/deps/v8/include/cppgc/type-traits.h @@ -5,6 +5,8 @@ #ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_ #define INCLUDE_CPPGC_TYPE_TRAITS_H_ +// This file should stay with minimal dependencies to allow embedder to check +// against Oilpan types without including any other parts. #include namespace cppgc { @@ -12,6 +14,14 @@ namespace cppgc { class Visitor; namespace internal { +template +class BasicMember; +struct DijkstraWriteBarrierPolicy; +struct NoWriteBarrierPolicy; +class StrongMemberTag; +class UntracedMemberTag; +class WeakMemberTag; // Pre-C++17 custom implementation of std::void_t. template @@ -25,18 +35,6 @@ using void_t = typename make_void::type; template struct IsWeak : std::false_type {}; -template class U> -struct IsSubclassOfTemplate { - private: - template - static std::true_type SubclassCheck(U*); - static std::false_type SubclassCheck(...); - - public: - static constexpr bool value = - decltype(SubclassCheck(std::declval()))::value; -}; - // IsTraceMethodConst is used to verify that all Trace methods are marked as // const. It is equivalent to IsTraceable but for a non-const object. template @@ -91,16 +89,56 @@ struct IsGarbageCollectedType< static_assert(sizeof(T), "T must be fully defined"); }; +template +struct IsSubclassOfBasicMemberTemplate { + private: + template + static std::true_type SubclassCheck( + BasicMember*); + static std::false_type SubclassCheck(...); + + public: + static constexpr bool value = + decltype(SubclassCheck(std::declval()))::value; +}; + +template ::value> +struct IsMemberType : std::false_type {}; + template -constexpr bool IsGarbageCollectedTypeV = - internal::IsGarbageCollectedType::value; +struct IsMemberType : std::true_type {}; + +template ::value> +struct IsWeakMemberType : std::false_type {}; template -constexpr bool IsGarbageCollectedMixinTypeV = - internal::IsGarbageCollectedMixinType::value; +struct IsWeakMemberType : std::true_type {}; + +template ::value> +struct IsUntracedMemberType : std::false_type {}; + +template +struct IsUntracedMemberType : std::true_type {}; } // namespace internal +template +constexpr bool IsGarbageCollectedMixinTypeV = + internal::IsGarbageCollectedMixinType::value; +template +constexpr bool IsGarbageCollectedTypeV = + internal::IsGarbageCollectedType::value; +template +constexpr bool IsMemberTypeV = internal::IsMemberType::value; +template +constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType::value; +template +constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType::value; template constexpr bool IsWeakV = internal::IsWeak::value; diff --git a/deps/v8/include/cppgc/visitor.h b/deps/v8/include/cppgc/visitor.h index 01f5f20e520b65..74024c3d0e2568 100644 --- a/deps/v8/include/cppgc/visitor.h +++ b/deps/v8/include/cppgc/visitor.h @@ -190,7 +190,7 @@ class V8_EXPORT Visitor { static_assert(internal::IsAllocatedOnCompactableSpace::value, "Only references to objects allocated on compactable spaces " "should be registered as movable slots."); - static_assert(!internal::IsGarbageCollectedMixinTypeV, + static_assert(!IsGarbageCollectedMixinTypeV, "Mixin types do not support compaction."); HandleMovableReference(reinterpret_cast(slot)); } diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl index 6971edd5103a72..42470d88efd577 100644 --- a/deps/v8/include/js_protocol.pdl +++ b/deps/v8/include/js_protocol.pdl @@ -211,21 +211,6 @@ domain Debugger # Exception details. optional Runtime.ExceptionDetails exceptionDetails - # Execute a Wasm Evaluator module on a given call frame. - experimental command executeWasmEvaluator - parameters - # WebAssembly call frame identifier to evaluate on. - CallFrameId callFrameId - # Code of the evaluator module. - binary evaluator - # Terminate execution after timing out (number of milliseconds). - experimental optional Runtime.TimeDelta timeout - returns - # Object wrapper for the evaluation result. - Runtime.RemoteObject result - # Exception details. - optional Runtime.ExceptionDetails exceptionDetails - # Returns possible locations for breakpoint. scriptId in start and end range locations should be # the same. command getPossibleBreakpoints @@ -508,6 +493,7 @@ domain Debugger enum reason ambiguous assert + CSPViolation debugCommand DOM EventListener @@ -1022,8 +1008,9 @@ domain Runtime boolean symbol bigint - wasm - # Object subtype hint. Specified for `object` or `wasm` type values only. + # Object subtype hint. Specified for `object` type values only. + # NOTE: If you change anything here, make sure to also update + # `subtype` in `ObjectPreview` and `PropertyPreview` below. optional enum subtype array null @@ -1042,12 +1029,7 @@ domain Runtime typedarray arraybuffer dataview - i32 - i64 - f32 - f64 - v128 - externref + webassemblymemory # Object class (constructor) name. Specified for `object` type values only. optional string className # Remote object value in case of primitive values or JSON values (if it was requested). @@ -1100,6 +1082,12 @@ domain Runtime iterator generator error + proxy + promise + typedarray + arraybuffer + dataview + webassemblymemory # String representation of the object. optional string description # True iff some of the properties or entries of the original object did not fit. @@ -1142,6 +1130,12 @@ domain Runtime iterator generator error + proxy + promise + typedarray + arraybuffer + dataview + webassemblymemory experimental type EntryPreview extends object properties @@ -1224,6 +1218,10 @@ domain Runtime string origin # Human readable name describing given context. string name + # A system-unique execution context identifier. Unlike the id, this is unique accross + # multiple processes, so can be reliably used to identify specific context while backend + # performs a cross-process navigation. + experimental string uniqueId # Embedder-specific auxiliary data. optional object auxData @@ -1387,6 +1385,9 @@ domain Runtime optional boolean silent # Specifies in which execution context to perform evaluation. If the parameter is omitted the # evaluation will be performed in the context of the inspected page. + # This is mutually exclusive with `uniqueContextId`, which offers an + # alternative way to identify the execution context that is more reliable + # in a multi-process environment. optional ExecutionContextId contextId # Whether the result is expected to be a JSON object that should be sent by value. optional boolean returnByValue @@ -1413,6 +1414,13 @@ domain Runtime # when called with non-callable arguments. This flag bypasses CSP for this # evaluation and allows unsafe-eval. Defaults to true. experimental optional boolean allowUnsafeEvalBlockedByCSP + # An alternative way to specify the execution context to evaluate in. + # Compared to contextId that may be reused accross processes, this is guaranteed to be + # system-unique, so it can be used to prevent accidental evaluation of the expression + # in context different than intended (e.g. as a result of navigation accross process + # boundaries). + # This is mutually exclusive with `contextId`. + experimental optional string uniqueContextId returns # Evaluation result. RemoteObject result diff --git a/deps/v8/include/libplatform/libplatform.h b/deps/v8/include/libplatform/libplatform.h index 1c874ba29b2e94..00de81df887fc4 100644 --- a/deps/v8/include/libplatform/libplatform.h +++ b/deps/v8/include/libplatform/libplatform.h @@ -43,6 +43,17 @@ V8_PLATFORM_EXPORT std::unique_ptr NewDefaultPlatform( InProcessStackDumping::kDisabled, std::unique_ptr tracing_controller = {}); +/** + * The same as NewDefaultPlatform but disables the worker thread pool. + * It must be used with the --single-threaded V8 flag. + */ +V8_PLATFORM_EXPORT std::unique_ptr +NewSingleThreadedDefaultPlatform( + IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, + InProcessStackDumping in_process_stack_dumping = + InProcessStackDumping::kDisabled, + std::unique_ptr tracing_controller = {}); + /** * Returns a new instance of the default v8::JobHandle implementation. * diff --git a/deps/v8/include/libplatform/v8-tracing.h b/deps/v8/include/libplatform/v8-tracing.h index 45822d00f371d4..c7a5c4f9f5fb5a 100644 --- a/deps/v8/include/libplatform/v8-tracing.h +++ b/deps/v8/include/libplatform/v8-tracing.h @@ -125,6 +125,8 @@ class V8_PLATFORM_EXPORT TraceWriter { static TraceWriter* CreateJSONTraceWriter(std::ostream& stream, const std::string& tag); + static TraceWriter* CreateSystemInstrumentationTraceWriter(); + private: // Disallow copy and assign TraceWriter(const TraceWriter&) = delete; diff --git a/deps/v8/include/v8-cppgc.h b/deps/v8/include/v8-cppgc.h index 805eb015e053d3..8a0d9cb9a0737e 100644 --- a/deps/v8/include/v8-cppgc.h +++ b/deps/v8/include/v8-cppgc.h @@ -5,12 +5,55 @@ #ifndef INCLUDE_V8_CPPGC_H_ #define INCLUDE_V8_CPPGC_H_ +#include +#include + +#include "cppgc/custom-space.h" +#include "cppgc/internal/write-barrier.h" #include "cppgc/visitor.h" #include "v8-internal.h" // NOLINT(build/include_directory) -#include "v8.h" // NOLINT(build/include_directory) +#include "v8.h" // NOLINT(build/include_directory) + +namespace cppgc { +class AllocationHandle; +class HeapHandle; +} // namespace cppgc namespace v8 { +namespace internal { +class CppHeap; +} // namespace internal + +struct V8_EXPORT CppHeapCreateParams { + std::vector> custom_spaces; +}; + +/** + * A heap for allocating managed C++ objects. + */ +class V8_EXPORT CppHeap { + public: + virtual ~CppHeap() = default; + + /** + * \returns the opaque handle for allocating objects using + * `MakeGarbageCollected()`. + */ + cppgc::AllocationHandle& GetAllocationHandle(); + + /** + * \returns the opaque heap handle which may be used to refer to this heap in + * other APIs. Valid as long as the underlying `CppHeap` is alive. + */ + cppgc::HeapHandle& GetHeapHandle(); + + private: + CppHeap() = default; + + friend class internal::CppHeap; +}; + class JSVisitor : public cppgc::Visitor { public: explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {} @@ -26,6 +69,64 @@ class JSVisitor : public cppgc::Visitor { virtual void Visit(const TracedReferenceBase& ref) {} }; +/** + * **DO NOT USE: Use the appropriate managed types.** + * + * Consistency helpers that aid in maintaining a consistent internal state of + * the garbage collector. + */ +class JSHeapConsistency final { + public: + using WriteBarrierParams = cppgc::internal::WriteBarrier::Params; + using WriteBarrierType = cppgc::internal::WriteBarrier::Type; + + /** + * Gets the required write barrier type for a specific write. + * + * \param ref The reference being written to. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType GetWriteBarrierType( + const TracedReferenceBase& ref, WriteBarrierParams& params) { + if (ref.IsEmpty()) return WriteBarrierType::kNone; + return cppgc::internal::WriteBarrier::GetWriteBarrierType(&ref, params); + } + + /** + * Conservative Dijkstra-style write barrier that processes an object if it + * has not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params, + cppgc::HeapHandle& heap_handle, + const TracedReferenceBase& ref) { + cppgc::internal::WriteBarrier::CheckParams(WriteBarrierType::kMarking, + params); + DijkstraMarkingBarrierSlow(heap_handle, ref); + } + + /** + * Generational barrier for maintaining consistency when running with multiple + * generations. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, + const TracedReferenceBase& ref) {} + + private: + JSHeapConsistency() = delete; + + static void DijkstraMarkingBarrierSlow(cppgc::HeapHandle&, + const TracedReferenceBase& ref); +}; + } // namespace v8 namespace cppgc { diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h index 86fcf5187701c1..a55518e45930e1 100644 --- a/deps/v8/include/v8-inspector.h +++ b/deps/v8/include/v8-inspector.h @@ -106,6 +106,7 @@ class V8_EXPORT V8StackTrace { virtual int topLineNumber() const = 0; virtual int topColumnNumber() const = 0; virtual StringView topScriptId() const = 0; + virtual int topScriptIdAsInteger() const = 0; virtual StringView topFunctionName() const = 0; virtual ~V8StackTrace() = default; @@ -228,6 +229,10 @@ class V8_EXPORT V8InspectorClient { const StringView& resourceName) { return nullptr; } + + // The caller would defer to generating a random 64 bit integer if + // this method returns 0. + virtual int64_t generateUniqueId() { return 0; } }; // These stack trace ids are intended to be passed between debuggers and be diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index 06846d7005550e..8abbcfb416b2a6 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -207,8 +207,10 @@ class Internals { kNumIsolateDataSlots * kApiSystemPointerSize; static const int kIsolateFastCCallCallerPcOffset = kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; - static const int kIsolateStackGuardOffset = + static const int kIsolateFastApiCallTargetOffset = kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize; + static const int kIsolateStackGuardOffset = + kIsolateFastApiCallTargetOffset + kApiSystemPointerSize; static const int kIsolateRootsOffset = kIsolateStackGuardOffset + 7 * kApiSystemPointerSize; diff --git a/deps/v8/include/v8-metrics.h b/deps/v8/include/v8-metrics.h index 69784dcb0fcbf6..1e2bd50acf6494 100644 --- a/deps/v8/include/v8-metrics.h +++ b/deps/v8/include/v8-metrics.h @@ -10,14 +10,12 @@ namespace v8 { namespace metrics { -// TODO(sartang@microsoft.com): Remove wall_clock_time_in_us. struct WasmModuleDecoded { bool async = false; bool streamed = false; bool success = false; size_t module_size_in_bytes = 0; size_t function_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; @@ -30,7 +28,6 @@ struct WasmModuleCompiled { bool success = false; size_t code_size_in_bytes = 0; size_t liftoff_bailout_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; @@ -38,14 +35,12 @@ struct WasmModuleInstantiated { bool async = false; bool success = false; size_t imported_function_count = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; struct WasmModuleTieredUp { bool lazy = false; size_t code_size_in_bytes = 0; - int64_t wall_clock_time_in_us = -1; int64_t wall_clock_duration_in_us = -1; }; diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index 1f1497f6ccd7f2..e27d26cb692e46 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -225,22 +225,24 @@ class JobHandle { virtual void CancelAndDetach() { Cancel(); } /** - * Returns true if there's currently no work pending and no worker running. - * TODO(etiennep): Deprecate IsCompleted in favor of IsActive once implemented - * by all embedders. + * Returns true if there's any work pending or any worker running. */ - virtual bool IsCompleted() = 0; - virtual bool IsActive() { return !IsCompleted(); } + virtual bool IsActive() = 0; + + // TODO(etiennep): Clean up once all overrides are removed. + V8_DEPRECATED("Use !IsActive() instead.") + virtual bool IsCompleted() { return !IsActive(); } /** * Returns true if associated with a Job and other methods may be called. * Returns false after Join() or Cancel() was called. This may return true * even if no workers are running and IsCompleted() returns true - * TODO(etiennep): Deprecate IsRunning in favor of IsValid once implemented by - * all embedders. */ - virtual bool IsRunning() = 0; - virtual bool IsValid() { return IsRunning(); } + virtual bool IsValid() = 0; + + // TODO(etiennep): Clean up once all overrides are removed. + V8_DEPRECATED("Use IsValid() instead.") + virtual bool IsRunning() { return IsValid(); } /** * Returns true if job priority can be changed. diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 8ecd81cb5dad1a..67c1c84b32b84b 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -9,9 +9,9 @@ // NOTE these macros are used by some of the tool scripts and the build // system so their names cannot be changed without changing the scripts. #define V8_MAJOR_VERSION 8 -#define V8_MINOR_VERSION 8 -#define V8_BUILD_NUMBER 278 -#define V8_PATCH_LEVEL 17 +#define V8_MINOR_VERSION 9 +#define V8_BUILD_NUMBER 255 +#define V8_PATCH_LEVEL 19 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index f6426f8edf2bab..e9235d17955089 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -48,6 +48,8 @@ class Boolean; class BooleanObject; class CFunction; class Context; +class CppHeap; +struct CppHeapCreateParams; class Data; class Date; class External; @@ -89,6 +91,7 @@ class Private; class Uint32; class Utils; class Value; +class WasmMemoryObject; class WasmModuleObject; template class Local; template @@ -433,7 +436,7 @@ static const int kEmbedderFieldsInWeakCallback = 2; template class WeakCallbackInfo { public: - typedef void (*Callback)(const WeakCallbackInfo& data); + using Callback = void (*)(const WeakCallbackInfo& data); WeakCallbackInfo(Isolate* isolate, T* parameter, void* embedder_fields[kEmbedderFieldsInWeakCallback], @@ -627,7 +630,7 @@ template class PersistentBase { template class NonCopyablePersistentTraits { public: - typedef Persistent > NonCopyablePersistent; + using NonCopyablePersistent = Persistent>; static const bool kResetInDestructor = false; template V8_INLINE static void Copy(const Persistent& source, @@ -644,7 +647,7 @@ class NonCopyablePersistentTraits { */ template struct CopyablePersistentTraits { - typedef Persistent > CopyablePersistent; + using CopyablePersistent = Persistent>; static const bool kResetInDestructor = true; template static V8_INLINE void Copy(const Persistent& source, @@ -806,7 +809,7 @@ class Global : public PersistentBase { /* * For compatibility with Chromium's base::Bind (base::Passed). */ - typedef void MoveOnlyTypeForCPP03; + using MoveOnlyTypeForCPP03 = void; Global(const Global&) = delete; void operator=(const Global&) = delete; @@ -1195,7 +1198,7 @@ class TracedReference : public BasicTracedReference { * handle and may deallocate it. The behavior of accessing a handle * for which the handle scope has been deleted is undefined. */ -class V8_EXPORT HandleScope { +class V8_EXPORT V8_NODISCARD HandleScope { public: explicit HandleScope(Isolate* isolate); @@ -1242,12 +1245,11 @@ class V8_EXPORT HandleScope { friend class Context; }; - /** * A HandleScope which first allocates a handle in the current scope * which will be later filled with the escape value. */ -class V8_EXPORT EscapableHandleScope : public HandleScope { +class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope { public: explicit EscapableHandleScope(Isolate* isolate); V8_INLINE ~EscapableHandleScope() = default; @@ -1288,7 +1290,7 @@ class V8_EXPORT EscapableHandleScope : public HandleScope { * are allowed. It can be useful for debugging handle leaks. * Handles can be allocated within inner normal HandleScopes. */ -class V8_EXPORT SealHandleScope { +class V8_EXPORT V8_NODISCARD SealHandleScope { public: explicit SealHandleScope(Isolate* isolate); ~SealHandleScope(); @@ -1309,7 +1311,6 @@ class V8_EXPORT SealHandleScope { int prev_sealed_level_; }; - // --- Special objects --- /** @@ -1422,10 +1423,10 @@ class ScriptOriginOptions { */ class ScriptOrigin { public: - V8_INLINE ScriptOrigin( - Local resource_name, - Local resource_line_offset = Local(), - Local resource_column_offset = Local(), + V8_DEPRECATE_SOON("Use constructor with primitvie C++ types") + V8_INLINE explicit ScriptOrigin( + Local resource_name, Local resource_line_offset, + Local resource_column_offset, Local resource_is_shared_cross_origin = Local(), Local script_id = Local(), Local source_map_url = Local(), @@ -1433,21 +1434,36 @@ class ScriptOrigin { Local is_wasm = Local(), Local is_module = Local(), Local host_defined_options = Local()); + V8_INLINE explicit ScriptOrigin( + Local resource_name, int resource_line_offset = 0, + int resource_column_offset = 0, + bool resource_is_shared_cross_origin = false, int script_id = -1, + Local source_map_url = Local(), + bool resource_is_opaque = false, bool is_wasm = false, + bool is_module = false, + Local host_defined_options = Local()); V8_INLINE Local ResourceName() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ResourceLineOffset() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ResourceColumnOffset() const; + V8_DEPRECATE_SOON("Use getter with primitvie C++ types.") V8_INLINE Local ScriptID() const; + V8_INLINE int LineOffset() const; + V8_INLINE int ColumnOffset() const; + V8_INLINE int ScriptId() const; V8_INLINE Local SourceMapUrl() const; V8_INLINE Local HostDefinedOptions() const; V8_INLINE ScriptOriginOptions Options() const { return options_; } private: + Isolate* isolate_; Local resource_name_; - Local resource_line_offset_; - Local resource_column_offset_; + int resource_line_offset_; + int resource_column_offset_; ScriptOriginOptions options_; - Local script_id_; + int script_id_; Local source_map_url_; Local host_defined_options_; }; @@ -1506,6 +1522,43 @@ class V8_EXPORT Location { int column_number_; }; +/** + * A fixed-sized array with elements of type Data. + */ +class V8_EXPORT FixedArray : public Data { + public: + int Length() const; + Local Get(Local context, int i) const; +}; + +class V8_EXPORT ModuleRequest : public Data { + public: + /** + * Returns the module specifier for this ModuleRequest. + */ + Local GetSpecifier() const; + + /** + * Returns the source code offset of this module request. + * Use Module::SourceOffsetToLocation to convert this to line/column numbers. + */ + int GetSourceOffset() const; + + /** + * Contains the import assertions for this request in the form: + * [key1, value1, source_offset1, key2, value2, source_offset2, ...]. + * The keys and values are of type v8::String, and the source offsets are of + * type Int32. Use Module::SourceOffsetToLocation to convert the source + * offsets to Locations with line/column numbers. + */ + Local GetImportAssertions() const; + + V8_INLINE static ModuleRequest* Cast(Data* data); + + private: + static void CheckCast(Data* obj); +}; + /** * A compiled JavaScript module. */ @@ -1540,28 +1593,48 @@ class V8_EXPORT Module : public Data { /** * Returns the number of modules requested by this module. */ + V8_DEPRECATE_SOON("Use Module::GetModuleRequests() and FixedArray::Length().") int GetModuleRequestsLength() const; /** * Returns the ith module specifier in this module. * i must be < GetModuleRequestsLength() and >= 0. */ + V8_DEPRECATE_SOON( + "Use Module::GetModuleRequests() and ModuleRequest::GetSpecifier().") Local GetModuleRequest(int i) const; /** * Returns the source location (line number and column number) of the ith * module specifier's first occurrence in this module. */ + V8_DEPRECATE_SOON( + "Use Module::GetModuleRequests(), ModuleRequest::GetSourceOffset(), and " + "Module::SourceOffsetToLocation().") Location GetModuleRequestLocation(int i) const; + /** + * Returns the ModuleRequests for this module. + */ + Local GetModuleRequests() const; + + /** + * For the given source text offset in this module, returns the corresponding + * Location with line and column numbers. + */ + Location SourceOffsetToLocation(int offset) const; + /** * Returns the identity hash for this object. */ int GetIdentityHash() const; - typedef MaybeLocal (*ResolveCallback)(Local context, - Local specifier, - Local referrer); + using ResolveCallback V8_DEPRECATE_SOON("Use ResolveModuleCallback") = + MaybeLocal (*)(Local context, Local specifier, + Local referrer); + using ResolveModuleCallback = MaybeLocal (*)( + Local context, Local specifier, + Local import_assertions, Local referrer); /** * Instantiates the module and its dependencies. @@ -1570,8 +1643,13 @@ class V8_EXPORT Module : public Data { * instantiation. (In the case where the callback throws an exception, that * exception is propagated.) */ + V8_DEPRECATE_SOON( + "Use the version of InstantiateModule that takes a ResolveModuleCallback " + "parameter") V8_WARN_UNUSED_RESULT Maybe InstantiateModule(Local context, ResolveCallback callback); + V8_WARN_UNUSED_RESULT Maybe InstantiateModule( + Local context, ResolveModuleCallback callback); /** * Evaluates the module and its dependencies. @@ -1630,8 +1708,8 @@ class V8_EXPORT Module : public Data { * exception was thrown) and return an empy MaybeLocal to indicate falure * (where an exception was thrown). */ - typedef MaybeLocal (*SyntheticModuleEvaluationSteps)( - Local context, Local module); + using SyntheticModuleEvaluationSteps = + MaybeLocal (*)(Local context, Local module); /** * Creates a new SyntheticModule with the specified export names, where @@ -1654,7 +1732,7 @@ class V8_EXPORT Module : public Data { */ V8_WARN_UNUSED_RESULT Maybe SetSyntheticModuleExport( Isolate* isolate, Local export_name, Local export_value); - V8_DEPRECATE_SOON( + V8_DEPRECATED( "Use the preceding SetSyntheticModuleExport with an Isolate parameter, " "instead of the one that follows. The former will throw a runtime " "error if called for an export that doesn't exist (as per spec); " @@ -1694,6 +1772,7 @@ class V8_EXPORT Script { Local GetUnboundScript(); }; +enum class ScriptType { kClassic, kModule }; /** * For compiling scripts. @@ -1746,8 +1825,8 @@ class V8_EXPORT ScriptCompiler { // Source takes ownership of CachedData. V8_INLINE Source(Local source_string, const ScriptOrigin& origin, CachedData* cached_data = nullptr); - V8_INLINE Source(Local source_string, - CachedData* cached_data = nullptr); + V8_INLINE explicit Source(Local source_string, + CachedData* cached_data = nullptr); V8_INLINE ~Source(); // Ownership of the CachedData or its buffers is *not* transferred to the @@ -1768,8 +1847,8 @@ class V8_EXPORT ScriptCompiler { // Origin information Local resource_name; - Local resource_line_offset; - Local resource_column_offset; + int resource_line_offset; + int resource_column_offset; ScriptOriginOptions resource_options; Local source_map_url; Local host_defined_options; @@ -1839,11 +1918,9 @@ class V8_EXPORT ScriptCompiler { public: enum Encoding { ONE_BYTE, TWO_BYTE, UTF8 }; -#if defined(_MSC_VER) && _MSC_VER >= 1910 /* Disable on VS2015 */ - V8_DEPRECATE_SOON( + V8_DEPRECATED( "This class takes ownership of source_stream, so use the constructor " "taking a unique_ptr to make these semantics clearer") -#endif StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); StreamedSource(std::unique_ptr source_stream, Encoding encoding); @@ -1948,12 +2025,13 @@ class V8_EXPORT ScriptCompiler { * This API allows to start the streaming with as little data as possible, and * the remaining data (for example, the ScriptOrigin) is passed to Compile. */ - V8_DEPRECATE_SOON("Use ScriptCompiler::StartStreamingScript instead.") + V8_DEPRECATED("Use ScriptCompiler::StartStreaming instead.") static ScriptStreamingTask* StartStreamingScript( Isolate* isolate, StreamedSource* source, CompileOptions options = kNoCompileOptions); - static ScriptStreamingTask* StartStreaming(Isolate* isolate, - StreamedSource* source); + static ScriptStreamingTask* StartStreaming( + Isolate* isolate, StreamedSource* source, + ScriptType type = ScriptType::kClassic); /** * Compiles a streamed script (bound to current context). @@ -1998,6 +2076,17 @@ class V8_EXPORT ScriptCompiler { CompileOptions options = kNoCompileOptions, NoCacheReason no_cache_reason = kNoCacheNoReason); + /** + * Compiles a streamed module script. + * + * This can only be called after the streaming has finished + * (ScriptStreamingTask has been run). V8 doesn't construct the source string + * during streaming, so the embedder needs to pass the full source here. + */ + static V8_WARN_UNUSED_RESULT MaybeLocal CompileModule( + Local context, StreamedSource* v8_source, + Local full_source_string, const ScriptOrigin& origin); + /** * Compile a function for a given context. This is equivalent to running * @@ -2873,6 +2962,11 @@ class V8_EXPORT Value : public Data { */ bool IsProxy() const; + /** + * Returns true if this value is a WasmMemoryObject. + */ + bool IsWasmMemoryObject() const; + /** * Returns true if this value is a WasmModuleObject. */ @@ -2995,11 +3089,11 @@ class V8_EXPORT Primitive : public Value { }; class V8_EXPORT Boolean : public Primitive { public: bool Value() const; - V8_INLINE static Boolean* Cast(v8::Value* obj); + V8_INLINE static Boolean* Cast(v8::Data* data); V8_INLINE static Local New(Isolate* isolate, bool value); private: - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3017,10 +3111,10 @@ class V8_EXPORT Name : public Primitive { */ int GetIdentityHash(); - V8_INLINE static Name* Cast(Value* obj); + V8_INLINE static Name* Cast(Data* data); private: - static void CheckCast(Value* obj); + static void CheckCast(Data* that); }; /** @@ -3133,14 +3227,6 @@ class V8_EXPORT String : public Name { */ V8_INLINE static Local Empty(Isolate* isolate); - /** - * Returns true if the string is external two-byte. - * - */ - V8_DEPRECATED( - "Use String::IsExternalTwoByte() or String::IsExternalOneByte()") - bool IsExternal() const; - /** * Returns true if the string is both external and two-byte. */ @@ -3276,7 +3362,7 @@ class V8_EXPORT String : public Name { */ const ExternalOneByteStringResource* GetExternalOneByteStringResource() const; - V8_INLINE static String* Cast(v8::Value* obj); + V8_INLINE static String* Cast(v8::Data* data); /** * Allocates a new string from a UTF-8 literal. This is equivalent to calling @@ -3433,7 +3519,7 @@ class V8_EXPORT String : public Name { const char* literal, NewStringType type, int length); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; // Zero-length string specialization (templated string size includes @@ -3454,7 +3540,7 @@ class V8_EXPORT Symbol : public Name { */ Local Description() const; - V8_DEPRECATE_SOON("Use Symbol::Description()") + V8_DEPRECATED("Use Symbol::Description()") Local Name() const { return Description(); } /** @@ -3493,11 +3579,11 @@ class V8_EXPORT Symbol : public Name { static Local GetToStringTag(Isolate* isolate); static Local GetUnscopables(Isolate* isolate); - V8_INLINE static Symbol* Cast(Value* obj); + V8_INLINE static Symbol* Cast(Data* data); private: Symbol(); - static void CheckCast(Value* obj); + static void CheckCast(Data* that); }; @@ -3546,10 +3632,11 @@ class V8_EXPORT Number : public Primitive { public: double Value() const; static Local New(Isolate* isolate, double value); - V8_INLINE static Number* Cast(v8::Value* obj); + V8_INLINE static Number* Cast(v8::Data* data); + private: Number(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3561,10 +3648,11 @@ class V8_EXPORT Integer : public Number { static Local New(Isolate* isolate, int32_t value); static Local NewFromUnsigned(Isolate* isolate, uint32_t value); int64_t Value() const; - V8_INLINE static Integer* Cast(v8::Value* obj); + V8_INLINE static Integer* Cast(v8::Data* data); + private: Integer(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3574,11 +3662,11 @@ class V8_EXPORT Integer : public Number { class V8_EXPORT Int32 : public Integer { public: int32_t Value() const; - V8_INLINE static Int32* Cast(v8::Value* obj); + V8_INLINE static Int32* Cast(v8::Data* data); private: Int32(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; @@ -3588,11 +3676,11 @@ class V8_EXPORT Int32 : public Integer { class V8_EXPORT Uint32 : public Integer { public: uint32_t Value() const; - V8_INLINE static Uint32* Cast(v8::Value* obj); + V8_INLINE static Uint32* Cast(v8::Data* data); private: Uint32(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; /** @@ -3643,11 +3731,11 @@ class V8_EXPORT BigInt : public Primitive { */ void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const; - V8_INLINE static BigInt* Cast(v8::Value* obj); + V8_INLINE static BigInt* Cast(v8::Data* data); private: BigInt(); - static void CheckCast(v8::Value* obj); + static void CheckCast(v8::Data* that); }; /** @@ -3669,23 +3757,17 @@ enum PropertyAttribute { * setting|getting a particular property. See Object and ObjectTemplate's * method SetAccessor. */ -typedef void (*AccessorGetterCallback)( - Local property, - const PropertyCallbackInfo& info); -typedef void (*AccessorNameGetterCallback)( - Local property, - const PropertyCallbackInfo& info); - - -typedef void (*AccessorSetterCallback)( - Local property, - Local value, - const PropertyCallbackInfo& info); -typedef void (*AccessorNameSetterCallback)( - Local property, - Local value, - const PropertyCallbackInfo& info); +using AccessorGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); +using AccessorNameGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); +using AccessorSetterCallback = void (*)(Local property, + Local value, + const PropertyCallbackInfo& info); +using AccessorNameSetterCallback = + void (*)(Local property, Local value, + const PropertyCallbackInfo& info); /** * Access control specifications. @@ -4537,8 +4619,7 @@ class PropertyCallbackInfo { internal::Address* args_; }; - -typedef void (*FunctionCallback)(const FunctionCallbackInfo& info); +using FunctionCallback = void (*)(const FunctionCallbackInfo& info); enum class ConstructorBehavior { kThrow, kAllow }; @@ -4899,6 +4980,22 @@ class V8_EXPORT CompiledWasmModule { const std::string source_url_; }; +// An instance of WebAssembly.Memory. +class V8_EXPORT WasmMemoryObject : public Object { + public: + WasmMemoryObject() = delete; + + /** + * Returns underlying ArrayBuffer. + */ + Local Buffer(); + + V8_INLINE static WasmMemoryObject* Cast(Value* obj); + + private: + static void CheckCast(Value* object); +}; + // An instance of WebAssembly.Module. class V8_EXPORT WasmModuleObject : public Object { public: @@ -6239,8 +6336,8 @@ class V8_EXPORT Template : public Data { * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyGetterCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyGetterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for set requests on an object. @@ -6263,9 +6360,9 @@ typedef void (*GenericNamedPropertyGetterCallback)( * See also * `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertySetterCallback)( - Local property, Local value, - const PropertyCallbackInfo& info); +using GenericNamedPropertySetterCallback = + void (*)(Local property, Local value, + const PropertyCallbackInfo& info); /** * Intercepts all requests that query the attributes of the @@ -6288,8 +6385,8 @@ typedef void (*GenericNamedPropertySetterCallback)( * See also * `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertyQueryCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyQueryCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Interceptor for delete requests on an object. @@ -6312,8 +6409,8 @@ typedef void (*GenericNamedPropertyQueryCallback)( * * See also `ObjectTemplate::SetHandler.` */ -typedef void (*GenericNamedPropertyDeleterCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyDeleterCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * Returns an array containing the names of the properties the named @@ -6321,8 +6418,8 @@ typedef void (*GenericNamedPropertyDeleterCallback)( * * Note: The values in the array must be of type v8::Name. */ -typedef void (*GenericNamedPropertyEnumeratorCallback)( - const PropertyCallbackInfo& info); +using GenericNamedPropertyEnumeratorCallback = + void (*)(const PropertyCallbackInfo& info); /** * Interceptor for defineProperty requests on an object. @@ -6344,9 +6441,9 @@ typedef void (*GenericNamedPropertyEnumeratorCallback)( * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyDefinerCallback)( - Local property, const PropertyDescriptor& desc, - const PropertyCallbackInfo& info); +using GenericNamedPropertyDefinerCallback = + void (*)(Local property, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); /** * Interceptor for getOwnPropertyDescriptor requests on an object. @@ -6367,37 +6464,33 @@ typedef void (*GenericNamedPropertyDefinerCallback)( * * See also `ObjectTemplate::SetHandler`. */ -typedef void (*GenericNamedPropertyDescriptorCallback)( - Local property, const PropertyCallbackInfo& info); +using GenericNamedPropertyDescriptorCallback = + void (*)(Local property, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyGetterCallback`. */ -typedef void (*IndexedPropertyGetterCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyGetterCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertySetterCallback`. */ -typedef void (*IndexedPropertySetterCallback)( - uint32_t index, - Local value, - const PropertyCallbackInfo& info); +using IndexedPropertySetterCallback = + void (*)(uint32_t index, Local value, + const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyQueryCallback`. */ -typedef void (*IndexedPropertyQueryCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyQueryCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDeleterCallback`. */ -typedef void (*IndexedPropertyDeleterCallback)( - uint32_t index, - const PropertyCallbackInfo& info); +using IndexedPropertyDeleterCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * Returns an array containing the indices of the properties the indexed @@ -6405,21 +6498,21 @@ typedef void (*IndexedPropertyDeleterCallback)( * * Note: The values in the array must be uint32_t. */ -typedef void (*IndexedPropertyEnumeratorCallback)( - const PropertyCallbackInfo& info); +using IndexedPropertyEnumeratorCallback = + void (*)(const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDefinerCallback`. */ -typedef void (*IndexedPropertyDefinerCallback)( - uint32_t index, const PropertyDescriptor& desc, - const PropertyCallbackInfo& info); +using IndexedPropertyDefinerCallback = + void (*)(uint32_t index, const PropertyDescriptor& desc, + const PropertyCallbackInfo& info); /** * See `v8::GenericNamedPropertyDescriptorCallback`. */ -typedef void (*IndexedPropertyDescriptorCallback)( - uint32_t index, const PropertyCallbackInfo& info); +using IndexedPropertyDescriptorCallback = + void (*)(uint32_t index, const PropertyCallbackInfo& info); /** * Access type specification. @@ -6437,9 +6530,9 @@ enum AccessType { * Returns true if the given context should be allowed to access the given * object. */ -typedef bool (*AccessCheckCallback)(Local accessing_context, - Local accessed_object, - Local data); +using AccessCheckCallback = bool (*)(Local accessing_context, + Local accessed_object, + Local data); /** * A FunctionTemplate is used to create functions at runtime. There @@ -7230,36 +7323,11 @@ class V8_EXPORT ResourceConstraints { initial_young_generation_size_ = initial_size; } - /** - * Deprecated functions. Do not use in new code. - */ - V8_DEPRECATED("Use code_range_size_in_bytes.") - size_t code_range_size() const { return code_range_size_ / kMB; } - V8_DEPRECATED("Use set_code_range_size_in_bytes.") - void set_code_range_size(size_t limit_in_mb) { - code_range_size_ = limit_in_mb * kMB; - } - V8_DEPRECATED("Use max_young_generation_size_in_bytes.") - size_t max_semi_space_size_in_kb() const; - V8_DEPRECATED("Use set_max_young_generation_size_in_bytes.") - void set_max_semi_space_size_in_kb(size_t limit_in_kb); - V8_DEPRECATED("Use max_old_generation_size_in_bytes.") - size_t max_old_space_size() const { return max_old_generation_size_ / kMB; } - V8_DEPRECATED("Use set_max_old_generation_size_in_bytes.") - void set_max_old_space_size(size_t limit_in_mb) { - max_old_generation_size_ = limit_in_mb * kMB; - } - V8_DEPRECATED("Zone does not pool memory any more.") - size_t max_zone_pool_size() const { return max_zone_pool_size_; } - V8_DEPRECATED("Zone does not pool memory any more.") - void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; } - private: static constexpr size_t kMB = 1048576u; size_t code_range_size_ = 0; size_t max_old_generation_size_ = 0; size_t max_young_generation_size_ = 0; - size_t max_zone_pool_size_ = 0; size_t initial_old_generation_size_ = 0; size_t initial_young_generation_size_ = 0; uint32_t* stack_limit_ = nullptr; @@ -7268,19 +7336,18 @@ class V8_EXPORT ResourceConstraints { // --- Exceptions --- +using FatalErrorCallback = void (*)(const char* location, const char* message); -typedef void (*FatalErrorCallback)(const char* location, const char* message); - -typedef void (*OOMErrorCallback)(const char* location, bool is_heap_oom); +using OOMErrorCallback = void (*)(const char* location, bool is_heap_oom); -typedef void (*DcheckErrorCallback)(const char* file, int line, - const char* message); +using DcheckErrorCallback = void (*)(const char* file, int line, + const char* message); -typedef void (*MessageCallback)(Local message, Local data); +using MessageCallback = void (*)(Local message, Local data); // --- Tracing --- -typedef void (*LogEventCallback)(const char* name, int event); +using LogEventCallback = void (*)(const char* name, int event); /** * Create new error objects by calling the corresponding error object @@ -7314,14 +7381,12 @@ class V8_EXPORT Exception { // --- Counters Callbacks --- -typedef int* (*CounterLookupCallback)(const char* name); +using CounterLookupCallback = int* (*)(const char* name); -typedef void* (*CreateHistogramCallback)(const char* name, - int min, - int max, - size_t buckets); +using CreateHistogramCallback = void* (*)(const char* name, int min, int max, + size_t buckets); -typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); +using AddHistogramSampleCallback = void (*)(void* histogram, int sample); // --- Crashkeys Callback --- enum class CrashKeyId { @@ -7332,11 +7397,11 @@ enum class CrashKeyId { kDumpType, }; -typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); +using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value); // --- Enter/Leave Script Callback --- -typedef void (*BeforeCallEnteredCallback)(Isolate*); -typedef void (*CallCompletedCallback)(Isolate*); +using BeforeCallEnteredCallback = void (*)(Isolate*); +using CallCompletedCallback = void (*)(Isolate*); /** * HostImportModuleDynamicallyCallback is called when we require the @@ -7358,7 +7423,7 @@ typedef void (*CallCompletedCallback)(Isolate*); * fails (e.g. due to stack overflow), the embedder must propagate * that exception by returning an empty MaybeLocal. */ -typedef MaybeLocal (*HostImportModuleDynamicallyCallback)( +using HostImportModuleDynamicallyCallback = MaybeLocal (*)( Local context, Local referrer, Local specifier); @@ -7372,9 +7437,9 @@ typedef MaybeLocal (*HostImportModuleDynamicallyCallback)( * The embedder should use v8::Object::CreateDataProperty to add properties on * the meta object. */ -typedef void (*HostInitializeImportMetaObjectCallback)(Local context, - Local module, - Local meta); +using HostInitializeImportMetaObjectCallback = void (*)(Local context, + Local module, + Local meta); /** * PrepareStackTraceCallback is called when the stack property of an error is @@ -7383,9 +7448,9 @@ typedef void (*HostInitializeImportMetaObjectCallback)(Local context, * |sites| is an array of call sites, specified in * https://v8.dev/docs/stack-trace-api */ -typedef MaybeLocal (*PrepareStackTraceCallback)(Local context, - Local error, - Local sites); +using PrepareStackTraceCallback = MaybeLocal (*)(Local context, + Local error, + Local sites); /** * PromiseHook with type kInit is called when a new promise is @@ -7405,8 +7470,8 @@ typedef MaybeLocal (*PrepareStackTraceCallback)(Local context, */ enum class PromiseHookType { kInit, kResolve, kBefore, kAfter }; -typedef void (*PromiseHook)(PromiseHookType type, Local promise, - Local parent); +using PromiseHook = void (*)(PromiseHookType type, Local promise, + Local parent); // --- Promise Reject Callback --- enum PromiseRejectEvent { @@ -7432,12 +7497,11 @@ class PromiseRejectMessage { Local value_; }; -typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); +using PromiseRejectCallback = void (*)(PromiseRejectMessage message); // --- Microtasks Callbacks --- -typedef void (*MicrotasksCompletedCallback)(Isolate*); -typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); -typedef void (*MicrotaskCallback)(void* data); +using MicrotasksCompletedCallbackWithData = void (*)(Isolate*, void*); +using MicrotaskCallback = void (*)(void* data); /** * Policy for running microtasks: @@ -7541,7 +7605,7 @@ class V8_EXPORT MicrotaskQueue { * kDoNotRunMicrotasks should be used to annotate calls not intended to trigger * microtasks. */ -class V8_EXPORT MicrotasksScope { +class V8_EXPORT V8_NODISCARD MicrotasksScope { public: enum Type { kRunMicrotasks, kDoNotRunMicrotasks }; @@ -7574,11 +7638,9 @@ class V8_EXPORT MicrotasksScope { bool run_; }; - // --- Failed Access Check Callback --- -typedef void (*FailedAccessCheckCallback)(Local target, - AccessType type, - Local data); +using FailedAccessCheckCallback = void (*)(Local target, + AccessType type, Local data); // --- AllowCodeGenerationFromStrings callbacks --- @@ -7586,8 +7648,8 @@ typedef void (*FailedAccessCheckCallback)(Local target, * Callback to check if code generation from strings is allowed. See * Context::AllowCodeGenerationFromStrings. */ -typedef bool (*AllowCodeGenerationFromStringsCallback)(Local context, - Local source); +using AllowCodeGenerationFromStringsCallback = bool (*)(Local context, + Local source); struct ModifyCodeGenerationFromStringsResult { // If true, proceed with the codegen algorithm. Otherwise, block it. @@ -7602,36 +7664,36 @@ struct ModifyCodeGenerationFromStringsResult { * Callback to check if codegen is allowed from a source object, and convert * the source to string if necessary. See: ModifyCodeGenerationFromStrings. */ -typedef ModifyCodeGenerationFromStringsResult ( - *ModifyCodeGenerationFromStringsCallback)(Local context, +using ModifyCodeGenerationFromStringsCallback = + ModifyCodeGenerationFromStringsResult (*)(Local context, Local source); -typedef ModifyCodeGenerationFromStringsResult ( - *ModifyCodeGenerationFromStringsCallback2)(Local context, - Local source, - bool is_code_like); +using ModifyCodeGenerationFromStringsCallback2 = + ModifyCodeGenerationFromStringsResult (*)(Local context, + Local source, + bool is_code_like); // --- WebAssembly compilation callbacks --- -typedef bool (*ExtensionCallback)(const FunctionCallbackInfo&); +using ExtensionCallback = bool (*)(const FunctionCallbackInfo&); -typedef bool (*AllowWasmCodeGenerationCallback)(Local context, - Local source); +using AllowWasmCodeGenerationCallback = bool (*)(Local context, + Local source); // --- Callback for APIs defined on v8-supported objects, but implemented // by the embedder. Example: WebAssembly.{compile|instantiate}Streaming --- -typedef void (*ApiImplementationCallback)(const FunctionCallbackInfo&); +using ApiImplementationCallback = void (*)(const FunctionCallbackInfo&); // --- Callback for WebAssembly.compileStreaming --- -typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo&); +using WasmStreamingCallback = void (*)(const FunctionCallbackInfo&); // --- Callback for checking if WebAssembly threads are enabled --- -typedef bool (*WasmThreadsEnabledCallback)(Local context); +using WasmThreadsEnabledCallback = bool (*)(Local context); // --- Callback for loading source map file for Wasm profiling support -typedef Local (*WasmLoadSourceMapCallback)(Isolate* isolate, - const char* name); +using WasmLoadSourceMapCallback = Local (*)(Isolate* isolate, + const char* name); // --- Callback for checking if WebAssembly Simd is enabled --- -typedef bool (*WasmSimdEnabledCallback)(Local context); +using WasmSimdEnabledCallback = bool (*)(Local context); // --- Garbage Collection Callbacks --- @@ -7675,9 +7737,9 @@ enum GCCallbackFlags { kGCCallbackScheduleIdleGarbageCollection = 1 << 6, }; -typedef void (*GCCallback)(GCType type, GCCallbackFlags flags); +using GCCallback = void (*)(GCType type, GCCallbackFlags flags); -typedef void (*InterruptCallback)(Isolate* isolate, void* data); +using InterruptCallback = void (*)(Isolate* isolate, void* data); /** * This callback is invoked when the heap size is close to the heap limit and @@ -7686,8 +7748,8 @@ typedef void (*InterruptCallback)(Isolate* isolate, void* data); * than the current_heap_limit. The initial heap limit is the limit that was * set after heap setup. */ -typedef size_t (*NearHeapLimitCallback)(void* data, size_t current_heap_limit, - size_t initial_heap_limit); +using NearHeapLimitCallback = size_t (*)(void* data, size_t current_heap_limit, + size_t initial_heap_limit); /** * Collection of shared per-process V8 memory information. @@ -7941,14 +8003,14 @@ enum JitCodeEventOptions { * * \param event code add, move or removal event. */ -typedef void (*JitCodeEventHandler)(const JitCodeEvent* event); +using JitCodeEventHandler = void (*)(const JitCodeEvent* event); /** * Callback function passed to SetUnhandledExceptionCallback. */ #if defined(V8_OS_WIN) -typedef int (*UnhandledExceptionCallback)( - _EXCEPTION_POINTERS* exception_pointers); +using UnhandledExceptionCallback = + int (*)(_EXCEPTION_POINTERS* exception_pointers); #endif /** @@ -8175,8 +8237,8 @@ class V8_EXPORT EmbedderHeapTracer { * serialized verbatim. */ struct SerializeInternalFieldsCallback { - typedef StartupData (*CallbackFunction)(Local holder, int index, - void* data); + using CallbackFunction = StartupData (*)(Local holder, int index, + void* data); SerializeInternalFieldsCallback(CallbackFunction function = nullptr, void* data_arg = nullptr) : callback(function), data(data_arg) {} @@ -8185,15 +8247,15 @@ struct SerializeInternalFieldsCallback { }; // Note that these fields are called "internal fields" in the API and called // "embedder fields" within V8. -typedef SerializeInternalFieldsCallback SerializeEmbedderFieldsCallback; +using SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback; /** * Callback and supporting data used to implement embedder logic to deserialize * internal fields. */ struct DeserializeInternalFieldsCallback { - typedef void (*CallbackFunction)(Local holder, int index, - StartupData payload, void* data); + using CallbackFunction = void (*)(Local holder, int index, + StartupData payload, void* data); DeserializeInternalFieldsCallback(CallbackFunction function = nullptr, void* data_arg = nullptr) : callback(function), data(data_arg) {} @@ -8201,7 +8263,7 @@ struct DeserializeInternalFieldsCallback { void* data); void* data; }; -typedef DeserializeInternalFieldsCallback DeserializeEmbedderFieldsCallback; +using DeserializeEmbedderFieldsCallback = DeserializeInternalFieldsCallback; /** * Controls how the default MeasureMemoryDelegate reports the result of @@ -8277,26 +8339,15 @@ class V8_EXPORT Isolate { /** * Initial configuration parameters for a new Isolate. */ - struct CreateParams { - CreateParams() - : code_event_handler(nullptr), - snapshot_blob(nullptr), - counter_lookup_callback(nullptr), - create_histogram_callback(nullptr), - add_histogram_sample_callback(nullptr), - array_buffer_allocator(nullptr), - array_buffer_allocator_shared(), - external_references(nullptr), - allow_atomics_wait(true), - only_terminate_in_safe_scope(false), - embedder_wrapper_type_index(-1), - embedder_wrapper_object_index(-1) {} + struct V8_EXPORT CreateParams { + CreateParams(); + ~CreateParams(); /** * Allows the host application to provide the address of a function that is * notified each time code is added, moved or removed. */ - JitCodeEventHandler code_event_handler; + JitCodeEventHandler code_event_handler = nullptr; /** * ResourceConstraints to use for the new Isolate. @@ -8306,14 +8357,13 @@ class V8_EXPORT Isolate { /** * Explicitly specify a startup snapshot blob. The embedder owns the blob. */ - StartupData* snapshot_blob; - + StartupData* snapshot_blob = nullptr; /** * Enables the host application to provide a mechanism for recording * statistics counters. */ - CounterLookupCallback counter_lookup_callback; + CounterLookupCallback counter_lookup_callback = nullptr; /** * Enables the host application to provide a mechanism for recording @@ -8321,8 +8371,8 @@ class V8_EXPORT Isolate { * histogram which will later be passed to the AddHistogramSample * function. */ - CreateHistogramCallback create_histogram_callback; - AddHistogramSampleCallback add_histogram_sample_callback; + CreateHistogramCallback create_histogram_callback = nullptr; + AddHistogramSampleCallback add_histogram_sample_callback = nullptr; /** * The ArrayBuffer::Allocator to use for allocating and freeing the backing @@ -8333,7 +8383,7 @@ class V8_EXPORT Isolate { * to the allocator, in order to facilitate lifetime * management for the allocator instance. */ - ArrayBuffer::Allocator* array_buffer_allocator; + ArrayBuffer::Allocator* array_buffer_allocator = nullptr; std::shared_ptr array_buffer_allocator_shared; /** @@ -8342,34 +8392,57 @@ class V8_EXPORT Isolate { * deserialization. This array and its content must stay valid for the * entire lifetime of the isolate. */ - const intptr_t* external_references; + const intptr_t* external_references = nullptr; /** * Whether calling Atomics.wait (a function that may block) is allowed in * this isolate. This can also be configured via SetAllowAtomicsWait. */ - bool allow_atomics_wait; + bool allow_atomics_wait = true; /** * Termination is postponed when there is no active SafeForTerminationScope. */ - bool only_terminate_in_safe_scope; + bool only_terminate_in_safe_scope = false; /** * The following parameters describe the offsets for addressing type info * for wrapped API objects and are used by the fast C API * (for details see v8-fast-api-calls.h). */ - int embedder_wrapper_type_index; - int embedder_wrapper_object_index; - }; + int embedder_wrapper_type_index = -1; + int embedder_wrapper_object_index = -1; + + /** + * If parameters are set, V8 creates a managed C++ heap as extension to its + * JavaScript heap. + * + * See v8::Isolate::GetCppHeap() for working with the heap. + * + * This is an experimental feature and may still change significantly. + */ + std::shared_ptr cpp_heap_params; + /** + * This list is provided by the embedder to indicate which import assertions + * they want to handle. Only import assertions whose keys are present in + * supported_import_assertions will be included in the import assertions + * lists of ModuleRequests that will be passed to the embedder. If + * supported_import_assertions is left empty, then the embedder will not + * receive any import assertions. + * + * This corresponds to the list returned by the HostGetSupportedAssertions + * host-defined abstract operation: + * https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions + */ + std::vector supported_import_assertions; + }; /** * Stack-allocated class which sets the isolate for all operations * executed within a local scope. */ - class V8_EXPORT Scope { + class V8_EXPORT V8_NODISCARD Scope { public: explicit Scope(Isolate* isolate) : isolate_(isolate) { isolate->Enter(); @@ -8385,11 +8458,10 @@ class V8_EXPORT Isolate { Isolate* const isolate_; }; - /** * Assert that no Javascript code is invoked. */ - class V8_EXPORT DisallowJavascriptExecutionScope { + class V8_EXPORT V8_NODISCARD DisallowJavascriptExecutionScope { public: enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE, DUMP_ON_FAILURE }; @@ -8407,11 +8479,10 @@ class V8_EXPORT Isolate { void* internal_; }; - /** * Introduce exception to DisallowJavascriptExecutionScope. */ - class V8_EXPORT AllowJavascriptExecutionScope { + class V8_EXPORT V8_NODISCARD AllowJavascriptExecutionScope { public: explicit AllowJavascriptExecutionScope(Isolate* isolate); ~AllowJavascriptExecutionScope(); @@ -8432,7 +8503,7 @@ class V8_EXPORT Isolate { * Do not run microtasks while this scope is active, even if microtasks are * automatically executed otherwise. */ - class V8_EXPORT SuppressMicrotaskExecutionScope { + class V8_EXPORT V8_NODISCARD SuppressMicrotaskExecutionScope { public: explicit SuppressMicrotaskExecutionScope( Isolate* isolate, MicrotaskQueue* microtask_queue = nullptr); @@ -8456,7 +8527,7 @@ class V8_EXPORT Isolate { * This scope allows terminations inside direct V8 API calls and forbid them * inside any recursive API calls without explicit SafeForTerminationScope. */ - class V8_EXPORT SafeForTerminationScope { + class V8_EXPORT V8_NODISCARD SafeForTerminationScope { public: explicit SafeForTerminationScope(v8::Isolate* isolate); ~SafeForTerminationScope(); @@ -8613,8 +8684,8 @@ class V8_EXPORT Isolate { kMessageWarning, }; - typedef void (*UseCounterCallback)(Isolate* isolate, - UseCounterFeature feature); + using UseCounterCallback = void (*)(Isolate* isolate, + UseCounterFeature feature); /** * Allocates a new isolate but does not initialize it. Does not change the @@ -8680,7 +8751,7 @@ class V8_EXPORT Isolate { * - the custom callback set returns true. * Otherwise, the custom callback will not be called and V8 will not abort. */ - typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*); + using AbortOnUncaughtExceptionCallback = bool (*)(Isolate*); void SetAbortOnUncaughtExceptionCallback( AbortOnUncaughtExceptionCallback callback); @@ -8844,7 +8915,7 @@ class V8_EXPORT Isolate { std::unique_ptr delegate, MeasureMemoryExecution execution = MeasureMemoryExecution::kDefault); - V8_DEPRECATE_SOON("Use the version with a delegate") + V8_DEPRECATED("Use the version with a delegate") MaybeLocal MeasureMemory(Local context, MeasureMemoryMode mode); @@ -8907,10 +8978,6 @@ class V8_EXPORT Isolate { */ Local GetCurrentContext(); - /** Returns the last context entered through V8's C++ API. */ - V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().") - Local GetEnteredContext(); - /** * Returns either the last context entered through V8's C++ API, or the * context of the currently running microtask while processing microtasks. @@ -8933,10 +9000,10 @@ class V8_EXPORT Isolate { */ Local ThrowException(Local exception); - typedef void (*GCCallback)(Isolate* isolate, GCType type, - GCCallbackFlags flags); - typedef void (*GCCallbackWithData)(Isolate* isolate, GCType type, - GCCallbackFlags flags, void* data); + using GCCallback = void (*)(Isolate* isolate, GCType type, + GCCallbackFlags flags); + using GCCallbackWithData = void (*)(Isolate* isolate, GCType type, + GCCallbackFlags flags, void* data); /** * Enables the host application to receive a notification before a @@ -8969,6 +9036,12 @@ class V8_EXPORT Isolate { */ EmbedderHeapTracer* GetEmbedderHeapTracer(); + /** + * \returns the C++ heap managed by V8. Only available if the Isolate was + * created with proper CreatePrams::cpp_heap_params option. + */ + CppHeap* GetCppHeap() const; + /** * Use for |AtomicsWaitCallback| to indicate the type of event it receives. */ @@ -9033,12 +9106,12 @@ class V8_EXPORT Isolate { * This callback may schedule exceptions, *unless* |event| is equal to * |kTerminatedExecution|. */ - typedef void (*AtomicsWaitCallback)(AtomicsWaitEvent event, - Local array_buffer, - size_t offset_in_bytes, int64_t value, - double timeout_in_ms, - AtomicsWaitWakeHandle* stop_handle, - void* data); + using AtomicsWaitCallback = void (*)(AtomicsWaitEvent event, + Local array_buffer, + size_t offset_in_bytes, int64_t value, + double timeout_in_ms, + AtomicsWaitWakeHandle* stop_handle, + void* data); /** * Set a new |AtomicsWaitCallback|. This overrides an earlier @@ -9070,7 +9143,7 @@ class V8_EXPORT Isolate { void* data = nullptr); void RemoveGCEpilogueCallback(GCCallback callback); - typedef size_t (*GetExternallyAllocatedMemoryInBytesCallback)(); + using GetExternallyAllocatedMemoryInBytesCallback = size_t (*)(); /** * Set the callback that tells V8 how much memory is currently allocated @@ -9189,12 +9262,6 @@ class V8_EXPORT Isolate { */ void SetPromiseRejectCallback(PromiseRejectCallback callback); - /** - * An alias for PerformMicrotaskCheckpoint. - */ - V8_DEPRECATED("Use PerformMicrotaskCheckpoint.") - void RunMicrotasks() { PerformMicrotaskCheckpoint(); } - /** * Runs the default MicrotaskQueue until it gets empty and perform other * microtask checkpoint steps, such as calling ClearKeptObjects. Asserts that @@ -9236,16 +9303,12 @@ class V8_EXPORT Isolate { * Executing scripts inside the callback will not re-trigger microtasks and * the callback. */ - V8_DEPRECATED("Use *WithData version.") - void AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void AddMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); /** * Removes callback that was installed by AddMicrotasksCompletedCallback. */ - V8_DEPRECATED("Use *WithData version.") - void RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void RemoveMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); @@ -9488,11 +9551,6 @@ class V8_EXPORT Isolate { * strings should be allowed. */ V8_DEPRECATED( - "Use Isolate::SetModifyCodeGenerationFromStringsCallback instead. " - "See http://crbug.com/v8/10096.") - void SetAllowCodeGenerationFromStringsCallback( - AllowCodeGenerationFromStringsCallback callback); - V8_DEPRECATE_SOON( "Use Isolate::SetModifyCodeGenerationFromStringsCallback with " "ModifyCodeGenerationFromStringsCallback2 instead. See " "http://crbug.com/1096017 and TC39 Dynamic Code Brand Checks proposal " @@ -9686,7 +9744,7 @@ class V8_EXPORT StartupData { * EntropySource is used as a callback function when v8 needs a source * of entropy. */ -typedef bool (*EntropySource)(unsigned char* buffer, size_t length); +using EntropySource = bool (*)(unsigned char* buffer, size_t length); /** * ReturnAddressLocationResolver is used as a callback function when v8 is @@ -9701,9 +9759,8 @@ typedef bool (*EntropySource)(unsigned char* buffer, size_t length); * * \note The resolver function must not cause garbage collection. */ -typedef uintptr_t (*ReturnAddressLocationResolver)( - uintptr_t return_addr_location); - +using ReturnAddressLocationResolver = + uintptr_t (*)(uintptr_t return_addr_location); /** * Container class for static utility functions. @@ -9857,7 +9914,7 @@ class V8_EXPORT V8 { * \param context The third argument passed to the Linux signal handler, which * points to a ucontext_t structure. */ - V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix") + V8_DEPRECATED("Use TryHandleWebAssemblyTrapPosix") static bool TryHandleSignal(int signal_number, void* info, void* context); #endif // V8_OS_POSIX @@ -10588,8 +10645,8 @@ class V8_EXPORT Context { * context, call the specified callback, and throw an exception. * To unset abort, pass nullptr as callback. */ - typedef void (*AbortScriptExecutionCallback)(Isolate* isolate, - Local context); + using AbortScriptExecutionCallback = void (*)(Isolate* isolate, + Local context); void SetAbortScriptExecution(AbortScriptExecutionCallback callback); /** @@ -10608,7 +10665,7 @@ class V8_EXPORT Context { * Stack-allocated class which sets the execution context for all * operations executed within a local scope. */ - class Scope { + class V8_NODISCARD Scope { public: explicit V8_INLINE Scope(Local context) : context_(context) { context_->Enter(); @@ -10624,7 +10681,7 @@ class V8_EXPORT Context { * stack. * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack */ - class V8_EXPORT BackupIncumbentScope final { + class V8_EXPORT V8_NODISCARD BackupIncumbentScope final { public: /** * |backup_incumbent_context| is pushed onto the backup incumbent settings @@ -10925,7 +10982,7 @@ void Persistent::Copy(const Persistent& that) { template bool PersistentBase::IsWeak() const { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return false; return I::GetNodeState(reinterpret_cast(this->val_)) == I::kNodeStateIsWeakValue; @@ -10966,7 +11023,7 @@ template V8_INLINE void PersistentBase::SetWeak( P* parameter, typename WeakCallbackInfo

::Callback callback, WeakCallbackType type) { - typedef typename WeakCallbackInfo::Callback Callback; + using Callback = WeakCallbackInfo::Callback; #if (__GNUC__ >= 8) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" @@ -10998,7 +11055,7 @@ void PersistentBase::AnnotateStrongRetainer(const char* label) { template void PersistentBase::SetWrapperClassId(uint16_t class_id) { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return; internal::Address* obj = reinterpret_cast(this->val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11008,7 +11065,7 @@ void PersistentBase::SetWrapperClassId(uint16_t class_id) { template uint16_t PersistentBase::WrapperClassId() const { - typedef internal::Internals I; + using I = internal::Internals; if (this->IsEmpty()) return 0; internal::Address* obj = reinterpret_cast(this->val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11206,7 +11263,7 @@ TracedReference& TracedReference::operator=(const TracedReference& rhs) { } void TracedReferenceBase::SetWrapperClassId(uint16_t class_id) { - typedef internal::Internals I; + using I = internal::Internals; if (IsEmpty()) return; internal::Address* obj = reinterpret_cast(val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11214,7 +11271,7 @@ void TracedReferenceBase::SetWrapperClassId(uint16_t class_id) { } uint16_t TracedReferenceBase::WrapperClassId() const { - typedef internal::Internals I; + using I = internal::Internals; if (IsEmpty()) return 0; internal::Address* obj = reinterpret_cast(val_); uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset; @@ -11274,7 +11331,7 @@ void ReturnValue::Set(double i) { template void ReturnValue::Set(int32_t i) { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; if (V8_LIKELY(I::IsValidSmi(i))) { *value_ = I::IntToSmi(i); return; @@ -11297,7 +11354,7 @@ void ReturnValue::Set(uint32_t i) { template void ReturnValue::Set(bool value) { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; int root_index; if (value) { root_index = I::kTrueValueRootIndex; @@ -11310,21 +11367,21 @@ void ReturnValue::Set(bool value) { template void ReturnValue::SetNull() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kNullValueRootIndex); } template void ReturnValue::SetUndefined() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); } template void ReturnValue::SetEmptyString() { static_assert(std::is_base_of::value, "type check"); - typedef internal::Internals I; + using I = internal::Internals; *value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); } @@ -11336,7 +11393,7 @@ Isolate* ReturnValue::GetIsolate() const { template Local ReturnValue::Get() const { - typedef internal::Internals I; + using I = internal::Internals; if (*value_ == *I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex)) return Local(*Undefined(GetIsolate())); return Local::New(GetIsolate(), reinterpret_cast(value_)); @@ -11416,23 +11473,33 @@ int FunctionCallbackInfo::Length() const { return length_; } -ScriptOrigin::ScriptOrigin(Local resource_name, - Local resource_line_offset, - Local resource_column_offset, - Local resource_is_shared_cross_origin, - Local script_id, - Local source_map_url, - Local resource_is_opaque, - Local is_wasm, Local is_module, +ScriptOrigin::ScriptOrigin( + Local resource_name, Local line_offset, + Local column_offset, Local is_shared_cross_origin, + Local script_id, Local source_map_url, + Local is_opaque, Local is_wasm, Local is_module, + Local host_defined_options) + : ScriptOrigin( + resource_name, + line_offset.IsEmpty() ? 0 : static_cast(line_offset->Value()), + column_offset.IsEmpty() ? 0 + : static_cast(column_offset->Value()), + !is_shared_cross_origin.IsEmpty() && is_shared_cross_origin->IsTrue(), + static_cast(script_id.IsEmpty() ? -1 : script_id->Value()), + source_map_url, !is_opaque.IsEmpty() && is_opaque->IsTrue(), + !is_wasm.IsEmpty() && is_wasm->IsTrue(), + !is_module.IsEmpty() && is_module->IsTrue(), host_defined_options) {} + +ScriptOrigin::ScriptOrigin(Local resource_name, int line_offset, + int column_offset, bool is_shared_cross_origin, + int script_id, Local source_map_url, + bool is_opaque, bool is_wasm, bool is_module, Local host_defined_options) - : resource_name_(resource_name), - resource_line_offset_(resource_line_offset), - resource_column_offset_(resource_column_offset), - options_(!resource_is_shared_cross_origin.IsEmpty() && - resource_is_shared_cross_origin->IsTrue(), - !resource_is_opaque.IsEmpty() && resource_is_opaque->IsTrue(), - !is_wasm.IsEmpty() && is_wasm->IsTrue(), - !is_module.IsEmpty() && is_module->IsTrue()), + : isolate_(Isolate::GetCurrent()), + resource_name_(resource_name), + resource_line_offset_(line_offset), + resource_column_offset_(column_offset), + options_(is_shared_cross_origin, is_opaque, is_wasm, is_module), script_id_(script_id), source_map_url_(source_map_url), host_defined_options_(host_defined_options) {} @@ -11444,17 +11511,22 @@ Local ScriptOrigin::HostDefinedOptions() const { } Local ScriptOrigin::ResourceLineOffset() const { - return resource_line_offset_; + return v8::Integer::New(isolate_, resource_line_offset_); } - Local ScriptOrigin::ResourceColumnOffset() const { - return resource_column_offset_; + return v8::Integer::New(isolate_, resource_column_offset_); +} + +Local ScriptOrigin::ScriptID() const { + return v8::Integer::New(isolate_, script_id_); } +int ScriptOrigin::LineOffset() const { return resource_line_offset_; } -Local ScriptOrigin::ScriptID() const { return script_id_; } +int ScriptOrigin::ColumnOffset() const { return resource_column_offset_; } +int ScriptOrigin::ScriptId() const { return script_id_; } Local ScriptOrigin::SourceMapUrl() const { return source_map_url_; } @@ -11462,8 +11534,8 @@ ScriptCompiler::Source::Source(Local string, const ScriptOrigin& origin, CachedData* data) : source_string(string), resource_name(origin.ResourceName()), - resource_line_offset(origin.ResourceLineOffset()), - resource_column_offset(origin.ResourceColumnOffset()), + resource_line_offset(origin.LineOffset()), + resource_column_offset(origin.ColumnOffset()), resource_options(origin.Options()), source_map_url(origin.SourceMapUrl()), host_defined_options(origin.HostDefinedOptions()), @@ -11528,8 +11600,8 @@ AccessorSignature* AccessorSignature::Cast(Data* data) { Local Object::GetInternalField(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. @@ -11556,8 +11628,8 @@ Local Object::GetInternalField(int index) { void* Object::GetAlignedPointerFromInternalField(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. @@ -11578,17 +11650,16 @@ void* Object::GetAlignedPointerFromInternalField(int index) { return SlowGetAlignedPointerFromInternalField(index); } -String* String::Cast(v8::Value* value) { +String* String::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - Local String::Empty(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kEmptyStringRootIndex); return Local(reinterpret_cast(slot)); @@ -11596,8 +11667,8 @@ Local String::Empty(Isolate* isolate) { String::ExternalStringResource* String::GetExternalStringResource() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); ExternalStringResource* result; @@ -11619,8 +11690,8 @@ String::ExternalStringResource* String::GetExternalStringResource() const { String::ExternalStringResourceBase* String::GetExternalStringResourceBase( String::Encoding* encoding_out) const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); int type = I::GetInstanceType(obj) & I::kFullStringRepresentationMask; *encoding_out = static_cast(type & I::kStringEncodingMask); @@ -11651,8 +11722,8 @@ bool Value::IsUndefined() const { } bool Value::QuickIsUndefined() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11669,8 +11740,8 @@ bool Value::IsNull() const { } bool Value::QuickIsNull() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11686,8 +11757,8 @@ bool Value::IsNullOrUndefined() const { } bool Value::QuickIsNullOrUndefined() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; @@ -11704,8 +11775,8 @@ bool Value::IsString() const { } bool Value::QuickIsString() const { - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A obj = *reinterpret_cast(this); if (!I::HasHeapObjectTag(obj)) return false; return (I::GetInstanceType(obj) < I::kFirstNonstringType); @@ -11724,30 +11795,27 @@ V8_INLINE Value* Value::Cast(Data* value) { return static_cast(value); } -Boolean* Boolean::Cast(v8::Value* value) { +Boolean* Boolean::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Name* Name::Cast(v8::Value* value) { +Name* Name::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Symbol* Symbol::Cast(v8::Value* value) { +Symbol* Symbol::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - Private* Private::Cast(Data* data) { #ifdef V8_ENABLE_CHECKS CheckCast(data); @@ -11755,6 +11823,13 @@ Private* Private::Cast(Data* data) { return reinterpret_cast(data); } +ModuleRequest* ModuleRequest::Cast(Data* data) { +#ifdef V8_ENABLE_CHECKS + CheckCast(data); +#endif + return reinterpret_cast(data); +} + Module* Module::Cast(Data* data) { #ifdef V8_ENABLE_CHECKS CheckCast(data); @@ -11762,42 +11837,39 @@ Module* Module::Cast(Data* data) { return reinterpret_cast(data); } -Number* Number::Cast(v8::Value* value) { +Number* Number::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Integer* Integer::Cast(v8::Value* value) { +Integer* Integer::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Int32* Int32::Cast(v8::Value* value) { +Int32* Int32::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } - -Uint32* Uint32::Cast(v8::Value* value) { +Uint32* Uint32::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } -BigInt* BigInt::Cast(v8::Value* value) { +BigInt* BigInt::Cast(v8::Data* data) { #ifdef V8_ENABLE_CHECKS - CheckCast(value); + CheckCast(data); #endif - return static_cast(value); + return static_cast(data); } Date* Date::Cast(v8::Value* value) { @@ -11901,6 +11973,13 @@ Proxy* Proxy::Cast(v8::Value* value) { return static_cast(value); } +WasmMemoryObject* WasmMemoryObject::Cast(v8::Value* value) { +#ifdef V8_ENABLE_CHECKS + CheckCast(value); +#endif + return static_cast(value); +} + WasmModuleObject* WasmModuleObject::Cast(v8::Value* value) { #ifdef V8_ENABLE_CHECKS CheckCast(value); @@ -12088,7 +12167,7 @@ ReturnValue PropertyCallbackInfo::GetReturnValue() const { template bool PropertyCallbackInfo::ShouldThrowOnError() const { - typedef internal::Internals I; + using I = internal::Internals; if (args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kInferShouldThrowMode)) { return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow); @@ -12098,8 +12177,8 @@ bool PropertyCallbackInfo::ShouldThrowOnError() const { } Local Undefined(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12107,8 +12186,8 @@ Local Undefined(Isolate* isolate) { Local Null(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kNullValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12116,8 +12195,8 @@ Local Null(Isolate* isolate) { Local True(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12125,8 +12204,8 @@ Local True(Isolate* isolate) { Local False(Isolate* isolate) { - typedef internal::Address S; - typedef internal::Internals I; + using S = internal::Address; + using I = internal::Internals; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex); return Local(reinterpret_cast(slot)); @@ -12134,19 +12213,19 @@ Local False(Isolate* isolate) { void Isolate::SetData(uint32_t slot, void* data) { - typedef internal::Internals I; + using I = internal::Internals; I::SetEmbedderData(this, slot, data); } void* Isolate::GetData(uint32_t slot) { - typedef internal::Internals I; + using I = internal::Internals; return I::GetEmbedderData(this, slot); } uint32_t Isolate::GetNumberOfDataSlots() { - typedef internal::Internals I; + using I = internal::Internals; return I::kNumIsolateDataSlots; } @@ -12159,8 +12238,8 @@ MaybeLocal Isolate::GetDataFromSnapshotOnce(size_t index) { Local Context::GetEmbedderData(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A ctx = *reinterpret_cast(this); A embedder_data = I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); @@ -12185,8 +12264,8 @@ Local Context::GetEmbedderData(int index) { void* Context::GetAlignedPointerFromEmbedderData(int index) { #ifndef V8_ENABLE_CHECKS - typedef internal::Address A; - typedef internal::Internals I; + using A = internal::Address; + using I = internal::Internals; A ctx = *reinterpret_cast(this); A embedder_data = I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h index ae89edb2c9b791..0886f691d56a19 100644 --- a/deps/v8/include/v8config.h +++ b/deps/v8/include/v8config.h @@ -239,6 +239,7 @@ // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) // supported +// V8_HAS_CPP_ATTRIBUTE_NODISCARD - [[nodiscard]] supported // V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported // V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported // V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported @@ -262,6 +263,12 @@ // ... // #endif +#if defined(__has_cpp_attribute) +#define V8_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE) +#else +#define V8_HAS_CPP_ATTRIBUTE(FEATURE) 0 +#endif + #if defined(__clang__) #if defined(__GNUC__) // Clang in gcc mode. @@ -276,6 +283,8 @@ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ (__has_attribute(warn_unused_result)) +# define V8_HAS_CPP_ATTRIBUTE_NODISCARD (V8_HAS_CPP_ATTRIBUTE(nodiscard)) + # define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) @@ -319,6 +328,7 @@ # define V8_HAS_ATTRIBUTE_UNUSED 1 # define V8_HAS_ATTRIBUTE_VISIBILITY 1 # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT (!V8_CC_INTEL) +# define V8_HAS_CPP_ATTRIBUTE_NODISCARD (V8_HAS_CPP_ATTRIBUTE(nodiscard)) # define V8_HAS_BUILTIN_ASSUME_ALIGNED 1 # define V8_HAS_BUILTIN_CLZ 1 @@ -436,6 +446,20 @@ #define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */ #endif + +// Annotate a class or constructor indicating the caller must assign the +// constructed instances. +// Apply to the whole class like: +// class V8_NODISCARD Foo() { ... }; +// or apply to just one constructor like: +// V8_NODISCARD Foo() { ... }; +// [[nodiscard]] comes in C++17 but supported in clang with -std >= c++11. +#if V8_HAS_CPP_ATTRIBUTE_NODISCARD +#define V8_NODISCARD [[nodiscard]] +#else +#define V8_NODISCARD /* NOT SUPPORTED */ +#endif + // Helper macro to define no_sanitize attributes only with clang. #if defined(__clang__) && defined(__has_attribute) #if __has_attribute(no_sanitize) @@ -484,4 +508,6 @@ V8 shared library set USING_V8_SHARED. // clang-format on +#undef V8_HAS_CPP_ATTRIBUTE + #endif // V8CONFIG_H_ diff --git a/deps/v8/infra/mb/mb_config.pyl b/deps/v8/infra/mb/mb_config.pyl index aab725feece2fa..b95f7d2fbf5033 100644 --- a/deps/v8/infra/mb/mb_config.pyl +++ b/deps/v8/infra/mb/mb_config.pyl @@ -68,11 +68,14 @@ # TODO(machenbach): Remove after switching to x64 on infra side. 'V8 Win64 ASAN': 'release_x64_asan_no_lsan', 'V8 Win64': 'release_x64_minimal_symbols', + 'V8 Win64 - dev image': 'release_x64_minimal_symbols', 'V8 Win64 - debug': 'debug_x64_minimal_symbols', 'V8 Win64 - msvc': 'release_x64_msvc', # Mac. 'V8 Mac64': 'release_x64', 'V8 Mac64 - debug': 'debug_x64', + 'V8 Official Mac ARM64': 'release_arm64', + 'V8 Official Mac ARM64 Debug': 'debug_arm64', 'V8 Mac64 GC Stress': 'debug_x64', 'V8 Mac64 ASAN': 'release_x64_asan_no_lsan', 'V8 Mac - arm64 - release builder': 'release_arm64', @@ -169,6 +172,8 @@ # IBM. 'V8 Linux - ppc64 - sim': 'release_simulate_ppc64', 'V8 Linux - s390x - sim': 'release_simulate_s390x', + # RISC-V + 'V8 Linux - riscv64 - sim - builder': 'release_simulate_riscv64', }, 'client.v8.branches': { 'V8 Linux - previous branch': 'release_x86', @@ -237,6 +242,7 @@ 'v8_linux64_cfi_rel_ng': 'release_x64_cfi', 'v8_linux64_fuzzilli_ng': 'release_x64_fuzzilli', 'v8_linux64_msan_rel_ng': 'release_simulate_arm64_msan_minimal_symbols', + 'v8_linux64_riscv64_rel_ng': 'release_simulate_riscv64', 'v8_linux64_tsan_rel_ng': 'release_x64_tsan_minimal_symbols', 'v8_linux64_tsan_no_cm_rel_ng': 'release_x64_tsan_no_cm', 'v8_linux64_tsan_isolates_rel_ng': @@ -401,6 +407,8 @@ 'release_bot', 'simulate_mips64el'], 'release_simulate_ppc64': [ 'release_bot', 'simulate_ppc64'], + 'release_simulate_riscv64': [ + 'release_bot', 'simulate_riscv64'], 'release_simulate_s390x': [ 'release_bot', 'simulate_s390x'], @@ -696,7 +704,7 @@ }, 'ios_simulator': { - 'gn_args': 'target_cpu="x64" target_os="ios" ios_use_goma_rbe=true', + 'gn_args': 'target_cpu="x64" target_os="ios"', }, 'lsan': { @@ -783,6 +791,10 @@ 'gn_args': 'target_cpu="x64" v8_target_cpu="ppc64"', }, + 'simulate_riscv64': { + 'gn_args': 'target_cpu="x64" v8_target_cpu="riscv64"', + }, + 'simulate_s390x': { 'gn_args': 'target_cpu="x64" v8_target_cpu="s390x"', }, diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl index 9414e17377abf2..bffd21d01b2c17 100644 --- a/deps/v8/infra/testing/builders.pyl +++ b/deps/v8/infra/testing/builders.pyl @@ -549,6 +549,16 @@ ], }, ############################################################################## + # Linux64 with RISC-V simulators + 'v8_linux64_riscv64_rel_ng_triggered': { + 'swarming_dimensions': { + 'os': 'Ubuntu-16.04', + }, + 'tests': [ + {'name': 'v8testing', 'shards': 3}, + ], + }, + ############################################################################## # Odroids with native arm 'v8_odroid_arm_rel_ng_triggered': { 'swarming_dimensions' : { @@ -685,7 +695,7 @@ 'v8_mac_arm64_rel_ng_triggered': { 'swarming_dimensions' : { 'cpu': 'arm64', - 'os': 'Mac-11', + 'os': 'Mac-11.0', 'pool': 'chromium.tests.mac-arm64', }, 'tests': [ @@ -695,7 +705,7 @@ 'v8_mac_arm64_dbg_ng_triggered': { 'swarming_dimensions' : { 'cpu': 'arm64', - 'os': 'Mac-11', + 'os': 'Mac-11.0', 'pool': 'chromium.tests.mac-arm64', }, 'tests': [ @@ -705,7 +715,7 @@ 'v8_mac_arm64_full_dbg_ng_triggered': { 'swarming_dimensions' : { 'cpu': 'arm64', - 'os': 'Mac-11', + 'os': 'Mac-11.0', 'pool': 'chromium.tests.mac-arm64', }, 'tests': [ @@ -1350,7 +1360,7 @@ }, 'V8 Mac - arm64 - release': { 'swarming_dimensions' : { - 'os': 'Mac-11', + 'os': 'Mac-11.0', 'cpu': 'arm64', 'pool': 'chromium.tests.mac-arm64', }, @@ -1754,6 +1764,19 @@ {'name': 'v8testing', 'shards': 3}, ], }, + 'V8 Linux - riscv64 - sim': { + 'swarming_dimensions': { + 'os': 'Ubuntu-16.04', + }, + 'swarming_task_attrs': { + 'expiration': 14400, + 'hard_timeout': 3600, + 'priority': 35, + }, + 'tests': [ + {'name': 'v8testing', 'shards': 3}, + ], + }, 'V8 Linux - s390x - sim': { 'swarming_dimensions': { 'os': 'Ubuntu-16.04', diff --git a/deps/v8/samples/cppgc/OWNERS b/deps/v8/samples/cppgc/OWNERS new file mode 100644 index 00000000000000..3c480d06f70bb8 --- /dev/null +++ b/deps/v8/samples/cppgc/OWNERS @@ -0,0 +1,3 @@ +bikineev@chromium.org +mlippautz@chromium.org +omerkatz@chromium.org diff --git a/deps/v8/samples/cppgc/cppgc-for-v8-embedders.cc b/deps/v8/samples/cppgc/cppgc-for-v8-embedders.cc deleted file mode 100644 index b4d7ed9e4d72da..00000000000000 --- a/deps/v8/samples/cppgc/cppgc-for-v8-embedders.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2020 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. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/** - * This sample program shows how to set up a stand-alone cppgc heap as an - * embedder of V8. Most importantly, this example shows how to reuse V8's - * platform for cppgc. - */ - -/** - * Simple string rope to illustrate allocation and garbage collection below. The - * rope keeps the next parts alive via regular managed reference. - */ -class Rope final : public cppgc::GarbageCollected { - public: - explicit Rope(std::string part, Rope* next = nullptr) - : part_(part), next_(next) {} - - void Trace(cppgc::Visitor* visitor) const { visitor->Trace(next_); } - - private: - std::string part_; - cppgc::Member next_; - - friend std::ostream& operator<<(std::ostream& os, const Rope& rope); -}; - -std::ostream& operator<<(std::ostream& os, const Rope& rope) { - os << rope.part_; - if (rope.next_) { - os << *rope.next_; - } - return os; -} - -int main(int argc, char* argv[]) { - // Create a platform that is used by cppgc::Heap for execution and backend - // allocation. - auto cppgc_platform = std::make_shared(); - // Initialize the process. This must happen before any cppgc::Heap::Create() - // calls. - cppgc::InitializeProcess(cppgc_platform->GetPageAllocator()); - // Create a managed heap. - std::unique_ptr heap = cppgc::Heap::Create(cppgc_platform); - // Allocate a string rope on the managed heap. - auto* greeting = cppgc::MakeGarbageCollected( - heap->GetAllocationHandle(), "Hello ", - cppgc::MakeGarbageCollected(heap->GetAllocationHandle(), "World!")); - // Manually trigger garbage collection. The object greeting is held alive - // through conservative stack scanning. - heap->ForceGarbageCollectionSlow("V8 embedders example", "Testing"); - std::cout << *greeting << std::endl; - // Gracefully shutdown the process. - cppgc::ShutdownProcess(); - return 0; -} diff --git a/deps/v8/samples/cppgc/cppgc-standalone.cc b/deps/v8/samples/cppgc/cppgc-sample.cc similarity index 77% rename from deps/v8/samples/cppgc/cppgc-standalone.cc rename to deps/v8/samples/cppgc/cppgc-sample.cc index f8cb4020c3a53d..befda9619796ff 100644 --- a/deps/v8/samples/cppgc/cppgc-standalone.cc +++ b/deps/v8/samples/cppgc/cppgc-sample.cc @@ -45,9 +45,13 @@ int main(int argc, char* argv[]) { // Create a default platform that is used by cppgc::Heap for execution and // backend allocation. auto cppgc_platform = std::make_shared(); - // Initialize the process. This must happen before any - // cppgc::Heap::Create() calls. - cppgc::InitializeProcess(cppgc_platform->GetPageAllocator()); + // Initialize the process. This must happen before any cppgc::Heap::Create() + // calls. cppgc::DefaultPlatform::InitializeProcess initializes both cppgc + // and v8 (if cppgc is not used as a standalone) as needed. + // If using a platform other than cppgc::DefaultPlatform, should call + // cppgc::InitializeProcess (for standalone builds) or + // v8::V8::InitializePlatform (for non-standalone builds) directly. + cppgc::DefaultPlatform::InitializeProcess(cppgc_platform.get()); // Create a managed heap. std::unique_ptr heap = cppgc::Heap::Create(cppgc_platform); // Allocate a string rope on the managed heap. @@ -56,7 +60,7 @@ int main(int argc, char* argv[]) { cppgc::MakeGarbageCollected(heap->GetAllocationHandle(), "World!")); // Manually trigger garbage collection. The object greeting is held alive // through conservative stack scanning. - heap->ForceGarbageCollectionSlow("CppGC stand-alone example", "Testing"); + heap->ForceGarbageCollectionSlow("CppGC example", "Testing"); std::cout << *greeting << std::endl; // Gracefully shutdown the process. cppgc::ShutdownProcess(); diff --git a/deps/v8/samples/process.cc b/deps/v8/samples/process.cc index dec0d570311f15..16e70a20644e50 100644 --- a/deps/v8/samples/process.cc +++ b/deps/v8/samples/process.cc @@ -219,7 +219,7 @@ bool JsHttpRequestProcessor::Initialize(map* opts, } // It is a function; cast it to a Function - Local process_fun = Local::Cast(process_val); + Local process_fun = process_val.As(); // Store the function in a Global handle, since we also want // that to remain after this call returns @@ -375,7 +375,7 @@ Local JsHttpRequestProcessor::WrapMap(map* obj) { // Utility function that extracts the C++ map pointer from a wrapper // object. map* JsHttpRequestProcessor::UnwrapMap(Local obj) { - Local field = Local::Cast(obj->GetInternalField(0)); + Local field = obj->GetInternalField(0).As(); void* ptr = field->Value(); return static_cast*>(ptr); } @@ -397,7 +397,7 @@ void JsHttpRequestProcessor::MapGet(Local name, map* obj = UnwrapMap(info.Holder()); // Convert the JavaScript string to a std::string. - string key = ObjectToString(info.GetIsolate(), Local::Cast(name)); + string key = ObjectToString(info.GetIsolate(), name.As()); // Look up the value if it exists using the standard STL ideom. map::iterator iter = obj->find(key); @@ -422,7 +422,7 @@ void JsHttpRequestProcessor::MapSet(Local name, Local value_obj, map* obj = UnwrapMap(info.Holder()); // Convert the key and value to std::strings. - string key = ObjectToString(info.GetIsolate(), Local::Cast(name)); + string key = ObjectToString(info.GetIsolate(), name.As()); string value = ObjectToString(info.GetIsolate(), value_obj); // Update the map. @@ -491,7 +491,7 @@ Local JsHttpRequestProcessor::WrapRequest(HttpRequest* request) { * wrapper object. */ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Local obj) { - Local field = Local::Cast(obj->GetInternalField(0)); + Local field = obj->GetInternalField(0).As(); void* ptr = field->Value(); return static_cast(ptr); } diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc index 70450296c76389..4cff77cc040f04 100644 --- a/deps/v8/samples/shell.cc +++ b/deps/v8/samples/shell.cc @@ -380,7 +380,7 @@ void ReportException(v8::Isolate* isolate, v8::TryCatch* try_catch) { v8::Local stack_trace_string; if (try_catch->StackTrace(context).ToLocal(&stack_trace_string) && stack_trace_string->IsString() && - v8::Local::Cast(stack_trace_string)->Length() > 0) { + stack_trace_string.As()->Length() > 0) { v8::String::Utf8Value stack_trace(isolate, stack_trace_string); const char* stack_trace_string = ToCString(stack_trace); fprintf(stderr, "%s\n", stack_trace_string); diff --git a/deps/v8/src/DEPS b/deps/v8/src/DEPS index e10d171f260d36..42d0c2d8a40371 100644 --- a/deps/v8/src/DEPS +++ b/deps/v8/src/DEPS @@ -8,6 +8,7 @@ include_rules = [ "+src/compiler/code-assembler.h", "+src/compiler/wasm-compiler.h", "-src/heap", + "+src/heap/basic-memory-chunk.h", "+src/heap/combined-heap.h", "+src/heap/embedder-tracing.h", "+src/heap/factory.h", @@ -25,6 +26,7 @@ include_rules = [ # TODO(v8:10496): Don't expose memory chunk outside of heap/. "+src/heap/memory-chunk.h", "+src/heap/memory-chunk-inl.h", + "+src/heap/parked-scope.h", "+src/heap/read-only-heap-inl.h", "+src/heap/read-only-heap.h", "+src/heap/safepoint.h", diff --git a/deps/v8/src/api/api-arguments-inl.h b/deps/v8/src/api/api-arguments-inl.h index 05bb35786a94e9..57b533c7c9fb11 100644 --- a/deps/v8/src/api/api-arguments-inl.h +++ b/deps/v8/src/api/api-arguments-inl.h @@ -57,8 +57,8 @@ inline Object PropertyCallbackArguments::receiver() { return *slot_at(T::kThisIndex); } -inline JSObject FunctionCallbackArguments::holder() { - return JSObject::cast(*slot_at(T::kHolderIndex)); +inline JSReceiver FunctionCallbackArguments::holder() { + return JSReceiver::cast(*slot_at(T::kHolderIndex)); } #define FOR_EACH_CALLBACK(F) \ diff --git a/deps/v8/src/api/api-arguments.h b/deps/v8/src/api/api-arguments.h index 18690b5db2b6d7..464ebadf37b360 100644 --- a/deps/v8/src/api/api-arguments.h +++ b/deps/v8/src/api/api-arguments.h @@ -74,6 +74,12 @@ class PropertyCallbackArguments PropertyCallbackArguments(Isolate* isolate, Object data, Object self, JSObject holder, Maybe should_throw); + // Don't copy PropertyCallbackArguments, because they would both have the + // same prev_ pointer. + PropertyCallbackArguments(const PropertyCallbackArguments&) = delete; + PropertyCallbackArguments& operator=(const PropertyCallbackArguments&) = + delete; + // ------------------------------------------------------------------------- // Accessor Callbacks // Also used for AccessorSetterCallback. @@ -141,10 +147,6 @@ class PropertyCallbackArguments inline JSObject holder(); inline Object receiver(); - - // Don't copy PropertyCallbackArguments, because they would both have the - // same prev_ pointer. - DISALLOW_COPY_AND_ASSIGN(PropertyCallbackArguments); }; class FunctionCallbackArguments @@ -175,7 +177,7 @@ class FunctionCallbackArguments inline Handle Call(CallHandlerInfo handler); private: - inline JSObject holder(); + inline JSReceiver holder(); internal::Address* argv_; int argc_; diff --git a/deps/v8/src/api/api-inl.h b/deps/v8/src/api/api-inl.h index f686424286d8fe..b8a5c195324937 100644 --- a/deps/v8/src/api/api-inl.h +++ b/deps/v8/src/api/api-inl.h @@ -104,7 +104,8 @@ MAKE_TO_LOCAL(ToLocal, BigInt, BigInt) MAKE_TO_LOCAL(ExternalToLocal, JSObject, External) MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function) MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive) -MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray) +MAKE_TO_LOCAL(FixedArrayToLocal, FixedArray, FixedArray) +MAKE_TO_LOCAL(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) MAKE_TO_LOCAL(ScriptOrModuleToLocal, Script, ScriptOrModule) #undef MAKE_TO_LOCAL_TYPED_ARRAY diff --git a/deps/v8/src/api/api-natives.cc b/deps/v8/src/api/api-natives.cc index f8f660ea15c939..43d0b3a166a339 100644 --- a/deps/v8/src/api/api-natives.cc +++ b/deps/v8/src/api/api-natives.cc @@ -18,7 +18,7 @@ namespace internal { namespace { -class InvokeScope { +class V8_NODISCARD InvokeScope { public: explicit InvokeScope(Isolate* isolate) : isolate_(isolate), save_context_(isolate) {} @@ -67,33 +67,31 @@ MaybeHandle Instantiate( } } -MaybeHandle DefineAccessorProperty( - Isolate* isolate, Handle object, Handle name, - Handle getter, Handle setter, PropertyAttributes attributes, - bool force_instantiate) { +MaybeHandle DefineAccessorProperty(Isolate* isolate, + Handle object, + Handle name, + Handle getter, + Handle setter, + PropertyAttributes attributes) { DCHECK(!getter->IsFunctionTemplateInfo() || !FunctionTemplateInfo::cast(*getter).do_not_cache()); DCHECK(!setter->IsFunctionTemplateInfo() || !FunctionTemplateInfo::cast(*setter).do_not_cache()); - if (getter->IsFunctionTemplateInfo()) { - if (force_instantiate || - FunctionTemplateInfo::cast(*getter).BreakAtEntry()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, getter, - InstantiateFunction(isolate, - Handle::cast(getter)), - Object); - } + if (getter->IsFunctionTemplateInfo() && + FunctionTemplateInfo::cast(*getter).BreakAtEntry()) { + ASSIGN_RETURN_ON_EXCEPTION( + isolate, getter, + InstantiateFunction(isolate, + Handle::cast(getter)), + Object); } - if (setter->IsFunctionTemplateInfo()) { - if (force_instantiate || - FunctionTemplateInfo::cast(*setter).BreakAtEntry()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, setter, - InstantiateFunction(isolate, - Handle::cast(setter)), - Object); - } + if (setter->IsFunctionTemplateInfo() && + FunctionTemplateInfo::cast(*setter).BreakAtEntry()) { + ASSIGN_RETURN_ON_EXCEPTION( + isolate, setter, + InstantiateFunction(isolate, + Handle::cast(setter)), + Object); } RETURN_ON_EXCEPTION( isolate, @@ -148,7 +146,7 @@ void EnableAccessChecks(Isolate* isolate, Handle object) { JSObject::MigrateToMap(isolate, object, new_map); } -class AccessCheckDisableScope { +class V8_NODISCARD AccessCheckDisableScope { public: AccessCheckDisableScope(Isolate* isolate, Handle obj) : isolate_(isolate), @@ -186,6 +184,8 @@ Object GetIntrinsic(Isolate* isolate, v8::Intrinsic intrinsic) { template MaybeHandle ConfigureInstance(Isolate* isolate, Handle obj, Handle data) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kConfigureInstance); HandleScope scope(isolate); // Disable access checks while instantiating the object. AccessCheckDisableScope access_check_scope(isolate, obj); @@ -254,7 +254,7 @@ MaybeHandle ConfigureInstance(Isolate* isolate, Handle obj, auto setter = handle(properties->get(i++), isolate); RETURN_ON_EXCEPTION(isolate, DefineAccessorProperty(isolate, obj, name, getter, - setter, attributes, false), + setter, attributes), JSObject); } } else { @@ -293,7 +293,7 @@ MaybeHandle ProbeInstantiationsCache( FixedArray fast_cache = native_context->fast_template_instantiations_cache(); Handle object{fast_cache.get(serial_number - 1), isolate}; - if (object->IsUndefined(isolate)) return {}; + if (object->IsTheHole(isolate)) return {}; return Handle::cast(object); } if (caching_mode == CachingMode::kUnlimited || @@ -357,7 +357,7 @@ void UncacheTemplateInstantiation(Isolate* isolate, bool IsSimpleInstantiation(Isolate* isolate, ObjectTemplateInfo info, JSReceiver new_target) { - DisallowHeapAllocation no_gc; + DisallowGarbageCollection no_gc; if (!new_target.IsJSFunction()) return false; JSFunction fun = JSFunction::cast(new_target); @@ -371,6 +371,8 @@ MaybeHandle InstantiateObject(Isolate* isolate, Handle info, Handle new_target, bool is_prototype) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kInstantiateObject); Handle constructor; int serial_number = info->serial_number(); if (!new_target.is_null()) { @@ -463,6 +465,8 @@ MaybeHandle GetInstancePrototype(Isolate* isolate, MaybeHandle InstantiateFunction( Isolate* isolate, Handle native_context, Handle data, MaybeHandle maybe_name) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kInstantiateFunction); int serial_number = data->serial_number(); if (serial_number) { Handle result; @@ -646,6 +650,8 @@ Handle ApiNatives::CreateApiFunction( Isolate* isolate, Handle native_context, Handle obj, Handle prototype, InstanceType type, MaybeHandle maybe_name) { + RuntimeCallTimerScope timer(isolate, + RuntimeCallCounterId::kCreateApiFunction); Handle shared = FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj, maybe_name); @@ -653,8 +659,7 @@ Handle ApiNatives::CreateApiFunction( DCHECK(shared->HasSharedName()); Handle result = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, - native_context); + Factory::JSFunctionBuilder{isolate, shared, native_context}.Build(); if (obj->remove_prototype()) { DCHECK(prototype.is_null()); diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index 66afdb19681517..9b19d155bd80c4 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -11,6 +11,7 @@ #include // For move #include +#include "include/cppgc/custom-space.h" #include "include/v8-cppgc.h" #include "include/v8-fast-api-calls.h" #include "include/v8-profiler.h" @@ -84,6 +85,7 @@ #include "src/objects/property-details.h" #include "src/objects/property.h" #include "src/objects/prototype.h" +#include "src/objects/shared-function-info.h" #include "src/objects/slots.h" #include "src/objects/smi.h" #include "src/objects/stack-frame-info-inl.h" @@ -99,6 +101,7 @@ #include "src/profiler/heap-snapshot-generator-inl.h" #include "src/profiler/profile-generator-inl.h" #include "src/profiler/tick-sample.h" +#include "src/regexp/regexp-stack.h" #include "src/regexp/regexp-utils.h" #include "src/runtime/runtime.h" #include "src/snapshot/code-serializer.h" @@ -131,6 +134,7 @@ #include "include/v8-wasm-trap-handler-win.h" #include "src/trap-handler/handler-inside-win.h" #if defined(V8_OS_WIN64) +#include "src/base/platform/wrappers.h" #include "src/diagnostics/unwinding-info-win64.h" #endif // V8_OS_WIN64 #endif // V8_OS_WIN @@ -216,11 +220,15 @@ namespace v8 { bailout_value, HandleScopeClass, false); \ i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)) -#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ - i::VMState __state__((isolate)); \ +// Lightweight version for APIs that don't require an active context. +#define ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) \ i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \ i::DisallowExceptions __no_exceptions__((isolate)) +#define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ + i::VMState __state__((isolate)); \ + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) + #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \ i::VMState __state__((isolate)); \ i::DisallowExceptions __no_exceptions__((isolate)) @@ -230,6 +238,8 @@ namespace v8 { ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \ bailout_value, HandleScopeClass, false) +#define ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate) + #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \ i::VMState __state__((isolate)); @@ -255,7 +265,7 @@ namespace v8 { namespace { -class InternalEscapableScope : public v8::EscapableHandleScope { +class V8_NODISCARD InternalEscapableScope : public v8::EscapableHandleScope { public: explicit inline InternalEscapableScope(i::Isolate* isolate) : v8::EscapableHandleScope(reinterpret_cast(isolate)) {} @@ -273,7 +283,7 @@ void CheckMicrotasksScopesConsistency(i::MicrotaskQueue* microtask_queue) { #endif template -class CallDepthScope { +class V8_NODISCARD CallDepthScope { public: CallDepthScope(i::Isolate* isolate, Local context) : isolate_(isolate), @@ -320,6 +330,9 @@ class CallDepthScope { isolate_->set_next_v8_call_is_safe_for_termination(safe_for_termination_); } + CallDepthScope(const CallDepthScope&) = delete; + CallDepthScope& operator=(const CallDepthScope&) = delete; + void Escape() { DCHECK(!escaped_); escaped_ = true; @@ -352,7 +365,6 @@ class CallDepthScope { friend class i::ThreadLocalTop; DISALLOW_NEW_AND_DELETE() - DISALLOW_COPY_AND_ASSIGN(CallDepthScope); }; } // namespace @@ -363,19 +375,13 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate, i::Handle source_map_url(script->source_mapping_url(), isolate); i::Handle host_defined_options(script->host_defined_options(), isolate); - v8::Isolate* v8_isolate = reinterpret_cast(isolate); ScriptOriginOptions options(script->origin_options()); v8::ScriptOrigin origin( - Utils::ToLocal(scriptName), - v8::Integer::New(v8_isolate, script->line_offset()), - v8::Integer::New(v8_isolate, script->column_offset()), - v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()), - v8::Integer::New(v8_isolate, script->id()), - Utils::ToLocal(source_map_url), - v8::Boolean::New(v8_isolate, options.IsOpaque()), - v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM), - v8::Boolean::New(v8_isolate, options.IsModule()), - Utils::ToLocal(host_defined_options)); + Utils::ToLocal(scriptName), script->line_offset(), + script->column_offset(), options.IsSharedCrossOrigin(), script->id(), + Utils::ToLocal(source_map_url), options.IsOpaque(), + script->type() == i::Script::TYPE_WASM, options.IsModule(), + Utils::PrimitiveArrayToLocal(host_defined_options)); return origin; } @@ -549,7 +555,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* data = __linux_calloc(length, 1); #else - void* data = calloc(length, 1); + void* data = base::Calloc(length, 1); #endif return data; } @@ -560,12 +566,12 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* data = __linux_malloc(length); #else - void* data = malloc(length); + void* data = base::Malloc(length); #endif return data; } - void Free(void* data, size_t) override { free(data); } + void Free(void* data, size_t) override { base::Free(data); } void* Reallocate(void* data, size_t old_length, size_t new_length) override { #if V8_OS_AIX && _LINUX_SOURCE_COMPAT @@ -573,7 +579,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839 void* new_data = __linux_realloc(data, new_length); #else - void* new_data = realloc(data, new_length); + void* new_data = base::Realloc(data, new_length); #endif if (new_length > old_length) { memset(reinterpret_cast(new_data) + old_length, 0, @@ -793,7 +799,7 @@ StartupData SnapshotCreator::CreateBlob( // Create a vector with all contexts and clear associated Persistent fields. // Note these contexts may be dead after calling Clear(), but will not be - // collected until serialization completes and the DisallowHeapAllocation + // collected until serialization completes and the DisallowGarbageCollection // scope above goes out of scope. std::vector contexts; contexts.reserve(num_contexts); @@ -954,17 +960,6 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, } } -size_t ResourceConstraints::max_semi_space_size_in_kb() const { - return i::Heap::SemiSpaceSizeFromYoungGenerationSize( - max_young_generation_size_) / - i::KB; -} - -void ResourceConstraints::set_max_semi_space_size_in_kb(size_t limit_in_kb) { - set_max_young_generation_size_in_bytes( - i::Heap::YoungGenerationSizeFromSemiSpaceSize(limit_in_kb * i::KB)); -} - i::Address* V8::GlobalizeReference(i::Isolate* isolate, i::Address* obj) { LOG_API(isolate, Persistent, New); i::Handle result = isolate->global_handles()->Create(*obj); @@ -1162,7 +1157,7 @@ void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); } bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); } bool Data::IsValue() const { - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; i::Handle self = Utils::OpenHandle(this); if (self->IsSmi()) { return true; @@ -1241,6 +1236,7 @@ static i::Handle EmbedderDataFor(Context* context, const char* location) { i::Handle env = Utils::OpenHandle(context); i::Isolate* isolate = env->GetIsolate(); + ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate); bool ok = Utils::ApiCheck(env->IsNativeContext(), location, "Not a native context") && Utils::ApiCheck(index >= 0, location, "Negative index"); @@ -1260,7 +1256,10 @@ static i::Handle EmbedderDataFor(Context* context, uint32_t Context::GetNumberOfEmbedderDataFields() { i::Handle context = Utils::OpenHandle(this); - CHECK(context->IsNativeContext()); + ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate()); + Utils::ApiCheck(context->IsNativeContext(), + "Context::GetNumberOfEmbedderDataFields", + "Not a native context"); // TODO(ishell): remove cast once embedder_data slot has a proper type. return static_cast( i::EmbedderDataArray::cast(context->embedder_data()).length()); @@ -1430,7 +1429,7 @@ static Local FunctionTemplateNew( i::Handle::cast(struct_obj); { // Disallow GC until all fields of obj have acceptable types. - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; InitializeFunctionTemplate(obj); obj->set_length(length); obj->set_do_not_cache(do_not_cache); @@ -1651,7 +1650,7 @@ static Local ObjectTemplateNew( i::Handle::cast(struct_obj); { // Disallow GC until all fields of obj have acceptable types. - i::DisallowHeapAllocation no_gc; + i::DisallowGarbageCollection no_gc; InitializeTemplate(obj, Consts::OBJECT_TEMPLATE); int next_serial_number = 0; if (!do_not_cache) { @@ -2052,9 +2051,11 @@ Local - -
-

Map Panel

- -

Search Map by Address

- - - - -
diff --git a/deps/v8/tools/system-analyzer/map-panel.mjs b/deps/v8/tools/system-analyzer/map-panel.mjs deleted file mode 100644 index 1516038a2df579..00000000000000 --- a/deps/v8/tools/system-analyzer/map-panel.mjs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2020 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 './stats-panel.mjs'; -import './map-panel/map-details.mjs'; -import './map-panel/map-transitions.mjs'; - -import {FocusEvent} from './events.mjs'; -import {DOM, V8CustomElement} from './helper.mjs'; -import {MapLogEntry} from './log/map.mjs'; - -DOM.defineCustomElement('map-panel', - (templateText) => - class MapPanel extends V8CustomElement { - _map; - constructor() { - super(templateText); - this.searchBarBtn.addEventListener('click', e => this.handleSearchBar(e)); - this.addEventListener(FocusEvent.name, e => this.handleUpdateMapDetails(e)); - } - - handleUpdateMapDetails(e) { - if (e.entry instanceof MapLogEntry) { - this.mapDetailsPanel.map = e.entry; - } - } - - get mapTransitionsPanel() { - return this.$('#map-transitions'); - } - - get mapDetailsPanel() { - return this.$('#map-details'); - } - - get searchBarBtn() { - return this.$('#searchBarBtn'); - } - - get searchBar() { - return this.$('#searchBar'); - } - - set timeline(timeline) { - this._timeline = timeline; - } - - set map(value) { - this._map = value; - this.mapTransitionsPanel.map = this._map; - } - - handleSearchBar(e) { - let searchBar = this.$('#searchBarInput'); - let searchBarInput = searchBar.value; - // access the map from model cache - let selectedMap = MapLogEntry.get(parseInt(searchBarInput)); - if (selectedMap) { - searchBar.className = 'success'; - } else { - searchBar.className = 'failure'; - } - this.dispatchEvent(new FocusEvent(selectedMap)); - } - - set selectedMapLogEntries(list) { - this.mapTransitionsPanel.selectedMapLogEntries = list; - } - get selectedMapLogEntries() { - return this.mapTransitionsPanel.selectedMapLogEntries; - } -}); diff --git a/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs b/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs deleted file mode 100644 index 60462a1db224df..00000000000000 --- a/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2020 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 {FocusEvent, SelectionEvent} from '../events.mjs'; -import {DOM, typeToColor, V8CustomElement} from '../helper.mjs'; - -DOM.defineCustomElement('./map-panel/map-transitions', - (templateText) => - class MapTransitions extends V8CustomElement { - _map; - _selectedMapLogEntries; - _displayedMapsInTree; - - constructor() { - super(templateText); - this.transitionView.addEventListener( - 'mousemove', (e) => this.handleTransitionViewChange(e)); - this.currentNode = this.transitionView; - this.currentMap = undefined; - } - - get transitionView() { - return this.$('#transitionView'); - } - - get tooltip() { - return this.$('#tooltip'); - } - - get tooltipContents() { - return this.$('#tooltipContents'); - } - - set map(value) { - this._map = value; - this.showMap(); - } - - handleTransitionViewChange(e) { - this.tooltip.style.left = e.pageX + 'px'; - this.tooltip.style.top = e.pageY + 'px'; - const map = e.target.map; - if (map) { - this.tooltipContents.innerText = map.description; - } - } - - _selectMap(map) { - this.dispatchEvent(new SelectionEvent([map])); - } - - showMap() { - if (this.currentMap === this._map) return; - this.currentMap = this._map; - this.selectedMapLogEntries = [this._map]; - this.update(); - } - - _update() { - this.transitionView.style.display = 'none'; - DOM.removeAllChildren(this.transitionView); - this._displayedMapsInTree = new Set(); - // Limit view to 200 maps for performance reasons. - this.selectedMapLogEntries.slice(0, 200).forEach( - (map) => this.addMapAndParentTransitions(map)); - this._displayedMapsInTree = undefined; - this.transitionView.style.display = ''; - } - - set selectedMapLogEntries(list) { - this._selectedMapLogEntries = list; - this.update(); - } - - get selectedMapLogEntries() { - return this._selectedMapLogEntries; - } - - addMapAndParentTransitions(map) { - if (map === void 0) return; - if (this._displayedMapsInTree.has(map)) return; - this._displayedMapsInTree.add(map); - this.currentNode = this.transitionView; - let parents = map.getParents(); - if (parents.length > 0) { - this.addTransitionTo(parents.pop()); - parents.reverse().forEach((each) => this.addTransitionTo(each)); - } - let mapNode = this.addSubtransitions(map); - // Mark and show the selected map. - mapNode.classList.add('selected'); - if (this.selectedMap == map) { - setTimeout( - () => mapNode.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - inline: 'nearest', - }), - 1); - } - } - - addSubtransitions(map) { - let mapNode = this.addTransitionTo(map); - // Draw outgoing linear transition line. - let current = map; - while (current.children.length == 1) { - current = current.children[0].to; - this.addTransitionTo(current); - } - return mapNode; - } - - addTransitionEdge(map) { - let classes = ['transitionEdge']; - let edge = DOM.div(classes); - edge.style.backgroundColor = typeToColor(map.edge); - let labelNode = DOM.div('transitionLabel'); - labelNode.innerText = map.edge.toString(); - edge.appendChild(labelNode); - return edge; - } - - addTransitionTo(map) { - // transition[ transitions[ transition[...], transition[...], ...]]; - this._displayedMapsInTree?.add(map); - let transition = DOM.div('transition'); - if (map.isDeprecated()) transition.classList.add('deprecated'); - if (map.edge) { - transition.appendChild(this.addTransitionEdge(map)); - } - let mapNode = this.addMapNode(map); - transition.appendChild(mapNode); - - let subtree = DOM.div('transitions'); - transition.appendChild(subtree); - - this.currentNode.appendChild(transition); - this.currentNode = subtree; - - return mapNode; - } - - addMapNode(map) { - let node = DOM.div('map'); - if (map.edge) node.style.backgroundColor = typeToColor(map.edge); - node.map = map; - node.addEventListener('click', () => this._selectMap(map)); - if (map.children.length > 1) { - node.innerText = map.children.length; - let showSubtree = DOM.div('showSubtransitions'); - showSubtree.addEventListener('click', (e) => this.toggleSubtree(e, node)); - node.appendChild(showSubtree); - } else if (map.children.length == 0) { - node.innerHTML = '●'; - } - this.currentNode.appendChild(node); - return node; - } - - toggleSubtree(event, node) { - let map = node.map; - event.target.classList.toggle('opened'); - let transitionsNode = node.parentElement.querySelector('.transitions'); - let subtransitionNodes = transitionsNode.children; - if (subtransitionNodes.length <= 1) { - // Add subtransitions excepth the one that's already shown. - let visibleTransitionMap = subtransitionNodes.length == 1 ? - transitionsNode.querySelector('.map').map : - void 0; - map.children.forEach((edge) => { - if (edge.to != visibleTransitionMap) { - this.currentNode = transitionsNode; - this.addSubtransitions(edge.to); - } - }); - } else { - // remove all but the first (currently selected) subtransition - for (let i = subtransitionNodes.length - 1; i > 0; i--) { - transitionsNode.removeChild(subtransitionNodes[i]); - } - } - } -}); diff --git a/deps/v8/tools/system-analyzer/processor.mjs b/deps/v8/tools/system-analyzer/processor.mjs index 49448bb9da0a19..9685e09ad6b076 100644 --- a/deps/v8/tools/system-analyzer/processor.mjs +++ b/deps/v8/tools/system-analyzer/processor.mjs @@ -5,7 +5,8 @@ import {LogReader, parseString, parseVarArgs} from '../logreader.mjs'; import {Profile} from '../profile.mjs'; -import {DeoptLogEntry} from './log/deopt.mjs'; +import {ApiLogEntry} from './log/api.mjs'; +import {CodeLogEntry, DeoptLogEntry} from './log/code.mjs'; import {IcLogEntry} from './log/ic.mjs'; import {Edge, MapLogEntry} from './log/map.mjs'; import {Timeline} from './timeline.mjs'; @@ -17,17 +18,28 @@ export class Processor extends LogReader { _mapTimeline = new Timeline(); _icTimeline = new Timeline(); _deoptTimeline = new Timeline(); + _codeTimeline = new Timeline(); + _apiTimeline = new Timeline(); _formatPCRegexp = /(.*):[0-9]+:[0-9]+$/; + _lastTimestamp = 0; + _lastCodeLogEntry; MAJOR_VERSION = 7; MINOR_VERSION = 6; constructor(logString) { super(); - this.propertyICParser = [ + const propertyICParser = [ parseInt, parseInt, parseInt, parseInt, parseString, parseString, parseString, parseString, parseString, parseString ]; this.dispatchTable_ = { __proto__: null, + 'v8-version': { + parsers: [ + parseInt, + parseInt, + ], + processor: this.processV8Version + }, 'code-creation': { parsers: [ parseString, parseInt, parseInt, parseInt, parseInt, parseString, @@ -42,20 +54,28 @@ export class Processor extends LogReader { ], processor: this.processCodeDeopt }, - 'v8-version': { + 'code-move': + {parsers: [parseInt, parseInt], processor: this.processCodeMove}, + 'code-delete': {parsers: [parseInt], processor: this.processCodeDelete}, + 'code-source-info': { + parsers: [ + parseInt, parseInt, parseInt, parseInt, parseString, parseString, + parseString + ], + processor: this.processCodeSourceInfo + }, + 'code-disassemble': { parsers: [ parseInt, - parseInt, + parseString, + parseString, ], - processor: this.processV8Version + processor: this.processCodeDisassemble }, 'script-source': { parsers: [parseInt, parseString, parseString], processor: this.processScriptSource }, - 'code-move': - {parsers: [parseInt, parseInt], processor: this.processCodeMove}, - 'code-delete': {parsers: [parseInt], processor: this.processCodeDelete}, 'sfi-move': {parsers: [parseInt, parseInt], processor: this.processFunctionMove}, 'map-create': @@ -72,33 +92,37 @@ export class Processor extends LogReader { processor: this.processMapDetails }, 'LoadGlobalIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'LoadGlobalIC') }, 'StoreGlobalIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'StoreGlobalIC') }, 'LoadIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'LoadIC') }, 'StoreIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'StoreIC') }, 'KeyedLoadIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'KeyedLoadIC') }, 'KeyedStoreIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'KeyedStoreIC') }, 'StoreInArrayLiteralIC': { - parsers: this.propertyICParser, + parsers: propertyICParser, processor: this.processPropertyIC.bind(this, 'StoreInArrayLiteralIC') }, + 'api': { + parsers: [parseString, parseVarArgs], + processor: this.processApiEvent + }, }; if (logString) this.processString(logString); } @@ -166,45 +190,56 @@ export class Processor extends LogReader { }); } - /** - * Parser for dynamic code optimization state. - */ - parseState(s) { - switch (s) { - case '': - return Profile.CodeState.COMPILED; - case '~': - return Profile.CodeState.OPTIMIZABLE; - case '*': - return Profile.CodeState.OPTIMIZED; + processV8Version(majorVersion, minorVersion) { + if ((majorVersion == this.MAJOR_VERSION && + minorVersion <= this.MINOR_VERSION) || + (majorVersion < this.MAJOR_VERSION)) { + window.alert( + `Unsupported version ${majorVersion}.${minorVersion}. \n` + + `Please use the matching tool for given the V8 version.`); } - throw new Error(`unknown code state: ${s}`); } processCodeCreation(type, kind, timestamp, start, size, name, maybe_func) { + this._lastTimestamp = timestamp; + let entry; + let stateName = ''; if (maybe_func.length) { const funcAddr = parseInt(maybe_func[0]); - const state = this.parseState(maybe_func[1]); - this._profile.addFuncCode( + stateName = maybe_func[1] ?? ''; + const state = Profile.parseState(maybe_func[1]); + entry = this._profile.addFuncCode( type, name, timestamp, start, size, funcAddr, state); } else { - this._profile.addCode(type, name, timestamp, start, size); + entry = this._profile.addCode(type, name, timestamp, start, size); } + this._lastCodeLogEntry = + new CodeLogEntry(type + stateName, timestamp, kind, entry); + this._codeTimeline.push(this._lastCodeLogEntry); } processCodeDeopt( timestamp, codeSize, instructionStart, inliningId, scriptOffset, deoptKind, deoptLocation, deoptReason) { - this._deoptTimeline.push(new DeoptLogEntry(deoptKind, timestamp)); - } - - processV8Version(majorVersion, minorVersion) { - if ((majorVersion == this.MAJOR_VERSION && - minorVersion <= this.MINOR_VERSION) || - (majorVersion < this.MAJOR_VERSION)) { - window.alert( - `Unsupported version ${majorVersion}.${minorVersion}. \n` + - `Please use the matching tool for given the V8 version.`); + this._lastTimestamp = timestamp; + const codeEntry = this._profile.findEntry(instructionStart); + const logEntry = new DeoptLogEntry( + deoptKind, timestamp, codeEntry, deoptReason, deoptLocation, + scriptOffset, instructionStart, codeSize, inliningId); + this._deoptTimeline.push(logEntry); + this.addSourcePosition(codeEntry, logEntry); + logEntry.functionSourcePosition = logEntry.sourcePosition; + // custom parse deopt location + if (deoptLocation !== '') { + const colSeparator = deoptLocation.lastIndexOf(':'); + const rowSeparator = deoptLocation.lastIndexOf(':', colSeparator - 1); + const script = this.getScript(deoptLocation.substring(1, rowSeparator)); + const line = + parseInt(deoptLocation.substring(rowSeparator + 1, colSeparator)); + const column = parseInt( + deoptLocation.substring(colSeparator + 1, deoptLocation.length - 1)); + logEntry.sourcePosition = + script.addSourcePosition(line, column, logEntry); } } @@ -224,111 +259,138 @@ export class Processor extends LogReader { this._profile.moveFunc(from, to); } - formatName(entry) { - if (!entry) return ''; - let name = entry.func.getName(); - let re = /(.*):[0-9]+:[0-9]+$/; - let array = re.exec(name); - if (!array) return name; - return entry.getState() + array[1]; + processCodeSourceInfo( + start, scriptId, startPos, endPos, sourcePositions, inliningPositions, + inlinedFunctions) { + this._profile.addSourcePositions( + start, scriptId, startPos, endPos, sourcePositions, inliningPositions, + inlinedFunctions); + let profileEntry = this._profile.findEntry(start); + if (profileEntry !== this._lastCodeLogEntry._entry) return; + this.addSourcePosition(profileEntry, this._lastCodeLogEntry); + this._lastCodeLogEntry = undefined; + } + + addSourcePosition(profileEntry, logEntry) { + let script = this.getProfileEntryScript(profileEntry); + const parts = profileEntry.getRawName().split(':'); + if (parts.length < 3) return; + const line = parseInt(parts[parts.length - 2]); + const column = parseInt(parts[parts.length - 1]); + logEntry.sourcePosition = script.addSourcePosition(line, column, logEntry); + } + + processCodeDisassemble(start, kind, disassemble) { + this._profile.addDisassemble(start, kind, disassemble); } processPropertyIC( - type, pc, time, line, column, old_state, new_state, map, key, modifier, + type, pc, time, line, column, old_state, new_state, mapId, key, modifier, slow_reason) { - let fnName = this.functionName(pc); - let parts = fnName.split(' '); - let fileName = parts[parts.length - 1]; - let script = this.getScript(fileName); + this._lastTimestamp = time; + const profileEntry = this._profile.findEntry(pc); + const fnName = this.formatProfileEntry(profileEntry); + const script = this.getProfileEntryScript(profileEntry); + const map = this.getOrCreateMapEntry(mapId, time); // TODO: Use SourcePosition here directly let entry = new IcLogEntry( type, fnName, time, line, column, key, old_state, new_state, map, - slow_reason, script, modifier); + slow_reason, modifier); if (script) { entry.sourcePosition = script.addSourcePosition(line, column, entry); } this._icTimeline.push(entry); } - functionName(pc) { - let entry = this._profile.findEntry(pc); - return this.formatName(entry); - } - formatPC(pc, line, column) { - let entry = this._profile.findEntry(pc); - if (!entry) return '' - if (entry.type === 'Builtin') { - return entry.name; - } - let name = entry.func.getName(); - let array = this._formatPCRegexp.exec(name); - if (array === null) { - entry = name; - } else { - entry = entry.getState() + array[1]; - } - return entry + ':' + line + ':' + column; + formatProfileEntry(profileEntry, line, column) { + if (!profileEntry) return ''; + if (profileEntry.type === 'Builtin') return profileEntry.name; + const name = profileEntry.func.getName(); + const array = this._formatPCRegexp.exec(name); + const formatted = + (array === null) ? name : profileEntry.getState() + array[1]; + if (line === undefined || column === undefined) return formatted; + return `${formatted}:${line}:${column}`; } - processFileName(filePositionLine) { - if (!filePositionLine.includes(' ')) return; - // Try to handle urls with file positions: https://foo.bar.com/:17:330" - filePositionLine = filePositionLine.split(' '); - let parts = filePositionLine[1].split(':'); - if (parts[0].length <= 5) return parts[0] + ':' + parts[1]; - return parts[1]; + getProfileEntryScript(profileEntry) { + if (!profileEntry) return undefined; + if (profileEntry.type === 'Builtin') return undefined; + const script = profileEntry.source?.script; + if (script !== undefined) return script; + // Slow path, try to get the script from the url: + const fnName = this.formatProfileEntry(profileEntry); + let parts = fnName.split(' '); + let fileName = parts[parts.length - 1]; + return this.getScript(fileName); } processMap(type, time, from, to, pc, line, column, reason, name) { - let time_ = parseInt(time); + this._lastTimestamp = time; + const time_ = parseInt(time); if (type === 'Deprecate') return this.deprecateMap(type, time_, from); - let from_ = this.getExistingMapEntry(from, time_); - let to_ = this.getExistingMapEntry(to, time_); + // Skip normalized maps that were cached so we don't introduce multiple + // edges with the same source and target map. + if (type === 'NormalizeCached') return; + const from_ = this.getOrCreateMapEntry(from, time_); + const to_ = this.getOrCreateMapEntry(to, time_); + if (type === 'Normalize') { + // Fix a bug where we log "Normalize" transitions for maps created from + // the NormalizedMapCache. + if (to_.parent()?.id === from || to_.time < from_.time || to_.depth > 0) { + console.log(`Skipping transition to cached normalized map`); + return; + } + } // TODO: use SourcePosition directly. let edge = new Edge(type, name, reason, time, from_, to_); - to_.filePosition = this.formatPC(pc, line, column); - let fileName = this.processFileName(to_.filePosition); - // TODO: avoid undefined source positions. - if (fileName !== undefined) { - to_.script = this.getScript(fileName); + const profileEntry = this._profile.findEntry(pc) + to_.entry = profileEntry; + let script = this.getProfileEntryScript(profileEntry); + if (script) { + to_.sourcePosition = script.addSourcePosition(line, column, to_) } - if (to_.script) { - to_.sourcePosition = to_.script.addSourcePosition(line, column, to_) + if (to_.parent() !== undefined && to_.parent() === from_) { + // Fix bug where we double log transitions. + console.warn('Fixing up double transition'); + to_.edge.updateFrom(edge); + } else { + edge.finishSetup(); } - edge.finishSetup(); } deprecateMap(type, time, id) { - this.getExistingMapEntry(id, time).deprecate(); + this._lastTimestamp = time; + this.getOrCreateMapEntry(id, time).deprecate(); } processMapCreate(time, id) { // map-create events might override existing maps if the addresses get // recycled. Hence we do not check for existing maps. - let map = this.createMapEntry(id, time); + this._lastTimestamp = time; + this.createMapEntry(id, time); } processMapDetails(time, id, string) { // TODO(cbruni): fix initial map logging. - let map = this.getExistingMapEntry(id, time); + const map = this.getOrCreateMapEntry(id, time); map.description = string; } createMapEntry(id, time) { - let map = new MapLogEntry(id, time); + this._lastTimestamp = time; + const map = new MapLogEntry(id, time); this._mapTimeline.push(map); return map; } - getExistingMapEntry(id, time) { + getOrCreateMapEntry(id, time) { if (id === '0x000000000000') return undefined; - let map = MapLogEntry.get(id, time); - if (map === undefined) { - console.error(`No map details provided: id=${id}`); - // Manually patch in a map to continue running. - return this.createMapEntry(id, time); - }; - return map; + const map = MapLogEntry.get(id, time); + if (map !== undefined) return map; + console.warn(`No map details provided: id=${id}`); + // Manually patch in a map to continue running. + return this.createMapEntry(id, time); } getScript(url) { @@ -340,6 +402,22 @@ export class Processor extends LogReader { return script; } + processApiEvent(type, varArgs) { + let name, arg1; + if (varArgs.length == 0) { + const index = type.indexOf(':'); + if (index > 0) { + name = type; + type = type.substr(0, index); + } + } else { + name = varArgs[0]; + arg1 = varArgs[1]; + } + this._apiTimeline.push( + new ApiLogEntry(type, this._lastTimestamp, name, arg1)); + } + get icTimeline() { return this._icTimeline; } @@ -352,7 +430,19 @@ export class Processor extends LogReader { return this._deoptTimeline; } + get codeTimeline() { + return this._codeTimeline; + } + + get apiTimeline() { + return this._apiTimeline; + } + get scripts() { return this._profile.scripts_.filter(script => script !== undefined); } + + get profile() { + return this._profile; + } } diff --git a/deps/v8/tools/system-analyzer/source-panel-template.html b/deps/v8/tools/system-analyzer/source-panel-template.html deleted file mode 100644 index 01b777042f3d6a..00000000000000 --- a/deps/v8/tools/system-analyzer/source-panel-template.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - -
-

Source Panel

- -
-

-  
-
diff --git a/deps/v8/tools/system-analyzer/stats-panel-template.html b/deps/v8/tools/system-analyzer/stats-panel-template.html deleted file mode 100644 index fb91fad1cf0050..00000000000000 --- a/deps/v8/tools/system-analyzer/stats-panel-template.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - -
-

Map Stats

-
- - - - - -
TypeCountPercent
- - - - - - - - -
CountPropery Name
Show more...
-
-
diff --git a/deps/v8/tools/system-analyzer/stats-panel.mjs b/deps/v8/tools/system-analyzer/stats-panel.mjs deleted file mode 100644 index dd0ac78489a790..00000000000000 --- a/deps/v8/tools/system-analyzer/stats-panel.mjs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2020 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 {SelectionEvent} from './events.mjs'; -import {DOM, V8CustomElement} from './helper.mjs'; -import {delay, LazyTable} from './helper.mjs'; - -DOM.defineCustomElement( - 'stats-panel', (templateText) => class StatsPanel extends V8CustomElement { - _timeline; - _transitions; - _selectedLogEntries; - constructor() { - super(templateText); - } - - get stats() { - return this.$('#stats'); - } - - set timeline(timeline) { - this._timeline = timeline; - this.selectedLogEntries = timeline.all - } - - set selectedLogEntries(entries) { - this._selectedLogEntries = entries; - this.update(); - } - - set transitions(value) { - this._transitions = value; - } - - _filterUniqueTransitions(filter) { - // Returns a list of Maps whose parent is not in the list. - return this._selectedLogEntries.filter((map) => { - if (filter(map) === false) return false; - let parent = map.parent(); - if (parent === undefined) return true; - return filter(parent) === false; - }); - } - - _update() { - this._updateGeneralStats(); - this._updateNamedTransitionsStats(); - } - - _updateGeneralStats() { - console.assert(this._timeline !== undefined, 'Timeline not set yet!'); - let pairs = [ - ['Transitions', 'primary', (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()], - ['Total', null, (e) => true], - ]; - - let tbody = document.createElement('tbody'); - let total = this._selectedLogEntries.length; - pairs.forEach(([name, color, filter]) => { - let row = DOM.tr(); - if (color !== null) { - row.appendChild(DOM.td(DOM.div(['colorbox', color]))); - } else { - row.appendChild(DOM.td('')); - } - row.classList.add('clickable'); - row.onclick = (e) => { - // lazily compute the stats - let node = e.target.parentNode; - if (node.maps == undefined) { - node.maps = this._filterUniqueTransitions(filter); - } - this.dispatchEvent(new SelectionEvent(node.maps)); - }; - row.appendChild(DOM.td(name)); - let count = this._count(filter); - row.appendChild(DOM.td(count)); - let percent = Math.round((count / total) * 1000) / 10; - row.appendChild(DOM.td(percent.toFixed(1) + '%')); - tbody.appendChild(row); - }); - this.$('#typeTable').replaceChild(tbody, this.$('#typeTable tbody')); - } - - _count(filter) { - let count = 0; - for (const map of this._selectedLogEntries) { - if (filter(map)) count++; - } - return count; - } - - _updateNamedTransitionsStats() { - let rowData = Array.from(this._transitions.entries()); - rowData.sort((a, b) => b[1].length - a[1].length); - new LazyTable(this.$('#nameTable'), rowData, ([name, maps]) => { - let row = DOM.tr(); - row.maps = maps; - row.classList.add('clickable'); - row.addEventListener( - 'click', - (e) => this.dispatchEvent(new SelectionEvent( - e.target.parentNode.maps.map((map) => map.to)))); - row.appendChild(DOM.td(maps.length)); - row.appendChild(DOM.td(name)); - return row; - }); - } - }); diff --git a/deps/v8/tools/system-analyzer/timeline-panel-template.html b/deps/v8/tools/system-analyzer/timeline-panel-template.html deleted file mode 100644 index 2641c714414190..00000000000000 --- a/deps/v8/tools/system-analyzer/timeline-panel-template.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - -
-

Timeline Panel

-
- -
-
diff --git a/deps/v8/tools/system-analyzer/timeline.mjs b/deps/v8/tools/system-analyzer/timeline.mjs index 996f108b6a456b..13e97553e6c105 100644 --- a/deps/v8/tools/system-analyzer/timeline.mjs +++ b/deps/v8/tools/system-analyzer/timeline.mjs @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {groupBy} from './helper.mjs' + class Timeline { // Class: _model; @@ -9,13 +11,13 @@ class Timeline { _values; // Current selection, subset of #values: _selection; - _uniqueTypes; + _breakdown; - constructor(model) { + constructor(model, values = [], startTime = 0, endTime = 0) { this._model = model; - this._values = []; - this.startTime = 0; - this.endTime = 0; + this._values = values; + this.startTime = startTime; + this.endTime = endTime; } get model() { @@ -30,21 +32,28 @@ class Timeline { return this._selection; } + get selectionOrSelf() { + return this._selection ?? this; + } + set selection(value) { this._selection = value; } - selectTimeRange(start, end) { - this._selection = this.filter(e => e.time >= start && e.time <= end); + selectTimeRange(startTime, endTime) { + const items = this.range(startTime, endTime); + this._selection = new Timeline(this._model, items, startTime, endTime); + } + + clearSelection() { + this._selection = undefined; } getChunks(windowSizeMs) { - // TODO(zcankara) Fill this one return this.chunkSizes(windowSizeMs); } get values() { - // TODO(zcankara) Not to break something delete later return this._values; } @@ -94,6 +103,10 @@ class Timeline { return this._values.length; } + slice(startIndex, endIndex) { + return this._values.slice(startIndex, endIndex); + } + first() { return this._values[0]; } @@ -102,17 +115,23 @@ class Timeline { return this._values[this._values.length - 1]; } + * [Symbol.iterator]() { + yield* this._values; + } + duration() { + if (this.isEmpty()) return 0; return this.last().time - this.first().time; } forEachChunkSize(count, fn) { + if (this.isEmpty()) return; const increment = this.duration() / count; let currentTime = this.first().time + increment; let index = 0; for (let i = 0; i < count; i++) { - let nextIndex = this.find(currentTime, index); - let nextTime = currentTime + increment; + const nextIndex = this.find(currentTime, index); + const nextTime = currentTime + increment; fn(index, nextIndex, currentTime, nextTime); index = nextIndex; currentTime = nextTime; @@ -120,56 +139,55 @@ class Timeline { } chunkSizes(count) { - let chunks = []; + const chunks = []; this.forEachChunkSize(count, (start, end) => chunks.push(end - start)); return chunks; } - chunks(count) { - let chunks = []; + chunks(count, predicate = undefined) { + const chunks = []; this.forEachChunkSize(count, (start, end, startTime, endTime) => { let items = this._values.slice(start, end); + if (predicate !== undefined) items = items.filter(predicate); chunks.push(new Chunk(chunks.length, startTime, endTime, items)); }); return chunks; } - range(start, end) { - const first = this.find(start); - if (first < 0) return []; - const last = this.find(end, first); - return this._values.slice(first, last); + // Return all entries in ({startTime}, {endTime}] + range(startTime, endTime) { + const firstIndex = this.find(startTime); + if (firstIndex < 0) return []; + const lastIndex = this.find(endTime, firstIndex + 1); + return this._values.slice(firstIndex, lastIndex); } + // Return the first index for the first element at {time}. find(time, offset = 0) { return this._find(this._values, each => each.time - time, offset); } - _find(array, cmp, offset = 0) { - let min = offset; - let max = array.length; - while (min < max) { - let mid = min + Math.floor((max - min) / 2); - let result = cmp(array[mid]); - if (result > 0) { - max = mid - 1; + // Return the first index for which compareFn(item) is >= 0; + _find(array, compareFn, offset = 0) { + let minIndex = offset; + let maxIndex = array.length - 1; + while (minIndex < maxIndex) { + const midIndex = minIndex + (((maxIndex - minIndex) / 2) | 0); + if (compareFn(array[midIndex]) < 0) { + minIndex = midIndex + 1; } else { - min = mid + 1; + maxIndex = midIndex; } } - return min; + return minIndex; } - initializeTypes() { - const types = new Map(); - for (const entry of this.all) { - types.get(entry.type)?.push(entry) ?? types.set(entry.type, [entry]) + getBreakdown(keyFunction) { + if (keyFunction) return groupBy(this._values, keyFunction); + if (this._breakdown === undefined) { + this._breakdown = groupBy(this._values, each => each.type); } - return this._uniqueTypes = types; - } - - get uniqueTypes() { - return this._uniqueTypes ?? this.initializeTypes(); + return this._breakdown; } depthHistogram() { @@ -215,6 +233,10 @@ class Chunk { return this.items.length; } + get length() { + return this.items.length; + } + yOffset(event) { // items[0] == oldest event, displayed at the top of the chunk // items[n-1] == youngest event, displayed at the bottom of the chunk @@ -248,17 +270,8 @@ class Chunk { return chunk; } - getBreakdown(event_fn) { - if (event_fn === void 0) { - event_fn = each => each; - } - let breakdown = {__proto__: null}; - this.items.forEach(each => { - const type = event_fn(each); - const v = breakdown[type]; - breakdown[type] = (v | 0) + 1; - }); - return Object.entries(breakdown).sort((a, b) => a[1] - b[1]); + getBreakdown(keyFunction) { + return groupBy(this.items, keyFunction); } filter() { diff --git a/deps/v8/tools/system-analyzer/timeline/timeline-track-template.html b/deps/v8/tools/system-analyzer/timeline/timeline-track-template.html deleted file mode 100644 index e14b927e4b374e..00000000000000 --- a/deps/v8/tools/system-analyzer/timeline/timeline-track-template.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - -
TypeCountPercent
-
-
-
-
-
Frequency
-
- -
\ No newline at end of file diff --git a/deps/v8/tools/system-analyzer/timeline/timeline-track.mjs b/deps/v8/tools/system-analyzer/timeline/timeline-track.mjs deleted file mode 100644 index a37bcce2c56b2f..00000000000000 --- a/deps/v8/tools/system-analyzer/timeline/timeline-track.mjs +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright 2020 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 {FocusEvent, SelectionEvent, SelectTimeEvent, SynchronizeSelectionEvent} from '../events.mjs'; -import {CSSColor, delay, DOM, V8CustomElement} from '../helper.mjs'; -import {kChunkHeight, kChunkWidth} from '../log/map.mjs'; - -const kColors = [ - CSSColor.green, - CSSColor.violet, - CSSColor.orange, - CSSColor.yellow, - CSSColor.primaryColor, - CSSColor.red, - CSSColor.blue, - CSSColor.yellow, - CSSColor.secondaryColor, -]; - -DOM.defineCustomElement('./timeline/timeline-track', - (templateText) => - class TimelineTrack extends V8CustomElement { - // TODO turn into static field once Safari supports it. - static get SELECTION_OFFSET() { - return 10 - }; - _timeline; - _nofChunks = 400; - _chunks; - _selectedEntry; - _timeToPixel; - _timeSelection = {start: -1, end: Infinity}; - _timeStartOffset; - _selectionOriginTime; - _typeToColor; - constructor() { - super(templateText); - this.timeline.addEventListener('scroll', e => this.handleTimelineScroll(e)); - this.timeline.addEventListener( - 'mousedown', e => this.handleTimeSelectionMouseDown(e)); - this.timeline.addEventListener( - 'mouseup', e => this.handleTimeSelectionMouseUp(e)); - this.timeline.addEventListener( - 'mousemove', e => this.handleTimeSelectionMouseMove(e)); - this.backgroundCanvas = document.createElement('canvas'); - this.isLocked = false; - } - - handleTimeSelectionMouseDown(e) { - let xPosition = e.clientX - // Update origin time in case we click on a handle. - if (this.isOnLeftHandle(xPosition)) { - xPosition = this.rightHandlePosX; - } - else if (this.isOnRightHandle(xPosition)) { - xPosition = this.leftHandlePosX; - } - this._selectionOriginTime = this.positionToTime(xPosition); - } - - isOnLeftHandle(posX) { - return ( - Math.abs(this.leftHandlePosX - posX) <= TimelineTrack.SELECTION_OFFSET); - } - - isOnRightHandle(posX) { - return ( - Math.abs(this.rightHandlePosX - posX) <= - TimelineTrack.SELECTION_OFFSET); - } - - handleTimeSelectionMouseMove(e) { - if (!this._isSelecting) return; - const currentTime = this.positionToTime(e.clientX); - this.dispatchEvent(new SynchronizeSelectionEvent( - Math.min(this._selectionOriginTime, currentTime), - Math.max(this._selectionOriginTime, currentTime))); - } - - handleTimeSelectionMouseUp(e) { - this._selectionOriginTime = -1; - const delta = this._timeSelection.end - this._timeSelection.start; - if (delta <= 1 || isNaN(delta)) return; - this.dispatchEvent(new SelectTimeEvent( - this._timeSelection.start, this._timeSelection.end)); - } - - set timeSelection(selection) { - this._timeSelection.start = selection.start; - this._timeSelection.end = selection.end; - this.updateSelection(); - } - - get _isSelecting() { - return this._selectionOriginTime >= 0; - } - - updateSelection() { - const startPosition = this.timeToPosition(this._timeSelection.start); - const endPosition = this.timeToPosition(this._timeSelection.end); - const delta = endPosition - startPosition; - this.leftHandle.style.left = startPosition + 'px'; - this.selection.style.left = startPosition + 'px'; - this.rightHandle.style.left = endPosition + 'px'; - this.selection.style.width = delta + 'px'; - } - - get leftHandlePosX() { - return this.leftHandle.getBoundingClientRect().x; - } - - get rightHandlePosX() { - return this.rightHandle.getBoundingClientRect().x; - } - - // Maps the clicked x position to the x position on timeline canvas - positionOnTimeline(posX) { - let rect = this.timeline.getBoundingClientRect(); - let posClickedX = posX - rect.left + this.timeline.scrollLeft; - return posClickedX; - } - - positionToTime(posX) { - let posTimelineX = this.positionOnTimeline(posX) + this._timeStartOffset; - return posTimelineX / this._timeToPixel; - } - - timeToPosition(time) { - let posX = time * this._timeToPixel; - posX -= this._timeStartOffset - return posX; - } - - get leftHandle() { - return this.$('.leftHandle'); - } - - get rightHandle() { - return this.$('.rightHandle'); - } - - get selection() { - return this.$('.selection'); - } - - get timelineCanvas() { - return this.$('#timelineCanvas'); - } - - get timelineChunks() { - return this.$('#timelineChunks'); - } - - get timeline() { - return this.$('#timeline'); - } - - get timelineLegend() { - return this.$('#legend'); - } - - get timelineLegendContent() { - return this.$('#legendContent'); - } - - set data(value) { - this._timeline = value; - this._resetTypeToColorCache(); - this.update(); - } - - _update() { - this._updateChunks(); - this._updateTimeline(); - this._renderLegend(); - } - - _resetTypeToColorCache() { - this._typeToColor = new Map(); - let lastIndex = 0; - for (const type of this.data.uniqueTypes.keys()) { - this._typeToColor.set(type, kColors[lastIndex++]); - } - } - - get data() { - return this._timeline; - } - - set nofChunks(count) { - this._nofChunks = count; - this.update(); - } - - get nofChunks() { - return this._nofChunks; - } - - _updateChunks() { - this._chunks = this.data.chunks(this.nofChunks); - } - - get chunks() { - return this._chunks; - } - - set selectedEntry(value) { - this._selectedEntry = value; - if (value.edge) this.redraw(); - } - - get selectedEntry() { - return this._selectedEntry; - } - - set scrollLeft(offset) { - this.timeline.scrollLeft = offset; - } - - typeToColor(type) { - return this._typeToColor.get(type); - } - - _renderLegend() { - let timelineLegendContent = this.timelineLegendContent; - DOM.removeAllChildren(timelineLegendContent); - this._timeline.uniqueTypes.forEach((entries, type) => { - let row = DOM.tr('clickable'); - row.entries = entries; - row.addEventListener('dblclick', e => this.handleEntryTypeDblClick(e)); - let color = this.typeToColor(type); - if (color !== null) { - let div = DOM.div('colorbox'); - div.style.backgroundColor = color; - row.appendChild(DOM.td(div)); - } else { - row.appendChild(DOM.td()); - } - let td = DOM.td(type); - row.appendChild(td); - row.appendChild(DOM.td(entries.length)); - let percent = (entries.length / this.data.all.length) * 100; - row.appendChild(DOM.td(percent.toFixed(1) + '%')); - timelineLegendContent.appendChild(row); - }); - // Add Total row. - let row = DOM.tr(); - row.appendChild(DOM.td('')); - row.appendChild(DOM.td('All')); - row.appendChild(DOM.td(this.data.all.length)); - row.appendChild(DOM.td('100%')); - timelineLegendContent.appendChild(row); - this.timelineLegend.appendChild(timelineLegendContent); - } - - handleEntryTypeDblClick(e) { - this.dispatchEvent(new SelectionEvent(e.target.parentNode.entries)); - } - - timelineIndicatorMove(offset) { - this.timeline.scrollLeft += offset; - } - - handleTimelineScroll(e) { - let horizontal = e.currentTarget.scrollLeft; - this.dispatchEvent(new CustomEvent( - 'scrolltrack', {bubbles: true, composed: true, detail: horizontal})); - } - - async setChunkBackgrounds(backgroundTodo) { - const kMaxDuration = 50; - let lastTime = 0; - for (let [chunk, node] of backgroundTodo) { - const current = performance.now(); - if (current - lastTime > kMaxDuration) { - await delay(25); - lastTime = current; - } - this.setChunkBackground(chunk, node); - } - } - - setChunkBackground(chunk, node) { - // Render the types of transitions as bar charts - const kHeight = chunk.height; - const kWidth = 1; - this.backgroundCanvas.width = kWidth; - this.backgroundCanvas.height = kHeight; - let ctx = this.backgroundCanvas.getContext('2d'); - ctx.clearRect(0, 0, kWidth, kHeight); - let y = 0; - let total = chunk.size(); - let type, count; - if (true) { - chunk.getBreakdown(map => map.type).forEach(([type, count]) => { - ctx.fillStyle = this.typeToColor(type); - let height = count / total * kHeight; - ctx.fillRect(0, y, kWidth, y + height); - y += height; - }); - } else { - chunk.items.forEach(map => { - ctx.fillStyle = this.typeToColor(map.type); - let y = chunk.yOffset(map); - ctx.fillRect(0, y, kWidth, y + 1); - }); - } - - let imageData = this.backgroundCanvas.toDataURL('image/webp', 0.2); - node.style.backgroundImage = `url(${imageData})`; - } - - _updateTimeline() { - let chunksNode = this.timelineChunks; - DOM.removeAllChildren(chunksNode); - let chunks = this.chunks; - let max = chunks.max(each => each.size()); - let start = this.data.startTime; - let end = this.data.endTime; - let duration = end - start; - this._timeToPixel = chunks.length * kChunkWidth / duration; - this._timeStartOffset = start * this._timeToPixel; - let addTimestamp = (time, name) => { - let timeNode = DOM.div('timestamp'); - timeNode.innerText = name; - timeNode.style.left = ((time - start) * this._timeToPixel) + 'px'; - chunksNode.appendChild(timeNode); - }; - let backgroundTodo = []; - for (let i = 0; i < chunks.length; i++) { - let chunk = chunks[i]; - let height = (chunk.size() / max * kChunkHeight); - chunk.height = height; - if (chunk.isEmpty()) continue; - let node = DOM.div(); - node.className = 'chunk'; - node.style.left = ((chunks[i].start - start) * this._timeToPixel) + 'px'; - node.style.height = height + 'px'; - node.chunk = chunk; - node.addEventListener('mousemove', e => this.handleChunkMouseMove(e)); - node.addEventListener('click', e => this.handleChunkClick(e)); - node.addEventListener('dblclick', e => this.handleChunkDoubleClick(e)); - backgroundTodo.push([chunk, node]) - chunksNode.appendChild(node); - } - this.setChunkBackgrounds(backgroundTodo); - - // Put a time marker roughly every 20 chunks. - let expected = duration / chunks.length * 20; - let interval = (10 ** Math.floor(Math.log10(expected))); - let correction = Math.log10(expected / interval); - correction = (correction < 0.33) ? 1 : (correction < 0.75) ? 2.5 : 5; - interval *= correction; - - let time = start; - while (time < end) { - addTimestamp(time, ((time - start) / 1000) + ' ms'); - time += interval; - } - this.redraw(); - } - - handleChunkMouseMove(event) { - if (this.isLocked) return false; - if (this._isSelecting) return false; - let chunk = event.target.chunk; - if (!chunk) return; - // topmost map (at chunk.height) == map #0. - let relativeIndex = - Math.round(event.layerY / event.target.offsetHeight * chunk.size()); - let map = chunk.at(relativeIndex); - this.dispatchEvent(new FocusEvent(map)); - } - - handleChunkClick(event) { - this.isLocked = !this.isLocked; - } - - handleChunkDoubleClick(event) { - let chunk = event.target.chunk; - if (!chunk) return; - this.dispatchEvent(new SelectTimeEvent(chunk.start, chunk.end)); - } - - redraw() { - let canvas = this.timelineCanvas; - canvas.width = (this.chunks.length + 1) * kChunkWidth; - canvas.height = kChunkHeight; - let ctx = canvas.getContext('2d'); - ctx.clearRect(0, 0, canvas.width, kChunkHeight); - if (!this.selectedEntry || !this.selectedEntry.edge) return; - this.drawEdges(ctx); - } - setMapStyle(map, ctx) { - ctx.fillStyle = map.edge && map.edge.from ? CSSColor.onBackgroundColor : - CSSColor.onPrimaryColor; - } - - setEdgeStyle(edge, ctx) { - let color = this.typeToColor(edge.type); - ctx.strokeStyle = color; - ctx.fillStyle = color; - } - - markMap(ctx, map) { - let [x, y] = map.position(this.chunks); - ctx.beginPath(); - this.setMapStyle(map, ctx); - ctx.arc(x, y, 3, 0, 2 * Math.PI); - ctx.fill(); - ctx.beginPath(); - ctx.fillStyle = CSSColor.onBackgroundColor; - ctx.arc(x, y, 2, 0, 2 * Math.PI); - ctx.fill(); - } - - markSelectedMap(ctx, map) { - let [x, y] = map.position(this.chunks); - ctx.beginPath(); - this.setMapStyle(map, ctx); - ctx.arc(x, y, 6, 0, 2 * Math.PI); - ctx.strokeStyle = CSSColor.onBackgroundColor; - ctx.stroke(); - } - - drawEdges(ctx) { - // Draw the trace of maps in reverse order to make sure the outgoing - // transitions of previous maps aren't drawn over. - const kMaxOutgoingEdges = 100; - let nofEdges = 0; - let stack = []; - let current = this.selectedEntry; - while (current && nofEdges < kMaxOutgoingEdges) { - nofEdges += current.children.length; - stack.push(current); - current = current.parent(); - } - ctx.save(); - this.drawOutgoingEdges(ctx, this.selectedEntry, 3); - ctx.restore(); - - let labelOffset = 15; - let xPrev = 0; - while (current = stack.pop()) { - if (current.edge) { - this.setEdgeStyle(current.edge, ctx); - let [xTo, yTo] = this.drawEdge(ctx, current.edge, true, labelOffset); - if (xTo == xPrev) { - labelOffset += 8; - } else { - labelOffset = 15 - } - xPrev = xTo; - } - this.markMap(ctx, current); - current = current.parent(); - ctx.save(); - // this.drawOutgoingEdges(ctx, current, 1); - ctx.restore(); - } - // Mark selected map - this.markSelectedMap(ctx, this.selectedEntry); - } - - drawEdge(ctx, edge, showLabel = true, labelOffset = 20) { - if (!edge.from || !edge.to) return [-1, -1]; - let [xFrom, yFrom] = edge.from.position(this.chunks); - let [xTo, yTo] = edge.to.position(this.chunks); - let sameChunk = xTo == xFrom; - if (sameChunk) labelOffset += 8; - - ctx.beginPath(); - ctx.moveTo(xFrom, yFrom); - let offsetX = 20; - let offsetY = 20; - let midX = xFrom + (xTo - xFrom) / 2; - let midY = (yFrom + yTo) / 2 - 100; - if (!sameChunk) { - ctx.quadraticCurveTo(midX, midY, xTo, yTo); - } else { - ctx.lineTo(xTo, yTo); - } - if (!showLabel) { - ctx.stroke(); - } else { - let centerX, centerY; - if (!sameChunk) { - centerX = (xFrom / 2 + midX + xTo / 2) / 2; - centerY = (yFrom / 2 + midY + yTo / 2) / 2; - } else { - centerX = xTo; - centerY = yTo; - } - ctx.moveTo(centerX, centerY); - ctx.lineTo(centerX + offsetX, centerY - labelOffset); - ctx.stroke(); - ctx.textAlign = 'left'; - ctx.fillStyle = this.typeToColor(edge.type); - ctx.fillText( - edge.toString(), centerX + offsetX + 2, centerY - labelOffset); - } - return [xTo, yTo]; - } - - drawOutgoingEdges(ctx, map, max = 10, depth = 0) { - if (!map) return; - if (depth >= max) return; - ctx.globalAlpha = 0.5 - depth * (0.3 / max); - ctx.strokeStyle = CSSColor.timelineBackgroundColor; - const limit = Math.min(map.children.length, 100) - for (let i = 0; i < limit; i++) { - let edge = map.children[i]; - this.drawEdge(ctx, edge, true); - this.drawOutgoingEdges(ctx, edge.to, max, depth + 1); - } - } -}); diff --git a/deps/v8/tools/system-analyzer/view/code-panel-template.html b/deps/v8/tools/system-analyzer/view/code-panel-template.html new file mode 100644 index 00000000000000..e04c6be8c182cb --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/code-panel-template.html @@ -0,0 +1,25 @@ + + + + + + +
+

Code Panel

+
+ + +
+
+

Disassembly

+

+    

Source Code

+

+  
+
diff --git a/deps/v8/tools/system-analyzer/view/code-panel.mjs b/deps/v8/tools/system-analyzer/view/code-panel.mjs new file mode 100644 index 00000000000000..3b5261e03c3fd9 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/code-panel.mjs @@ -0,0 +1,82 @@ +// Copyright 2020 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 {IcLogEntry} from '../log/ic.mjs'; +import {MapLogEntry} from '../log/map.mjs'; + +import {FocusEvent, SelectionEvent, ToolTipEvent} from './events.mjs'; +import {delay, DOM, formatBytes, formatMicroSeconds, V8CustomElement} from './helper.mjs'; + +DOM.defineCustomElement('view/code-panel', + (templateText) => + class CodePanel extends V8CustomElement { + _timeline; + _selectedEntries; + _entry; + + constructor() { + super(templateText); + this._codeSelectNode.onchange = this._handleSelectCode.bind(this); + this.$('#selectedRelatedButton').onclick = + this._handleSelectRelated.bind(this) + } + + set timeline(timeline) { + this._timeline = timeline; + this.$('.panel').style.display = timeline.isEmpty() ? 'none' : 'inherit'; + this.update(); + } + + set selectedEntries(entries) { + this._selectedEntries = entries; + // TODO: add code selection dropdown + this._updateSelect(); + this.entry = entries.first(); + } + + set entry(entry) { + this._entry = entry; + this.update(); + } + + get _disassemblyNode() { + return this.$('#disassembly'); + } + + get _sourceNode() { + return this.$('#sourceCode'); + } + + get _codeSelectNode() { + return this.$('#codeSelect'); + } + + _update() { + this._disassemblyNode.innerText = this._entry?.disassemble ?? ''; + this._sourceNode.innerText = this._entry?.source ?? ''; + } + + _updateSelect() { + const select = this._codeSelectNode; + select.options.length = 0; + const sorted = + this._selectedEntries.slice().sort((a, b) => a.time - b.time); + for (const code of this._selectedEntries) { + const option = DOM.element('option'); + option.text = + `${code.name}(...) t=${formatMicroSeconds(code.time)} size=${ + formatBytes(code.size)} script=${code.script?.toString()}`; + option.data = code; + select.add(option); + } + } + + _handleSelectCode() { + this.entry = this._codeSelectNode.selectedOptions[0].data; + } + + _handleSelectRelated(e) { + if (!this._entry) return; + this.dispatchEvent(new SelectRelatedEvent(this._entry)); + } +}); \ No newline at end of file diff --git a/deps/v8/tools/system-analyzer/view/events.mjs b/deps/v8/tools/system-analyzer/view/events.mjs new file mode 100644 index 00000000000000..4204973f8f2027 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/events.mjs @@ -0,0 +1,93 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +class AppEvent extends CustomEvent { + constructor(name) { + super(name, {bubbles: true, composed: true}); + } +} + +export class SelectionEvent extends AppEvent { + // TODO: turn into static class fields once Safari supports it. + static get name() { + return 'select'; + } + + constructor(entries) { + super(SelectionEvent.name); + if (!Array.isArray(entries) || entries.length == 0) { + throw new Error('No valid entries selected!'); + } + this.entries = entries; + } +} + +export class SelectRelatedEvent extends AppEvent { + static get name() { + return 'selectrelated'; + } + + constructor(entry) { + super(SelectRelatedEvent.name); + this.entry = entry; + } +} + +export class FocusEvent extends AppEvent { + static get name() { + return 'showentrydetail'; + } + + constructor(entry) { + super(FocusEvent.name); + this.entry = entry; + } +} + +export class SelectTimeEvent extends AppEvent { + static get name() { + return 'timerangeselect'; + } + + constructor(start = 0, end = Infinity) { + super(SelectTimeEvent.name); + this.start = start; + this.end = end; + } +} + +export class SynchronizeSelectionEvent extends AppEvent { + static get name() { + return 'syncselection'; + } + + constructor(start, end) { + super(SynchronizeSelectionEvent.name); + this.start = start; + this.end = end; + } +} + +export class ToolTipEvent extends AppEvent { + static get name() { + return 'showtooltip'; + } + + constructor(content, positionOrTargetNode) { + super(ToolTipEvent.name); + this._content = content; + if (!positionOrTargetNode && !node) { + throw Error('Either provide a valid position or targetNode'); + } + this._positionOrTargetNode = positionOrTargetNode; + } + + get content() { + return this._content; + } + + get positionOrTargetNode() { + return this._positionOrTargetNode; + } +} diff --git a/deps/v8/tools/system-analyzer/view/helper.mjs b/deps/v8/tools/system-analyzer/view/helper.mjs new file mode 100644 index 00000000000000..780864ef5a0a92 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/helper.mjs @@ -0,0 +1,314 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +class CSSColor { + static _cache = new Map(); + + static get(name) { + let color = this._cache.get(name); + if (color !== undefined) return color; + const style = getComputedStyle(document.body); + color = style.getPropertyValue(`--${name}`); + if (color === undefined) { + throw new Error(`CSS color does not exist: ${name}`); + } + color = color.trim(); + this._cache.set(name, color); + return color; + } + static reset() { + this._cache.clear(); + } + + static get backgroundColor() { + return this.get('background-color'); + } + static get surfaceColor() { + return this.get('surface-color'); + } + static get primaryColor() { + return this.get('primary-color'); + } + static get secondaryColor() { + return this.get('secondary-color'); + } + static get onSurfaceColor() { + return this.get('on-surface-color'); + } + static get onBackgroundColor() { + return this.get('on-background-color'); + } + static get onPrimaryColor() { + return this.get('on-primary-color'); + } + static get onSecondaryColor() { + return this.get('on-secondary-color'); + } + static get defaultColor() { + return this.get('default-color'); + } + static get errorColor() { + return this.get('error-color'); + } + static get mapBackgroundColor() { + return this.get('map-background-color'); + } + static get timelineBackgroundColor() { + return this.get('timeline-background-color'); + } + static get red() { + return this.get('red'); + } + static get green() { + return this.get('green'); + } + static get yellow() { + return this.get('yellow'); + } + static get blue() { + return this.get('blue'); + } + + static get orange() { + return this.get('orange'); + } + + static get violet() { + return this.get('violet'); + } + + static at(index) { + return this.list[index % this.list.length]; + } + + static darken(hexColorString, amount = -40) { + if (hexColorString[0] !== '#') { + throw new Error(`Unsupported color: ${hexColorString}`); + } + let color = parseInt(hexColorString.substring(1), 16); + let b = Math.min(Math.max((color & 0xFF) + amount, 0), 0xFF); + let g = Math.min(Math.max(((color >> 8) & 0xFF) + amount, 0), 0xFF); + let r = Math.min(Math.max(((color >> 16) & 0xFF) + amount, 0), 0xFF); + color = (r << 16) + (g << 8) + b; + return `#${color.toString(16).padStart(6, '0')}`; + } + + static get list() { + if (!this._colors) { + this._colors = [ + this.green, + this.violet, + this.orange, + this.yellow, + this.primaryColor, + this.red, + this.blue, + this.yellow, + this.secondaryColor, + this.darken(this.green), + this.darken(this.violet), + this.darken(this.orange), + this.darken(this.yellow), + this.darken(this.primaryColor), + this.darken(this.red), + this.darken(this.blue), + this.darken(this.yellow), + this.darken(this.secondaryColor), + ]; + } + return this._colors; + } +} + +class DOM { + static element(type, classes) { + const node = document.createElement(type); + if (classes === undefined) return node; + if (typeof classes === 'string') { + node.className = classes; + } else { + classes.forEach(cls => node.classList.add(cls)); + } + return node; + } + + static text(string) { + return document.createTextNode(string); + } + + static div(classes) { + return this.element('div', classes); + } + + static span(classes) { + return this.element('span', classes); + } + + static table(classes) { + return this.element('table', classes); + } + + static tbody(classes) { + return this.element('tbody', classes); + } + + static td(textOrNode, className) { + const node = this.element('td'); + if (typeof textOrNode === 'object') { + node.appendChild(textOrNode); + } else if (textOrNode) { + node.innerText = textOrNode; + } + if (className) node.className = className; + return node; + } + + static tr(classes) { + return this.element('tr', classes); + } + + static removeAllChildren(node) { + let range = document.createRange(); + range.selectNodeContents(node); + range.deleteContents(); + } + + static defineCustomElement(path, generator) { + let name = path.substring(path.lastIndexOf('/') + 1, path.length); + path = path + '-template.html'; + fetch(path) + .then(stream => stream.text()) + .then( + templateText => + customElements.define(name, generator(templateText))); + } +} + +function $(id) { + return document.querySelector(id) +} + +class V8CustomElement extends HTMLElement { + _updateTimeoutId; + _updateCallback = this._update.bind(this); + + constructor(templateText) { + super(); + const shadowRoot = this.attachShadow({mode: 'open'}); + shadowRoot.innerHTML = templateText; + this._updateCallback = this._update.bind(this); + } + + $(id) { + return this.shadowRoot.querySelector(id); + } + + querySelectorAll(query) { + return this.shadowRoot.querySelectorAll(query); + } + + update(useAnimation = false) { + if (useAnimation) { + window.cancelAnimationFrame(this._updateTimeoutId); + this._updateTimeoutId = + window.requestAnimationFrame(this._updateCallback); + } else { + // Use timeout tasks to asynchronously update the UI without blocking. + clearTimeout(this._updateTimeoutId); + const kDelayMs = 5; + this._updateTimeoutId = setTimeout(this._updateCallback, kDelayMs); + } + } + + _update() { + throw Error('Subclass responsibility'); + } +} + +class Chunked { + constructor(iterable, limit) { + this._iterator = iterable[Symbol.iterator](); + this._limit = limit; + } + + * next(limit = undefined) { + for (let i = 0; i < (limit ?? this._limit); i++) { + const {value, done} = this._iterator.next(); + if (done) { + this._iterator = undefined; + return; + }; + yield value; + } + } + + get hasMore() { + return this._iterator !== undefined; + } +} + +class LazyTable { + constructor(table, rowData, rowElementCreator, limit = 100) { + this._table = table; + this._chunkedRowData = new Chunked(rowData, limit); + this._rowElementCreator = rowElementCreator; + if (table.tBodies.length == 0) { + table.appendChild(DOM.tbody()); + } else { + table.replaceChild(DOM.tbody(), table.tBodies[0]); + } + if (!table.tFoot) { + const td = table.appendChild(DOM.element('tfoot')) + .appendChild(DOM.tr()) + .appendChild(DOM.td()); + for (let count of [10, 100]) { + const button = DOM.element('button'); + button.innerText = `+${count}`; + button.onclick = (e) => this._addMoreRows(count); + td.appendChild(button); + } + td.setAttribute('colspan', 100); + } + table.tFoot.addEventListener('click', this._clickHandler); + this._addMoreRows(); + } + + _addMoreRows(count = undefined) { + const fragment = new DocumentFragment(); + for (let row of this._chunkedRowData.next(count)) { + const tr = this._rowElementCreator(row); + fragment.appendChild(tr); + } + this._table.tBodies[0].appendChild(fragment); + if (!this._chunkedRowData.hasMore) { + DOM.removeAllChildren(this._table.tFoot); + } + } +} + +export function gradientStopsFromGroups( + totalLength, maxHeight, groups, colorFn) { + const kMaxHeight = maxHeight === '%' ? 100 : maxHeight; + const kUnit = maxHeight === '%' ? '%' : 'px'; + let increment = 0; + let lastHeight = 0.0; + const stops = []; + for (let group of groups) { + const color = colorFn(group.key); + increment += group.count; + let height = (increment / totalLength * kMaxHeight) | 0; + stops.push(`${color} ${lastHeight}${kUnit} ${height}${kUnit}`) + lastHeight = height; + } + return stops; +} + +export * from '../helper.mjs'; +export { + DOM, + $, + V8CustomElement, + CSSColor, + LazyTable, +}; diff --git a/deps/v8/tools/system-analyzer/view/list-panel-template.html b/deps/v8/tools/system-analyzer/view/list-panel-template.html new file mode 100644 index 00000000000000..4714f97c02f8c8 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/list-panel-template.html @@ -0,0 +1,78 @@ + + + + + + + +
+ + +

+
+ + + + + + +
+ +
+ + +
+
+
diff --git a/deps/v8/tools/system-analyzer/view/list-panel.mjs b/deps/v8/tools/system-analyzer/view/list-panel.mjs new file mode 100644 index 00000000000000..85e3cd47e28f36 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/list-panel.mjs @@ -0,0 +1,198 @@ +// Copyright 2020 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 {Script, SourcePosition} from '../../profile.mjs'; +import {LogEntry} from '../log/log.mjs'; + +import {FocusEvent} from './events.mjs'; +import {groupBy, LazyTable} from './helper.mjs'; +import {DOM, V8CustomElement} from './helper.mjs'; + +DOM.defineCustomElement('view/list-panel', + (templateText) => + class ListPanel extends V8CustomElement { + _selectedLogEntries = []; + _displayedLogEntries = []; + _timeline; + + _detailsClickHandler = this._handleDetailsClick.bind(this); + _logEntryClickHandler = this._handleLogEntryClick.bind(this); + + constructor() { + super(templateText); + this.groupKey.addEventListener('change', e => this.update()); + this.showAllRadio.onclick = _ => this._showEntries(this._timeline); + this.showTimerangeRadio.onclick = _ => + this._showEntries(this._timeline.selectionOrSelf); + this.showSelectionRadio.onclick = _ => + this._showEntries(this._selectedLogEntries); + } + + static get observedAttributes() { + return ['title']; + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name == 'title') { + this.$('#title').innerHTML = newValue; + } + } + + set timeline(timeline) { + console.assert(timeline !== undefined, 'timeline undefined!'); + this._timeline = timeline; + this.$('.panel').style.display = timeline.isEmpty() ? 'none' : 'inherit'; + this._initGroupKeySelect(); + } + + set selectedLogEntries(entries) { + if (entries === this._timeline) { + this.showAllRadio.click(); + } else if (entries === this._timeline.selection) { + this.showTimerangeRadio.click(); + } else { + this._selectedLogEntries = entries; + this.showSelectionRadio.click(); + } + } + + get entryClass() { + return this._timeline.at(0)?.constructor; + } + + get groupKey() { + return this.$('#group-key'); + } + + get table() { + return this.$('#table'); + } + + get showAllRadio() { + return this.$('#show-all'); + } + get showTimerangeRadio() { + return this.$('#show-timerange'); + } + get showSelectionRadio() { + return this.$('#show-selection'); + } + + get _propertyNames() { + return this.entryClass?.propertyNames ?? []; + } + + _initGroupKeySelect() { + const select = this.groupKey; + select.options.length = 0; + for (const propertyName of this._propertyNames) { + const option = DOM.element('option'); + option.text = propertyName; + select.add(option); + } + } + + _showEntries(entries) { + this._displayedLogEntries = entries; + this.update(); + } + + _update() { + if (this._timeline.isEmpty()) return; + DOM.removeAllChildren(this.table); + if (this._displayedLogEntries.length == 0) return; + const propertyName = this.groupKey.selectedOptions[0].text; + const groups = + groupBy(this._displayedLogEntries, each => each[propertyName], true); + this._render(groups, this.table); + } + + createSubgroups(group) { + const map = new Map(); + for (let propertyName of this._propertyNames) { + map.set( + propertyName, + groupBy(group.entries, each => each[propertyName], true)); + } + return map; + } + + _handleLogEntryClick(e) { + const group = e.currentTarget.group; + this.dispatchEvent(new FocusEvent(group.key)); + } + + _handleDetailsClick(event) { + event.stopPropagation(); + const tr = event.target.parentNode; + const group = tr.group; + // Create subgroup in-place if the don't exist yet. + if (tr.groups === undefined) { + const groups = tr.groups = this.createSubgroups(group); + this.renderDrilldown(groups, tr); + } + const detailsTr = tr.nextSibling; + if (tr.classList.contains('open')) { + tr.classList.remove('open'); + detailsTr.style.display = 'none'; + } else { + tr.classList.add('open'); + detailsTr.style.display = 'table-row'; + } + } + + renderDrilldown(groups, previousSibling) { + const tr = DOM.tr('entry-details'); + tr.style.display = 'none'; + // indent by one td. + tr.appendChild(DOM.td()); + const td = DOM.td(); + td.colSpan = 3; + groups.forEach((group, key) => { + this.renderDrilldownGroup(td, group, key); + }); + tr.appendChild(td); + // Append the new TR after previousSibling. + previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling); + } + + renderDrilldownGroup(td, groups, key) { + const div = DOM.div('drilldown-group-title'); + div.textContent = `Grouped by ${key}: ${groups[0]?.parentTotal ?? 0}#`; + td.appendChild(div); + const table = DOM.table(); + this._render(groups, table, false) + td.appendChild(table); + } + + _render(groups, table) { + let last; + new LazyTable(table, groups, group => { + if (last && last.count < group.count) { + console.log(last, group); + } + last = group; + const tr = DOM.tr(); + tr.group = group; + const details = tr.appendChild(DOM.td('', 'toggle')); + details.onclick = this._detailsClickHandler; + tr.appendChild(DOM.td(`${group.percent.toFixed(2)}%`, 'percentage')); + tr.appendChild(DOM.td(group.count, 'count')); + const valueTd = tr.appendChild(DOM.td(`${group.key}`, 'key')); + if (this._isClickable(group.key)) { + tr.onclick = this._logEntryClickHandler; + valueTd.classList.add('clickable'); + } + return tr; + }, 10); + } + + _isClickable(object) { + if (typeof object !== 'object') return false; + if (object instanceof LogEntry) return true; + if (object instanceof SourcePosition) return true; + if (object instanceof Script) return true; + return false; + } +}); diff --git a/deps/v8/tools/system-analyzer/log-file-reader-template.html b/deps/v8/tools/system-analyzer/view/log-file-reader-template.html similarity index 100% rename from deps/v8/tools/system-analyzer/log-file-reader-template.html rename to deps/v8/tools/system-analyzer/view/log-file-reader-template.html diff --git a/deps/v8/tools/system-analyzer/log-file-reader.mjs b/deps/v8/tools/system-analyzer/view/log-file-reader.mjs similarity index 97% rename from deps/v8/tools/system-analyzer/log-file-reader.mjs rename to deps/v8/tools/system-analyzer/view/log-file-reader.mjs index c46d792d0062d4..fd935f2f836353 100644 --- a/deps/v8/tools/system-analyzer/log-file-reader.mjs +++ b/deps/v8/tools/system-analyzer/view/log-file-reader.mjs @@ -3,7 +3,7 @@ // found in the LICENSE file. import {DOM, V8CustomElement} from './helper.mjs'; -DOM.defineCustomElement('log-file-reader', +DOM.defineCustomElement('view/log-file-reader', (templateText) => class LogFileReader extends V8CustomElement { constructor() { diff --git a/deps/v8/tools/system-analyzer/view/map-panel-template.html b/deps/v8/tools/system-analyzer/view/map-panel-template.html new file mode 100644 index 00000000000000..8a2b23ee3d4b00 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/map-panel-template.html @@ -0,0 +1,36 @@ + + + + + + +
+ + +

Map Panel

+
+ + + + + + +
+

All Transitions

+ +

Search Map by Address

+ + + + +

Details Transitions

+ +

Details

+ +
diff --git a/deps/v8/tools/system-analyzer/view/map-panel.mjs b/deps/v8/tools/system-analyzer/view/map-panel.mjs new file mode 100644 index 00000000000000..7ee2325f34c4a8 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/map-panel.mjs @@ -0,0 +1,106 @@ +// Copyright 2020 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 './map-panel/map-details.mjs'; +import './map-panel/map-transitions.mjs'; + +import {MapLogEntry} from '../log/map.mjs'; + +import {FocusEvent} from './events.mjs'; +import {DOM, V8CustomElement} from './helper.mjs'; + +DOM.defineCustomElement( + 'view/map-panel', (templateText) => class MapPanel extends V8CustomElement { + _map; + _timeline; + _selectedLogEntries = []; + _displayedLogEntries = []; + + constructor() { + super(templateText); + this.searchBarBtn.addEventListener('click', e => this._handleSearch(e)); + this.showAllRadio.onclick = _ => this._showEntries(this._timeline); + this.showTimerangeRadio.onclick = _ => + this._showEntries(this._timeline.selectionOrSelf); + this.showSelectionRadio.onclick = _ => + this._showEntries(this._selectedLogEntries); + } + + get showAllRadio() { + return this.$('#show-all'); + } + get showTimerangeRadio() { + return this.$('#show-timerange'); + } + get showSelectionRadio() { + return this.$('#show-selection'); + } + + get mapTransitionsPanel() { + return this.$('#map-transitions'); + } + + get mapDetailsTransitionsPanel() { + return this.$('#map-details-transitions'); + } + + get mapDetailsPanel() { + return this.$('#map-details'); + } + + get searchBarBtn() { + return this.$('#searchBarBtn'); + } + + get searchBar() { + return this.$('#searchBar'); + } + + set timeline(timeline) { + console.assert(timeline !== undefined, 'timeline undefined!'); + this._timeline = timeline; + this.$('.panel').style.display = + timeline.isEmpty() ? 'none' : 'inherit'; + this.mapTransitionsPanel.timeline = timeline; + this.mapDetailsTransitionsPanel.timeline = timeline; + } + + set selectedLogEntries(entries) { + if (entries === this._timeline.selection) { + this.showTimerangeRadio.click(); + } else if (entries == this._timeline) { + this.showAllRadio.click(); + } else { + this._selectedLogEntries = entries; + this.showSelectionRadio.click(); + } + } + + set map(map) { + this._map = map; + this.mapDetailsTransitionsPanel.selectedLogEntries = [map]; + this.mapDetailsPanel.map = map; + } + + _showEntries(entries) { + this._displayedLogEntries = entries; + this.mapTransitionsPanel.selectedLogEntries = entries; + } + + update() { + // nothing to do + } + + _handleSearch(e) { + let searchBar = this.$('#searchBarInput'); + let searchBarInput = searchBar.value; + // access the map from model cache + let selectedMap = MapLogEntry.get(searchBarInput); + if (selectedMap) { + searchBar.className = 'success'; + this.dispatchEvent(new FocusEvent(selectedMap)); + } else { + searchBar.className = 'failure'; + } + } + }); diff --git a/deps/v8/tools/system-analyzer/map-panel/map-details-template.html b/deps/v8/tools/system-analyzer/view/map-panel/map-details-template.html similarity index 54% rename from deps/v8/tools/system-analyzer/map-panel/map-details-template.html rename to deps/v8/tools/system-analyzer/view/map-panel/map-details-template.html index 6d1b268c5dd412..b109d4c8ac7bbb 100644 --- a/deps/v8/tools/system-analyzer/map-panel/map-details-template.html +++ b/deps/v8/tools/system-analyzer/view/map-panel/map-details-template.html @@ -8,16 +8,12 @@ -
-

Map Details

-
-
-
+
+
diff --git a/deps/v8/tools/system-analyzer/map-panel/map-details.mjs b/deps/v8/tools/system-analyzer/view/map-panel/map-details.mjs similarity index 97% rename from deps/v8/tools/system-analyzer/map-panel/map-details.mjs rename to deps/v8/tools/system-analyzer/view/map-panel/map-details.mjs index bcf8f9c9aa1867..446475a5b088cf 100644 --- a/deps/v8/tools/system-analyzer/map-panel/map-details.mjs +++ b/deps/v8/tools/system-analyzer/view/map-panel/map-details.mjs @@ -5,7 +5,7 @@ import {FocusEvent} from '../events.mjs'; import {DOM, V8CustomElement} from '../helper.mjs'; DOM.defineCustomElement( - './map-panel/map-details', + './view/map-panel/map-details', (templateText) => class MapDetails extends V8CustomElement { _map; diff --git a/deps/v8/tools/system-analyzer/map-panel/map-transitions-template.html b/deps/v8/tools/system-analyzer/view/map-panel/map-transitions-template.html similarity index 93% rename from deps/v8/tools/system-analyzer/map-panel/map-transitions-template.html rename to deps/v8/tools/system-analyzer/view/map-panel/map-transitions-template.html index c4cab2bf46aae7..d5dcca07a78a2b 100644 --- a/deps/v8/tools/system-analyzer/map-panel/map-transitions-template.html +++ b/deps/v8/tools/system-analyzer/view/map-panel/map-transitions-template.html @@ -137,12 +137,4 @@ padding-bottom: 10px; } -
-
-

Transitions

-
-
-
-
-
-
+
diff --git a/deps/v8/tools/system-analyzer/view/map-panel/map-transitions.mjs b/deps/v8/tools/system-analyzer/view/map-panel/map-transitions.mjs new file mode 100644 index 00000000000000..f60bd37d3929b7 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/map-panel/map-transitions.mjs @@ -0,0 +1,181 @@ +// Copyright 2020 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 {FocusEvent, SelectRelatedEvent, ToolTipEvent} from '../events.mjs'; +import {CSSColor} from '../helper.mjs'; +import {DOM, V8CustomElement} from '../helper.mjs'; + +DOM.defineCustomElement( + './view/map-panel/map-transitions', + (templateText) => class MapTransitions extends V8CustomElement { + _timeline; + _map; + _edgeToColor = new Map(); + _selectedLogEntries; + _displayedMapsInTree; + _toggleSubtreeHandler = this._handleToggleSubtree.bind(this); + _mapClickHandler = this._handleMapClick.bind(this); + _mapDoubleClickHandler = this._handleMapDoubleClick.bind(this); + _mouseoverMapHandler = this._handleMouseoverMap.bind(this); + + constructor() { + super(templateText); + this.currentNode = this.transitionView; + } + + get transitionView() { + return this.$('#transitionView'); + } + + set timeline(timeline) { + this._timeline = timeline; + this._edgeToColor.clear(); + timeline.getBreakdown().forEach(breakdown => { + this._edgeToColor.set(breakdown.key, CSSColor.at(breakdown.id)); + }); + } + + set selectedLogEntries(list) { + this._selectedLogEntries = list; + this.update(); + } + + _update() { + this.transitionView.style.display = 'none'; + DOM.removeAllChildren(this.transitionView); + if (this._selectedLogEntries.length == 0) return; + this._displayedMapsInTree = new Set(); + // Limit view to 200 maps for performance reasons. + this._selectedLogEntries.slice(0, 200).forEach( + (map) => this._addMapAndParentTransitions(map)); + this._displayedMapsInTree = undefined; + this.transitionView.style.display = ''; + } + + _addMapAndParentTransitions(map) { + if (map === undefined) return; + if (this._displayedMapsInTree.has(map)) return; + this._displayedMapsInTree.add(map); + this.currentNode = this.transitionView; + let parents = map.getParents(); + if (parents.length > 0) { + this._addTransitionTo(parents.pop()); + parents.reverse().forEach((each) => this._addTransitionTo(each)); + } + let mapNode = this._addSubtransitions(map); + // Mark and show the selected map. + mapNode.classList.add('selected'); + if (this.selectedMap == map) { + setTimeout( + () => mapNode.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + inline: 'nearest', + }), + 1); + } + } + + _addSubtransitions(map) { + let mapNode = this._addTransitionTo(map); + // Draw outgoing linear transition line. + let current = map; + while (current.children.length == 1) { + current = current.children[0].to; + this._addTransitionTo(current); + } + return mapNode; + } + + _addTransitionEdge(map) { + let classes = ['transitionEdge']; + let edge = DOM.div(classes); + edge.style.backgroundColor = this._edgeToColor.get(map.edge.type); + let labelNode = DOM.div('transitionLabel'); + labelNode.innerText = map.edge.toString(); + edge.appendChild(labelNode); + return edge; + } + + _addTransitionTo(map) { + // transition[ transitions[ transition[...], transition[...], ...]]; + this._displayedMapsInTree?.add(map); + let transition = DOM.div('transition'); + if (map.isDeprecated()) transition.classList.add('deprecated'); + if (map.edge) { + transition.appendChild(this._addTransitionEdge(map)); + } + let mapNode = this._addMapNode(map); + transition.appendChild(mapNode); + + let subtree = DOM.div('transitions'); + transition.appendChild(subtree); + + this.currentNode.appendChild(transition); + this.currentNode = subtree; + + return mapNode; + } + + _addMapNode(map) { + let node = DOM.div('map'); + if (map.edge) + node.style.backgroundColor = this._edgeToColor.get(map.edge.type); + node.map = map; + node.onclick = this._mapClickHandler + node.ondblclick = this._mapDoubleClickHandler + node.onmouseover = this._mouseoverMapHandler + if (map.children.length > 1) { + node.innerText = map.children.length; + const showSubtree = DOM.div('showSubtransitions'); + showSubtree.onclick = this._toggleSubtreeHandler + node.appendChild(showSubtree); + } + else if (map.children.length == 0) { + node.innerHTML = '●'; + } + this.currentNode.appendChild(node); + return node; + } + + _handleMapClick(event) { + const map = event.currentTarget.map; + this.dispatchEvent(new FocusEvent(map)); + } + + _handleMapDoubleClick(event) { + this.dispatchEvent(new SelectRelatedEvent(event.currentTarget.map)); + } + + _handleMouseoverMap(event) { + this.dispatchEvent(new ToolTipEvent( + event.currentTarget.map.toStringLong(), event.currentTarget)); + } + + _handleToggleSubtree(event) { + event.preventDefault(); + const node = event.currentTarget.parentElement; + let map = node.map; + event.target.classList.toggle('opened'); + let transitionsNode = node.parentElement.querySelector('.transitions'); + let subtransitionNodes = transitionsNode.children; + if (subtransitionNodes.length <= 1) { + // Add subtransitions except the one that's already shown. + let visibleTransitionMap = subtransitionNodes.length == 1 ? + transitionsNode.querySelector('.map').map : + undefined; + map.children.forEach((edge) => { + if (edge.to != visibleTransitionMap) { + this.currentNode = transitionsNode; + this._addSubtransitions(edge.to); + } + }); + } else { + // remove all but the first (currently selected) subtransition + for (let i = subtransitionNodes.length - 1; i > 0; i--) { + transitionsNode.removeChild(subtransitionNodes[i]); + } + } + return false; + } + }); diff --git a/deps/v8/tools/system-analyzer/view/script-panel-template.html b/deps/v8/tools/system-analyzer/view/script-panel-template.html new file mode 100644 index 00000000000000..27fd3d83eb6e31 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/script-panel-template.html @@ -0,0 +1,72 @@ + + + + + + +
+

Source Panel

+
+ + +
+
+
+
+
diff --git a/deps/v8/tools/system-analyzer/source-panel.mjs b/deps/v8/tools/system-analyzer/view/script-panel.mjs similarity index 67% rename from deps/v8/tools/system-analyzer/source-panel.mjs rename to deps/v8/tools/system-analyzer/view/script-panel.mjs index a4dc07fb451cab..b0dac6960c3a46 100644 --- a/deps/v8/tools/system-analyzer/source-panel.mjs +++ b/deps/v8/tools/system-analyzer/view/script-panel.mjs @@ -1,22 +1,26 @@ // Copyright 2020 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 {FocusEvent, SelectionEvent} from './events.mjs'; -import {delay, DOM, formatBytes, V8CustomElement} from './helper.mjs'; -import {IcLogEntry} from './log/ic.mjs'; -import {MapLogEntry} from './log/map.mjs'; +import {groupBy} from '../helper.mjs'; +import {App} from '../index.mjs' -DOM.defineCustomElement('source-panel', +import {SelectRelatedEvent, ToolTipEvent} from './events.mjs'; +import {CSSColor, delay, DOM, formatBytes, gradientStopsFromGroups, V8CustomElement} from './helper.mjs'; + +DOM.defineCustomElement('view/script-panel', (templateText) => class SourcePanel extends V8CustomElement { _selectedSourcePositions = []; - _sourcePositionsToMarkNodes; + _sourcePositionsToMarkNodes = []; _scripts = []; _script; + constructor() { super(templateText); this.scriptDropdown.addEventListener( 'change', e => this._handleSelectScript(e)); + this.$('#selectedRelatedButton').onclick = + this._handleSelectRelated.bind(this); } get script() { @@ -41,7 +45,11 @@ DOM.defineCustomElement('source-panel', this._focusSelectedMarkers(); } - set data(scripts) { + set focusedSourcePositions(sourcePositions) { + this.selectedSourcePositions = sourcePositions; + } + + set scripts(scripts) { this._scripts = scripts; this._initializeScriptDropdown(); } @@ -71,13 +79,13 @@ DOM.defineCustomElement('source-panel', let scriptNode; if (this._script) { await delay(1); - const builder = - new LineBuilder(this, this._script, this._selectedSourcePositions); + const builder = new LineBuilder(this, this._script); scriptNode = builder.createScriptNode(); this._sourcePositionsToMarkNodes = builder.sourcePositionToMarkers; } else { - scriptNode = document.createElement('pre'); + scriptNode = DOM.div(); this._selectedMarkNodes = undefined; + this._sourcePositionsToMarkNodes = new Map(); } const oldScriptNode = this.script.childNodes[1]; this.script.replaceChild(scriptNode, oldScriptNode); @@ -90,9 +98,15 @@ DOM.defineCustomElement('source-panel', markNode.className = ''; } for (let sourcePosition of this._selectedSourcePositions) { + if (sourcePosition.script !== this._script) continue; this._sourcePositionsToMarkNodes.get(sourcePosition).className = 'marked'; } - const sourcePosition = this._selectedSourcePositions[0]; + this._scrollToFirstSourcePosition() + } + + _scrollToFirstSourcePosition() { + const sourcePosition = this._selectedSourcePositions.find( + each => each.script === this._script); if (!sourcePosition) return; const markNode = this._sourcePositionsToMarkNodes.get(sourcePosition); markNode.scrollIntoView( @@ -103,29 +117,32 @@ DOM.defineCustomElement('source-panel', const option = this.scriptDropdown.options[this.scriptDropdown.selectedIndex]; this.script = option.script; - this.selectLogEntries(this._script.entries()); + } + + _handleSelectRelated(e) { + if (!this._script) return; + this.dispatchEvent(new SelectRelatedEvent(this._script)); } handleSourcePositionClick(e) { - this.selectLogEntries(e.target.sourcePosition.entries) - } - - selectLogEntries(logEntries) { - let icLogEntries = []; - let mapLogEntries = []; - for (const entry of logEntries) { - if (entry instanceof MapLogEntry) { - mapLogEntries.push(entry); - } else if (entry instanceof IcLogEntry) { - icLogEntries.push(entry); - } - } - if (icLogEntries.length > 0) { - this.dispatchEvent(new SelectionEvent(icLogEntries)); - } - if (mapLogEntries.length > 0) { - this.dispatchEvent(new SelectionEvent(mapLogEntries)); - } + const sourcePosition = e.target.sourcePosition; + this.dispatchEvent(new SelectRelatedEvent(sourcePosition)); + } + + handleSourcePositionMouseOver(e) { + const entries = e.target.sourcePosition.entries; + let text = groupBy(entries, each => each.constructor, true) + .map(group => { + let text = `${group.key.name}: ${group.count}\n` + text += groupBy(group.entries, each => each.type, true) + .map(group => { + return ` - ${group.key}: ${group.count}`; + }) + .join('\n'); + return text; + }) + .join('\n'); + this.dispatchEvent(new ToolTipEvent(text, e.target)); } }); @@ -177,16 +194,28 @@ function* lineIterator(source) { } class LineBuilder { + static _colorMap = (function() { + const map = new Map(); + let i = 0; + for (let type of App.allEventTypes) { + map.set(type, CSSColor.at(i++)); + } + return map; + })(); + static get colorMap() { + return this._colorMap; + } + _script; _clickHandler; + _mouseoverHandler; _sourcePositions; - _selection; _sourcePositionToMarkers = new Map(); - constructor(panel, script, highlightPositions) { + constructor(panel, script) { this._script = script; - this._selection = new Set(highlightPositions); this._clickHandler = panel.handleSourcePositionClick.bind(panel); + this._mouseoverHandler = panel.handleSourcePositionMouseOver.bind(panel); // TODO: sort on script finalization. script.sourcePositions.sort((a, b) => { if (a.line === b.line) return a.column - b.column; @@ -200,8 +229,7 @@ class LineBuilder { } createScriptNode() { - const scriptNode = document.createElement('pre'); - scriptNode.classList.add('scriptNode'); + const scriptNode = DOM.div('scriptNode'); for (let [lineIndex, line] of lineIterator(this._script.source)) { scriptNode.appendChild(this._createLineNode(lineIndex, line)); } @@ -209,7 +237,7 @@ class LineBuilder { } _createLineNode(lineIndex, line) { - const lineNode = document.createElement('span'); + const lineNode = DOM.span(); let columnIndex = 0; for (const sourcePosition of this._sourcePositions.forLine(lineIndex)) { const nextColumnIndex = sourcePosition.column - 1; @@ -232,6 +260,14 @@ class LineBuilder { marker.textContent = text; marker.sourcePosition = sourcePosition; marker.onclick = this._clickHandler; + marker.onmouseover = this._mouseoverHandler; + + const entries = sourcePosition.entries; + const stops = gradientStopsFromGroups( + entries.length, '%', groupBy(entries, entry => entry.constructor), + type => LineBuilder.colorMap.get(type)); + marker.style.backgroundImage = `linear-gradient(0deg,${stops.join(',')})` + return marker; } -} \ No newline at end of file +} diff --git a/deps/v8/tools/system-analyzer/view/timeline-panel-template.html b/deps/v8/tools/system-analyzer/view/timeline-panel-template.html new file mode 100644 index 00000000000000..da0ce26380907c --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/timeline-panel-template.html @@ -0,0 +1,29 @@ + + + + + + +
+

Timeline Panel

+
+
+ +
+
diff --git a/deps/v8/tools/system-analyzer/timeline-panel.mjs b/deps/v8/tools/system-analyzer/view/timeline-panel.mjs similarity index 98% rename from deps/v8/tools/system-analyzer/timeline-panel.mjs rename to deps/v8/tools/system-analyzer/view/timeline-panel.mjs index a61d2efc90570b..331db401e96db9 100644 --- a/deps/v8/tools/system-analyzer/timeline-panel.mjs +++ b/deps/v8/tools/system-analyzer/view/timeline-panel.mjs @@ -8,7 +8,7 @@ import {SynchronizeSelectionEvent} from './events.mjs'; import {DOM, V8CustomElement} from './helper.mjs'; DOM.defineCustomElement( - 'timeline-panel', + 'view/timeline-panel', (templateText) => class TimelinePanel extends V8CustomElement { constructor() { super(templateText); diff --git a/deps/v8/tools/system-analyzer/view/timeline/timeline-track-template.html b/deps/v8/tools/system-analyzer/view/timeline/timeline-track-template.html new file mode 100644 index 00000000000000..b27ad66b59a7d0 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/timeline/timeline-track-template.html @@ -0,0 +1,205 @@ + + + + + + + +
+ + +

+ +
+
+
+
+
+
+
Frequency
+
+ +
+ +
+ + + + + + + + + +
TypeCountPercent
+
+
\ No newline at end of file diff --git a/deps/v8/tools/system-analyzer/view/timeline/timeline-track.mjs b/deps/v8/tools/system-analyzer/view/timeline/timeline-track.mjs new file mode 100644 index 00000000000000..60216af2eef4b7 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/timeline/timeline-track.mjs @@ -0,0 +1,605 @@ +// Copyright 2020 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 {kChunkHeight, kChunkWidth} from '../../log/map.mjs'; +import {MapLogEntry} from '../../log/map.mjs'; +import {FocusEvent, SelectionEvent, SelectTimeEvent, SynchronizeSelectionEvent, ToolTipEvent,} from '../events.mjs'; +import {CSSColor, DOM, gradientStopsFromGroups, V8CustomElement} from '../helper.mjs'; + +DOM.defineCustomElement('view/timeline/timeline-track', + (templateText) => + class TimelineTrack extends V8CustomElement { + _timeline; + _nofChunks = 400; + _chunks; + _selectedEntry; + _timeToPixel; + _timeStartOffset; + _legend; + + _chunkMouseMoveHandler = this._handleChunkMouseMove.bind(this); + _chunkClickHandler = this._handleChunkClick.bind(this); + _chunkDoubleClickHandler = this._handleChunkDoubleClick.bind(this); + + constructor() { + super(templateText); + this._selectionHandler = new SelectionHandler(this); + this._legend = new Legend(this.$('#legendTable')); + this._legend.onFilter = (type) => this._handleFilterTimeline(); + this.timelineNode.addEventListener( + 'scroll', e => this._handleTimelineScroll(e)); + this.timelineNode.ondblclick = (e) => + this._selectionHandler.clearSelection(); + this.isLocked = false; + } + + static get observedAttributes() { + return ['title']; + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name == 'title') { + this.$('#title').innerHTML = newValue; + } + } + + _handleFilterTimeline(type) { + this._updateChunks(); + } + + set data(timeline) { + this._timeline = timeline; + this._legend.timeline = timeline; + this.$('.content').style.display = timeline.isEmpty() ? 'none' : 'relative'; + this._updateChunks(); + } + + set timeSelection(selection) { + this._selectionHandler.timeSelection = selection; + this.updateSelection(); + } + + updateSelection() { + this._selectionHandler.update(); + this._legend.update(); + } + + // Maps the clicked x position to the x position on timeline canvas + positionOnTimeline(posX) { + let rect = this.timelineNode.getBoundingClientRect(); + let posClickedX = posX - rect.left + this.timelineNode.scrollLeft; + return posClickedX; + } + + positionToTime(posX) { + let posTimelineX = this.positionOnTimeline(posX) + this._timeStartOffset; + return posTimelineX / this._timeToPixel; + } + + timeToPosition(time) { + let posX = time * this._timeToPixel; + posX -= this._timeStartOffset; + return posX; + } + + get timelineCanvas() { + return this.$('#timelineCanvas'); + } + + get timelineChunks() { + return this.$('#timelineChunks'); + } + + get timelineNode() { + return this.$('#timeline'); + } + + _update() { + this._updateTimeline(); + this._legend.update(); + } + + set nofChunks(count) { + this._nofChunks = count; + this._updateChunks(); + } + + get nofChunks() { + return this._nofChunks; + } + + _updateChunks() { + this._chunks = + this._timeline.chunks(this.nofChunks, this._legend.filterPredicate); + this.update(); + } + + get chunks() { + return this._chunks; + } + + set selectedEntry(value) { + this._selectedEntry = value; + if (value.edge) this.redraw(); + } + + get selectedEntry() { + return this._selectedEntry; + } + + set scrollLeft(offset) { + this.timelineNode.scrollLeft = offset; + } + + handleEntryTypeDoubleClick(e) { + this.dispatchEvent(new SelectionEvent(e.target.parentNode.entries)); + } + + timelineIndicatorMove(offset) { + this.timelineNode.scrollLeft += offset; + } + + _handleTimelineScroll(e) { + let horizontal = e.currentTarget.scrollLeft; + this.dispatchEvent(new CustomEvent( + 'scrolltrack', {bubbles: true, composed: true, detail: horizontal})); + } + + _createBackgroundImage(chunk) { + const stops = gradientStopsFromGroups( + chunk.length, chunk.height, chunk.getBreakdown(event => event.type), + type => this._legend.colorForType(type)); + return `linear-gradient(0deg,${stops.join(',')})`; + } + + _updateTimeline() { + const reusableNodes = Array.from(this.timelineChunks.childNodes).reverse(); + let fragment = new DocumentFragment(); + let chunks = this.chunks; + let max = chunks.max(each => each.size()); + let start = this._timeline.startTime; + let end = this._timeline.endTime; + let duration = end - start; + this._timeToPixel = chunks.length * kChunkWidth / duration; + this._timeStartOffset = start * this._timeToPixel; + for (let i = 0; i < chunks.length; i++) { + let chunk = chunks[i]; + let height = (chunk.size() / max * kChunkHeight); + chunk.height = height; + if (chunk.isEmpty()) continue; + let node = reusableNodes[reusableNodes.length - 1]; + let reusedNode = false; + if (node?.className == 'chunk') { + reusableNodes.pop(); + reusedNode = true; + } else { + node = DOM.div('chunk'); + node.onmousemove = this._chunkMouseMoveHandler; + node.onclick = this._chunkClickHandler; + node.ondblclick = this._chunkDoubleClickHandler; + } + const style = node.style; + style.left = `${((chunk.start - start) * this._timeToPixel) | 0}px`; + style.height = `${height | 0}px`; + style.backgroundImage = this._createBackgroundImage(chunk); + node.chunk = chunk; + if (!reusedNode) fragment.appendChild(node); + } + + // Put a time marker roughly every 20 chunks. + let expected = duration / chunks.length * 20; + let interval = (10 ** Math.floor(Math.log10(expected))); + let correction = Math.log10(expected / interval); + correction = (correction < 0.33) ? 1 : (correction < 0.75) ? 2.5 : 5; + interval *= correction; + + let time = start; + while (time < end) { + let timeNode = DOM.div('timestamp'); + timeNode.innerText = `${((time - start) / 1000) | 0} ms`; + timeNode.style.left = `${((time - start) * this._timeToPixel) | 0}px`; + fragment.appendChild(timeNode); + time += interval; + } + + // Remove superfluos nodes lazily, for Chrome this is a very expensive + // operation. + if (reusableNodes.length > 0) { + for (const node of reusableNodes) { + node.style.display = 'none'; + } + setTimeout(() => { + const range = document.createRange(); + const first = reusableNodes[reusableNodes.length - 1]; + const last = reusableNodes[0]; + range.setStartBefore(first); + range.setEndAfter(last); + range.deleteContents(); + }, 100); + } + this.timelineChunks.appendChild(fragment); + this.redraw(); + } + + _handleChunkMouseMove(event) { + if (this.isLocked) return false; + if (this._selectionHandler.isSelecting) return false; + let chunk = event.target.chunk; + if (!chunk) return; + if (chunk.isEmpty()) return; + // topmost map (at chunk.height) == map #0. + let relativeIndex = Math.round( + event.layerY / event.target.offsetHeight * (chunk.size() - 1)); + let logEntry = chunk.at(relativeIndex); + this.dispatchEvent(new FocusEvent(logEntry)); + this.dispatchEvent(new ToolTipEvent(logEntry.toStringLong(), event.target)); + } + + _handleChunkClick(event) { + this.isLocked = !this.isLocked; + } + + _handleChunkDoubleClick(event) { + let chunk = event.target.chunk; + if (!chunk) return; + event.stopPropagation(); + this.dispatchEvent(new SelectTimeEvent(chunk.start, chunk.end)); + } + + redraw() { + window.requestAnimationFrame(() => this._redraw()); + } + + _redraw() { + if (!(this._timeline.at(0) instanceof MapLogEntry)) return; + let canvas = this.timelineCanvas; + let width = (this.chunks.length + 1) * kChunkWidth; + if (width > 32767) width = 32767; + canvas.width = width; + canvas.height = kChunkHeight; + let ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, kChunkHeight); + if (!this.selectedEntry || !this.selectedEntry.edge) return; + this.drawEdges(ctx); + } + + setMapStyle(map, ctx) { + ctx.fillStyle = map.edge && map.edge.from ? CSSColor.onBackgroundColor : + CSSColor.onPrimaryColor; + } + + setEdgeStyle(edge, ctx) { + let color = this._legend.colorForType(edge.type); + ctx.strokeStyle = color; + ctx.fillStyle = color; + } + + markMap(ctx, map) { + let [x, y] = map.position(this.chunks); + ctx.beginPath(); + this.setMapStyle(map, ctx); + ctx.arc(x, y, 3, 0, 2 * Math.PI); + ctx.fill(); + ctx.beginPath(); + ctx.fillStyle = CSSColor.onBackgroundColor; + ctx.arc(x, y, 2, 0, 2 * Math.PI); + ctx.fill(); + } + + markSelectedMap(ctx, map) { + let [x, y] = map.position(this.chunks); + ctx.beginPath(); + this.setMapStyle(map, ctx); + ctx.arc(x, y, 6, 0, 2 * Math.PI); + ctx.strokeStyle = CSSColor.onBackgroundColor; + ctx.stroke(); + } + + drawEdges(ctx) { + // Draw the trace of maps in reverse order to make sure the outgoing + // transitions of previous maps aren't drawn over. + const kMaxOutgoingEdges = 100; + let nofEdges = 0; + let stack = []; + let current = this.selectedEntry; + while (current && nofEdges < kMaxOutgoingEdges) { + nofEdges += current.children.length; + stack.push(current); + current = current.parent(); + } + ctx.save(); + this.drawOutgoingEdges(ctx, this.selectedEntry, 3); + ctx.restore(); + + let labelOffset = 15; + let xPrev = 0; + while (current = stack.pop()) { + if (current.edge) { + this.setEdgeStyle(current.edge, ctx); + let [xTo, yTo] = this.drawEdge(ctx, current.edge, true, labelOffset); + if (xTo == xPrev) { + labelOffset += 8; + } else { + labelOffset = 15 + } + xPrev = xTo; + } + this.markMap(ctx, current); + current = current.parent(); + ctx.save(); + // this.drawOutgoingEdges(ctx, current, 1); + ctx.restore(); + } + // Mark selected map + this.markSelectedMap(ctx, this.selectedEntry); + } + + drawEdge(ctx, edge, showLabel = true, labelOffset = 20) { + if (!edge.from || !edge.to) return [-1, -1]; + let [xFrom, yFrom] = edge.from.position(this.chunks); + let [xTo, yTo] = edge.to.position(this.chunks); + let sameChunk = xTo == xFrom; + if (sameChunk) labelOffset += 8; + + ctx.beginPath(); + ctx.moveTo(xFrom, yFrom); + let offsetX = 20; + let offsetY = 20; + let midX = xFrom + (xTo - xFrom) / 2; + let midY = (yFrom + yTo) / 2 - 100; + if (!sameChunk) { + ctx.quadraticCurveTo(midX, midY, xTo, yTo); + } else { + ctx.lineTo(xTo, yTo); + } + if (!showLabel) { + ctx.stroke(); + } else { + let centerX, centerY; + if (!sameChunk) { + centerX = (xFrom / 2 + midX + xTo / 2) / 2; + centerY = (yFrom / 2 + midY + yTo / 2) / 2; + } else { + centerX = xTo; + centerY = yTo; + } + ctx.moveTo(centerX, centerY); + ctx.lineTo(centerX + offsetX, centerY - labelOffset); + ctx.stroke(); + ctx.textAlign = 'left'; + ctx.fillStyle = this._legend.colorForType(edge.type); + ctx.fillText( + edge.toString(), centerX + offsetX + 2, centerY - labelOffset); + } + return [xTo, yTo]; + } + + drawOutgoingEdges(ctx, map, max = 10, depth = 0) { + if (!map) return; + if (depth >= max) return; + ctx.globalAlpha = 0.5 - depth * (0.3 / max); + ctx.strokeStyle = CSSColor.timelineBackgroundColor; + const limit = Math.min(map.children.length, 100) + for (let i = 0; i < limit; i++) { + let edge = map.children[i]; + this.drawEdge(ctx, edge, true); + this.drawOutgoingEdges(ctx, edge.to, max, depth + 1); + } + } +}); + +class SelectionHandler { + // TODO turn into static field once Safari supports it. + static get SELECTION_OFFSET() { + return 10 + }; + + _timeSelection = {start: -1, end: Infinity}; + _selectionOriginTime = -1; + + constructor(timeline) { + this._timeline = timeline; + this._timelineNode.addEventListener( + 'mousedown', e => this._handleTimeSelectionMouseDown(e)); + this._timelineNode.addEventListener( + 'mouseup', e => this._handleTimeSelectionMouseUp(e)); + this._timelineNode.addEventListener( + 'mousemove', e => this._handleTimeSelectionMouseMove(e)); + } + + update() { + if (!this.hasSelection) { + this._selectionNode.style.display = 'none'; + return; + } + this._selectionNode.style.display = 'inherit'; + const startPosition = this.timeToPosition(this._timeSelection.start); + const endPosition = this.timeToPosition(this._timeSelection.end); + this._leftHandleNode.style.left = startPosition + 'px'; + this._rightHandleNode.style.left = endPosition + 'px'; + const delta = endPosition - startPosition; + const selectionNode = this._selectionBackgroundNode; + selectionNode.style.left = startPosition + 'px'; + selectionNode.style.width = delta + 'px'; + } + + set timeSelection(selection) { + this._timeSelection.start = selection.start; + this._timeSelection.end = selection.end; + } + + clearSelection() { + this._timeline.dispatchEvent(new SelectTimeEvent()); + } + + timeToPosition(posX) { + return this._timeline.timeToPosition(posX); + } + + positionToTime(posX) { + return this._timeline.positionToTime(posX); + } + + get isSelecting() { + return this._selectionOriginTime >= 0; + } + + get hasSelection() { + return this._timeSelection.start >= 0 && + this._timeSelection.end != Infinity; + } + + get _timelineNode() { + return this._timeline.$('#timeline'); + } + + get _selectionNode() { + return this._timeline.$('#selection'); + } + + get _selectionBackgroundNode() { + return this._timeline.$('#selectionBackground'); + } + + get _leftHandleNode() { + return this._timeline.$('#leftHandle'); + } + + get _rightHandleNode() { + return this._timeline.$('#rightHandle'); + } + + get _leftHandlePosX() { + return this._leftHandleNode.getBoundingClientRect().x; + } + + get _rightHandlePosX() { + return this._rightHandleNode.getBoundingClientRect().x; + } + + _isOnLeftHandle(posX) { + return Math.abs(this._leftHandlePosX - posX) <= + SelectionHandler.SELECTION_OFFSET; + } + + _isOnRightHandle(posX) { + return Math.abs(this._rightHandlePosX - posX) <= + SelectionHandler.SELECTION_OFFSET; + } + + _handleTimeSelectionMouseDown(e) { + let xPosition = e.clientX + // Update origin time in case we click on a handle. + if (this._isOnLeftHandle(xPosition)) { + xPosition = this._rightHandlePosX; + } + else if (this._isOnRightHandle(xPosition)) { + xPosition = this._leftHandlePosX; + } + this._selectionOriginTime = this.positionToTime(xPosition); + } + + _handleTimeSelectionMouseMove(e) { + if (!this.isSelecting) return; + const currentTime = this.positionToTime(e.clientX); + this._timeline.dispatchEvent(new SynchronizeSelectionEvent( + Math.min(this._selectionOriginTime, currentTime), + Math.max(this._selectionOriginTime, currentTime))); + } + + _handleTimeSelectionMouseUp(e) { + this._selectionOriginTime = -1; + const delta = this._timeSelection.end - this._timeSelection.start; + if (delta <= 1 || isNaN(delta)) return; + this._timeline.dispatchEvent(new SelectTimeEvent( + this._timeSelection.start, this._timeSelection.end)); + } +} + +class Legend { + _timeline; + _typesFilters = new Map(); + _typeClickHandler = this._handleTypeClick.bind(this); + _filterPredicate = this.filter.bind(this); + onFilter = () => {}; + + constructor(table) { + this._table = table; + } + + set timeline(timeline) { + this._timeline = timeline; + const groups = timeline.getBreakdown(); + this._typesFilters = new Map(groups.map(each => [each.key, true])); + this._colors = + new Map(groups.map(each => [each.key, CSSColor.at(each.id)])); + } + + get selection() { + return this._timeline.selectionOrSelf; + } + + get filterPredicate() { + for (let visible of this._typesFilters.values()) { + if (!visible) return this._filterPredicate; + } + return undefined; + } + + colorForType(type) { + return this._colors.get(type); + } + + filter(logEntry) { + return this._typesFilters.get(logEntry.type); + } + + update() { + const tbody = DOM.tbody(); + const missingTypes = new Set(this._typesFilters.keys()); + this.selection.getBreakdown().forEach(group => { + tbody.appendChild(this._addTypeRow(group)); + missingTypes.delete(group.key); + }); + missingTypes.forEach(key => tbody.appendChild(this._row('', key, 0, '0%'))); + if (this._timeline.selection) { + tbody.appendChild( + this._row('', 'Selection', this.selection.length, '100%')); + } + tbody.appendChild(this._row('', 'All', this._timeline.length, '')); + this._table.tBodies[0].replaceWith(tbody); + } + + _row(color, type, count, percent) { + const row = DOM.tr(); + row.appendChild(DOM.td(color)); + row.appendChild(DOM.td(type)); + row.appendChild(DOM.td(count.toString())); + row.appendChild(DOM.td(percent)); + return row + } + + _addTypeRow(group) { + const color = this.colorForType(group.key); + const colorDiv = DOM.div('colorbox'); + if (this._typesFilters.get(group.key)) { + colorDiv.style.backgroundColor = color; + } else { + colorDiv.style.borderColor = color; + colorDiv.style.backgroundColor = CSSColor.backgroundImage; + } + let percent = `${(group.count / this.selection.length * 100).toFixed(1)}%`; + const row = this._row(colorDiv, group.key, group.count, percent); + row.className = 'clickable'; + row.onclick = this._typeClickHandler; + row.data = group.key; + return row; + } + + _handleTypeClick(e) { + const type = e.currentTarget.data; + this._typesFilters.set(type, !this._typesFilters.get(type)); + this.onFilter(type); + } +} \ No newline at end of file diff --git a/deps/v8/tools/system-analyzer/view/tool-tip-template.html b/deps/v8/tools/system-analyzer/view/tool-tip-template.html new file mode 100644 index 00000000000000..b0e9c72c45cdf6 --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/tool-tip-template.html @@ -0,0 +1,81 @@ + + + + + + +
+
+
+
+
diff --git a/deps/v8/tools/system-analyzer/view/tool-tip.mjs b/deps/v8/tools/system-analyzer/view/tool-tip.mjs new file mode 100644 index 00000000000000..896c04dd29857f --- /dev/null +++ b/deps/v8/tools/system-analyzer/view/tool-tip.mjs @@ -0,0 +1,110 @@ +// Copyright 2020 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 {DOM, V8CustomElement} from './helper.mjs'; + +DOM.defineCustomElement( + 'view/tool-tip', (templateText) => class Tooltip extends V8CustomElement { + _targetNode; + _content; + _isHidden = true; + constructor() { + super(templateText); + this._intersectionObserver = new IntersectionObserver((entries) => { + if (entries[0].intersectionRatio <= 0) { + this.hide(); + } else { + this.show(); + this.update(true); + } + }); + } + + _update() { + if (!this._targetNode || this._isHidden) return; + const rect = this._targetNode.getBoundingClientRect(); + rect.x += rect.width / 2; + let atRight = this._useRight(rect.x); + let atBottom = this._useBottom(rect.y); + if (atBottom) { + rect.y += rect.height; + } + this._setPosition(rect, atRight, atBottom); + this.update(true); + } + + set positionOrTargetNode(positionOrTargetNode) { + if (positionOrTargetNode.nodeType === undefined) { + this.position = positionOrTargetNode; + } else { + this.targetNode = positionOrTargetNode; + } + } + + set targetNode(targetNode) { + this._intersectionObserver.disconnect(); + this._targetNode = targetNode; + if (targetNode) { + this._intersectionObserver.observe(targetNode); + this.update(true); + } + } + + set position(position) { + this._targetNode = undefined; + this._setPosition( + position, this._useRight(position.x), this._useBottom(position.y)); + } + + _setPosition(viewportPosition, atRight, atBottom) { + const horizontalMode = atRight ? 'right' : 'left'; + const verticalMode = atBottom ? 'bottom' : 'top'; + this.bodyNode.className = horizontalMode + ' ' + verticalMode; + const pageX = viewportPosition.x + window.scrollX; + this.style.left = `${pageX}px`; + const pageY = viewportPosition.y + window.scrollY; + this.style.top = `${pageY}px`; + } + + _useBottom(viewportY) { + return viewportY <= 400; + } + + _useRight(viewportX) { + return viewportX < document.documentElement.clientWidth / 2; + } + + set content(content) { + if (!content) return this.hide(); + this.show(); + if (typeof content === 'string') { + this.contentNode.innerHTML = content; + this.contentNode.className = 'textContent'; + } else { + const newContent = DOM.div(); + newContent.appendChild(content); + this.contentNode.replaceWith(newContent); + newContent.id = 'content'; + } + } + + hide() { + this._isHidden = true; + this.bodyNode.style.display = 'none'; + this.targetNode = undefined; + } + + show() { + this.bodyNode.style.display = 'block'; + this._isHidden = false; + } + + get bodyNode() { + return this.$('#body'); + } + + get contentNode() { + return this.$('#content'); + } + }); diff --git a/deps/v8/tools/testrunner/base_runner.py b/deps/v8/tools/testrunner/base_runner.py index d3674a4f8b9ff8..54a9e61b160a92 100644 --- a/deps/v8/tools/testrunner/base_runner.py +++ b/deps/v8/tools/testrunner/base_runner.py @@ -351,9 +351,6 @@ def _add_parser_default_options(self, parser): help="Path to a file for storing json results.") parser.add_option('--slow-tests-cutoff', type="int", default=100, help='Collect N slowest tests') - parser.add_option("--junitout", help="File name of the JUnit output") - parser.add_option("--junittestsuite", default="v8tests", - help="The testsuite name in the JUnit output file") parser.add_option("--exit-after-n-failures", type="int", default=100, help="Exit after the first N failures instead of " "running all tests. Pass 0 to disable this feature.") @@ -760,9 +757,6 @@ def _get_shard_info(self, options): def _create_progress_indicators(self, test_count, options): procs = [PROGRESS_INDICATORS[options.progress]()] - if options.junitout: - procs.append(progress.JUnitTestProgressIndicator(options.junitout, - options.junittestsuite)) if options.json_test_results: procs.append(progress.JsonTestProgressIndicator(self.framework_name)) diff --git a/deps/v8/tools/testrunner/local/junit_output.py b/deps/v8/tools/testrunner/local/junit_output.py deleted file mode 100644 index 52f31ec422a69b..00000000000000 --- a/deps/v8/tools/testrunner/local/junit_output.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2013 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. - - -import xml.etree.ElementTree as xml - - -class JUnitTestOutput: - def __init__(self, test_suite_name): - self.root = xml.Element("testsuite") - self.root.attrib["name"] = test_suite_name - - def HasRunTest(self, test_name, test_cmd, test_duration, test_failure): - testCaseElement = xml.Element("testcase") - testCaseElement.attrib["name"] = test_name - testCaseElement.attrib["cmd"] = test_cmd - testCaseElement.attrib["time"] = str(round(test_duration, 3)) - if len(test_failure): - failureElement = xml.Element("failure") - failureElement.text = test_failure - testCaseElement.append(failureElement) - self.root.append(testCaseElement) - - def FinishAndWrite(self, f): - xml.ElementTree(self.root).write(f, "UTF-8") diff --git a/deps/v8/tools/testrunner/local/utils.py b/deps/v8/tools/testrunner/local/utils.py index a6b92dc7566189..8fdc16b4bb736d 100644 --- a/deps/v8/tools/testrunner/local/utils.py +++ b/deps/v8/tools/testrunner/local/utils.py @@ -90,7 +90,8 @@ def GuessOS(): return 'solaris' elif system == 'NetBSD': return 'netbsd' - elif system == 'AIX': + elif system in ['AIX', 'OS400']: + # OS400 runs an AIX emulator called PASE return 'aix' else: return None diff --git a/deps/v8/tools/testrunner/local/variants.py b/deps/v8/tools/testrunner/local/variants.py index 4236c1678a0882..69ca853de3f91f 100644 --- a/deps/v8/tools/testrunner/local/variants.py +++ b/deps/v8/tools/testrunner/local/variants.py @@ -53,12 +53,14 @@ # implications defined in flag-definitions.h. INCOMPATIBLE_FLAGS_PER_VARIANT = { "assert_types": ["--no-assert-types"], - "jitless": ["--opt", "--liftoff", "--track-field-types", "--validate-asm"], + "jitless": ["--opt", "--always-opt", "--liftoff", "--track-field-types", "--validate-asm"], "no_wasm_traps": ["--wasm-trap-handler"], - "nooptimization": ["--opt", "--no-liftoff", "--predictable", "--wasm-tier-up"], + "nooptimization": ["--opt", "--always-opt", "--no-liftoff", "--wasm-tier-up"], "slow_path": ["--no-force-slow-path"], + "stress_concurrent_allocation": ["--single-threaded-gc", "--predictable"], "stress_incremental_marking": ["--no-stress-incremental-marking"], - "stress_js_bg_compile_wasm_code_gc": ["--no-stress-background-compile"], + "future": ["--parallel-compile-tasks"], + "stress_js_bg_compile_wasm_code_gc": ["--no-stress-background-compile", "--parallel-compile-tasks"], "stress": ["--no-stress-opt", "--always-opt", "--no-always-opt", "--liftoff", "--max-inlined-bytecode-size=*", "--max-inlined-bytecode-size-cumulative=*", "--stress-inline"], "turboprop": ["--interrupt-budget=*", "--no-turboprop"], @@ -77,7 +79,8 @@ + INCOMPATIBLE_FLAGS_PER_VARIANT["jitless"], "predictable": ["--liftoff", "--parallel-compile-tasks", "--concurrent-recompilation", - "--wasm-num-compilation-tasks=*"], + "--wasm-num-compilation-tasks=*", + "--stress-concurrent-allocation"], } # Flags that lead to a contradiction when a certain extra-flag is present. @@ -92,7 +95,9 @@ "--no-enable-sse3": ["--enable-sse3"], "--no-enable-sse4-1": ["--enable-sse4-1"], "--optimize-for-size": ["--max-semi-space-size=*"], + "--stress_concurrent_allocation": ["--single-threaded-gc", "--predictable"], "--stress-flush-bytecode": ["--no-stress-flush-bytecode"], + "--future": ["--parallel-compile-tasks"], "--stress-incremental-marking": INCOMPATIBLE_FLAGS_PER_VARIANT["stress_incremental_marking"], } diff --git a/deps/v8/tools/testrunner/testproc/progress.py b/deps/v8/tools/testrunner/testproc/progress.py index 634ef7c2f2e3c0..9ff943a5c2b4bd 100644 --- a/deps/v8/tools/testrunner/testproc/progress.py +++ b/deps/v8/tools/testrunner/testproc/progress.py @@ -15,7 +15,6 @@ from . import base from . import util -from ..local import junit_output def print_failure_header(test): @@ -349,45 +348,6 @@ def _clear_line(self, last_length): print(("\r" + (" " * last_length) + "\r"), end='') -class JUnitTestProgressIndicator(ProgressIndicator): - def __init__(self, junitout, junittestsuite): - super(JUnitTestProgressIndicator, self).__init__() - self._requirement = base.DROP_PASS_STDOUT - - self.outputter = junit_output.JUnitTestOutput(junittestsuite) - if junitout: - self.outfile = open(junitout, "w") - else: - self.outfile = sys.stdout - - def _on_result_for(self, test, result): - # TODO(majeski): Support for dummy/grouped results - fail_text = "" - output = result.output - if result.has_unexpected_output: - stdout = output.stdout.strip() - if len(stdout): - fail_text += "stdout:\n%s\n" % stdout - stderr = output.stderr.strip() - if len(stderr): - fail_text += "stderr:\n%s\n" % stderr - fail_text += "Command: %s" % result.cmd.to_string() - if output.HasCrashed(): - fail_text += "exit code: %d\n--- CRASHED ---" % output.exit_code - if output.HasTimedOut(): - fail_text += "--- TIMEOUT ---" - self.outputter.HasRunTest( - test_name=str(test), - test_cmd=result.cmd.to_string(relative=True), - test_duration=output.duration, - test_failure=fail_text) - - def finished(self): - self.outputter.FinishAndWrite(self.outfile) - if self.outfile != sys.stdout: - self.outfile.close() - - class JsonTestProgressIndicator(ProgressIndicator): def __init__(self, framework_name): super(JsonTestProgressIndicator, self).__init__() diff --git a/deps/v8/tools/tickprocessor.mjs b/deps/v8/tools/tickprocessor.mjs index 5b746d943a5adc..54c37e68e0a0ec 100644 --- a/deps/v8/tools/tickprocessor.mjs +++ b/deps/v8/tools/tickprocessor.mjs @@ -31,11 +31,6 @@ import { Profile, JsonProfile } from "./profile.mjs"; import { ViewBuilder } from "./profile_view.mjs"; -export function inherits(childCtor, parentCtor) { - childCtor.prototype.__proto__ = parentCtor.prototype; -}; - - class V8Profile extends Profile { static IC_RE = /^(LoadGlobalIC: )|(Handler: )|(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/; @@ -75,20 +70,8 @@ export function readFile(fileName) { } -/** - * Parser for dynamic code optimization state. - */ -function parseState(s) { - switch (s) { - case "": return Profile.CodeState.COMPILED; - case "~": return Profile.CodeState.OPTIMIZABLE; - case "*": return Profile.CodeState.OPTIMIZED; - } - throw new Error(`unknown code state: ${s}`); -} - - -export function TickProcessor( +export class TickProcessor extends LogReader { + constructor( cppEntriesProvider, separateIc, separateBytecodes, @@ -105,8 +88,10 @@ export function TickProcessor( onlySummary, runtimeTimerFilter, preprocessJson) { - this.preprocessJson = preprocessJson; - LogReader.call(this, { + super({}, + timedRange, + pairwiseTimedRange); + this.dispatchTable_ = { 'shared-library': { parsers: [parseString, parseInt, parseInt, parseInt], processor: this.processSharedLibrary }, 'code-creation': { @@ -155,10 +140,10 @@ export function TickProcessor( // Obsolete row types. 'code-allocate': null, 'begin-code-region': null, - 'end-code-region': null }, - timedRange, - pairwiseTimedRange); + 'end-code-region': null + }; + this.preprocessJson = preprocessJson; this.cppEntriesProvider_ = cppEntriesProvider; this.callGraphSize_ = callGraphSize; this.ignoreUnknown_ = ignoreUnknown; @@ -214,11 +199,10 @@ export function TickProcessor( this.generation_ = 1; this.currentProducerProfile_ = null; this.onlySummary_ = onlySummary; -}; -inherits(TickProcessor, LogReader); +} -TickProcessor.VmStates = { +static VmStates = { JS: 0, GC: 1, PARSER: 2, @@ -230,7 +214,7 @@ TickProcessor.VmStates = { }; -TickProcessor.CodeTypes = { +static CodeTypes = { CPP: 0, SHARED_LIB: 1 }; @@ -238,56 +222,56 @@ TickProcessor.CodeTypes = { // codeTypes_ map because there can be zillions of them. -TickProcessor.CALL_PROFILE_CUTOFF_PCT = 1.0; +static CALL_PROFILE_CUTOFF_PCT = 1.0; -TickProcessor.CALL_GRAPH_SIZE = 5; +static CALL_GRAPH_SIZE = 5; /** * @override */ -TickProcessor.prototype.printError = function(str) { +printError(str) { printErr(str); -}; +} -TickProcessor.prototype.setCodeType = function(name, type) { +setCodeType(name, type) { this.codeTypes_[name] = TickProcessor.CodeTypes[type]; -}; +} -TickProcessor.prototype.isSharedLibrary = function(name) { +isSharedLibrary(name) { return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; -}; +} -TickProcessor.prototype.isCppCode = function(name) { +isCppCode(name) { return this.codeTypes_[name] == TickProcessor.CodeTypes.CPP; -}; +} -TickProcessor.prototype.isJsCode = function(name) { +isJsCode(name) { return name !== "UNKNOWN" && !(name in this.codeTypes_); -}; +} -TickProcessor.prototype.processLogFile = function(fileName) { +processLogFile(fileName) { this.lastLogFileName_ = fileName; let line; while (line = readline()) { this.processLogLine(line); } -}; +} -TickProcessor.prototype.processLogFileInTest = function(fileName) { +processLogFileInTest(fileName) { // Hack file name to avoid dealing with platform specifics. this.lastLogFileName_ = 'v8.log'; const contents = readFile(fileName); this.processLogChunk(contents); -}; +} -TickProcessor.prototype.processSharedLibrary = function( +processSharedLibrary( name, startAddr, endAddr, aslrSlide) { const entry = this.profile_.addLibrary(name, startAddr, endAddr, aslrSlide); this.setCodeType(entry.getName(), 'SHARED_LIB'); @@ -298,67 +282,67 @@ TickProcessor.prototype.processSharedLibrary = function( self.profile_.addStaticCode(fName, fStart, fEnd); self.setCodeType(fName, 'CPP'); }); -}; +} -TickProcessor.prototype.processCodeCreation = function( +processCodeCreation( type, kind, timestamp, start, size, name, maybe_func) { if (maybe_func.length) { const funcAddr = parseInt(maybe_func[0]); - const state = parseState(maybe_func[1]); + const state = Profile.parseState(maybe_func[1]); this.profile_.addFuncCode(type, name, timestamp, start, size, funcAddr, state); } else { this.profile_.addCode(type, name, timestamp, start, size); } -}; +} -TickProcessor.prototype.processCodeDeopt = function( +processCodeDeopt( timestamp, size, code, inliningId, scriptOffset, bailoutType, sourcePositionText, deoptReasonText) { this.profile_.deoptCode(timestamp, code, inliningId, scriptOffset, bailoutType, sourcePositionText, deoptReasonText); -}; +} -TickProcessor.prototype.processCodeMove = function(from, to) { +processCodeMove(from, to) { this.profile_.moveCode(from, to); -}; +} -TickProcessor.prototype.processCodeDelete = function(start) { +processCodeDelete(start) { this.profile_.deleteCode(start); -}; +} -TickProcessor.prototype.processCodeSourceInfo = function( +processCodeSourceInfo( start, script, startPos, endPos, sourcePositions, inliningPositions, inlinedFunctions) { this.profile_.addSourcePositions(start, script, startPos, endPos, sourcePositions, inliningPositions, inlinedFunctions); -}; +} -TickProcessor.prototype.processScriptSource = function(script, url, source) { +processScriptSource(script, url, source) { this.profile_.addScriptSource(script, url, source); -}; +} -TickProcessor.prototype.processFunctionMove = function(from, to) { +processFunctionMove(from, to) { this.profile_.moveFunc(from, to); -}; +} -TickProcessor.prototype.includeTick = function(vmState) { +includeTick(vmState) { if (this.stateFilter_ !== null) { return this.stateFilter_ == vmState; } else if (this.runtimeTimerFilter_ !== null) { return this.currentRuntimeTimer == this.runtimeTimerFilter_; } return true; -}; +} -TickProcessor.prototype.processRuntimeTimerEvent = function(name) { +processRuntimeTimerEvent(name) { this.currentRuntimeTimer = name; } -TickProcessor.prototype.processTick = function(pc, +processTick(pc, ns_since_start, is_external_callback, tos_or_external_callback, @@ -394,21 +378,21 @@ TickProcessor.prototype.processTick = function(pc, this.profile_.recordTick( ns_since_start, vmState, this.processStack(pc, tos_or_external_callback, stack)); -}; +} -TickProcessor.prototype.advanceDistortion = function() { +advanceDistortion() { this.distortion += this.distortion_per_entry; } -TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) { +processHeapSampleBegin(space, state, ticks) { if (space != 'Heap') return; this.currentProducerProfile_ = new CallTree(); -}; +} -TickProcessor.prototype.processHeapSampleEnd = function(space, state) { +processHeapSampleEnd(space, state) { if (space != 'Heap' || !this.currentProducerProfile_) return; print(`Generation ${this.generation_}:`); @@ -423,10 +407,10 @@ TickProcessor.prototype.processHeapSampleEnd = function(space, state) { this.currentProducerProfile_ = null; this.generation_++; -}; +} -TickProcessor.prototype.printStatistics = function() { +printStatistics() { if (this.preprocessJson) { this.profile_.writeJson(); return; @@ -505,29 +489,16 @@ TickProcessor.prototype.printStatistics = function() { (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1) ); this.printHeavyProfile(heavyView.head.children); } -}; - - -function padLeft(s, len) { - s = s.toString(); - if (s.length < len) { - const padLength = len - s.length; - if (!(padLength in padLeft)) { - padLeft[padLength] = new Array(padLength + 1).join(' '); - } - s = padLeft[padLength] + s; - } - return s; -}; +} -TickProcessor.prototype.printHeader = function(headerTitle) { +printHeader(headerTitle) { print(`\n [${headerTitle}]:`); print(' ticks total nonlib name'); -}; +} -TickProcessor.prototype.printLine = function( +printLine( entry, ticks, totalTicks, nonLibTicks) { const pct = ticks * 100 / totalTicks; const nonLibPct = nonLibTicks != null @@ -539,7 +510,7 @@ TickProcessor.prototype.printLine = function( entry); } -TickProcessor.prototype.printHeavyProfHeader = function() { +printHeavyProfHeader() { print('\n [Bottom up (heavy) profile]:'); print(' Note: percentage shows a share of a particular caller in the ' + 'total\n' + @@ -548,10 +519,10 @@ TickProcessor.prototype.printHeavyProfHeader = function() { TickProcessor.CALL_PROFILE_CUTOFF_PCT.toFixed(1) + '% are not shown.\n'); print(' ticks parent name'); -}; +} -TickProcessor.prototype.processProfile = function( +processProfile( profile, filterP, func) { for (let i = 0, n = profile.length; i < n; ++i) { const rec = profile[i]; @@ -562,7 +533,7 @@ TickProcessor.prototype.processProfile = function( } }; -TickProcessor.prototype.getLineAndColumn = function(name) { +getLineAndColumn(name) { const re = /:([0-9]+):([0-9]+)$/; const array = re.exec(name); if (!array) { @@ -571,12 +542,12 @@ TickProcessor.prototype.getLineAndColumn = function(name) { return {line: array[1], column: array[2]}; } -TickProcessor.prototype.hasSourceMap = function() { +hasSourceMap() { return this.sourceMap != null; -}; +} -TickProcessor.prototype.formatFunctionName = function(funcName) { +formatFunctionName(funcName) { if (!this.hasSourceMap()) { return funcName; } @@ -593,9 +564,9 @@ TickProcessor.prototype.formatFunctionName = function(funcName) { const sourceColumn = entry[4] + 1; return sourceFile + ':' + sourceLine + ':' + sourceColumn + ' -> ' + funcName; -}; +} -TickProcessor.prototype.printEntries = function( +printEntries( profile, totalTicks, nonLibTicks, filterP, callback, printAllTicks) { const that = this; this.processProfile(profile, filterP, function (rec) { @@ -606,10 +577,9 @@ TickProcessor.prototype.printEntries = function( that.printLine(funcName, rec.selfTime, totalTicks, nonLibTicks); } }); -}; - +} -TickProcessor.prototype.printHeavyProfile = function(profile, opt_indent) { + printHeavyProfile(profile, opt_indent) { const self = this; const indent = opt_indent || 0; const indentStr = padLeft('', indent); @@ -629,14 +599,27 @@ TickProcessor.prototype.printHeavyProfile = function(profile, opt_indent) { print(''); } }); -}; +} +} -function CppEntriesProvider() { + +function padLeft(s, len) { + s = s.toString(); + if (s.length < len) { + const padLength = len - s.length; + if (!(padLength in padLeft)) { + padLeft[padLength] = new Array(padLength + 1).join(' '); + } + s = padLeft[padLength] + s; + } + return s; }; -CppEntriesProvider.prototype.parseVmSymbols = function( +class CppEntriesProvider { + +parseVmSymbols( libName, libStart, libEnd, libASLRSlide, processorFunc) { this.loadSymbols(libName); @@ -699,17 +682,20 @@ CppEntriesProvider.prototype.parseVmSymbols = function( addEntry(funcInfo); } addEntry({name: '', start: libEnd}); -}; +} -CppEntriesProvider.prototype.loadSymbols = function(libName) { -}; +loadSymbols(libName) { +} +parseNextLine() { return false } -CppEntriesProvider.prototype.parseNextLine = () => false; +} -export function UnixCppEntriesProvider(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) { +export class UnixCppEntriesProvider extends CppEntriesProvider { + constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) { + super(); this.symbols = []; // File offset of a symbol minus the virtual address of a symbol found in // the symbol table. @@ -720,11 +706,10 @@ export function UnixCppEntriesProvider(nmExec, objdumpExec, targetRootFS, apkEmb this.targetRootFS = targetRootFS; this.apkEmbeddedLibrary = apkEmbeddedLibrary; this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ([0-9a-fA-F]{8,16} )?[tTwW] (.*)$/; -}; -inherits(UnixCppEntriesProvider, CppEntriesProvider); +} -UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { +loadSymbols(libName) { this.parsePos = 0; if (this.apkEmbeddedLibrary && libName.endsWith('.apk')) { libName = this.apkEmbeddedLibrary; @@ -750,10 +735,10 @@ UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { // If the library cannot be found on this system let's not panic. this.symbols = ['', '']; } -}; +} -UnixCppEntriesProvider.prototype.parseNextLine = function() { +parseNextLine() { if (this.symbols.length == 0) { return false; } @@ -775,18 +760,18 @@ UnixCppEntriesProvider.prototype.parseNextLine = function() { } } return funcInfo; -}; - +} +} -export function MacCppEntriesProvider(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) { - UnixCppEntriesProvider.call(this, nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary); +export class MacCppEntriesProvider extends UnixCppEntriesProvider { + constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) { + super(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary); // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups. this.FUNC_RE = /^([0-9a-fA-F]{8,16})() (.*)$/; -}; -inherits(MacCppEntriesProvider, UnixCppEntriesProvider); +} -MacCppEntriesProvider.prototype.loadSymbols = function(libName) { +loadSymbols(libName) { this.parsePos = 0; libName = this.targetRootFS + libName; @@ -798,34 +783,36 @@ MacCppEntriesProvider.prototype.loadSymbols = function(libName) { // If the library cannot be found on this system let's not panic. this.symbols = ''; } -}; +} +} -export function WindowsCppEntriesProvider(_ignored_nmExec, _ignored_objdumpExec, targetRootFS, +export class WindowsCppEntriesProvider extends CppEntriesProvider { + constructor(_ignored_nmExec, _ignored_objdumpExec, targetRootFS, _ignored_apkEmbeddedLibrary) { + super(); this.targetRootFS = targetRootFS; this.symbols = ''; this.parsePos = 0; }; -inherits(WindowsCppEntriesProvider, CppEntriesProvider); -WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.([^.]+)$/; +static FILENAME_RE = /^(.*)\.([^.]+)$/; -WindowsCppEntriesProvider.FUNC_RE = +static FUNC_RE = /^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/; -WindowsCppEntriesProvider.IMAGE_BASE_RE = +static IMAGE_BASE_RE = /^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/; // This is almost a constant on Windows. -WindowsCppEntriesProvider.EXE_IMAGE_BASE = 0x00400000; +static EXE_IMAGE_BASE = 0x00400000; -WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) { +loadSymbols(libName) { libName = this.targetRootFS + libName; const fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE); if (!fileNameFields) return; @@ -840,7 +827,7 @@ WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) { }; -WindowsCppEntriesProvider.prototype.parseNextLine = function() { +parseNextLine() { const lineEndPos = this.symbols.indexOf('\r\n', this.parsePos); if (lineEndPos == -1) { return false; @@ -875,14 +862,15 @@ WindowsCppEntriesProvider.prototype.parseNextLine = function() { * * ?LookupInDescriptor@JSObject@internal@v8@@...arguments info... */ -WindowsCppEntriesProvider.prototype.unmangleName = function(name) { + unmangleName(name) { // Empty or non-mangled name. if (name.length < 1 || name.charAt(0) != '?') return name; const nameEndPos = name.indexOf('@@'); const components = name.substring(1, nameEndPos).split('@'); components.reverse(); return components.join('::'); -}; +} +} export class ArgumentsProcessor extends BaseArgumentsProcessor { diff --git a/deps/v8/tools/v8heapconst.py b/deps/v8/tools/v8heapconst.py index 0dd31d4ad259fc..cfd41e6bbd19d1 100644 --- a/deps/v8/tools/v8heapconst.py +++ b/deps/v8/tools/v8heapconst.py @@ -11,8 +11,6 @@ 2: "EXTERNAL_INTERNALIZED_STRING_TYPE", 8: "ONE_BYTE_INTERNALIZED_STRING_TYPE", 10: "EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE", - 18: "UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE", - 26: "UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE", 32: "STRING_TYPE", 33: "CONS_STRING_TYPE", 34: "EXTERNAL_STRING_TYPE", @@ -77,294 +75,301 @@ 113: "WASM_EXPORTED_FUNCTION_DATA_TYPE", 114: "WASM_INDIRECT_FUNCTION_TABLE_TYPE", 115: "WASM_JS_FUNCTION_DATA_TYPE", - 116: "WASM_VALUE_TYPE", - 117: "FIXED_ARRAY_TYPE", - 118: "HASH_TABLE_TYPE", - 119: "EPHEMERON_HASH_TABLE_TYPE", - 120: "GLOBAL_DICTIONARY_TYPE", - 121: "NAME_DICTIONARY_TYPE", - 122: "NUMBER_DICTIONARY_TYPE", - 123: "ORDERED_HASH_MAP_TYPE", - 124: "ORDERED_HASH_SET_TYPE", - 125: "ORDERED_NAME_DICTIONARY_TYPE", - 126: "SIMPLE_NUMBER_DICTIONARY_TYPE", - 127: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", - 128: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", - 129: "SCOPE_INFO_TYPE", - 130: "SCRIPT_CONTEXT_TABLE_TYPE", - 131: "BYTE_ARRAY_TYPE", - 132: "BYTECODE_ARRAY_TYPE", - 133: "FIXED_DOUBLE_ARRAY_TYPE", - 134: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE", - 135: "SLOPPY_ARGUMENTS_ELEMENTS_TYPE", - 136: "AWAIT_CONTEXT_TYPE", - 137: "BLOCK_CONTEXT_TYPE", - 138: "CATCH_CONTEXT_TYPE", - 139: "DEBUG_EVALUATE_CONTEXT_TYPE", - 140: "EVAL_CONTEXT_TYPE", - 141: "FUNCTION_CONTEXT_TYPE", - 142: "MODULE_CONTEXT_TYPE", - 143: "NATIVE_CONTEXT_TYPE", - 144: "SCRIPT_CONTEXT_TYPE", - 145: "WITH_CONTEXT_TYPE", - 146: "EXPORTED_SUB_CLASS_BASE_TYPE", - 147: "EXPORTED_SUB_CLASS_TYPE", - 148: "EXPORTED_SUB_CLASS2_TYPE", - 149: "SMALL_ORDERED_HASH_MAP_TYPE", - 150: "SMALL_ORDERED_HASH_SET_TYPE", - 151: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", - 152: "DESCRIPTOR_ARRAY_TYPE", - 153: "STRONG_DESCRIPTOR_ARRAY_TYPE", - 154: "SOURCE_TEXT_MODULE_TYPE", - 155: "SYNTHETIC_MODULE_TYPE", - 156: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", - 157: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", - 158: "WEAK_FIXED_ARRAY_TYPE", - 159: "TRANSITION_ARRAY_TYPE", - 160: "CELL_TYPE", - 161: "CODE_TYPE", - 162: "CODE_DATA_CONTAINER_TYPE", - 163: "COVERAGE_INFO_TYPE", - 164: "EMBEDDER_DATA_ARRAY_TYPE", - 165: "FEEDBACK_METADATA_TYPE", - 166: "FEEDBACK_VECTOR_TYPE", - 167: "FILLER_TYPE", - 168: "FREE_SPACE_TYPE", - 169: "INTERNAL_CLASS_TYPE", - 170: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE", - 171: "MAP_TYPE", - 172: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE", - 173: "PREPARSE_DATA_TYPE", - 174: "PROPERTY_ARRAY_TYPE", - 175: "PROPERTY_CELL_TYPE", - 176: "SHARED_FUNCTION_INFO_TYPE", - 177: "SMI_BOX_TYPE", - 178: "SMI_PAIR_TYPE", - 179: "SORT_STATE_TYPE", - 180: "WASM_ARRAY_TYPE", - 181: "WASM_CAPI_FUNCTION_DATA_TYPE", - 182: "WASM_STRUCT_TYPE", - 183: "WEAK_ARRAY_LIST_TYPE", - 184: "WEAK_CELL_TYPE", - 185: "JS_PROXY_TYPE", + 116: "FIXED_ARRAY_TYPE", + 117: "HASH_TABLE_TYPE", + 118: "EPHEMERON_HASH_TABLE_TYPE", + 119: "GLOBAL_DICTIONARY_TYPE", + 120: "NAME_DICTIONARY_TYPE", + 121: "NUMBER_DICTIONARY_TYPE", + 122: "ORDERED_HASH_MAP_TYPE", + 123: "ORDERED_HASH_SET_TYPE", + 124: "ORDERED_NAME_DICTIONARY_TYPE", + 125: "SIMPLE_NUMBER_DICTIONARY_TYPE", + 126: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", + 127: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", + 128: "SCOPE_INFO_TYPE", + 129: "SCRIPT_CONTEXT_TABLE_TYPE", + 130: "BYTE_ARRAY_TYPE", + 131: "BYTECODE_ARRAY_TYPE", + 132: "FIXED_DOUBLE_ARRAY_TYPE", + 133: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE", + 134: "SLOPPY_ARGUMENTS_ELEMENTS_TYPE", + 135: "AWAIT_CONTEXT_TYPE", + 136: "BLOCK_CONTEXT_TYPE", + 137: "CATCH_CONTEXT_TYPE", + 138: "DEBUG_EVALUATE_CONTEXT_TYPE", + 139: "EVAL_CONTEXT_TYPE", + 140: "FUNCTION_CONTEXT_TYPE", + 141: "MODULE_CONTEXT_TYPE", + 142: "NATIVE_CONTEXT_TYPE", + 143: "SCRIPT_CONTEXT_TYPE", + 144: "WITH_CONTEXT_TYPE", + 145: "EXPORTED_SUB_CLASS_BASE_TYPE", + 146: "EXPORTED_SUB_CLASS_TYPE", + 147: "EXPORTED_SUB_CLASS2_TYPE", + 148: "SMALL_ORDERED_HASH_MAP_TYPE", + 149: "SMALL_ORDERED_HASH_SET_TYPE", + 150: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", + 151: "DESCRIPTOR_ARRAY_TYPE", + 152: "STRONG_DESCRIPTOR_ARRAY_TYPE", + 153: "SOURCE_TEXT_MODULE_TYPE", + 154: "SYNTHETIC_MODULE_TYPE", + 155: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", + 156: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", + 157: "WEAK_FIXED_ARRAY_TYPE", + 158: "TRANSITION_ARRAY_TYPE", + 159: "CELL_TYPE", + 160: "CODE_TYPE", + 161: "CODE_DATA_CONTAINER_TYPE", + 162: "COVERAGE_INFO_TYPE", + 163: "EMBEDDER_DATA_ARRAY_TYPE", + 164: "FEEDBACK_METADATA_TYPE", + 165: "FEEDBACK_VECTOR_TYPE", + 166: "FILLER_TYPE", + 167: "FREE_SPACE_TYPE", + 168: "INTERNAL_CLASS_TYPE", + 169: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE", + 170: "MAP_TYPE", + 171: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE", + 172: "PREPARSE_DATA_TYPE", + 173: "PROPERTY_ARRAY_TYPE", + 174: "PROPERTY_CELL_TYPE", + 175: "SHARED_FUNCTION_INFO_TYPE", + 176: "SMI_BOX_TYPE", + 177: "SMI_PAIR_TYPE", + 178: "SORT_STATE_TYPE", + 179: "WASM_ARRAY_TYPE", + 180: "WASM_CAPI_FUNCTION_DATA_TYPE", + 181: "WASM_STRUCT_TYPE", + 182: "WEAK_ARRAY_LIST_TYPE", + 183: "WEAK_CELL_TYPE", + 184: "JS_PROXY_TYPE", 1057: "JS_OBJECT_TYPE", - 186: "JS_GLOBAL_OBJECT_TYPE", - 187: "JS_GLOBAL_PROXY_TYPE", - 188: "JS_MODULE_NAMESPACE_TYPE", + 185: "JS_GLOBAL_OBJECT_TYPE", + 186: "JS_GLOBAL_PROXY_TYPE", + 187: "JS_MODULE_NAMESPACE_TYPE", 1040: "JS_SPECIAL_API_OBJECT_TYPE", 1041: "JS_PRIMITIVE_WRAPPER_TYPE", - 1042: "JS_MAP_KEY_ITERATOR_TYPE", - 1043: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", - 1044: "JS_MAP_VALUE_ITERATOR_TYPE", - 1045: "JS_SET_KEY_VALUE_ITERATOR_TYPE", - 1046: "JS_SET_VALUE_ITERATOR_TYPE", - 1047: "JS_GENERATOR_OBJECT_TYPE", - 1048: "JS_ASYNC_FUNCTION_OBJECT_TYPE", - 1049: "JS_ASYNC_GENERATOR_OBJECT_TYPE", - 1050: "JS_DATA_VIEW_TYPE", - 1051: "JS_TYPED_ARRAY_TYPE", - 1052: "JS_MAP_TYPE", - 1053: "JS_SET_TYPE", - 1054: "JS_WEAK_MAP_TYPE", - 1055: "JS_WEAK_SET_TYPE", + 1042: "JS_ARRAY_ITERATOR_PROTOTYPE_TYPE", + 1043: "JS_ITERATOR_PROTOTYPE_TYPE", + 1044: "JS_MAP_ITERATOR_PROTOTYPE_TYPE", + 1045: "JS_OBJECT_PROTOTYPE_TYPE", + 1046: "JS_PROMISE_PROTOTYPE_TYPE", + 1047: "JS_REG_EXP_PROTOTYPE_TYPE", + 1048: "JS_SET_ITERATOR_PROTOTYPE_TYPE", + 1049: "JS_SET_PROTOTYPE_TYPE", + 1050: "JS_STRING_ITERATOR_PROTOTYPE_TYPE", + 1051: "JS_TYPED_ARRAY_PROTOTYPE_TYPE", + 1052: "JS_GENERATOR_OBJECT_TYPE", + 1053: "JS_ASYNC_FUNCTION_OBJECT_TYPE", + 1054: "JS_ASYNC_GENERATOR_OBJECT_TYPE", + 1055: "JS_ARGUMENTS_OBJECT_TYPE", 1056: "JS_API_OBJECT_TYPE", - 1058: "JS_ARGUMENTS_OBJECT_TYPE", - 1059: "JS_ARRAY_TYPE", - 1060: "JS_ARRAY_BUFFER_TYPE", - 1061: "JS_ARRAY_ITERATOR_TYPE", - 1062: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE", - 1063: "JS_COLLATOR_TYPE", - 1064: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", - 1065: "JS_DATE_TYPE", - 1066: "JS_DATE_TIME_FORMAT_TYPE", - 1067: "JS_DISPLAY_NAMES_TYPE", - 1068: "JS_ERROR_TYPE", - 1069: "JS_FINALIZATION_REGISTRY_TYPE", - 1070: "JS_LIST_FORMAT_TYPE", - 1071: "JS_LOCALE_TYPE", - 1072: "JS_MESSAGE_OBJECT_TYPE", - 1073: "JS_NUMBER_FORMAT_TYPE", - 1074: "JS_PLURAL_RULES_TYPE", - 1075: "JS_PROMISE_TYPE", - 1076: "JS_REG_EXP_TYPE", - 1077: "JS_REG_EXP_STRING_ITERATOR_TYPE", - 1078: "JS_RELATIVE_TIME_FORMAT_TYPE", - 1079: "JS_SEGMENT_ITERATOR_TYPE", - 1080: "JS_SEGMENTER_TYPE", - 1081: "JS_SEGMENTS_TYPE", - 1082: "JS_STRING_ITERATOR_TYPE", - 1083: "JS_V8_BREAK_ITERATOR_TYPE", - 1084: "JS_WEAK_REF_TYPE", - 1085: "WASM_EXCEPTION_OBJECT_TYPE", - 1086: "WASM_GLOBAL_OBJECT_TYPE", - 1087: "WASM_INSTANCE_OBJECT_TYPE", - 1088: "WASM_MEMORY_OBJECT_TYPE", - 1089: "WASM_MODULE_OBJECT_TYPE", - 1090: "WASM_TABLE_OBJECT_TYPE", - 1091: "JS_BOUND_FUNCTION_TYPE", - 1092: "JS_FUNCTION_TYPE", + 1058: "JS_MAP_KEY_ITERATOR_TYPE", + 1059: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", + 1060: "JS_MAP_VALUE_ITERATOR_TYPE", + 1061: "JS_SET_KEY_VALUE_ITERATOR_TYPE", + 1062: "JS_SET_VALUE_ITERATOR_TYPE", + 1063: "JS_DATA_VIEW_TYPE", + 1064: "JS_TYPED_ARRAY_TYPE", + 1065: "JS_MAP_TYPE", + 1066: "JS_SET_TYPE", + 1067: "JS_BOUND_FUNCTION_TYPE", + 1068: "JS_FUNCTION_TYPE", + 1069: "JS_WEAK_MAP_TYPE", + 1070: "JS_WEAK_SET_TYPE", + 1071: "JS_ARRAY_TYPE", + 1072: "JS_ARRAY_BUFFER_TYPE", + 1073: "JS_ARRAY_ITERATOR_TYPE", + 1074: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE", + 1075: "JS_COLLATOR_TYPE", + 1076: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", + 1077: "JS_DATE_TYPE", + 1078: "JS_DATE_TIME_FORMAT_TYPE", + 1079: "JS_DISPLAY_NAMES_TYPE", + 1080: "JS_ERROR_TYPE", + 1081: "JS_FINALIZATION_REGISTRY_TYPE", + 1082: "JS_LIST_FORMAT_TYPE", + 1083: "JS_LOCALE_TYPE", + 1084: "JS_MESSAGE_OBJECT_TYPE", + 1085: "JS_NUMBER_FORMAT_TYPE", + 1086: "JS_PLURAL_RULES_TYPE", + 1087: "JS_PROMISE_TYPE", + 1088: "JS_REG_EXP_TYPE", + 1089: "JS_REG_EXP_STRING_ITERATOR_TYPE", + 1090: "JS_RELATIVE_TIME_FORMAT_TYPE", + 1091: "JS_SEGMENT_ITERATOR_TYPE", + 1092: "JS_SEGMENTER_TYPE", + 1093: "JS_SEGMENTS_TYPE", + 1094: "JS_STRING_ITERATOR_TYPE", + 1095: "JS_V8_BREAK_ITERATOR_TYPE", + 1096: "JS_WEAK_REF_TYPE", + 1097: "WASM_EXCEPTION_OBJECT_TYPE", + 1098: "WASM_GLOBAL_OBJECT_TYPE", + 1099: "WASM_INSTANCE_OBJECT_TYPE", + 1100: "WASM_MEMORY_OBJECT_TYPE", + 1101: "WASM_MODULE_OBJECT_TYPE", + 1102: "WASM_TABLE_OBJECT_TYPE", } # List of known V8 maps. KNOWN_MAPS = { - ("read_only_space", 0x02115): (171, "MetaMap"), + ("read_only_space", 0x02115): (170, "MetaMap"), ("read_only_space", 0x0213d): (67, "NullMap"), - ("read_only_space", 0x02165): (153, "StrongDescriptorArrayMap"), - ("read_only_space", 0x0218d): (158, "WeakFixedArrayMap"), + ("read_only_space", 0x02165): (152, "StrongDescriptorArrayMap"), + ("read_only_space", 0x0218d): (157, "WeakFixedArrayMap"), ("read_only_space", 0x021cd): (96, "EnumCacheMap"), - ("read_only_space", 0x02201): (117, "FixedArrayMap"), + ("read_only_space", 0x02201): (116, "FixedArrayMap"), ("read_only_space", 0x0224d): (8, "OneByteInternalizedStringMap"), - ("read_only_space", 0x02299): (168, "FreeSpaceMap"), - ("read_only_space", 0x022c1): (167, "OnePointerFillerMap"), - ("read_only_space", 0x022e9): (167, "TwoPointerFillerMap"), + ("read_only_space", 0x02299): (167, "FreeSpaceMap"), + ("read_only_space", 0x022c1): (166, "OnePointerFillerMap"), + ("read_only_space", 0x022e9): (166, "TwoPointerFillerMap"), ("read_only_space", 0x02311): (67, "UninitializedMap"), ("read_only_space", 0x02389): (67, "UndefinedMap"), ("read_only_space", 0x023cd): (66, "HeapNumberMap"), ("read_only_space", 0x02401): (67, "TheHoleMap"), ("read_only_space", 0x02461): (67, "BooleanMap"), - ("read_only_space", 0x02505): (131, "ByteArrayMap"), - ("read_only_space", 0x0252d): (117, "FixedCOWArrayMap"), - ("read_only_space", 0x02555): (118, "HashTableMap"), + ("read_only_space", 0x02505): (130, "ByteArrayMap"), + ("read_only_space", 0x0252d): (116, "FixedCOWArrayMap"), + ("read_only_space", 0x02555): (117, "HashTableMap"), ("read_only_space", 0x0257d): (64, "SymbolMap"), ("read_only_space", 0x025a5): (40, "OneByteStringMap"), - ("read_only_space", 0x025cd): (129, "ScopeInfoMap"), - ("read_only_space", 0x025f5): (176, "SharedFunctionInfoMap"), - ("read_only_space", 0x0261d): (161, "CodeMap"), - ("read_only_space", 0x02645): (160, "CellMap"), - ("read_only_space", 0x0266d): (175, "GlobalPropertyCellMap"), + ("read_only_space", 0x025cd): (128, "ScopeInfoMap"), + ("read_only_space", 0x025f5): (175, "SharedFunctionInfoMap"), + ("read_only_space", 0x0261d): (160, "CodeMap"), + ("read_only_space", 0x02645): (159, "CellMap"), + ("read_only_space", 0x0266d): (174, "GlobalPropertyCellMap"), ("read_only_space", 0x02695): (70, "ForeignMap"), - ("read_only_space", 0x026bd): (159, "TransitionArrayMap"), + ("read_only_space", 0x026bd): (158, "TransitionArrayMap"), ("read_only_space", 0x026e5): (45, "ThinOneByteStringMap"), - ("read_only_space", 0x0270d): (166, "FeedbackVectorMap"), - ("read_only_space", 0x0273d): (67, "ArgumentsMarkerMap"), - ("read_only_space", 0x0279d): (67, "ExceptionMap"), - ("read_only_space", 0x027f9): (67, "TerminationExceptionMap"), - ("read_only_space", 0x02861): (67, "OptimizedOutMap"), - ("read_only_space", 0x028c1): (67, "StaleRegisterMap"), - ("read_only_space", 0x02921): (130, "ScriptContextTableMap"), - ("read_only_space", 0x02949): (127, "ClosureFeedbackCellArrayMap"), - ("read_only_space", 0x02971): (165, "FeedbackMetadataArrayMap"), - ("read_only_space", 0x02999): (117, "ArrayListMap"), - ("read_only_space", 0x029c1): (65, "BigIntMap"), - ("read_only_space", 0x029e9): (128, "ObjectBoilerplateDescriptionMap"), - ("read_only_space", 0x02a11): (132, "BytecodeArrayMap"), - ("read_only_space", 0x02a39): (162, "CodeDataContainerMap"), - ("read_only_space", 0x02a61): (163, "CoverageInfoMap"), - ("read_only_space", 0x02a89): (133, "FixedDoubleArrayMap"), - ("read_only_space", 0x02ab1): (120, "GlobalDictionaryMap"), - ("read_only_space", 0x02ad9): (97, "ManyClosuresCellMap"), - ("read_only_space", 0x02b01): (117, "ModuleInfoMap"), - ("read_only_space", 0x02b29): (121, "NameDictionaryMap"), - ("read_only_space", 0x02b51): (97, "NoClosuresCellMap"), - ("read_only_space", 0x02b79): (122, "NumberDictionaryMap"), - ("read_only_space", 0x02ba1): (97, "OneClosureCellMap"), - ("read_only_space", 0x02bc9): (123, "OrderedHashMapMap"), - ("read_only_space", 0x02bf1): (124, "OrderedHashSetMap"), - ("read_only_space", 0x02c19): (125, "OrderedNameDictionaryMap"), - ("read_only_space", 0x02c41): (173, "PreparseDataMap"), - ("read_only_space", 0x02c69): (174, "PropertyArrayMap"), - ("read_only_space", 0x02c91): (93, "SideEffectCallHandlerInfoMap"), - ("read_only_space", 0x02cb9): (93, "SideEffectFreeCallHandlerInfoMap"), - ("read_only_space", 0x02ce1): (93, "NextCallSideEffectFreeCallHandlerInfoMap"), - ("read_only_space", 0x02d09): (126, "SimpleNumberDictionaryMap"), - ("read_only_space", 0x02d31): (149, "SmallOrderedHashMapMap"), - ("read_only_space", 0x02d59): (150, "SmallOrderedHashSetMap"), - ("read_only_space", 0x02d81): (151, "SmallOrderedNameDictionaryMap"), - ("read_only_space", 0x02da9): (154, "SourceTextModuleMap"), - ("read_only_space", 0x02dd1): (155, "SyntheticModuleMap"), - ("read_only_space", 0x02df9): (157, "UncompiledDataWithoutPreparseDataMap"), - ("read_only_space", 0x02e21): (156, "UncompiledDataWithPreparseDataMap"), - ("read_only_space", 0x02e49): (71, "WasmTypeInfoMap"), - ("read_only_space", 0x02e71): (183, "WeakArrayListMap"), - ("read_only_space", 0x02e99): (119, "EphemeronHashTableMap"), - ("read_only_space", 0x02ec1): (164, "EmbedderDataArrayMap"), - ("read_only_space", 0x02ee9): (184, "WeakCellMap"), - ("read_only_space", 0x02f11): (32, "StringMap"), - ("read_only_space", 0x02f39): (41, "ConsOneByteStringMap"), - ("read_only_space", 0x02f61): (33, "ConsStringMap"), - ("read_only_space", 0x02f89): (37, "ThinStringMap"), - ("read_only_space", 0x02fb1): (35, "SlicedStringMap"), - ("read_only_space", 0x02fd9): (43, "SlicedOneByteStringMap"), - ("read_only_space", 0x03001): (34, "ExternalStringMap"), - ("read_only_space", 0x03029): (42, "ExternalOneByteStringMap"), - ("read_only_space", 0x03051): (50, "UncachedExternalStringMap"), - ("read_only_space", 0x03079): (0, "InternalizedStringMap"), - ("read_only_space", 0x030a1): (2, "ExternalInternalizedStringMap"), - ("read_only_space", 0x030c9): (10, "ExternalOneByteInternalizedStringMap"), - ("read_only_space", 0x030f1): (18, "UncachedExternalInternalizedStringMap"), - ("read_only_space", 0x03119): (26, "UncachedExternalOneByteInternalizedStringMap"), - ("read_only_space", 0x03141): (58, "UncachedExternalOneByteStringMap"), - ("read_only_space", 0x03169): (67, "SelfReferenceMarkerMap"), - ("read_only_space", 0x03191): (67, "BasicBlockCountersMarkerMap"), - ("read_only_space", 0x031d5): (87, "ArrayBoilerplateDescriptionMap"), - ("read_only_space", 0x032bd): (99, "InterceptorInfoMap"), - ("read_only_space", 0x053c9): (72, "PromiseFulfillReactionJobTaskMap"), - ("read_only_space", 0x053f1): (73, "PromiseRejectReactionJobTaskMap"), - ("read_only_space", 0x05419): (74, "CallableTaskMap"), - ("read_only_space", 0x05441): (75, "CallbackTaskMap"), - ("read_only_space", 0x05469): (76, "PromiseResolveThenableJobTaskMap"), - ("read_only_space", 0x05491): (79, "FunctionTemplateInfoMap"), - ("read_only_space", 0x054b9): (80, "ObjectTemplateInfoMap"), - ("read_only_space", 0x054e1): (81, "AccessCheckInfoMap"), - ("read_only_space", 0x05509): (82, "AccessorInfoMap"), - ("read_only_space", 0x05531): (83, "AccessorPairMap"), - ("read_only_space", 0x05559): (84, "AliasedArgumentsEntryMap"), - ("read_only_space", 0x05581): (85, "AllocationMementoMap"), - ("read_only_space", 0x055a9): (88, "AsmWasmDataMap"), - ("read_only_space", 0x055d1): (89, "AsyncGeneratorRequestMap"), - ("read_only_space", 0x055f9): (90, "BreakPointMap"), - ("read_only_space", 0x05621): (91, "BreakPointInfoMap"), - ("read_only_space", 0x05649): (92, "CachedTemplateObjectMap"), - ("read_only_space", 0x05671): (94, "ClassPositionsMap"), - ("read_only_space", 0x05699): (95, "DebugInfoMap"), - ("read_only_space", 0x056c1): (98, "FunctionTemplateRareDataMap"), - ("read_only_space", 0x056e9): (100, "InterpreterDataMap"), - ("read_only_space", 0x05711): (101, "ModuleRequestMap"), - ("read_only_space", 0x05739): (102, "PromiseCapabilityMap"), - ("read_only_space", 0x05761): (103, "PromiseReactionMap"), - ("read_only_space", 0x05789): (104, "PropertyDescriptorObjectMap"), - ("read_only_space", 0x057b1): (105, "PrototypeInfoMap"), - ("read_only_space", 0x057d9): (106, "ScriptMap"), - ("read_only_space", 0x05801): (107, "SourceTextModuleInfoEntryMap"), - ("read_only_space", 0x05829): (108, "StackFrameInfoMap"), - ("read_only_space", 0x05851): (109, "StackTraceFrameMap"), - ("read_only_space", 0x05879): (110, "TemplateObjectDescriptionMap"), - ("read_only_space", 0x058a1): (111, "Tuple2Map"), - ("read_only_space", 0x058c9): (112, "WasmExceptionTagMap"), - ("read_only_space", 0x058f1): (113, "WasmExportedFunctionDataMap"), - ("read_only_space", 0x05919): (114, "WasmIndirectFunctionTableMap"), - ("read_only_space", 0x05941): (115, "WasmJSFunctionDataMap"), - ("read_only_space", 0x05969): (116, "WasmValueMap"), - ("read_only_space", 0x05991): (135, "SloppyArgumentsElementsMap"), - ("read_only_space", 0x059b9): (152, "DescriptorArrayMap"), - ("read_only_space", 0x059e1): (172, "OnHeapBasicBlockProfilerDataMap"), - ("read_only_space", 0x05a09): (181, "WasmCapiFunctionDataMap"), - ("read_only_space", 0x05a31): (169, "InternalClassMap"), - ("read_only_space", 0x05a59): (178, "SmiPairMap"), - ("read_only_space", 0x05a81): (177, "SmiBoxMap"), - ("read_only_space", 0x05aa9): (146, "ExportedSubClassBaseMap"), - ("read_only_space", 0x05ad1): (147, "ExportedSubClassMap"), - ("read_only_space", 0x05af9): (68, "AbstractInternalClassSubclass1Map"), - ("read_only_space", 0x05b21): (69, "AbstractInternalClassSubclass2Map"), - ("read_only_space", 0x05b49): (134, "InternalClassWithSmiElementsMap"), - ("read_only_space", 0x05b71): (170, "InternalClassWithStructElementsMap"), - ("read_only_space", 0x05b99): (148, "ExportedSubClass2Map"), - ("read_only_space", 0x05bc1): (179, "SortStateMap"), - ("read_only_space", 0x05be9): (86, "AllocationSiteWithWeakNextMap"), - ("read_only_space", 0x05c11): (86, "AllocationSiteWithoutWeakNextMap"), - ("read_only_space", 0x05c39): (77, "LoadHandler1Map"), - ("read_only_space", 0x05c61): (77, "LoadHandler2Map"), - ("read_only_space", 0x05c89): (77, "LoadHandler3Map"), - ("read_only_space", 0x05cb1): (78, "StoreHandler0Map"), - ("read_only_space", 0x05cd9): (78, "StoreHandler1Map"), - ("read_only_space", 0x05d01): (78, "StoreHandler2Map"), - ("read_only_space", 0x05d29): (78, "StoreHandler3Map"), + ("read_only_space", 0x0270d): (165, "FeedbackVectorMap"), + ("read_only_space", 0x02749): (67, "ArgumentsMarkerMap"), + ("read_only_space", 0x027a9): (67, "ExceptionMap"), + ("read_only_space", 0x02805): (67, "TerminationExceptionMap"), + ("read_only_space", 0x0286d): (67, "OptimizedOutMap"), + ("read_only_space", 0x028cd): (67, "StaleRegisterMap"), + ("read_only_space", 0x0292d): (129, "ScriptContextTableMap"), + ("read_only_space", 0x02955): (126, "ClosureFeedbackCellArrayMap"), + ("read_only_space", 0x0297d): (164, "FeedbackMetadataArrayMap"), + ("read_only_space", 0x029a5): (116, "ArrayListMap"), + ("read_only_space", 0x029cd): (65, "BigIntMap"), + ("read_only_space", 0x029f5): (127, "ObjectBoilerplateDescriptionMap"), + ("read_only_space", 0x02a1d): (131, "BytecodeArrayMap"), + ("read_only_space", 0x02a45): (161, "CodeDataContainerMap"), + ("read_only_space", 0x02a6d): (162, "CoverageInfoMap"), + ("read_only_space", 0x02a95): (132, "FixedDoubleArrayMap"), + ("read_only_space", 0x02abd): (119, "GlobalDictionaryMap"), + ("read_only_space", 0x02ae5): (97, "ManyClosuresCellMap"), + ("read_only_space", 0x02b0d): (116, "ModuleInfoMap"), + ("read_only_space", 0x02b35): (120, "NameDictionaryMap"), + ("read_only_space", 0x02b5d): (97, "NoClosuresCellMap"), + ("read_only_space", 0x02b85): (121, "NumberDictionaryMap"), + ("read_only_space", 0x02bad): (97, "OneClosureCellMap"), + ("read_only_space", 0x02bd5): (122, "OrderedHashMapMap"), + ("read_only_space", 0x02bfd): (123, "OrderedHashSetMap"), + ("read_only_space", 0x02c25): (124, "OrderedNameDictionaryMap"), + ("read_only_space", 0x02c4d): (172, "PreparseDataMap"), + ("read_only_space", 0x02c75): (173, "PropertyArrayMap"), + ("read_only_space", 0x02c9d): (93, "SideEffectCallHandlerInfoMap"), + ("read_only_space", 0x02cc5): (93, "SideEffectFreeCallHandlerInfoMap"), + ("read_only_space", 0x02ced): (93, "NextCallSideEffectFreeCallHandlerInfoMap"), + ("read_only_space", 0x02d15): (125, "SimpleNumberDictionaryMap"), + ("read_only_space", 0x02d3d): (148, "SmallOrderedHashMapMap"), + ("read_only_space", 0x02d65): (149, "SmallOrderedHashSetMap"), + ("read_only_space", 0x02d8d): (150, "SmallOrderedNameDictionaryMap"), + ("read_only_space", 0x02db5): (153, "SourceTextModuleMap"), + ("read_only_space", 0x02ddd): (154, "SyntheticModuleMap"), + ("read_only_space", 0x02e05): (71, "WasmTypeInfoMap"), + ("read_only_space", 0x02e2d): (182, "WeakArrayListMap"), + ("read_only_space", 0x02e55): (118, "EphemeronHashTableMap"), + ("read_only_space", 0x02e7d): (163, "EmbedderDataArrayMap"), + ("read_only_space", 0x02ea5): (183, "WeakCellMap"), + ("read_only_space", 0x02ecd): (32, "StringMap"), + ("read_only_space", 0x02ef5): (41, "ConsOneByteStringMap"), + ("read_only_space", 0x02f1d): (33, "ConsStringMap"), + ("read_only_space", 0x02f45): (37, "ThinStringMap"), + ("read_only_space", 0x02f6d): (35, "SlicedStringMap"), + ("read_only_space", 0x02f95): (43, "SlicedOneByteStringMap"), + ("read_only_space", 0x02fbd): (34, "ExternalStringMap"), + ("read_only_space", 0x02fe5): (42, "ExternalOneByteStringMap"), + ("read_only_space", 0x0300d): (50, "UncachedExternalStringMap"), + ("read_only_space", 0x03035): (0, "InternalizedStringMap"), + ("read_only_space", 0x0305d): (2, "ExternalInternalizedStringMap"), + ("read_only_space", 0x03085): (10, "ExternalOneByteInternalizedStringMap"), + ("read_only_space", 0x030ad): (58, "UncachedExternalOneByteStringMap"), + ("read_only_space", 0x030d5): (67, "SelfReferenceMarkerMap"), + ("read_only_space", 0x030fd): (67, "BasicBlockCountersMarkerMap"), + ("read_only_space", 0x03141): (87, "ArrayBoilerplateDescriptionMap"), + ("read_only_space", 0x03229): (99, "InterceptorInfoMap"), + ("read_only_space", 0x05355): (72, "PromiseFulfillReactionJobTaskMap"), + ("read_only_space", 0x0537d): (73, "PromiseRejectReactionJobTaskMap"), + ("read_only_space", 0x053a5): (74, "CallableTaskMap"), + ("read_only_space", 0x053cd): (75, "CallbackTaskMap"), + ("read_only_space", 0x053f5): (76, "PromiseResolveThenableJobTaskMap"), + ("read_only_space", 0x0541d): (79, "FunctionTemplateInfoMap"), + ("read_only_space", 0x05445): (80, "ObjectTemplateInfoMap"), + ("read_only_space", 0x0546d): (81, "AccessCheckInfoMap"), + ("read_only_space", 0x05495): (82, "AccessorInfoMap"), + ("read_only_space", 0x054bd): (83, "AccessorPairMap"), + ("read_only_space", 0x054e5): (84, "AliasedArgumentsEntryMap"), + ("read_only_space", 0x0550d): (85, "AllocationMementoMap"), + ("read_only_space", 0x05535): (88, "AsmWasmDataMap"), + ("read_only_space", 0x0555d): (89, "AsyncGeneratorRequestMap"), + ("read_only_space", 0x05585): (90, "BreakPointMap"), + ("read_only_space", 0x055ad): (91, "BreakPointInfoMap"), + ("read_only_space", 0x055d5): (92, "CachedTemplateObjectMap"), + ("read_only_space", 0x055fd): (94, "ClassPositionsMap"), + ("read_only_space", 0x05625): (95, "DebugInfoMap"), + ("read_only_space", 0x0564d): (98, "FunctionTemplateRareDataMap"), + ("read_only_space", 0x05675): (100, "InterpreterDataMap"), + ("read_only_space", 0x0569d): (101, "ModuleRequestMap"), + ("read_only_space", 0x056c5): (102, "PromiseCapabilityMap"), + ("read_only_space", 0x056ed): (103, "PromiseReactionMap"), + ("read_only_space", 0x05715): (104, "PropertyDescriptorObjectMap"), + ("read_only_space", 0x0573d): (105, "PrototypeInfoMap"), + ("read_only_space", 0x05765): (106, "ScriptMap"), + ("read_only_space", 0x0578d): (107, "SourceTextModuleInfoEntryMap"), + ("read_only_space", 0x057b5): (108, "StackFrameInfoMap"), + ("read_only_space", 0x057dd): (109, "StackTraceFrameMap"), + ("read_only_space", 0x05805): (110, "TemplateObjectDescriptionMap"), + ("read_only_space", 0x0582d): (111, "Tuple2Map"), + ("read_only_space", 0x05855): (112, "WasmExceptionTagMap"), + ("read_only_space", 0x0587d): (113, "WasmExportedFunctionDataMap"), + ("read_only_space", 0x058a5): (114, "WasmIndirectFunctionTableMap"), + ("read_only_space", 0x058cd): (115, "WasmJSFunctionDataMap"), + ("read_only_space", 0x058f5): (134, "SloppyArgumentsElementsMap"), + ("read_only_space", 0x0591d): (151, "DescriptorArrayMap"), + ("read_only_space", 0x05945): (156, "UncompiledDataWithoutPreparseDataMap"), + ("read_only_space", 0x0596d): (155, "UncompiledDataWithPreparseDataMap"), + ("read_only_space", 0x05995): (171, "OnHeapBasicBlockProfilerDataMap"), + ("read_only_space", 0x059bd): (180, "WasmCapiFunctionDataMap"), + ("read_only_space", 0x059e5): (168, "InternalClassMap"), + ("read_only_space", 0x05a0d): (177, "SmiPairMap"), + ("read_only_space", 0x05a35): (176, "SmiBoxMap"), + ("read_only_space", 0x05a5d): (145, "ExportedSubClassBaseMap"), + ("read_only_space", 0x05a85): (146, "ExportedSubClassMap"), + ("read_only_space", 0x05aad): (68, "AbstractInternalClassSubclass1Map"), + ("read_only_space", 0x05ad5): (69, "AbstractInternalClassSubclass2Map"), + ("read_only_space", 0x05afd): (133, "InternalClassWithSmiElementsMap"), + ("read_only_space", 0x05b25): (169, "InternalClassWithStructElementsMap"), + ("read_only_space", 0x05b4d): (147, "ExportedSubClass2Map"), + ("read_only_space", 0x05b75): (178, "SortStateMap"), + ("read_only_space", 0x05b9d): (86, "AllocationSiteWithWeakNextMap"), + ("read_only_space", 0x05bc5): (86, "AllocationSiteWithoutWeakNextMap"), + ("read_only_space", 0x05bed): (77, "LoadHandler1Map"), + ("read_only_space", 0x05c15): (77, "LoadHandler2Map"), + ("read_only_space", 0x05c3d): (77, "LoadHandler3Map"), + ("read_only_space", 0x05c65): (78, "StoreHandler0Map"), + ("read_only_space", 0x05c8d): (78, "StoreHandler1Map"), + ("read_only_space", 0x05cb5): (78, "StoreHandler2Map"), + ("read_only_space", 0x05cdd): (78, "StoreHandler3Map"), ("map_space", 0x02115): (1057, "ExternalMap"), - ("map_space", 0x0213d): (1072, "JSMessageObjectMap"), - ("map_space", 0x02165): (182, "WasmRttEqrefMap"), - ("map_space", 0x0218d): (182, "WasmRttExternrefMap"), - ("map_space", 0x021b5): (182, "WasmRttFuncrefMap"), - ("map_space", 0x021dd): (182, "WasmRttI31refMap"), + ("map_space", 0x0213d): (1084, "JSMessageObjectMap"), + ("map_space", 0x02165): (181, "WasmRttEqrefMap"), + ("map_space", 0x0218d): (181, "WasmRttAnyrefMap"), + ("map_space", 0x021b5): (181, "WasmRttExternrefMap"), + ("map_space", 0x021dd): (181, "WasmRttFuncrefMap"), + ("map_space", 0x02205): (181, "WasmRttI31refMap"), } # List of known V8 objects. @@ -383,37 +388,37 @@ ("read_only_space", 0x024c9): "FalseValue", ("read_only_space", 0x024f9): "empty_string", ("read_only_space", 0x02735): "EmptyScopeInfo", - ("read_only_space", 0x02765): "ArgumentsMarker", - ("read_only_space", 0x027c5): "Exception", - ("read_only_space", 0x02821): "TerminationException", - ("read_only_space", 0x02889): "OptimizedOut", - ("read_only_space", 0x028e9): "StaleRegister", - ("read_only_space", 0x031b9): "EmptyPropertyArray", - ("read_only_space", 0x031c1): "EmptyByteArray", - ("read_only_space", 0x031c9): "EmptyObjectBoilerplateDescription", - ("read_only_space", 0x031fd): "EmptyArrayBoilerplateDescription", - ("read_only_space", 0x03209): "EmptyClosureFeedbackCellArray", - ("read_only_space", 0x03211): "EmptySlowElementDictionary", - ("read_only_space", 0x03235): "EmptyOrderedHashMap", - ("read_only_space", 0x03249): "EmptyOrderedHashSet", - ("read_only_space", 0x0325d): "EmptyFeedbackMetadata", - ("read_only_space", 0x03269): "EmptyPropertyCell", - ("read_only_space", 0x0327d): "EmptyPropertyDictionary", - ("read_only_space", 0x032a5): "EmptyOrderedPropertyDictionary", - ("read_only_space", 0x032e5): "NoOpInterceptorInfo", - ("read_only_space", 0x0330d): "EmptyWeakArrayList", - ("read_only_space", 0x03319): "InfinityValue", - ("read_only_space", 0x03325): "MinusZeroValue", - ("read_only_space", 0x03331): "MinusInfinityValue", - ("read_only_space", 0x0333d): "SelfReferenceMarker", - ("read_only_space", 0x0337d): "BasicBlockCountersMarker", - ("read_only_space", 0x033c1): "OffHeapTrampolineRelocationInfo", - ("read_only_space", 0x033cd): "TrampolineTrivialCodeDataContainer", - ("read_only_space", 0x033d9): "TrampolinePromiseRejectionCodeDataContainer", - ("read_only_space", 0x033e5): "GlobalThisBindingScopeInfo", - ("read_only_space", 0x0341d): "EmptyFunctionScopeInfo", - ("read_only_space", 0x03445): "NativeScopeInfo", - ("read_only_space", 0x03461): "HashSeed", + ("read_only_space", 0x02771): "ArgumentsMarker", + ("read_only_space", 0x027d1): "Exception", + ("read_only_space", 0x0282d): "TerminationException", + ("read_only_space", 0x02895): "OptimizedOut", + ("read_only_space", 0x028f5): "StaleRegister", + ("read_only_space", 0x03125): "EmptyPropertyArray", + ("read_only_space", 0x0312d): "EmptyByteArray", + ("read_only_space", 0x03135): "EmptyObjectBoilerplateDescription", + ("read_only_space", 0x03169): "EmptyArrayBoilerplateDescription", + ("read_only_space", 0x03175): "EmptyClosureFeedbackCellArray", + ("read_only_space", 0x0317d): "EmptySlowElementDictionary", + ("read_only_space", 0x031a1): "EmptyOrderedHashMap", + ("read_only_space", 0x031b5): "EmptyOrderedHashSet", + ("read_only_space", 0x031c9): "EmptyFeedbackMetadata", + ("read_only_space", 0x031d5): "EmptyPropertyCell", + ("read_only_space", 0x031e9): "EmptyPropertyDictionary", + ("read_only_space", 0x03211): "EmptyOrderedPropertyDictionary", + ("read_only_space", 0x03251): "NoOpInterceptorInfo", + ("read_only_space", 0x03279): "EmptyWeakArrayList", + ("read_only_space", 0x03285): "InfinityValue", + ("read_only_space", 0x03291): "MinusZeroValue", + ("read_only_space", 0x0329d): "MinusInfinityValue", + ("read_only_space", 0x032a9): "SelfReferenceMarker", + ("read_only_space", 0x032e9): "BasicBlockCountersMarker", + ("read_only_space", 0x0332d): "OffHeapTrampolineRelocationInfo", + ("read_only_space", 0x03339): "TrampolineTrivialCodeDataContainer", + ("read_only_space", 0x03345): "TrampolinePromiseRejectionCodeDataContainer", + ("read_only_space", 0x03351): "GlobalThisBindingScopeInfo", + ("read_only_space", 0x03389): "EmptyFunctionScopeInfo", + ("read_only_space", 0x033b1): "NativeScopeInfo", + ("read_only_space", 0x033cd): "HashSeed", ("old_space", 0x02115): "ArgumentsIteratorAccessor", ("old_space", 0x02159): "ArrayLengthAccessor", ("old_space", 0x0219d): "BoundFunctionLengthAccessor", @@ -427,49 +432,49 @@ ("old_space", 0x023bd): "RegExpResultIndicesAccessor", ("old_space", 0x02401): "StringLengthAccessor", ("old_space", 0x02445): "InvalidPrototypeValidityCell", - ("old_space", 0x024cd): "EmptyScript", - ("old_space", 0x0250d): "ManyClosuresCell", - ("old_space", 0x02519): "ArrayConstructorProtector", - ("old_space", 0x0252d): "NoElementsProtector", - ("old_space", 0x02541): "IsConcatSpreadableProtector", - ("old_space", 0x02555): "ArraySpeciesProtector", - ("old_space", 0x02569): "TypedArraySpeciesProtector", - ("old_space", 0x0257d): "PromiseSpeciesProtector", - ("old_space", 0x02591): "RegExpSpeciesProtector", - ("old_space", 0x025a5): "StringLengthProtector", - ("old_space", 0x025b9): "ArrayIteratorProtector", - ("old_space", 0x025cd): "ArrayBufferDetachingProtector", - ("old_space", 0x025e1): "PromiseHookProtector", - ("old_space", 0x025f5): "PromiseResolveProtector", - ("old_space", 0x02609): "MapIteratorProtector", - ("old_space", 0x0261d): "PromiseThenProtector", - ("old_space", 0x02631): "SetIteratorProtector", - ("old_space", 0x02645): "StringIteratorProtector", - ("old_space", 0x02659): "SingleCharacterStringCache", - ("old_space", 0x02a61): "StringSplitCache", - ("old_space", 0x02e69): "RegExpMultipleCache", - ("old_space", 0x03271): "BuiltinsConstantsTable", - ("old_space", 0x03651): "AsyncFunctionAwaitRejectSharedFun", - ("old_space", 0x03679): "AsyncFunctionAwaitResolveSharedFun", - ("old_space", 0x036a1): "AsyncGeneratorAwaitRejectSharedFun", - ("old_space", 0x036c9): "AsyncGeneratorAwaitResolveSharedFun", - ("old_space", 0x036f1): "AsyncGeneratorYieldResolveSharedFun", - ("old_space", 0x03719): "AsyncGeneratorReturnResolveSharedFun", - ("old_space", 0x03741): "AsyncGeneratorReturnClosedRejectSharedFun", - ("old_space", 0x03769): "AsyncGeneratorReturnClosedResolveSharedFun", - ("old_space", 0x03791): "AsyncIteratorValueUnwrapSharedFun", - ("old_space", 0x037b9): "PromiseAllResolveElementSharedFun", - ("old_space", 0x037e1): "PromiseAllSettledResolveElementSharedFun", - ("old_space", 0x03809): "PromiseAllSettledRejectElementSharedFun", - ("old_space", 0x03831): "PromiseAnyRejectElementSharedFun", - ("old_space", 0x03859): "PromiseCapabilityDefaultRejectSharedFun", - ("old_space", 0x03881): "PromiseCapabilityDefaultResolveSharedFun", - ("old_space", 0x038a9): "PromiseCatchFinallySharedFun", - ("old_space", 0x038d1): "PromiseGetCapabilitiesExecutorSharedFun", - ("old_space", 0x038f9): "PromiseThenFinallySharedFun", - ("old_space", 0x03921): "PromiseThrowerFinallySharedFun", - ("old_space", 0x03949): "PromiseValueThunkFinallySharedFun", - ("old_space", 0x03971): "ProxyRevokeSharedFun", + ("old_space", 0x02531): "EmptyScript", + ("old_space", 0x02571): "ManyClosuresCell", + ("old_space", 0x0257d): "ArrayConstructorProtector", + ("old_space", 0x02591): "NoElementsProtector", + ("old_space", 0x025a5): "IsConcatSpreadableProtector", + ("old_space", 0x025b9): "ArraySpeciesProtector", + ("old_space", 0x025cd): "TypedArraySpeciesProtector", + ("old_space", 0x025e1): "PromiseSpeciesProtector", + ("old_space", 0x025f5): "RegExpSpeciesProtector", + ("old_space", 0x02609): "StringLengthProtector", + ("old_space", 0x0261d): "ArrayIteratorProtector", + ("old_space", 0x02631): "ArrayBufferDetachingProtector", + ("old_space", 0x02645): "PromiseHookProtector", + ("old_space", 0x02659): "PromiseResolveProtector", + ("old_space", 0x0266d): "MapIteratorProtector", + ("old_space", 0x02681): "PromiseThenProtector", + ("old_space", 0x02695): "SetIteratorProtector", + ("old_space", 0x026a9): "StringIteratorProtector", + ("old_space", 0x026bd): "SingleCharacterStringCache", + ("old_space", 0x02ac5): "StringSplitCache", + ("old_space", 0x02ecd): "RegExpMultipleCache", + ("old_space", 0x032d5): "BuiltinsConstantsTable", + ("old_space", 0x036bd): "AsyncFunctionAwaitRejectSharedFun", + ("old_space", 0x036e1): "AsyncFunctionAwaitResolveSharedFun", + ("old_space", 0x03705): "AsyncGeneratorAwaitRejectSharedFun", + ("old_space", 0x03729): "AsyncGeneratorAwaitResolveSharedFun", + ("old_space", 0x0374d): "AsyncGeneratorYieldResolveSharedFun", + ("old_space", 0x03771): "AsyncGeneratorReturnResolveSharedFun", + ("old_space", 0x03795): "AsyncGeneratorReturnClosedRejectSharedFun", + ("old_space", 0x037b9): "AsyncGeneratorReturnClosedResolveSharedFun", + ("old_space", 0x037dd): "AsyncIteratorValueUnwrapSharedFun", + ("old_space", 0x03801): "PromiseAllResolveElementSharedFun", + ("old_space", 0x03825): "PromiseAllSettledResolveElementSharedFun", + ("old_space", 0x03849): "PromiseAllSettledRejectElementSharedFun", + ("old_space", 0x0386d): "PromiseAnyRejectElementSharedFun", + ("old_space", 0x03891): "PromiseCapabilityDefaultRejectSharedFun", + ("old_space", 0x038b5): "PromiseCapabilityDefaultResolveSharedFun", + ("old_space", 0x038d9): "PromiseCatchFinallySharedFun", + ("old_space", 0x038fd): "PromiseGetCapabilitiesExecutorSharedFun", + ("old_space", 0x03921): "PromiseThenFinallySharedFun", + ("old_space", 0x03945): "PromiseThrowerFinallySharedFun", + ("old_space", 0x03969): "PromiseValueThunkFinallySharedFun", + ("old_space", 0x0398d): "ProxyRevokeSharedFun", } # Lower 32 bits of first page addresses for various heap spaces. diff --git a/deps/v8/tools/v8windbg/src/object-inspection.cc b/deps/v8/tools/v8windbg/src/object-inspection.cc index b206dfa792f85d..b682f5b1b9e7e0 100644 --- a/deps/v8/tools/v8windbg/src/object-inspection.cc +++ b/deps/v8/tools/v8windbg/src/object-inspection.cc @@ -17,6 +17,7 @@ V8CachedObject::V8CachedObject(Location location, uncompressed_type_name_(std::move(uncompressed_type_name)), context_(std::move(context)), is_compressed_(is_compressed) {} + HRESULT V8CachedObject::Create(IModelObject* p_v8_object_instance, IV8CachedObject** result) { Location location; @@ -25,15 +26,16 @@ HRESULT V8CachedObject::Create(IModelObject* p_v8_object_instance, WRL::ComPtr context; RETURN_IF_FAIL(p_v8_object_instance->GetContext(&context)); + WRL::ComPtr sp_type; + _bstr_t type_name; + RETURN_IF_FAIL(p_v8_object_instance->GetTypeInfo(&sp_type)); + RETURN_IF_FAIL(sp_type->GetName(type_name.GetAddress())); + // If the object is of type v8::internal::TaggedValue, and this build uses // compressed pointers, then the value is compressed. Other types such as // v8::internal::Object represent uncompressed tagged values. - WRL::ComPtr sp_type; - _bstr_t type_name; bool is_compressed = COMPRESS_POINTERS_BOOL && - SUCCEEDED(p_v8_object_instance->GetTypeInfo(&sp_type)) && - SUCCEEDED(sp_type->GetName(type_name.GetAddress())) && static_cast(type_name) == std::string(kTaggedValue); const char* uncompressed_type_name = @@ -44,6 +46,7 @@ HRESULT V8CachedObject::Create(IModelObject* p_v8_object_instance, .Detach(); return S_OK; } + V8CachedObject::V8CachedObject(V8HeapObject heap_object) : heap_object_(std::move(heap_object)), heap_object_initialized_(true) {} diff --git a/deps/v8/tools/v8windbg/src/v8-debug-helper-interop.cc b/deps/v8/tools/v8windbg/src/v8-debug-helper-interop.cc index 74d0a9df2646ce..443303423776fb 100644 --- a/deps/v8/tools/v8windbg/src/v8-debug-helper-interop.cc +++ b/deps/v8/tools/v8windbg/src/v8-debug-helper-interop.cc @@ -16,7 +16,7 @@ namespace d = v8::debug_helper; // We need a plain C function pointer for interop with v8_debug_helper. We can // use this to get one as long as we never need two at once. -class MemReaderScope { +class V8_NODISCARD MemReaderScope { public: explicit MemReaderScope(WRL::ComPtr sp_context) : sp_context_(sp_context) { diff --git a/deps/v8/tools/v8windbg/test/v8windbg-test.cc b/deps/v8/tools/v8windbg/test/v8windbg-test.cc index 59414f341da97b..6b40af0ff17813 100644 --- a/deps/v8/tools/v8windbg/test/v8windbg-test.cc +++ b/deps/v8/tools/v8windbg/test/v8windbg-test.cc @@ -20,7 +20,7 @@ namespace { // Loads a named extension library upon construction and unloads it upon // destruction. -class LoadExtensionScope { +class V8_NODISCARD LoadExtensionScope { public: LoadExtensionScope(WRL::ComPtr p_debug_control, std::wstring extension_path) @@ -49,7 +49,7 @@ class LoadExtensionScope { }; // Initializes COM upon construction and uninitializes it upon destruction. -class ComScope { +class V8_NODISCARD ComScope { public: ComScope() { hr_ = CoInitializeEx(nullptr, COINIT_MULTITHREADED); } ~ComScope() { diff --git a/deps/v8/tools/wasm/update-wasm-fuzzers.sh b/deps/v8/tools/wasm/update-wasm-fuzzers.sh index ffd7e016330be5..d85b86700bd5f4 100755 --- a/deps/v8/tools/wasm/update-wasm-fuzzers.sh +++ b/deps/v8/tools/wasm/update-wasm-fuzzers.sh @@ -3,40 +3,29 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -set -e +set -ex -TOOLS_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd "$( dirname "${BASH_SOURCE[0]}" )" +cd ../.. -cd ${TOOLS_WASM_DIR}/../.. +BUILD_DIR=out/mk_wasm_fuzzer_corpus +CORPUS_DIR=test/fuzzer/wasm_corpus -rm -rf test/fuzzer/wasm_corpus +rm -rf $BUILD_DIR $CORPUS_DIR +mkdir -p $CORPUS_DIR -tools/dev/gm.py x64.release all +# Build optdebug such that the --dump-wasm-module flag is available. +gn gen $BUILD_DIR --args='is_debug=true v8_optimized_debug=true target_cpu="x64" use_goma=true' +autoninja -C $BUILD_DIR -mkdir -p test/fuzzer/wasm_corpus +./tools/run-tests.py --outdir=$BUILD_DIR --extra-flags="--dump-wasm-module \ + --dump-wasm-module-path=./$CORPUS_DIR/" -# wasm -./tools/run-tests.py -j8 --variants=default --timeout=10 --arch=x64 \ - --mode=release --no-presubmit --extra-flags="--dump-wasm-module \ - --dump-wasm-module-path=./test/fuzzer/wasm_corpus/" unittests -./tools/run-tests.py -j8 --variants=default --timeout=10 --arch=x64 \ - --mode=release --no-presubmit --extra-flags="--dump-wasm-module \ - --dump-wasm-module-path=./test/fuzzer/wasm_corpus/" wasm-spec-tests/* -./tools/run-tests.py -j8 --variants=default --timeout=10 --arch=x64 \ - --mode=release --no-presubmit --extra-flags="--dump-wasm-module \ - --dump-wasm-module-path=./test/fuzzer/wasm_corpus/" mjsunit/wasm/* -./tools/run-tests.py -j8 --variants=default --timeout=10 --arch=x64 \ - --mode=release --no-presubmit --extra-flags="--dump-wasm-module \ - --dump-wasm-module-path=./test/fuzzer/wasm_corpus/" \ - $(cd test/; ls cctest/wasm/test-*.cc | \ - sed -es/wasm\\///g | sed -es/[.]cc/\\/\\*/g) +rm -rf $BUILD_DIR # Delete items over 20k. -for x in $(find ./test/fuzzer/wasm_corpus/ -type f -size +20k) -do - rm $x -done +find $CORPUS_DIR -type f -size +20k | xargs rm # Upload changes. -cd test/fuzzer +cd $CORPUS_DIR/.. upload_to_google_storage.py -a -b v8-wasm-fuzzer wasm_corpus diff --git a/deps/v8/tools/whitespace.txt b/deps/v8/tools/whitespace.txt index d6024b5b7d94ce..8fcce8dda7f238 100644 --- a/deps/v8/tools/whitespace.txt +++ b/deps/v8/tools/whitespace.txt @@ -8,7 +8,7 @@ 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........................ -I can't add trailing whitespaces, so I'm adding this line....... +I can't add trailing whitespaces, so I'm adding this line........... I'm starting to think that just adding trailing whitespaces might not be bad. Because whitespaces are not that funny..... diff --git a/deps/v8/tools/windows-tick-processor.bat b/deps/v8/tools/windows-tick-processor.bat index 56637e051cb3b3..ae74df95359d6c 100755 --- a/deps/v8/tools/windows-tick-processor.bat +++ b/deps/v8/tools/windows-tick-processor.bat @@ -27,4 +27,4 @@ IF NOT %arg8:~0,2% == 8 (IF NOT %arg8:~0,2% == 8- SET log_file=%8) SET arg9=9%9 IF NOT %arg9:~0,2% == 9 (IF NOT %arg9:~0,2% == 9- SET log_file=%9) -type %log_file% | %D8_PATH%\d8 --module %tools_dir%tickprocessor-driver.js -- --windows %* +type %log_file% | %D8_PATH%\d8 --module %tools_dir%tickprocessor-driver.mjs -- --windows %* diff --git a/deps/v8/tools/wpr.wprp b/deps/v8/tools/wpr.wprp new file mode 100644 index 00000000000000..a6282490a8354b --- /dev/null +++ b/deps/v8/tools/wpr.wprp @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +