diff --git a/deps/v8/.git-blame-ignore-revs b/deps/v8/.git-blame-ignore-revs index 5ae39770316425..4c53e208e3acec 100644 --- a/deps/v8/.git-blame-ignore-revs +++ b/deps/v8/.git-blame-ignore-revs @@ -23,3 +23,6 @@ e50b49a0e38b34e2b28e026f4d1c7e0da0c7bb1a # Rewrite code base to use "." instead of "->" to access Object members. 878ccb33bd3cf0e6dc018ff8d15843f585ac07be + +# Move test/mjsunit/regress-*.js => test/mjsunit/regress/ +cb67be1a3842fcf6a0da18aee444e3b7ea789e04 diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 819d147096c496..7036ecd42bc461 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -77,11 +77,13 @@ Daniel Andersson Daniel Bevenius Daniel James David Carlier +David Manouchehri Deepak Mohan Deon Dior Dominic Farolini Douglas Crosher Dusan Milosavljevic +Eric Rannaud Erich Ocean Evan Lucas Fedor Indutny @@ -97,12 +99,14 @@ Henrique Ferreiro Hirofumi Mako Honggyu Kim Huáng Jùnliàng +Iain Ireland Ingvar Stepanyan Ioseb Dzmanashvili Isiah Meadows Jaime Bernardo Jan de Mooij Jan Krems +Janusz Majnert Jay Freeman James Pike James M Snell @@ -151,6 +155,7 @@ Oliver Dunk Paolo Giarrusso Patrick Gansterer Peng Fei +Peng-Yu Chen Peter Rybin Peter Varga Peter Wong @@ -195,6 +200,7 @@ Vladimir Krivosheev Vladimir Shutoff Wenlu Wang Wiktor Garbacz +Wouter Vermeiren Xiaoyin Liu Yannic Bonenberger Yong Wang diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 0ffa2b794df744..b2dde3f9d70312 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -107,7 +107,7 @@ declare_args() { # Enable pointer compression (sets -dV8_COMPRESS_POINTERS). v8_enable_pointer_compression = "" - v8_enable_31bit_smis_on_64bit_arch = true + v8_enable_31bit_smis_on_64bit_arch = false # Sets -dOBJECT_PRINT. v8_enable_object_print = "" @@ -128,7 +128,7 @@ declare_args() { v8_enable_concurrent_marking = true # Sets -dV8_ARRAY_BUFFER_EXTENSION - v8_enable_array_buffer_extension = false + v8_enable_array_buffer_extension = true # Enables various testing features. v8_enable_test_features = "" @@ -211,6 +211,13 @@ declare_args() { # Enable additional targets necessary for verification of torque # file generation v8_verify_torque_generation_invariance = false + + # Disable all snapshot compression. + v8_enable_snapshot_compression = true + + # Enable control-flow integrity features, such as pointer authentication for + # ARM64. + v8_control_flow_integrity = false } # Derived defaults. @@ -270,6 +277,9 @@ assert(!v8_disable_write_barriers || v8_enable_single_generation, assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations, "Untrusted code mitigations are unsupported on ia32") +assert(v8_current_cpu == "arm64" || !v8_control_flow_integrity, + "Control-flow integrity is only supported on arm64") + assert( !v8_enable_pointer_compression || !v8_enable_shared_ro_heap, "Pointer compression is not supported with shared read-only heap enabled") @@ -298,6 +308,7 @@ config("internal_config") { "//build/config/compiler:wexit_time_destructors", ":internal_config_base", ":v8_header_features", + ":v8_tracing_config", ] if (is_component_build) { @@ -305,6 +316,17 @@ config("internal_config") { } } +# Should be applied to all targets that write trace events. +config("v8_tracing_config") { + if (v8_use_perfetto) { + include_dirs = [ + "third_party/perfetto/include", + "$root_gen_dir/third_party/perfetto", + "$root_gen_dir/third_party/perfetto/build_config", + ] + } +} + # This config should be applied to code using the libplatform. config("libplatform_config") { include_dirs = [ "include" ] @@ -501,6 +523,15 @@ config("features") { if (v8_enable_regexp_interpreter_threaded_dispatch) { defines += [ "V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH" ] } + if (v8_enable_snapshot_compression) { + defines += [ "V8_SNAPSHOT_COMPRESSION" ] + } + if (v8_control_flow_integrity) { + defines += [ "V8_ENABLE_CONTROL_FLOW_INTEGRITY" ] + } + if (v8_enable_wasm_gdb_remote_debugging) { + defines += [ "V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING" ] + } } config("toolchain") { @@ -543,6 +574,12 @@ config("toolchain") { } if (v8_current_cpu == "arm64") { defines += [ "V8_TARGET_ARCH_ARM64" ] + if (v8_control_flow_integrity) { + # TODO(v8:10026): Enable this in src/build. + if (current_cpu == "arm64") { + cflags += [ "-mbranch-protection=standard" ] + } + } } # Mips64el/mipsel simulators. @@ -618,6 +655,7 @@ config("toolchain") { } if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") { defines += [ "V8_TARGET_ARCH_S390" ] + cflags += [ "-ffp-contract=off" ] if (v8_current_cpu == "s390x") { defines += [ "V8_TARGET_ARCH_S390X" ] } @@ -628,8 +666,9 @@ config("toolchain") { } } if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") { - defines += [ "V8_TARGET_ARCH_PPC" ] - if (v8_current_cpu == "ppc64") { + if (v8_current_cpu == "ppc") { + defines += [ "V8_TARGET_ARCH_PPC" ] + } else if (v8_current_cpu == "ppc64") { defines += [ "V8_TARGET_ARCH_PPC64" ] } if (host_byteorder == "little") { @@ -1138,11 +1177,14 @@ template("run_torque") { "bit-fields-tq.h", "builtin-definitions-tq.h", "interface-descriptors-tq.inc", + "factory-tq.cc", + "factory-tq.inc", "field-offsets-tq.h", "class-verifiers-tq.cc", "class-verifiers-tq.h", "enum-verifiers-tq.cc", "objects-printer-tq.cc", + "objects-body-descriptors-tq-inl.h", "class-definitions-tq.cc", "class-definitions-tq-inl.h", "class-definitions-tq.h", @@ -1264,6 +1306,7 @@ v8_source_set("torque_generated_definitions") { "$target_gen_dir/torque-generated/class-definitions-tq.cc", "$target_gen_dir/torque-generated/class-verifiers-tq.cc", "$target_gen_dir/torque-generated/class-verifiers-tq.h", + "$target_gen_dir/torque-generated/factory-tq.cc", "$target_gen_dir/torque-generated/objects-printer-tq.cc", ] @@ -1631,11 +1674,16 @@ v8_source_set("v8_initializers") { ### gcmole(arch:mips64el) ### "src/builtins/mips64/builtins-mips64.cc", ] - } else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") { + } else if (v8_current_cpu == "ppc") { sources += [ ### gcmole(arch:ppc) ### "src/builtins/ppc/builtins-ppc.cc", ] + } else if (v8_current_cpu == "ppc64") { + sources += [ + ### gcmole(arch:ppc64) ### + "src/builtins/ppc/builtins-ppc.cc", + ] } else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") { sources += [ ### gcmole(arch:s390) ### @@ -1684,6 +1732,7 @@ v8_header_set("v8_headers") { public_configs = [ ":v8_header_features" ] sources = [ + "include/v8-fast-api-calls.h", "include/v8-internal.h", "include/v8.h", "include/v8config.h", @@ -1865,7 +1914,6 @@ v8_compiler_sources = [ "src/compiler/memory-optimizer.cc", "src/compiler/memory-optimizer.h", "src/compiler/node-aux-data.h", - "src/compiler/node-cache.cc", "src/compiler/node-cache.h", "src/compiler/node-marker.cc", "src/compiler/node-marker.h", @@ -2005,6 +2053,7 @@ v8_source_set("v8_base_without_compiler") { ### gcmole(all) ### "$target_gen_dir/builtins-generated/bytecodes-builtins-list.h", + "include/v8-fast-api-calls.h", "include/v8-inspector-protocol.h", "include/v8-inspector.h", "include/v8-internal.h", @@ -2235,6 +2284,9 @@ v8_source_set("v8_base_without_compiler") { "src/execution/messages.h", "src/execution/microtask-queue.cc", "src/execution/microtask-queue.h", + "src/execution/off-thread-isolate.cc", + "src/execution/off-thread-isolate.h", + "src/execution/pointer-authentication.h", "src/execution/protectors-inl.h", "src/execution/protectors.cc", "src/execution/protectors.h", @@ -2273,6 +2325,9 @@ v8_source_set("v8_base_without_compiler") { "src/handles/handles-inl.h", "src/handles/handles.cc", "src/handles/handles.h", + "src/handles/local-handles-inl.h", + "src/handles/local-handles.cc", + "src/handles/local-handles.h", "src/handles/maybe-handles-inl.h", "src/handles/maybe-handles.h", "src/heap/array-buffer-collector.cc", @@ -2298,6 +2353,8 @@ v8_source_set("v8_base_without_compiler") { "src/heap/factory-inl.h", "src/heap/factory.cc", "src/heap/factory.h", + "src/heap/finalization-registry-cleanup-task.cc", + "src/heap/finalization-registry-cleanup-task.h", "src/heap/gc-idle-time-handler.cc", "src/heap/gc-idle-time-handler.h", "src/heap/gc-tracer.cc", @@ -2321,6 +2378,8 @@ v8_source_set("v8_base_without_compiler") { "src/heap/item-parallel-job.h", "src/heap/local-allocator-inl.h", "src/heap/local-allocator.h", + "src/heap/local-heap.cc", + "src/heap/local-heap.h", "src/heap/mark-compact-inl.h", "src/heap/mark-compact.cc", "src/heap/mark-compact.h", @@ -2346,6 +2405,8 @@ v8_source_set("v8_base_without_compiler") { "src/heap/read-only-heap.cc", "src/heap/read-only-heap.h", "src/heap/remembered-set.h", + "src/heap/safepoint.cc", + "src/heap/safepoint.h", "src/heap/scavenge-job.cc", "src/heap/scavenge-job.h", "src/heap/scavenger-inl.h", @@ -2446,6 +2507,7 @@ v8_source_set("v8_base_without_compiler") { "src/logging/log-utils.h", "src/logging/log.cc", "src/logging/log.h", + "src/logging/off-thread-logger.h", "src/numbers/bignum-dtoa.cc", "src/numbers/bignum-dtoa.h", "src/numbers/bignum.cc", @@ -2688,6 +2750,7 @@ v8_source_set("v8_base_without_compiler") { "src/objects/tagged-impl-inl.h", "src/objects/tagged-impl.cc", "src/objects/tagged-impl.h", + "src/objects/tagged-index.h", "src/objects/tagged-value-inl.h", "src/objects/tagged-value.h", "src/objects/template-objects-inl.h", @@ -2773,6 +2836,8 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/regexp-compiler.h", "src/regexp/regexp-dotprinter.cc", "src/regexp/regexp-dotprinter.h", + "src/regexp/regexp-error.cc", + "src/regexp/regexp-error.h", "src/regexp/regexp-interpreter.cc", "src/regexp/regexp-interpreter.h", "src/regexp/regexp-macro-assembler-arch.h", @@ -2858,6 +2923,8 @@ v8_source_set("v8_base_without_compiler") { "src/snapshot/serializer.cc", "src/snapshot/serializer.h", "src/snapshot/snapshot-common.cc", + "src/snapshot/snapshot-compression.cc", + "src/snapshot/snapshot-compression.h", "src/snapshot/snapshot-source-sink.cc", "src/snapshot/snapshot-source-sink.h", "src/snapshot/snapshot.h", @@ -2964,6 +3031,8 @@ 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", @@ -3010,10 +3079,30 @@ v8_source_set("v8_base_without_compiler") { "src/zone/zone.h", ] + if (!v8_control_flow_integrity) { + sources += [ "src/execution/pointer-authentication-dummy.h" ] + } + if (v8_enable_third_party_heap) { sources += v8_third_party_heap_files } + if (v8_enable_wasm_gdb_remote_debugging) { + sources += [ + "src/debug/wasm/gdb-server/gdb-server-thread.cc", + "src/debug/wasm/gdb-server/gdb-server-thread.h", + "src/debug/wasm/gdb-server/gdb-server.cc", + "src/debug/wasm/gdb-server/gdb-server.h", + "src/debug/wasm/gdb-server/session.cc", + "src/debug/wasm/gdb-server/session.h", + "src/debug/wasm/gdb-server/target.cc", + "src/debug/wasm/gdb-server/target.h", + "src/debug/wasm/gdb-server/transport.cc", + "src/debug/wasm/gdb-server/transport.h", + "src/debug/wasm/gdb-server/util.h", + ] + } + if (v8_check_header_includes) { # This file will be generated by tools/generate-header-include-checks.py # if the "check_v8_header_includes" gclient variable is set. @@ -3167,6 +3256,9 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/arm64/regexp-macro-assembler-arm64.h", "src/wasm/baseline/arm64/liftoff-assembler-arm64.h", ] + if (v8_control_flow_integrity) { + sources += [ "src/execution/arm64/pointer-authentication-arm64.h" ] + } if (is_win) { sources += [ "src/diagnostics/unwinding-info-win64.cc", @@ -3227,7 +3319,7 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/mips64/regexp-macro-assembler-mips64.h", "src/wasm/baseline/mips64/liftoff-assembler-mips64.h", ] - } else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") { + } else if (v8_current_cpu == "ppc") { sources += [ ### gcmole(arch:ppc) ### "src/codegen/ppc/assembler-ppc-inl.h", "src/codegen/ppc/assembler-ppc.cc", @@ -3257,6 +3349,36 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/ppc/regexp-macro-assembler-ppc.h", "src/wasm/baseline/ppc/liftoff-assembler-ppc.h", ] + } else if (v8_current_cpu == "ppc64") { + sources += [ ### gcmole(arch:ppc64) ### + "src/codegen/ppc/assembler-ppc-inl.h", + "src/codegen/ppc/assembler-ppc.cc", + "src/codegen/ppc/assembler-ppc.h", + "src/codegen/ppc/constants-ppc.cc", + "src/codegen/ppc/constants-ppc.h", + "src/codegen/ppc/cpu-ppc.cc", + "src/codegen/ppc/interface-descriptors-ppc.cc", + "src/codegen/ppc/macro-assembler-ppc.cc", + "src/codegen/ppc/macro-assembler-ppc.h", + "src/codegen/ppc/register-ppc.h", + "src/compiler/backend/ppc/code-generator-ppc.cc", + "src/compiler/backend/ppc/instruction-codes-ppc.h", + "src/compiler/backend/ppc/instruction-scheduler-ppc.cc", + "src/compiler/backend/ppc/instruction-selector-ppc.cc", + "src/compiler/backend/ppc/unwinding-info-writer-ppc.cc", + "src/compiler/backend/ppc/unwinding-info-writer-ppc.h", + "src/debug/ppc/debug-ppc.cc", + "src/deoptimizer/ppc/deoptimizer-ppc.cc", + "src/diagnostics/ppc/disasm-ppc.cc", + "src/diagnostics/ppc/eh-frame-ppc.cc", + "src/execution/ppc/frame-constants-ppc.cc", + "src/execution/ppc/frame-constants-ppc.h", + "src/execution/ppc/simulator-ppc.cc", + "src/execution/ppc/simulator-ppc.h", + "src/regexp/ppc/regexp-macro-assembler-ppc.cc", + "src/regexp/ppc/regexp-macro-assembler-ppc.h", + "src/wasm/baseline/ppc/liftoff-assembler-ppc.h", + ] } else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") { sources += [ ### gcmole(arch:s390) ### "src/codegen/s390/assembler-s390-inl.h", @@ -3357,7 +3479,10 @@ v8_source_set("v8_base_without_compiler") { ] } - deps += [ "//third_party/zlib" ] + deps += [ + "//third_party/zlib", + "//third_party/zlib/google:compression_utils_portable", + ] if (v8_postmortem_support) { sources += [ "$target_gen_dir/debug-support.cc" ] @@ -3519,6 +3644,7 @@ v8_component("v8_libbase") { "src/base/atomicops_internals_std.h", "src/base/base-export.h", "src/base/bit-field.h", + "src/base/bits-iterator.h", "src/base/bits.cc", "src/base/bits.h", "src/base/bounded-page-allocator.cc", @@ -3797,6 +3923,47 @@ v8_source_set("fuzzer_support") { ] } +v8_source_set("cppgc_base") { + visibility = [ ":*" ] + + sources = [ + "include/cppgc/allocation.h", + "include/cppgc/api-constants.h", + "include/cppgc/finalizer-trait.h", + "include/cppgc/garbage-collected.h", + "include/cppgc/gc-info.h", + "include/cppgc/heap.h", + "include/cppgc/platform.h", + "include/v8config.h", + "src/heap/cppgc/allocation.cc", + "src/heap/cppgc/gc-info-table.cc", + "src/heap/cppgc/gc-info-table.h", + "src/heap/cppgc/gc-info.cc", + "src/heap/cppgc/heap-inl.h", + "src/heap/cppgc/heap-object-header-inl.h", + "src/heap/cppgc/heap-object-header.cc", + "src/heap/cppgc/heap-object-header.h", + "src/heap/cppgc/heap.cc", + "src/heap/cppgc/heap.h", + "src/heap/cppgc/platform.cc", + "src/heap/cppgc/sanitizers.h", + "src/heap/cppgc/stack.cc", + "src/heap/cppgc/stack.h", + ] + + if (target_cpu == "x64") { + if (is_win) { + sources += [ "src/heap/cppgc/asm/x64/push_registers_win.S" ] + } else { + sources += [ "src/heap/cppgc/asm/x64/push_registers.S" ] + } + } + + configs = [ ":internal_config" ] + + public_deps = [ ":v8_libbase" ] +} + ############################################################################### # Produce a single static library for embedders # @@ -3843,6 +4010,12 @@ v8_static_library("wee8") { ] } +v8_static_library("cppgc") { + deps = [ ":cppgc_base" ] + + configs = [ ":internal_config" ] +} + ############################################################################### # Executables # @@ -4074,7 +4247,7 @@ group("v8_archive") { if (is_fuchsia && !build_with_chromium) { import("//build/config/fuchsia/rules.gni") - fuchsia_package("d8_fuchsia_pkg") { + cr_fuchsia_package("d8_fuchsia_pkg") { testonly = true binary = ":d8" package_name_override = "d8" @@ -4134,6 +4307,15 @@ if (is_component_build) { public_configs = [ ":external_config" ] } + + v8_component("cppgc_for_testing") { + testonly = true + + public_deps = [ ":cppgc_base" ] + + configs = [ ":internal_config" ] + public_configs = [ ":external_config" ] + } } else { group("v8") { public_deps = [ @@ -4157,6 +4339,14 @@ if (is_component_build) { public_configs = [ ":external_config" ] } + + group("cppgc_for_testing") { + testonly = true + + public_deps = [ ":cppgc_base" ] + + public_configs = [ ":external_config" ] + } } v8_executable("d8") { @@ -4177,6 +4367,7 @@ v8_executable("d8") { # the :external_config applied to it by virtue of depending on :v8, and # you can't have both applied to the same target. ":internal_config_base", + ":v8_tracing_config", ] deps = [ @@ -4203,7 +4394,7 @@ v8_executable("d8") { } if (v8_use_perfetto) { - deps += [ "//third_party/perfetto/include/perfetto/tracing" ] + deps += [ "//third_party/perfetto/src/tracing:in_process_backend" ] } } diff --git a/deps/v8/COMMON_OWNERS b/deps/v8/COMMON_OWNERS index cf53fe80e0bad7..1eee48173a1576 100644 --- a/deps/v8/COMMON_OWNERS +++ b/deps/v8/COMMON_OWNERS @@ -29,9 +29,11 @@ petermarshall@chromium.org rmcilroy@chromium.org sigurds@chromium.org solanes@chromium.org +syg@chromium.org szuend@chromium.org tebbi@chromium.org -titzer@chromium.org ulan@chromium.org verwaest@chromium.org +victorgomes@chromium.org yangguo@chromium.org +zhin@chromium.org diff --git a/deps/v8/DEPS b/deps/v8/DEPS index 880ff6c4b82d59..1bc687beaf6ead 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -4,13 +4,9 @@ gclient_gn_args_file = 'v8/build/config/gclient_args.gni' gclient_gn_args = [ - 'checkout_aemu' ] vars = { - # By Default, do not checkout AEMU, as it is too big, as is done in Chromium. - 'checkout_aemu': False, - # Fetches only the SDK boot images which match at least one of the whitelist # entries in a comma-separated list. # @@ -35,10 +31,10 @@ vars = { 'check_v8_header_includes': False, # GN CIPD package version. - 'gn_version': 'git_revision:97cc440d84f050f99ff0161f9414bfa2ffa38f65', + 'gn_version': 'git_revision:5ed3c9cc67b090d5e311e4bd2aba072173e82db9', # luci-go CIPD package version. - 'luci_go': 'git_revision:37a855b64d59b7f079c9a0e5368f2757099d14d3', + 'luci_go': 'git_revision:de73cf6c4bde86f0a9c8d54151b69b0154a398f1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version @@ -69,10 +65,6 @@ vars = { # and whatever else without interference from each other. 'android_sdk_sources_version': '4gxhM8E62bvZpQs7Q3d0DinQaW0RLCIefhXrQBFkNy8C', # Three lines of non-changing comments so that - # the commit queue can handle CLs rolling android_sdk_tools_version - # and whatever else without interference from each other. - 'android_sdk_tools_version': 'wYcRQC2WHsw2dKWs4EA7fw9Qsyzu1ds1_fRjKmGxe5QC', - # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_tools-lint_version # and whatever else without interference from each other. 'android_sdk_tools-lint_version': '89hXqZYzCum3delB5RV7J_QyWkaRodqdtQS0s3LMh3wC', @@ -80,15 +72,15 @@ vars = { deps = { 'v8/build': - Var('chromium_url') + '/chromium/src/build.git' + '@' + '2f17606c25956e800b6c4670c294a03620e78551', + Var('chromium_url') + '/chromium/src/build.git' + '@' + '26e9d485d01d6e0eb9dadd21df767a63494c8fea', 'v8/third_party/depot_tools': - Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'ea8b58b970c0c94b4a36270b806ee307547cd77e', + Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '2b2aec6506a810f8d7bd018609de2c2450b3c121', 'v8/third_party/icu': - Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'dbd3825b31041d782c5b504c59dcfb5ac7dda08c', + Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'd7aff76cf6bb0fbef3afa6c07718f78a80a70f8f', 'v8/third_party/instrumented_libraries': Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'bb3f1802c237dd19105dd0f7919f99e536a39d10', 'v8/buildtools': - Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + 'afc5b798c72905e85f9991152be878714c579958', + Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '7977eb176752aeec29d888cfe8e677ac12ed1c41', 'v8/buildtools/clang_format/script': Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917', 'v8/buildtools/linux64': { @@ -112,11 +104,11 @@ deps = { 'condition': 'host_os == "mac"', }, 'v8/buildtools/third_party/libc++/trunk': - Var('chromium_url') + '/chromium/llvm-project/libcxx.git' + '@' + '78d6a7767ed57b50122a161b91f59f19c9bd0d19', + Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + 'd9040c75cfea5928c804ab7c235fed06a63f743a', 'v8/buildtools/third_party/libc++abi/trunk': - Var('chromium_url') + '/chromium/llvm-project/libcxxabi.git' + '@' + '0d529660e32d77d9111912d73f2c74fc5fa2a858', + Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + '196ba1aaa8ac285d94f4ea8d9836390a45360533', 'v8/buildtools/third_party/libunwind/trunk': - Var('chromium_url') + '/external/llvm.org/libunwind.git' + '@' + '69d9b84cca8354117b9fe9705a4430d789ee599b', + Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '43bb9f872232f531bac80093ceb4de61c64b9ab7', 'v8/buildtools/win': { 'packages': [ { @@ -128,7 +120,7 @@ deps = { 'condition': 'host_os == "win"', }, 'v8/base/trace_event/common': - Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'bd79231eb1f9e7de2efb4ad79e530d9a7e70d9a5', + Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'dab187b372fc17e51f5b9fad8201813d0aed5129', 'v8/third_party/android_ndk': { 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '27c0a8d090c666a50e40fceb4ee5b40b1a2d3f87', 'condition': 'checkout_android', @@ -167,10 +159,6 @@ deps = { 'package': 'chromium/third_party/android_sdk/public/sources/android-29', 'version': Var('android_sdk_sources_version'), }, - { - 'package': 'chromium/third_party/android_sdk/public/tools', - 'version': Var('android_sdk_tools_version'), - }, { 'package': 'chromium/third_party/android_sdk/public/tools-lint', 'version': Var('android_sdk_tools-lint_version'), @@ -180,7 +168,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/third_party/catapult': { - 'url': Var('chromium_url') + '/catapult.git' + '@' + '2e0a0cb9ad546be8c835e65d7537507cb7896e03', + 'url': Var('chromium_url') + '/catapult.git' + '@' + '032c78376792ef343ea361bca2181ba6dec6b95f', 'condition': 'checkout_android', }, 'v8/third_party/colorama/src': { @@ -188,23 +176,23 @@ deps = { 'condition': 'checkout_android', }, 'v8/third_party/fuchsia-sdk': { - 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '19c8ac5e150fbd147ec5987425a41aa9e97098b2', + 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '2457e41d8dc379f74662d3157e76339ba92cee06', 'condition': 'checkout_fuchsia', }, 'v8/third_party/googletest/src': - Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '306f3754a71d6d1ac644681d3544d06744914228', + Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '10b1902d893ea8cc43c69541d70868f91af3646b', 'v8/third_party/jinja2': Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'b41863e42637544c2941b574c7877d3e1f663e25', 'v8/third_party/markupsafe': Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + '8f45f5cfa0009d2a70589bcda0349b8cb2b72783', 'v8/tools/swarming_client': - Var('chromium_url') + '/infra/luci/client-py.git' + '@' + '885b3febcc170a60f25795304e60927b77d1e92d', + Var('chromium_url') + '/infra/luci/client-py.git' + '@' + 'cc958279ffd6853e0a1b227a7e957ca334fe56af', 'v8/test/benchmarks/data': Var('chromium_url') + '/v8/deps/third_party/benchmarks.git' + '@' + '05d7188267b4560491ff9155c5ee13e207ecd65f', 'v8/test/mozilla/data': Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be', 'v8/test/test262/data': - Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '28b4fcca4b1b1d278dfe0cc0e69c7d9d59b31aab', + Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'f6b2ccdd091ff82da54150796297c3a96d7edb41', 'v8/test/test262/harness': Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b', 'v8/third_party/qemu-linux-x64': { @@ -227,8 +215,28 @@ deps = { 'condition': 'host_os == "mac" and checkout_fuchsia', 'dep_type': 'cipd', }, + 'v8/third_party/aemu-linux-x64': { + 'packages': [ + { + 'package': 'fuchsia/third_party/aemu/linux-amd64', + 'version': '7YlCgase5GlIanqHn-nZClSlZ5kQETJyVUYRF7Jjy6UC' + }, + ], + 'condition': 'host_os == "linux" and checkout_fuchsia', + 'dep_type': 'cipd', + }, + 'v8/third_party/aemu-mac-x64': { + 'packages': [ + { + 'package': 'fuchsia/third_party/aemu/mac-amd64', + 'version': 'T9bWxf8aUC5TwCFgPxpuW29Mfy-7Z9xCfXB9QO8MfU0C' + }, + ], + 'condition': 'host_os == "mac" and checkout_fuchsia', + 'dep_type': 'cipd', + }, 'v8/tools/clang': - Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '535dbf16a84c7fc238f7ed11b5a75381407e38f6', + Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '105a8460911176861a422738eee4daad8dfe88a2', 'v8/tools/luci-go': { 'packages': [ { @@ -258,11 +266,11 @@ deps = { 'dep_type': 'cipd', }, 'v8/third_party/perfetto': - Var('android_url') + '/platform/external/perfetto.git' + '@' + '12dc10e0278cded35205cf84f80a821348cb6c56', + Var('android_url') + '/platform/external/perfetto.git' + '@' + 'b9b24d1b0b80aafec393af085067e9eae829412f', 'v8/third_party/protobuf': Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91', 'v8/third_party/zlib': - Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + 'b9b9a5af7cca2e683e5f2aead8418e5bf9d5a7d5', + Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '156be8c52f80cde343088b4a69a80579101b6e67', 'v8/third_party/ittapi': { # Force checkout ittapi libraries to pass v8 header includes check on # bots that has check_v8_header_includes enabled. diff --git a/deps/v8/base/trace_event/common/trace_event_common.h b/deps/v8/base/trace_event/common/trace_event_common.h index 3f741d816f722d..a7bffbdbeb44c7 100644 --- a/deps/v8/base/trace_event/common/trace_event_common.h +++ b/deps/v8/base/trace_event/common/trace_event_common.h @@ -61,28 +61,30 @@ // current process id, thread id, and a timestamp in microseconds. // // To trace an asynchronous procedure such as an IPC send/receive, use -// ASYNC_BEGIN and ASYNC_END: +// NESTABLE_ASYNC_BEGIN and NESTABLE_ASYNC_END: // [single threaded sender code] // static int send_count = 0; // ++send_count; -// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count); +// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( +// "ipc", "message", TRACE_ID_LOCAL(send_count)); // Send(new MyMessage(send_count)); // [receive code] // void OnMyMessage(send_count) { -// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count); +// TRACE_NESTABLE_EVENT_ASYNC_END0( +// "ipc", "message", TRACE_ID_LOCAL(send_count)); // } -// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs. -// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. -// Pointers can be used for the ID parameter, and they will be annotated -// internally so that the same pointer on two different processes will not -// match. For example: +// The third parameter is a unique ID to match NESTABLE_ASYNC_BEGIN/ASYNC_END +// pairs. NESTABLE_ASYNC_BEGIN and ASYNC_END can occur on any thread of any +// traced process. // Pointers can be used for the ID parameter, and they will +// be annotated internally so that the same pointer on two different processes +// will not match. For example: // class MyTracedClass { // public: // MyTracedClass() { -// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this); +// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("category", "MyTracedClass", this); // } // ~MyTracedClass() { -// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this); +// TRACE_EVENT_NESTABLE_ASYNC_END0("category", "MyTracedClass", this); // } // } // @@ -512,9 +514,11 @@ name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ arg1_val) -// ASYNC_STEP_* APIs should be only used by legacy code. New code should -// consider using NESTABLE_ASYNC_* APIs to describe substeps within an async -// event. +// -- TRACE_EVENT_ASYNC is DEPRECATED! -- +// +// TRACE_EVENT_ASYNC_* APIs should be only used by legacy code. New code should +// use TRACE_EVENT_NESTABLE_ASYNC_* APIs instead. +// // Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2 // associated arguments. If the category is not enabled, then this // does nothing. @@ -566,9 +570,6 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category_group, name, id, flags) // Similar to TRACE_EVENT_ASYNC_BEGINx but with a custom |at| timestamp // provided. @@ -595,11 +596,6 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \ - category_group, name, id, timestamp, flags) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \ - TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) // Records a single ASYNC_STEP_INTO event for |step| immediately. If the // category is not enabled, then this does nothing. The |name| and |id| must @@ -671,9 +667,6 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category_group, name, id, flags) // Similar to TRACE_EVENT_ASYNC_ENDx but with a custom |at| timestamp provided. #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \ @@ -699,11 +692,6 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \ - id, timestamp, flags) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \ - TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) // NESTABLE_ASYNC_* APIs are used to describe an async operation, which can // be nested within a NESTABLE_ASYNC event and/or have inner NESTABLE_ASYNC @@ -742,6 +730,10 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) +#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \ + flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \ + category_group, name, id, flags) // Records a single NESTABLE_ASYNC_END event called "name" immediately, with 0 // or 2 associated arguments. If the category is not enabled, then this does // nothing. @@ -761,6 +753,10 @@ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) +#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \ + flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \ + category_group, name, id, flags) // Records a single NESTABLE_ASYNC_INSTANT event called "name" immediately, // with none, one or two associated argument. If the category is not enabled, @@ -808,6 +804,11 @@ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val) +#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \ + category_group, name, id, timestamp, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ + TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \ + TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \ id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ @@ -826,6 +827,11 @@ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val, arg2_name, arg2_val) +#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0( \ + category_group, name, id, timestamp, flags) \ + INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ + TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \ + TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags) #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0( \ category_group, name, id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ diff --git a/deps/v8/gni/proto_library.gni b/deps/v8/gni/proto_library.gni index b16d8f93bd8fcd..eca3ffb84e55ac 100644 --- a/deps/v8/gni/proto_library.gni +++ b/deps/v8/gni/proto_library.gni @@ -124,9 +124,13 @@ template("proto_library") { rebase_path(proto_in_dir, root_build_dir), ] if (generate_cc) { + cc_generator_options_ = "" + if (defined(invoker.cc_generator_options)) { + cc_generator_options_ = invoker.cc_generator_options + } args += [ "--cpp_out", - rel_cc_out_dir, + cc_generator_options_ + rel_cc_out_dir, ] } if (generate_descriptor != "") { @@ -153,13 +157,9 @@ template("proto_library") { args += rebase_path(proto_sources, root_build_dir) - inputs = [ - protoc_path, - ] + inputs = [ protoc_path ] - deps = [ - protoc_label, - ] + deps = [ protoc_label ] if (generate_with_plugin) { inputs += [ plugin_path ] if (defined(plugin_host_label)) { @@ -201,21 +201,23 @@ template("proto_library") { public_configs = [] } - public_configs += [ - "//:protobuf_gen_config", - ":$config_name", - ] + public_configs += [ "//:protobuf_gen_config" ] + + propagate_imports_configs = !defined(invoker.propagate_imports_configs) || + invoker.propagate_imports_configs + if (propagate_imports_configs) { + public_configs += [ ":$config_name" ] + } else { + # Embedder handles include directory propagation to dependents. + configs += [ ":$config_name" ] + } # Use protobuf_full only for tests. if (defined(invoker.use_protobuf_full) && invoker.use_protobuf_full == true) { - deps = [ - "//:protobuf_full", - ] + deps = [ "//:protobuf_full" ] } else { - deps = [ - "//:protobuf_lite", - ] + deps = [ "//:protobuf_lite" ] } deps += [ ":$action_name" ] diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni index eaf76a471b3395..0b2806ca949b77 100644 --- a/deps/v8/gni/v8.gni +++ b/deps/v8/gni/v8.gni @@ -57,6 +57,12 @@ declare_args() { # Use Perfetto (https://perfetto.dev) as the default TracingController. Not # currently implemented. v8_use_perfetto = false + + # Override global symbol level setting for v8 + v8_symbol_level = symbol_level + + # Enable WebAssembly debugging via GDB-remote protocol. + v8_enable_wasm_gdb_remote_debugging = false } if (v8_use_external_startup_data == "") { @@ -109,6 +115,13 @@ if (is_debug && !v8_optimized_debug) { } } +if (!is_debug) { + v8_remove_configs += [ + # Too much performance impact, unclear security benefit. + "//build/config/compiler:default_init_stack_vars", + ] +} + if (v8_code_coverage && !is_clang) { v8_add_configs += [ v8_path_prefix + ":v8_gcov_coverage_cflags", @@ -116,6 +129,19 @@ if (v8_code_coverage && !is_clang) { ] } +if (v8_symbol_level != symbol_level) { + v8_remove_configs += [ "//build/config/compiler:default_symbols" ] + if (v8_symbol_level == 0) { + v8_add_configs += [ "//build/config/compiler:no_symbols" ] + } else if (v8_symbol_level == 1) { + v8_add_configs += [ "//build/config/compiler:minimal_symbols" ] + } else if (v8_symbol_level == 2) { + v8_add_configs += [ "//build/config/compiler:symbols" ] + } else { + assert(false) + } +} + if ((is_posix || is_fuchsia) && (v8_enable_backtrace || v8_monolithic || v8_expose_symbols)) { v8_remove_configs += [ "//build/config/gcc:symbol_visibility_hidden" ] @@ -217,6 +243,25 @@ template("v8_component") { } } +template("v8_shared_library") { + shared_library(target_name) { + forward_variables_from(invoker, + "*", + [ + "configs", + "remove_configs", + ]) + configs -= v8_remove_configs + configs += v8_add_configs + if (defined(invoker.remove_configs)) { + configs -= invoker.remove_configs + } + if (defined(invoker.configs)) { + configs += invoker.configs + } + } +} + template("v8_static_library") { static_library(target_name) { complete_static_lib = true diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS index 1e0794df7a2796..4f90a5c8c70692 100644 --- a/deps/v8/include/OWNERS +++ b/deps/v8/include/OWNERS @@ -1,5 +1,6 @@ adamk@chromium.org danno@chromium.org +mlippautz@chromium.org ulan@chromium.org verwaest@chromium.org yangguo@chromium.org diff --git a/deps/v8/include/cppgc/README.md b/deps/v8/include/cppgc/README.md new file mode 100644 index 00000000000000..3a2db6dfa97ece --- /dev/null +++ b/deps/v8/include/cppgc/README.md @@ -0,0 +1,5 @@ +# C++ Garbage Collection + +This directory provides an open-source garbage collection library for C++. + +The library is under construction, meaning that *all APIs in this directory are incomplete and considered unstable and should not be used*. \ No newline at end of file diff --git a/deps/v8/include/cppgc/allocation.h b/deps/v8/include/cppgc/allocation.h new file mode 100644 index 00000000000000..3e717ad7d428f8 --- /dev/null +++ b/deps/v8/include/cppgc/allocation.h @@ -0,0 +1,91 @@ +// 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_ALLOCATION_H_ +#define INCLUDE_CPPGC_ALLOCATION_H_ + +#include +#include + +#include "include/cppgc/garbage-collected.h" +#include "include/cppgc/gc-info.h" +#include "include/cppgc/heap.h" +#include "include/cppgc/internals.h" + +namespace cppgc { + +template +class MakeGarbageCollectedTraitBase; + +namespace internal { + +class V8_EXPORT MakeGarbageCollectedTraitInternal { + protected: + static inline void MarkObjectAsFullyConstructed(const void* payload) { + // See api_constants for an explanation of the constants. + std::atomic* atomic_mutable_bitfield = + reinterpret_cast*>( + 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); + } + + static void* Allocate(cppgc::Heap* heap, size_t size, GCInfoIndex index); + + friend class HeapObjectHeader; +}; + +} // namespace internal + +// Users with custom allocation needs (e.g. overriding size) should override +// MakeGarbageCollectedTrait (see below) and inherit their trait from +// MakeGarbageCollectedTraitBase to get access to low-level primitives. +template +class MakeGarbageCollectedTraitBase + : private internal::MakeGarbageCollectedTraitInternal { + protected: + // Allocates an object of |size| bytes on |heap|. + // + // TODO(mlippautz): Allow specifying arena for specific embedder uses. + static void* Allocate(Heap* heap, size_t size) { + return internal::MakeGarbageCollectedTraitInternal::Allocate( + heap, size, internal::GCInfoTrait::Index()); + } + + // Marks an object as being fully constructed, resulting in precise handling + // by the garbage collector. + static void MarkObjectAsFullyConstructed(const void* payload) { + // internal::MarkObjectAsFullyConstructed(payload); + internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed( + payload); + } +}; + +template +class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase { + public: + template + static T* Call(Heap* heap, Args&&... args) { + static_assert(internal::IsGarbageCollectedType::value, + "T needs to be a garbage collected object"); + void* memory = MakeGarbageCollectedTraitBase::Allocate(heap, sizeof(T)); + T* object = ::new (memory) T(std::forward(args)...); + MakeGarbageCollectedTraitBase::MarkObjectAsFullyConstructed(object); + return object; + } +}; + +// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage +// collected type. +template +T* MakeGarbageCollected(Heap* heap, Args&&... args) { + return MakeGarbageCollectedTrait::Call(heap, std::forward(args)...); +} + +} // namespace cppgc + +#endif // INCLUDE_CPPGC_ALLOCATION_H_ diff --git a/deps/v8/include/cppgc/finalizer-trait.h b/deps/v8/include/cppgc/finalizer-trait.h new file mode 100644 index 00000000000000..12216ed84ed9f6 --- /dev/null +++ b/deps/v8/include/cppgc/finalizer-trait.h @@ -0,0 +1,90 @@ +// 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_FINALIZER_TRAIT_H_ +#define INCLUDE_CPPGC_FINALIZER_TRAIT_H_ + +#include + +#include "include/cppgc/internals.h" + +namespace cppgc { +namespace internal { + +using FinalizationCallback = void (*)(void*); + +template +struct HasFinalizeGarbageCollectedObject : std::false_type {}; + +template +struct HasFinalizeGarbageCollectedObject< + T, void_t().FinalizeGarbageCollectedObject())>> + : std::true_type {}; + +// The FinalizerTraitImpl specifies how to finalize objects. +template +struct FinalizerTraitImpl; + +template +struct FinalizerTraitImpl { + private: + // Dispatch to custom FinalizeGarbageCollectedObject(). + struct Custom { + static void Call(void* obj) { + static_cast(obj)->FinalizeGarbageCollectedObject(); + } + }; + + // Dispatch to regular destructor. + struct Destructor { + static void Call(void* obj) { static_cast(obj)->~T(); } + }; + + using FinalizeImpl = + std::conditional_t::value, Custom, + Destructor>; + + public: + static void Finalize(void* obj) { + static_assert(sizeof(T), "T must be fully defined"); + FinalizeImpl::Call(obj); + } +}; + +template +struct FinalizerTraitImpl { + static void Finalize(void* obj) { + static_assert(sizeof(T), "T must be fully defined"); + } +}; + +// The FinalizerTrait is used to determine if a type requires finalization and +// what finalization means. +template +struct FinalizerTrait { + private: + // Object has a finalizer if it has + // - a custom FinalizeGarbageCollectedObject method, or + // - a destructor. + static constexpr bool kNonTrivialFinalizer = + internal::HasFinalizeGarbageCollectedObject::value || + !std::is_trivially_destructible::type>::value; + + static void Finalize(void* obj) { + internal::FinalizerTraitImpl::Finalize(obj); + } + + public: + // The callback used to finalize an object of type T. + static constexpr FinalizationCallback kCallback = + kNonTrivialFinalizer ? Finalize : nullptr; +}; + +template +constexpr FinalizationCallback FinalizerTrait::kCallback; + +} // namespace internal +} // namespace cppgc + +#endif // INCLUDE_CPPGC_FINALIZER_TRAIT_H_ diff --git a/deps/v8/include/cppgc/garbage-collected.h b/deps/v8/include/cppgc/garbage-collected.h new file mode 100644 index 00000000000000..6c62daafdc5d8d --- /dev/null +++ b/deps/v8/include/cppgc/garbage-collected.h @@ -0,0 +1,53 @@ +// 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_GARBAGE_COLLECTED_H_ +#define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_ + +#include + +#include "include/cppgc/internals.h" +#include "include/cppgc/platform.h" + +namespace cppgc { +namespace internal { + +template +struct IsGarbageCollectedType : std::false_type { + static_assert(sizeof(T), "T must be fully defined"); +}; + +template +struct IsGarbageCollectedType< + T, void_t::IsGarbageCollectedTypeMarker>> + : std::true_type { + static_assert(sizeof(T), "T must be fully defined"); +}; + +} // namespace internal + +template +class GarbageCollected { + public: + using IsGarbageCollectedTypeMarker = void; + + // Must use MakeGarbageCollected. + void* operator new(size_t) = delete; + void* operator new[](size_t) = delete; + // The garbage collector is taking care of reclaiming the object. Also, + // virtual destructor requires an unambiguous, accessible 'operator delete'. + void operator delete(void*) { +#ifdef V8_ENABLE_CHECKS + internal::Abort(); +#endif // V8_ENABLE_CHECKS + } + void operator delete[](void*) = delete; + + protected: + GarbageCollected() = default; +}; + +} // namespace cppgc + +#endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_ diff --git a/deps/v8/include/cppgc/gc-info.h b/deps/v8/include/cppgc/gc-info.h new file mode 100644 index 00000000000000..987ba34fa4254c --- /dev/null +++ b/deps/v8/include/cppgc/gc-info.h @@ -0,0 +1,43 @@ +// 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_GC_INFO_H_ +#define INCLUDE_CPPGC_GC_INFO_H_ + +#include + +#include "include/cppgc/finalizer-trait.h" +#include "include/v8config.h" + +namespace cppgc { +namespace internal { + +using GCInfoIndex = uint16_t; + +class V8_EXPORT RegisteredGCInfoIndex final { + public: + RegisteredGCInfoIndex(FinalizationCallback finalization_callback, + bool has_v_table); + GCInfoIndex GetIndex() const { return index_; } + + private: + const GCInfoIndex index_; +}; + +// Trait determines how the garbage collector treats objects wrt. to traversing, +// finalization, and naming. +template +struct GCInfoTrait { + static GCInfoIndex Index() { + static_assert(sizeof(T), "T must be fully defined"); + static const RegisteredGCInfoIndex registered_index( + FinalizerTrait::kCallback, std::is_polymorphic::value); + return registered_index.GetIndex(); + } +}; + +} // namespace internal +} // namespace cppgc + +#endif // INCLUDE_CPPGC_GC_INFO_H_ diff --git a/deps/v8/include/cppgc/heap.h b/deps/v8/include/cppgc/heap.h new file mode 100644 index 00000000000000..a0568d534fbee2 --- /dev/null +++ b/deps/v8/include/cppgc/heap.h @@ -0,0 +1,31 @@ +// 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_H_ +#define INCLUDE_CPPGC_HEAP_H_ + +#include + +#include "include/v8config.h" + +namespace cppgc { +namespace internal { +class Heap; +} // namespace internal + +class V8_EXPORT Heap { + public: + static std::unique_ptr Create(); + + virtual ~Heap() = default; + + private: + Heap() = default; + + friend class internal::Heap; +}; + +} // namespace cppgc + +#endif // INCLUDE_CPPGC_HEAP_H_ diff --git a/deps/v8/include/cppgc/internals.h b/deps/v8/include/cppgc/internals.h new file mode 100644 index 00000000000000..1e57779758b6c7 --- /dev/null +++ b/deps/v8/include/cppgc/internals.h @@ -0,0 +1,41 @@ +// 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_INTERNALS_H_ +#define INCLUDE_CPPGC_INTERNALS_H_ + +#include +#include + +#include "include/v8config.h" + +namespace cppgc { +namespace internal { + +// Pre-C++17 custom implementation of std::void_t. +template +struct make_void { + typedef void type; +}; +template +using void_t = typename make_void::type; + +// Embedders should not rely on this code! + +// Internal constants to avoid exposing internal types on the API surface. +namespace api_constants { +// Offset of the uint16_t bitfield from the payload contaning the +// in-construction bit. This is subtracted from the payload pointer to get +// to the right bitfield. +static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload = + 2 * sizeof(uint16_t); +// Mask for in-construction bit. +static constexpr size_t kFullyConstructedBitMask = size_t{1}; + +} // namespace api_constants + +} // namespace internal +} // namespace cppgc + +#endif // INCLUDE_CPPGC_INTERNALS_H_ diff --git a/deps/v8/include/cppgc/platform.h b/deps/v8/include/cppgc/platform.h new file mode 100644 index 00000000000000..f216c2730a4dea --- /dev/null +++ b/deps/v8/include/cppgc/platform.h @@ -0,0 +1,31 @@ +// 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_PLATFORM_H_ +#define INCLUDE_CPPGC_PLATFORM_H_ + +#include "include/v8-platform.h" +#include "include/v8config.h" + +namespace cppgc { + +// TODO(v8:10346): Put PageAllocator in a non-V8 include header to avoid +// depending on namespace v8. +using PageAllocator = v8::PageAllocator; + +// Initializes the garbage collector with the provided platform. Must be called +// before creating a Heap. +V8_EXPORT void InitializePlatform(PageAllocator* page_allocator); + +// Must be called after destroying the last used heap. +V8_EXPORT void ShutdownPlatform(); + +namespace internal { + +V8_EXPORT void Abort(); + +} // namespace internal +} // namespace cppgc + +#endif // INCLUDE_CPPGC_PLATFORM_H_ diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl index 28b8e610767142..3f5410d1e1f787 100644 --- a/deps/v8/include/js_protocol.pdl +++ b/deps/v8/include/js_protocol.pdl @@ -119,6 +119,7 @@ domain Debugger script eval module + wasm-expression-stack # Object representing the scope. For `global` and `with` scopes it represents the actual # object; for the rest of the scopes, it is artificial transient object enumerating scope # variables as its properties. @@ -273,6 +274,13 @@ domain Debugger # Resumes JavaScript execution. command resume + parameters + # Set to true to terminate execution upon resuming execution. In contrast + # to Runtime.terminateExecution, this will allows to execute further + # JavaScript (i.e. via evaluation) until execution of the paused code + # is actually resumed, at which point termination is triggered. + # If execution is currently not paused, this parameter has no effect. + optional boolean terminateOnResume # Searches for given string in script content. command searchInContent @@ -496,6 +504,12 @@ domain Debugger # Fired when the virtual machine resumed execution. event resumed + # Enum of possible script languages. + type ScriptLanguage extends string + enum + JavaScript + WebAssembly + # Fired when virtual machine fails to parse the script. event scriptFailedToParse parameters @@ -527,6 +541,10 @@ domain Debugger optional integer length # JavaScript top stack frame of where the script parsed event was triggered if available. experimental optional Runtime.StackTrace stackTrace + # If the scriptLanguage is WebAssembly, the code section offset in the module. + experimental optional integer codeOffset + # The language of the script. + experimental optional Debugger.ScriptLanguage scriptLanguage # Fired when virtual machine parses script. This event is also fired for all known and uncollected # scripts upon enabling debugger. @@ -562,6 +580,10 @@ domain Debugger optional integer length # JavaScript top stack frame of where the script parsed event was triggered if available. experimental optional Runtime.StackTrace stackTrace + # If the scriptLanguage is WebAssembly, the code section offset in the module. + experimental optional integer codeOffset + # The language of the script. + experimental optional Debugger.ScriptLanguage scriptLanguage experimental domain HeapProfiler depends on Runtime @@ -824,6 +846,8 @@ domain Profiler optional boolean callCount # Collect block-based coverage. optional boolean detailed + # Allow the backend to send updates on its own initiative + optional boolean allowTriggeredUpdates returns # Monotonically increasing time (in seconds) when the coverage update was taken in the backend. number timestamp @@ -931,7 +955,8 @@ domain Runtime boolean symbol bigint - # Object subtype hint. Specified for `object` type values only. + wasm + # Object subtype hint. Specified for `object` or `wasm` type values only. optional enum subtype array null @@ -950,6 +975,11 @@ domain Runtime typedarray arraybuffer dataview + i32 + i64 + f32 + f64 + v128 # 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). @@ -1306,7 +1336,9 @@ domain Runtime experimental optional TimeDelta timeout # Disable breakpoints during execution. experimental optional boolean disableBreaks - # Reserved flag for future REPL mode support. Setting this flag has currently no effect. + # Setting this flag to true enables `let` re-declaration and top-level `await`. + # Note that `let` variables can only be re-declared if they originate from + # `replMode` themselves. experimental optional boolean replMode returns # Evaluation result. diff --git a/deps/v8/include/v8-fast-api-calls.h b/deps/v8/include/v8-fast-api-calls.h new file mode 100644 index 00000000000000..bfce66b652dd2d --- /dev/null +++ b/deps/v8/include/v8-fast-api-calls.h @@ -0,0 +1,408 @@ +// 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. + +/** + * This file provides additional API on top of the default one for making + * API calls, which come from embedder C++ functions. The functions are being + * called directly from optimized code, doing all the necessary typechecks + * in the compiler itself, instead of on the embedder side. Hence the "fast" + * in the name. Example usage might look like: + * + * \code + * void FastMethod(int param, bool another_param); + * + * v8::FunctionTemplate::New(isolate, SlowCallback, data, + * signature, length, constructor_behavior + * side_effect_type, + * &v8::CFunction::Make(FastMethod)); + * \endcode + * + * An example for custom embedder type support might employ a way to wrap/ + * unwrap various C++ types in JSObject instances, e.g: + * + * \code + * + * // Represents the way this type system maps C++ and JS values. + * struct WrapperTypeInfo { + * // Store e.g. a method to map from exposed C++ types to the already + * // created v8::FunctionTemplate's for instantiating them. + * }; + * + * // Helper method with a sanity check. + * template + * inline T* GetInternalField(v8::Local wrapper) { + * assert(offset < wrapper->InternalFieldCount()); + * return reinterpret_cast( + * wrapper->GetAlignedPointerFromInternalField(offset)); + * } + * + * // Returns the type info from a wrapper JS object. + * inline const WrapperTypeInfo* ToWrapperTypeInfo( + * v8::Local wrapper) { + * return GetInternalField(wrapper); + * } + * + * class CustomEmbedderType { + * public: + * static constexpr const WrapperTypeInfo* GetWrapperTypeInfo() { + * return &custom_type_wrapper_type_info; + * } + * // Returns the raw C object from a wrapper JS object. + * static CustomEmbedderType* Unwrap(v8::Local wrapper) { + * return GetInternalField(wrapper); + * } + * static void FastMethod(CustomEmbedderType* receiver, int param) { + * assert(receiver != nullptr); + * // Type checks are already done by the optimized code. + * // Then call some performance-critical method like: + * // receiver->Method(param); + * } + * + * static void SlowMethod( + * const v8::FunctionCallbackInfo& info) { + * v8::Local instance = + * v8::Local::Cast(info.Holder()); + * CustomEmbedderType* receiver = Unwrap(instance); + * // TODO: Do type checks and extract {param}. + * FastMethod(receiver, param); + * } + * + * private: + * static const WrapperTypeInfo custom_type_wrapper_type_info; + * }; + * + * // Support for custom embedder types via specialization of WrapperTraits. + * namespace v8 { + * template <> + * class WrapperTraits { + * public: + * static const void* GetTypeInfo() { + * // We use the already defined machinery for the custom type. + * return CustomEmbedderType::GetWrapperTypeInfo(); + * } + * }; + * } // namespace v8 + * + * // The constants kV8EmbedderWrapperTypeIndex and + * // kV8EmbedderWrapperObjectIndex describe the offsets for the type info + * // struct (the one returned by WrapperTraits::GetTypeInfo) and the + * // native object, when expressed as internal field indices within a + * // JSObject. The existance of this helper function assumes that all + * // embedder objects have their JSObject-side type info at the same + * // offset, but this is not a limitation of the API itself. For a detailed + * // use case, see the third example. + * static constexpr int kV8EmbedderWrapperTypeIndex = 0; + * static constexpr int kV8EmbedderWrapperObjectIndex = 1; + * + * // The following setup function can be templatized based on + * // the {embedder_object} argument. + * void SetupCustomEmbedderObject(v8::Isolate* isolate, + * v8::Local context, + * CustomEmbedderType* embedder_object) { + * isolate->set_embedder_wrapper_type_index( + * kV8EmbedderWrapperTypeIndex); + * isolate->set_embedder_wrapper_object_index( + * kV8EmbedderWrapperObjectIndex); + * + * v8::CFunction c_func = + * MakeV8CFunction(CustomEmbedderType::FastMethod); + * + * Local method_template = + * v8::FunctionTemplate::New( + * isolate, CustomEmbedderType::SlowMethod, v8::Local(), + * v8::Local(), 1, v8::ConstructorBehavior::kAllow, + * v8::SideEffectType::kHasSideEffect, &c_func); + * + * v8::Local object_template = + * v8::ObjectTemplate::New(isolate); + * object_template->SetInternalFieldCount( + * kV8EmbedderWrapperObjectIndex + 1); + * object_template->Set( + v8::String::NewFromUtf8Literal(isolate, "method"), method_template); + * + * // Instantiate the wrapper JS object. + * v8::Local object = + * object_template->NewInstance(context).ToLocalChecked(); + * object->SetAlignedPointerInInternalField( + * kV8EmbedderWrapperObjectIndex, + * reinterpret_cast(embedder_object)); + * + * // TODO: Expose {object} where it's necessary. + * } + * \endcode + * + * For instance if {object} is exposed via a global "obj" variable, + * one could write in JS: + * function hot_func() { + * obj.method(42); + * } + * and once {hot_func} gets optimized, CustomEmbedderType::FastMethod + * will be called instead of the slow version, with the following arguments: + * receiver := the {embedder_object} from above + * param := 42 + * + * Currently only void return types are supported. + * Currently supported argument types: + * - pointer to an embedder type + * - bool + * - int32_t + * - uint32_t + * To be supported types: + * - int64_t + * - uint64_t + * - float32_t + * - float64_t + * - arrays of C types + * - arrays of embedder types + */ + +#ifndef INCLUDE_V8_FAST_API_CALLS_H_ +#define INCLUDE_V8_FAST_API_CALLS_H_ + +#include +#include + +#include "v8config.h" // NOLINT(build/include) + +namespace v8 { + +class CTypeInfo { + public: + enum class Type : char { + kVoid, + kBool, + kInt32, + kUint32, + kInt64, + kUint64, + kFloat32, + kFloat64, + kUnwrappedApiObject, + }; + + enum ArgFlags : char { + None = 0, + IsArrayBit = 1 << 0, // This argument is first in an array of values. + }; + + static CTypeInfo FromWrapperType(const void* wrapper_type_info, + ArgFlags flags = ArgFlags::None) { + uintptr_t wrapper_type_info_ptr = + reinterpret_cast(wrapper_type_info); + // Check that the lower kIsWrapperTypeBit bits are 0's. + CHECK_EQ( + wrapper_type_info_ptr & ~(static_cast(~0) + << static_cast(kIsWrapperTypeBit)), + 0); + // TODO(mslekova): Refactor the manual bit manipulations to use + // PointerWithPayload instead. + return CTypeInfo(wrapper_type_info_ptr | flags | kIsWrapperTypeBit); + } + + static constexpr CTypeInfo FromCType(Type ctype, + ArgFlags flags = ArgFlags::None) { + // ctype cannot be Type::kUnwrappedApiObject. + return CTypeInfo( + ((static_cast(ctype) << kTypeOffset) & kTypeMask) | flags); + } + + const void* GetWrapperInfo() const; + + constexpr Type GetType() const { + if (payload_ & kIsWrapperTypeBit) { + return Type::kUnwrappedApiObject; + } + return static_cast((payload_ & kTypeMask) >> kTypeOffset); + } + + constexpr bool IsArray() const { return payload_ & ArgFlags::IsArrayBit; } + + private: + explicit constexpr CTypeInfo(uintptr_t payload) : payload_(payload) {} + + // That must be the last bit after ArgFlags. + static constexpr uintptr_t kIsWrapperTypeBit = 1 << 1; + static constexpr uintptr_t kWrapperTypeInfoMask = static_cast(~0) + << 2; + + static constexpr unsigned int kTypeOffset = kIsWrapperTypeBit; + static constexpr unsigned int kTypeSize = 8 - kTypeOffset; + static constexpr uintptr_t kTypeMask = + (~(static_cast(~0) << kTypeSize)) << kTypeOffset; + + const uintptr_t payload_; +}; + +class CFunctionInfo { + public: + virtual const CTypeInfo& ReturnInfo() const = 0; + virtual unsigned int ArgumentCount() const = 0; + virtual const CTypeInfo& ArgumentInfo(unsigned int index) const = 0; +}; + +template +class WrapperTraits { + public: + static const void* GetTypeInfo() { + static_assert(sizeof(T) != sizeof(T), + "WrapperTraits must be specialized for this type."); + return nullptr; + } +}; + +namespace internal { + +template +struct GetCType { + static_assert(sizeof(T) != sizeof(T), "Unsupported CType"); +}; + +#define SPECIALIZE_GET_C_TYPE_FOR(ctype, ctypeinfo) \ + template <> \ + struct GetCType { \ + static constexpr CTypeInfo Get() { \ + return CTypeInfo::FromCType(CTypeInfo::Type::ctypeinfo); \ + } \ + }; + +#define SUPPORTED_C_TYPES(V) \ + V(void, kVoid) \ + V(bool, kBool) \ + V(int32_t, kInt32) \ + V(uint32_t, kUint32) \ + V(int64_t, kInt64) \ + V(uint64_t, kUint64) \ + V(float, kFloat32) \ + V(double, kFloat64) + +SUPPORTED_C_TYPES(SPECIALIZE_GET_C_TYPE_FOR) + +template +struct EnableIfHasWrapperTypeInfo {}; + +template <> +struct EnableIfHasWrapperTypeInfo {}; + +template +struct EnableIfHasWrapperTypeInfo::GetTypeInfo(), + void())> { + typedef void type; +}; + +// T* where T is a primitive (array of primitives). +template +struct GetCTypePointerImpl { + static constexpr CTypeInfo Get() { + return CTypeInfo::FromCType(GetCType::Get().GetType(), + CTypeInfo::IsArrayBit); + } +}; + +// T* where T is an API object. +template +struct GetCTypePointerImpl::type> { + static constexpr CTypeInfo Get() { + return CTypeInfo::FromWrapperType(WrapperTraits::GetTypeInfo()); + } +}; + +// T** where T is a primitive. Not allowed. +template +struct GetCTypePointerPointerImpl { + static_assert(sizeof(T**) != sizeof(T**), "Unsupported type"); +}; + +// T** where T is an API object (array of API objects). +template +struct GetCTypePointerPointerImpl< + T, typename EnableIfHasWrapperTypeInfo::type> { + static constexpr CTypeInfo Get() { + return CTypeInfo::FromWrapperType(WrapperTraits::GetTypeInfo(), + CTypeInfo::IsArrayBit); + } +}; + +template +struct GetCType : public GetCTypePointerPointerImpl {}; + +template +struct GetCType : public GetCTypePointerImpl {}; + +template +class CFunctionInfoImpl : public CFunctionInfo { + public: + CFunctionInfoImpl() + : return_info_(i::GetCType::Get()), + arg_count_(sizeof...(Args)), + arg_info_{i::GetCType::Get()...} { + static_assert(i::GetCType::Get().GetType() == CTypeInfo::Type::kVoid, + "Only void return types are currently supported."); + } + + const CTypeInfo& ReturnInfo() const override { return return_info_; } + unsigned int ArgumentCount() const override { return arg_count_; } + const CTypeInfo& ArgumentInfo(unsigned int index) const override { + CHECK_LT(index, ArgumentCount()); + return arg_info_[index]; + } + + private: + CTypeInfo return_info_; + const unsigned int arg_count_; + CTypeInfo arg_info_[sizeof...(Args)]; +}; + +} // namespace internal + +class V8_EXPORT CFunction { + public: + const CTypeInfo& ReturnInfo() const { return type_info_->ReturnInfo(); } + + const CTypeInfo& ArgumentInfo(unsigned int index) const { + return type_info_->ArgumentInfo(index); + } + + unsigned int ArgumentCount() const { return type_info_->ArgumentCount(); } + + const void* GetAddress() const { return address_; } + const CFunctionInfo* GetTypeInfo() const { return type_info_; } + + template + static CFunction Make(F* func) { + return ArgUnwrap::Make(func); + } + + private: + const void* address_; + const CFunctionInfo* type_info_; + + CFunction(const void* address, const CFunctionInfo* type_info); + + template + static CFunctionInfo* GetCFunctionInfo() { + static internal::CFunctionInfoImpl instance; + return &instance; + } + + template + class ArgUnwrap { + static_assert(sizeof(F) != sizeof(F), + "CFunction must be created from a function pointer."); + }; + + template + class ArgUnwrap { + public: + static CFunction Make(R (*func)(Args...)) { + return CFunction(reinterpret_cast(func), + GetCFunctionInfo()); + } + }; +}; + +} // namespace v8 + +#endif // INCLUDE_V8_FAST_API_CALLS_H_ diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h index b9a48665338782..01274625c1f476 100644 --- a/deps/v8/include/v8-inspector.h +++ b/deps/v8/include/v8-inspector.h @@ -65,15 +65,15 @@ class V8_EXPORT StringView { class V8_EXPORT StringBuffer { public: virtual ~StringBuffer() = default; - virtual const StringView& string() = 0; + virtual StringView string() const = 0; // This method copies contents. - static std::unique_ptr create(const StringView&); + static std::unique_ptr create(StringView); }; class V8_EXPORT V8ContextInfo { public: V8ContextInfo(v8::Local context, int contextGroupId, - const StringView& humanReadableName) + StringView humanReadableName) : context(context), contextGroupId(contextGroupId), humanReadableName(humanReadableName), @@ -132,37 +132,36 @@ class V8_EXPORT V8InspectorSession { virtual void addInspectedObject(std::unique_ptr) = 0; // Dispatching protocol messages. - static bool canDispatchMethod(const StringView& method); - virtual void dispatchProtocolMessage(const StringView& message) = 0; + static bool canDispatchMethod(StringView method); + virtual void dispatchProtocolMessage(StringView message) = 0; virtual std::vector state() = 0; virtual std::vector> supportedDomains() = 0; // Debugger actions. - virtual void schedulePauseOnNextStatement(const StringView& breakReason, - const StringView& breakDetails) = 0; + virtual void schedulePauseOnNextStatement(StringView breakReason, + StringView breakDetails) = 0; virtual void cancelPauseOnNextStatement() = 0; - virtual void breakProgram(const StringView& breakReason, - const StringView& breakDetails) = 0; + virtual void breakProgram(StringView breakReason, + StringView breakDetails) = 0; virtual void setSkipAllPauses(bool) = 0; - virtual void resume() = 0; + virtual void resume(bool setTerminateOnResume = false) = 0; virtual void stepOver() = 0; virtual std::vector> - searchInTextByLines(const StringView& text, const StringView& query, - bool caseSensitive, bool isRegex) = 0; + searchInTextByLines(StringView text, StringView query, bool caseSensitive, + bool isRegex) = 0; // Remote objects. virtual std::unique_ptr wrapObject( - v8::Local, v8::Local, const StringView& groupName, + v8::Local, v8::Local, StringView groupName, bool generatePreview) = 0; virtual bool unwrapObject(std::unique_ptr* error, - const StringView& objectId, v8::Local*, + StringView objectId, v8::Local*, v8::Local*, std::unique_ptr* objectGroup) = 0; - virtual void releaseObjectGroup(const StringView&) = 0; - virtual void triggerPreciseCoverageDeltaUpdate( - const StringView& occassion) = 0; + virtual void releaseObjectGroup(StringView) = 0; + virtual void triggerPreciseCoverageDeltaUpdate(StringView occassion) = 0; }; class V8_EXPORT V8InspectorClient { @@ -240,7 +239,7 @@ struct V8_EXPORT V8StackTraceId { V8StackTraceId(uintptr_t id, const std::pair debugger_id); V8StackTraceId(uintptr_t id, const std::pair debugger_id, bool should_pause); - explicit V8StackTraceId(const StringView&); + explicit V8StackTraceId(StringView); V8StackTraceId& operator=(const V8StackTraceId&) = default; V8StackTraceId& operator=(V8StackTraceId&&) noexcept = default; ~V8StackTraceId() = default; @@ -265,26 +264,26 @@ class V8_EXPORT V8Inspector { virtual void idleFinished() = 0; // Async stack traces instrumentation. - virtual void asyncTaskScheduled(const StringView& taskName, void* task, + virtual void asyncTaskScheduled(StringView taskName, void* task, bool recurring) = 0; virtual void asyncTaskCanceled(void* task) = 0; virtual void asyncTaskStarted(void* task) = 0; virtual void asyncTaskFinished(void* task) = 0; virtual void allAsyncTasksCanceled() = 0; - virtual V8StackTraceId storeCurrentStackTrace( - const StringView& description) = 0; + virtual V8StackTraceId storeCurrentStackTrace(StringView description) = 0; virtual void externalAsyncTaskStarted(const V8StackTraceId& parent) = 0; virtual void externalAsyncTaskFinished(const V8StackTraceId& parent) = 0; // Exceptions instrumentation. - virtual unsigned exceptionThrown( - v8::Local, const StringView& message, - v8::Local exception, const StringView& detailedMessage, - const StringView& url, unsigned lineNumber, unsigned columnNumber, - std::unique_ptr, int scriptId) = 0; + virtual unsigned exceptionThrown(v8::Local, StringView message, + v8::Local exception, + StringView detailedMessage, StringView url, + unsigned lineNumber, unsigned columnNumber, + std::unique_ptr, + int scriptId) = 0; virtual void exceptionRevoked(v8::Local, unsigned exceptionId, - const StringView& message) = 0; + StringView message) = 0; // Connection. class V8_EXPORT Channel { @@ -295,8 +294,9 @@ class V8_EXPORT V8Inspector { virtual void sendNotification(std::unique_ptr message) = 0; virtual void flushProtocolNotifications() = 0; }; - virtual std::unique_ptr connect( - int contextGroupId, Channel*, const StringView& state) = 0; + virtual std::unique_ptr connect(int contextGroupId, + Channel*, + StringView state) = 0; // API methods. virtual std::unique_ptr createStackTrace( diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index e4d698e6ce7e4c..876408ebba98f9 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -160,10 +160,10 @@ class Internals { kNumIsolateDataSlots * kApiSystemPointerSize; static const int kExternalMemoryLimitOffset = kExternalMemoryOffset + kApiInt64Size; - static const int kExternalMemoryAtLastMarkCompactOffset = + static const int kExternalMemoryLowSinceMarkCompactOffset = kExternalMemoryLimitOffset + kApiInt64Size; static const int kIsolateFastCCallCallerFpOffset = - kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size; + kExternalMemoryLowSinceMarkCompactOffset + kApiInt64Size; static const int kIsolateFastCCallCallerPcOffset = kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; static const int kIsolateStackGuardOffset = diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index f21a0b8dd0fd69..64f184866537b5 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 1 -#define V8_BUILD_NUMBER 307 -#define V8_PATCH_LEVEL 31 +#define V8_MINOR_VERSION 3 +#define V8_BUILD_NUMBER 110 +#define V8_PATCH_LEVEL 9 // 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 54bc4f08359125..9926b308b15cda 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -120,6 +120,8 @@ class EscapableHandleScope; template class ReturnValue; namespace internal { +enum class ArgumentsType; +template class Arguments; class DeferredHandles; class Heap; @@ -149,11 +151,6 @@ class ConsoleCallArguments; // --- Handles --- -#define TYPE_CHECK(T, S) \ - while (false) { \ - *(static_cast(0)) = static_cast(0); \ - } - /** * An object reference managed by the v8 garbage collector. * @@ -197,7 +194,7 @@ class Local { * handles. For example, converting from a Local to a * Local. */ - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** @@ -363,7 +360,7 @@ class MaybeLocal { template V8_INLINE MaybeLocal(Local that) : val_(reinterpret_cast(*that)) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } V8_INLINE bool IsEmpty() const { return val_ == nullptr; } @@ -532,11 +529,16 @@ template class PersistentBase { } /** - * Install a finalization callback on this object. - * NOTE: There is no guarantee as to *when* or even *if* the callback is - * invoked. The invocation is performed solely on a best effort basis. - * As always, GC-based finalization should *not* be relied upon for any - * critical form of resource management! + * Install a finalization callback on this object. + * NOTE: There is no guarantee as to *when* or even *if* the callback is + * invoked. The invocation is performed solely on a best effort basis. + * As always, GC-based finalization should *not* be relied upon for any + * critical form of resource management! + * + * The callback is supposed to reset the handle. No further V8 API may be + * called in this callback. In case additional work involving V8 needs to be + * done, a second callback can be scheduled using + * WeakCallbackInfo::SetSecondPassCallback. */ template V8_INLINE void SetWeak(P* parameter, @@ -618,11 +620,8 @@ class NonCopyablePersistentTraits { template V8_INLINE static void Copy(const Persistent& source, NonCopyablePersistent* dest) { - Uncompilable(); - } - // TODO(dcarney): come up with a good compile error here. - template V8_INLINE static void Uncompilable() { - TYPE_CHECK(O, Primitive); + static_assert(sizeof(S) < 0, + "NonCopyablePersistentTraits::Copy is not instantiable"); } }; @@ -665,7 +664,7 @@ template class Persistent : public PersistentBase { template V8_INLINE Persistent(Isolate* isolate, Local that) : PersistentBase(PersistentBase::New(isolate, *that)) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** * Construct a Persistent from a Persistent. @@ -675,7 +674,7 @@ template class Persistent : public PersistentBase { template V8_INLINE Persistent(Isolate* isolate, const Persistent& that) : PersistentBase(PersistentBase::New(isolate, *that)) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** * The copy constructors and assignment operator create a Persistent @@ -760,7 +759,7 @@ class Global : public PersistentBase { template V8_INLINE Global(Isolate* isolate, Local that) : PersistentBase(PersistentBase::New(isolate, *that)) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** @@ -771,7 +770,7 @@ class Global : public PersistentBase { template V8_INLINE Global(Isolate* isolate, const PersistentBase& that) : PersistentBase(PersistentBase::New(isolate, that.val_)) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** @@ -951,7 +950,7 @@ class TracedGlobal : public TracedReferenceBase { TracedGlobal(Isolate* isolate, Local that) : TracedReferenceBase() { this->val_ = this->New(isolate, that.val_, &this->val_, TracedReferenceBase::kWithDestructor); - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** @@ -1074,7 +1073,7 @@ class TracedReference : public TracedReferenceBase { TracedReference(Isolate* isolate, Local that) : TracedReferenceBase() { this->val_ = this->New(isolate, that.val_, &this->val_, TracedReferenceBase::kWithoutDestructor); - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } /** @@ -1128,17 +1127,11 @@ class TracedReference : public TracedReferenceBase { /** * Copy assignment operator initializing TracedGlobal from an existing one. - * - * Note: Prohibited when |other| has a finalization callback set through - * |SetFinalizationCallback|. */ V8_INLINE TracedReference& operator=(const TracedReference& rhs); /** * Copy assignment operator initializing TracedGlobal from an existing one. - * - * Note: Prohibited when |other| has a finalization callback set through - * |SetFinalizationCallback|. */ template V8_INLINE TracedReference& operator=(const TracedReference& rhs); @@ -1155,20 +1148,6 @@ class TracedReference : public TracedReferenceBase { return reinterpret_cast&>( const_cast&>(*this)); } - - /** - * Adds a finalization callback to the handle. The type of this callback is - * similar to WeakCallbackType::kInternalFields, i.e., it will pass the - * parameter and the first two internal fields of the object. - * - * The callback is then supposed to reset the handle in the callback. No - * further V8 API may be called in this callback. In case additional work - * involving V8 needs to be done, a second callback can be scheduled using - * WeakCallbackInfo::SetSecondPassCallback. - */ - V8_DEPRECATED("Use TracedGlobal<> if callbacks are required.") - V8_INLINE void SetFinalizationCallback( - void* parameter, WeakCallbackInfo::Callback callback); }; /** @@ -1773,11 +1752,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( "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); @@ -2201,6 +2178,7 @@ enum StateTag { COMPILER, OTHER, EXTERNAL, + ATOMICS_WAIT, IDLE }; @@ -2466,14 +2444,6 @@ class V8_EXPORT ValueDeserializer { */ void SetSupportsLegacyWireFormat(bool supports_legacy_wire_format); - /** - * Expect inline wasm in the data stream (rather than in-memory transfer) - */ - V8_DEPRECATED( - "Wasm module serialization is only supported via explicit methods, e.g. " - "CompiledWasmModule::Serialize()") - void SetExpectInlineWasm(bool allow_inline_wasm) {} - /** * Reads the underlying wire format version. Likely mostly to be useful to * legacy code reading old wire format versions. Must be called after @@ -2813,9 +2783,6 @@ class V8_EXPORT Value : public Data { */ bool IsWasmModuleObject() const; - V8_DEPRECATED("Use IsWasmModuleObject") - bool IsWebAssemblyCompiledModule() const; - /** * Returns true if the value is a Module Namespace Object. */ @@ -3206,6 +3173,23 @@ class V8_EXPORT String : public Name { V8_INLINE static String* Cast(v8::Value* obj); + /** + * Allocates a new string from a UTF-8 literal. This is equivalent to calling + * String::NewFromUtf(isolate, "...").ToLocalChecked(), but without the check + * overhead. + * + * When called on a string literal containing '\0', the inferred length is the + * length of the input array minus 1 (for the final '\0') and not the value + * returned by strlen. + **/ + template + static V8_WARN_UNUSED_RESULT Local NewFromUtf8Literal( + Isolate* isolate, const char (&literal)[N], + NewStringType type = NewStringType::kNormal) { + static_assert(N <= kMaxLength, "String is too long"); + return NewFromUtf8Literal(isolate, literal, type, N - 1); + } + /** Allocates a new string from UTF-8 data. Only returns an empty value when * length > kMaxLength. **/ static V8_WARN_UNUSED_RESULT MaybeLocal NewFromUtf8( @@ -3340,9 +3324,20 @@ class V8_EXPORT String : public Name { ExternalStringResourceBase* GetExternalStringResourceBaseSlow( String::Encoding* encoding_out) const; + static Local NewFromUtf8Literal(Isolate* isolate, + const char* literal, + NewStringType type, int length); + static void CheckCast(v8::Value* obj); }; +// Zero-length string specialization (templated string size includes +// terminator). +template <> +inline V8_WARN_UNUSED_RESULT Local String::NewFromUtf8Literal( + Isolate* isolate, const char (&literal)[1], NewStringType type) { + return String::Empty(isolate); +} /** * A JavaScript symbol (ECMA-262 edition 6) @@ -4049,6 +4044,13 @@ class V8_EXPORT Object : public Value { */ bool IsApiWrapper(); + /** + * True if this object was created from an object template which was marked + * as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more + * information. + */ + bool IsUndetectable(); + /** * Call an Object as a function if a callback is set by the * ObjectTemplate::SetCallAsFunctionHandler method. @@ -4205,7 +4207,7 @@ class ReturnValue { public: template V8_INLINE ReturnValue(const ReturnValue& that) : value_(that.value_) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); } // Local setters template @@ -4785,27 +4787,9 @@ class V8_EXPORT WasmModuleObject : public Object { */ CompiledWasmModule GetCompiledModule(); - /** - * If possible, deserialize the module, otherwise compile it from the provided - * uncompiled bytes. - */ - V8_DEPRECATED( - "Use WasmStreaming for deserialization from cache or the " - "CompiledWasmModule to transfer between isolates") - static MaybeLocal DeserializeOrCompile( - Isolate* isolate, MemorySpan serialized_module, - MemorySpan wire_bytes); - V8_INLINE static WasmModuleObject* Cast(Value* obj); private: - static MaybeLocal Deserialize( - Isolate* isolate, MemorySpan serialized_module, - MemorySpan wire_bytes); - static MaybeLocal Compile(Isolate* isolate, - const uint8_t* start, - size_t length); - static void CheckCast(Value* obj); }; @@ -4978,6 +4962,34 @@ class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase { */ bool IsShared() const; + /** + * Wrapper around ArrayBuffer::Allocator::Reallocate that preserves IsShared. + * Assumes that the backing_store was allocated by the ArrayBuffer allocator + * of the given isolate. + */ + static std::unique_ptr Reallocate( + v8::Isolate* isolate, std::unique_ptr backing_store, + size_t byte_length); + + /** + * This callback is used only if the memory block for a BackingStore cannot be + * allocated with an ArrayBuffer::Allocator. In such cases the destructor of + * the BackingStore invokes the callback to free the memory block. + */ + using DeleterCallback = void (*)(void* data, size_t length, + void* deleter_data); + + /** + * If the memory block of a BackingStore is static or is managed manually, + * then this empty deleter along with nullptr deleter_data can be passed to + * ArrayBuffer::NewBackingStore to indicate that. + * + * The manually managed case should be used with caution and only when it + * is guaranteed that the memory block freeing happens after detaching its + * ArrayBuffer. + */ + static void EmptyDeleter(void* data, size_t length, void* deleter_data); + private: /** * See [Shared]ArrayBuffer::GetBackingStore and @@ -4986,14 +4998,13 @@ class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase { BackingStore(); }; -/** - * This callback is used only if the memory block for this backing store cannot - * be allocated with an ArrayBuffer::Allocator. In such cases the destructor - * of this backing store object invokes the callback to free the memory block. - */ +#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS) +// Use v8::BackingStore::DeleterCallback instead. using BackingStoreDeleterCallback = void (*)(void* data, size_t length, void* deleter_data); +#endif + /** * An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5). */ @@ -5019,13 +5030,13 @@ class V8_EXPORT ArrayBuffer : public Object { virtual ~Allocator() = default; /** - * Allocate |length| bytes. Return NULL if allocation is not successful. + * Allocate |length| bytes. Return nullptr if allocation is not successful. * Memory should be initialized to zeroes. */ virtual void* Allocate(size_t length) = 0; /** - * Allocate |length| bytes. Return NULL if allocation is not successful. + * Allocate |length| bytes. Return nullptr if allocation is not successful. * Memory does not have to be initialized. */ virtual void* AllocateUninitialized(size_t length) = 0; @@ -5036,6 +5047,20 @@ class V8_EXPORT ArrayBuffer : public Object { */ virtual void Free(void* data, size_t length) = 0; + /** + * Reallocate the memory block of size |old_length| to a memory block of + * size |new_length| by expanding, contracting, or copying the existing + * memory block. If |new_length| > |old_length|, then the new part of + * the memory must be initialized to zeros. Return nullptr if reallocation + * is not successful. + * + * The caller guarantees that the memory block was previously allocated + * using Allocate or AllocateUninitialized. + * + * The default implementation allocates a new block and copies data. + */ + virtual void* Reallocate(void* data, size_t old_length, size_t new_length); + /** * ArrayBuffer allocation mode. kNormal is a malloc/free style allocation, * while kReservation is for larger allocations with the ability to set @@ -5167,7 +5192,7 @@ class V8_EXPORT ArrayBuffer : public Object { * to the buffer must not be passed again to any V8 API function. */ static std::unique_ptr NewBackingStore( - void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, void* deleter_data); /** @@ -5649,7 +5674,7 @@ class V8_EXPORT SharedArrayBuffer : public Object { * to the buffer must not be passed again to any V8 functions. */ static std::unique_ptr NewBackingStore( - void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, void* deleter_data); /** @@ -5909,14 +5934,15 @@ class V8_EXPORT RegExp : public Object { }; /** - * An instance of the built-in FinalizationGroup constructor. + * An instance of the built-in FinalizationRegistry constructor. * - * This API is experimental and may change significantly. + * The C++ name is FinalizationGroup for backwards compatibility. This API is + * experimental and deprecated. */ class V8_EXPORT FinalizationGroup : public Object { public: /** - * Runs the cleanup callback of the given FinalizationGroup. + * Runs the cleanup callback of the given FinalizationRegistry. * * V8 will inform the embedder that there are finalizer callbacks be * called through HostCleanupFinalizationGroupCallback. @@ -5931,6 +5957,9 @@ class V8_EXPORT FinalizationGroup : public Object { * occurred. Otherwise the result is |true| if the cleanup callback * was called successfully. The result is never |false|. */ + V8_DEPRECATED( + "FinalizationGroup cleanup is automatic if " + "HostCleanupFinalizationGroupCallback is not set") static V8_WARN_UNUSED_RESULT Maybe Cleanup( Local finalization_group); }; @@ -5948,13 +5977,14 @@ class V8_EXPORT External : public Value { static void CheckCast(v8::Value* obj); }; -#define V8_INTRINSICS_LIST(F) \ - F(ArrayProto_entries, array_entries_iterator) \ - F(ArrayProto_forEach, array_for_each_iterator) \ - F(ArrayProto_keys, array_keys_iterator) \ - F(ArrayProto_values, array_values_iterator) \ - F(ErrorPrototype, initial_error_prototype) \ - F(IteratorPrototype, initial_iterator_prototype) +#define V8_INTRINSICS_LIST(F) \ + F(ArrayProto_entries, array_entries_iterator) \ + F(ArrayProto_forEach, array_for_each_iterator) \ + F(ArrayProto_keys, array_keys_iterator) \ + F(ArrayProto_values, array_values_iterator) \ + F(ErrorPrototype, initial_error_prototype) \ + F(IteratorPrototype, initial_iterator_prototype) \ + F(ObjProto_valueOf, object_value_of_function) enum Intrinsic { #define V8_DECL_INTRINSIC(name, iname) k##name, @@ -6300,6 +6330,7 @@ typedef bool (*AccessCheckCallback)(Local accessing_context, Local accessed_object, Local data); +class CFunction; /** * A FunctionTemplate is used to create functions at runtime. There * can only be one function created from a FunctionTemplate in a @@ -6335,11 +6366,12 @@ typedef bool (*AccessCheckCallback)(Local accessing_context, * proto_t->Set(isolate, "proto_const", v8::Number::New(isolate, 2)); * * v8::Local instance_t = t->InstanceTemplate(); - * instance_t->SetAccessor(String::NewFromUtf8(isolate, "instance_accessor"), - * InstanceAccessorCallback); + * instance_t->SetAccessor( + String::NewFromUtf8Literal(isolate, "instance_accessor"), + * InstanceAccessorCallback); * instance_t->SetHandler( * NamedPropertyHandlerConfiguration(PropertyHandlerCallback)); - * instance_t->Set(String::NewFromUtf8(isolate, "instance_property"), + * instance_t->Set(String::NewFromUtf8Literal(isolate, "instance_property"), * Number::New(isolate, 3)); * * v8::Local function = t->GetFunction(); @@ -6399,6 +6431,12 @@ typedef bool (*AccessCheckCallback)(Local accessing_context, * child_instance.instance_accessor calls 'InstanceAccessorCallback' * child_instance.instance_property == 3; * \endcode + * + * The additional 'c_function' parameter refers to a fast API call, which + * must not trigger GC or JavaScript execution, or call into V8 in other + * ways. For more information how to define them, see + * include/v8-fast-api-calls.h. Please note that this feature is still + * experimental. */ class V8_EXPORT FunctionTemplate : public Template { public: @@ -6408,7 +6446,8 @@ class V8_EXPORT FunctionTemplate : public Template { Local data = Local(), Local signature = Local(), int length = 0, ConstructorBehavior behavior = ConstructorBehavior::kAllow, - SideEffectType side_effect_type = SideEffectType::kHasSideEffect); + SideEffectType side_effect_type = SideEffectType::kHasSideEffect, + const CFunction* c_function = nullptr); /** Get a template included in the snapshot by index. */ V8_DEPRECATED("Use v8::Isolate::GetDataFromSnapshotOnce instead") @@ -6440,11 +6479,13 @@ class V8_EXPORT FunctionTemplate : public Template { /** * Set the call-handler callback for a FunctionTemplate. This * callback is called whenever the function created from this - * FunctionTemplate is called. + * FunctionTemplate is called. The 'c_function' represents a fast + * API call, see the comment above the class declaration. */ void SetCallHandler( FunctionCallback callback, Local data = Local(), - SideEffectType side_effect_type = SideEffectType::kHasSideEffect); + SideEffectType side_effect_type = SideEffectType::kHasSideEffect, + const CFunction* c_function = nullptr); /** Set the predefined length property for the FunctionTemplate. */ void SetLength(int length); @@ -7293,14 +7334,15 @@ class PromiseRejectMessage { typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); // --- Microtasks Callbacks --- +V8_DEPRECATE_SOON("Use *WithData version.") typedef void (*MicrotasksCompletedCallback)(Isolate*); typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); typedef void (*MicrotaskCallback)(void* data); - /** * Policy for running microtasks: - * - explicit: microtasks are invoked with Isolate::RunMicrotasks() method; + * - explicit: microtasks are invoked with the + * Isolate::PerformMicrotaskCheckpoint() method; * - scoped: microtasks invocation is controlled by MicrotasksScope objects; * - auto: microtasks are invoked when the script call depth decrements * to zero. @@ -7391,7 +7433,7 @@ class V8_EXPORT MicrotaskQueue { }; /** - * This scope is used to control microtasks when kScopeMicrotasksInvocation + * This scope is used to control microtasks when MicrotasksPolicy::kScoped * is used on Isolate. In this mode every non-primitive call to V8 should be * done inside some MicrotasksScope. * Microtasks are executed when topmost MicrotasksScope marked as kRunMicrotasks @@ -7480,7 +7522,7 @@ typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo&); // --- Callback for checking if WebAssembly threads are enabled --- typedef bool (*WasmThreadsEnabledCallback)(Local context); -// --- Callback for loading source map file for WASM profiling support +// --- Callback for loading source map file for Wasm profiling support typedef Local (*WasmLoadSourceMapCallback)(Isolate* isolate, const char* name); @@ -7576,6 +7618,8 @@ class V8_EXPORT HeapStatistics { size_t total_heap_size_executable() { return total_heap_size_executable_; } size_t total_physical_size() { return total_physical_size_; } size_t total_available_size() { return total_available_size_; } + size_t total_global_handles_size() { return total_global_handles_size_; } + size_t used_global_handles_size() { return used_global_handles_size_; } size_t used_heap_size() { return used_heap_size_; } size_t heap_size_limit() { return heap_size_limit_; } size_t malloced_memory() { return malloced_memory_; } @@ -7603,6 +7647,8 @@ class V8_EXPORT HeapStatistics { bool does_zap_garbage_; size_t number_of_native_contexts_; size_t number_of_detached_contexts_; + size_t total_global_handles_size_; + size_t used_global_handles_size_; friend class V8; friend class Isolate; @@ -8407,6 +8453,13 @@ class V8_EXPORT Isolate { kRegExpReplaceCalledOnSlowRegExp = 80, kDisplayNames = 81, kSharedArrayBufferConstructed = 82, + kArrayPrototypeHasElements = 83, + kObjectPrototypeHasElements = 84, + kNumberFormatStyleUnit = 85, + kDateTimeFormatRange = 86, + kDateTimeFormatDateTimeStyle = 87, + kBreakIteratorTypeWord = 88, + kBreakIteratorTypeLine = 89, // If you add new values here, you'll also need to update Chromium's: // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to @@ -8472,10 +8525,13 @@ class V8_EXPORT Isolate { * objects are originally built when a WeakRef is created or * successfully dereferenced. * - * The embedder is expected to call this when a synchronous sequence - * of ECMAScript execution completes. It's the embedders - * responsiblity to make this call at a time which does not - * interrupt synchronous ECMAScript code execution. + * This is invoked automatically after microtasks are run. See + * MicrotasksPolicy for when microtasks are run. + * + * This needs to be manually invoked only if the embedder is manually running + * microtasks via a custom MicrotaskQueue class's PerformCheckpoint. In that + * case, it is the embedder's responsibility to make this call at a time which + * does not interrupt synchronous ECMAScript code execution. */ void ClearKeptObjects(); @@ -8493,10 +8549,13 @@ class V8_EXPORT Isolate { AbortOnUncaughtExceptionCallback callback); /** - * This specifies the callback to be called when finalization groups + * This specifies the callback to be called when FinalizationRegistries * are ready to be cleaned up and require FinalizationGroup::Cleanup() * to be called in a future task. */ + V8_DEPRECATED( + "FinalizationRegistry cleanup is automatic if " + "HostCleanupFinalizationGroupCallback is not set") void SetHostCleanupFinalizationGroupCallback( HostCleanupFinalizationGroupCallback callback); @@ -9000,10 +9059,18 @@ class V8_EXPORT Isolate { void SetPromiseRejectCallback(PromiseRejectCallback callback); /** - * Runs the default MicrotaskQueue until it gets empty. - * Any exceptions thrown by microtask callbacks are swallowed. + * An alias for PerformMicrotaskCheckpoint. + */ + V8_DEPRECATE_SOON("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 + * the MicrotasksPolicy is not kScoped. Any exceptions thrown by microtask + * callbacks are swallowed. */ - void RunMicrotasks(); + void PerformMicrotaskCheckpoint(); /** * Enqueues the callback to the default MicrotaskQueue @@ -9101,10 +9168,10 @@ class V8_EXPORT Isolate { void LowMemoryNotification(); /** - * Optional notification that a context has been disposed. V8 uses - * these notifications to guide the GC heuristic. Returns the number - * of context disposals - including this one - since the last time - * V8 had a chance to clean up. + * Optional notification that a context has been disposed. V8 uses these + * notifications to guide the GC heuristic and cancel FinalizationRegistry + * cleanup tasks. Returns the number of context disposals - including this one + * - since the last time V8 had a chance to clean up. * * The optional parameter |dependant_context| specifies whether the disposed * context was depending on state from other contexts or not. @@ -9218,7 +9285,7 @@ class V8_EXPORT Isolate { * Returns the UnwindState necessary for use with the Unwinder API. */ // TODO(petermarshall): Remove this API. - V8_DEPRECATE_SOON("Use entry_stubs + code_pages version.") + V8_DEPRECATED("Use entry_stubs + code_pages version.") UnwindState GetUnwindState(); /** @@ -10346,6 +10413,18 @@ class V8_EXPORT Context { Local context); void SetAbortScriptExecution(AbortScriptExecutionCallback callback); + /** + * Returns the value that was set or restored by + * SetContinuationPreservedEmbedderData(), if any. + */ + Local GetContinuationPreservedEmbedderData() const; + + /** + * Sets a value that will be stored on continuations and reset while the + * continuation runs. + */ + void SetContinuationPreservedEmbedderData(Local context); + /** * Stack-allocated class which sets the execution context for all * operations executed within a local scope. @@ -10563,7 +10642,7 @@ class V8_EXPORT Unwinder { * \return True on success. */ // TODO(petermarshall): Remove this API - V8_DEPRECATE_SOON("Use entry_stubs + code_pages version.") + V8_DEPRECATED("Use entry_stubs + code_pages version.") static bool TryUnwindV8Frames(const UnwindState& unwind_state, RegisterState* register_state, const void* stack_base); @@ -10591,7 +10670,7 @@ class V8_EXPORT Unwinder { * (but not necessarily) be successful. */ // TODO(petermarshall): Remove this API - V8_DEPRECATE_SOON("Use code_pages version.") + V8_DEPRECATED("Use code_pages version.") static bool PCIsInV8(const UnwindState& unwind_state, void* pc); /** @@ -10632,7 +10711,7 @@ Local Local::New(Isolate* isolate, T* that) { template template void Eternal::Set(Isolate* isolate, Local handle) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); val_ = reinterpret_cast( V8::Eternalize(isolate, reinterpret_cast(*handle))); } @@ -10676,7 +10755,7 @@ T* PersistentBase::New(Isolate* isolate, T* that) { template template void Persistent::Copy(const Persistent& that) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); this->Reset(); if (that.IsEmpty()) return; internal::Address* p = reinterpret_cast(that.val_); @@ -10704,7 +10783,7 @@ void PersistentBase::Reset() { template template void PersistentBase::Reset(Isolate* isolate, const Local& other) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); Reset(); if (other.IsEmpty()) return; this->val_ = New(isolate, other.val_); @@ -10715,7 +10794,7 @@ template template void PersistentBase::Reset(Isolate* isolate, const PersistentBase& other) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); Reset(); if (other.IsEmpty()) return; this->val_ = New(isolate, other.val_); @@ -10781,7 +10860,7 @@ Global::Global(Global&& other) : PersistentBase(other.val_) { template template Global& Global::operator=(Global&& rhs) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); if (this != &rhs) { this->Reset(); if (rhs.val_ != nullptr) { @@ -10816,7 +10895,7 @@ void TracedReferenceBase::Reset() { template template void TracedGlobal::Reset(Isolate* isolate, const Local& other) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); Reset(); if (other.IsEmpty()) return; this->val_ = this->New(isolate, other.val_, &this->val_, @@ -10826,7 +10905,7 @@ void TracedGlobal::Reset(Isolate* isolate, const Local& other) { template template TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); *this = std::move(rhs.template As()); return *this; } @@ -10834,7 +10913,7 @@ TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) { template template TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); *this = rhs.template As(); return *this; } @@ -10865,7 +10944,7 @@ TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) { template template void TracedReference::Reset(Isolate* isolate, const Local& other) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); Reset(); if (other.IsEmpty()) return; this->val_ = this->New(isolate, other.val_, &this->val_, @@ -10875,7 +10954,7 @@ void TracedReference::Reset(Isolate* isolate, const Local& other) { template template TracedReference& TracedReference::operator=(TracedReference&& rhs) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); *this = std::move(rhs.template As()); return *this; } @@ -10884,7 +10963,7 @@ template template TracedReference& TracedReference::operator=( const TracedReference& rhs) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); *this = rhs.template As(); return *this; } @@ -10937,20 +11016,13 @@ void TracedGlobal::SetFinalizationCallback( reinterpret_cast(this->val_), parameter, callback); } -template -void TracedReference::SetFinalizationCallback( - void* parameter, typename WeakCallbackInfo::Callback callback) { - V8::SetFinalizationCallbackTraced( - reinterpret_cast(this->val_), parameter, callback); -} - template ReturnValue::ReturnValue(internal::Address* slot) : value_(slot) {} template template void ReturnValue::Set(const Global& handle) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { @@ -10961,7 +11033,7 @@ void ReturnValue::Set(const Global& handle) { template template void ReturnValue::Set(const TracedReferenceBase& handle) { - TYPE_CHECK(T, S); + static_assert(std::is_base_of::value, "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { @@ -10972,7 +11044,8 @@ void ReturnValue::Set(const TracedReferenceBase& handle) { template template void ReturnValue::Set(const Local handle) { - TYPE_CHECK(T, S); + static_assert(std::is_void::value || std::is_base_of::value, + "type check"); if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { @@ -10982,13 +11055,13 @@ void ReturnValue::Set(const Local handle) { template void ReturnValue::Set(double i) { - TYPE_CHECK(T, Number); + static_assert(std::is_base_of::value, "type check"); Set(Number::New(GetIsolate(), i)); } template void ReturnValue::Set(int32_t i) { - TYPE_CHECK(T, Integer); + static_assert(std::is_base_of::value, "type check"); typedef internal::Internals I; if (V8_LIKELY(I::IsValidSmi(i))) { *value_ = I::IntToSmi(i); @@ -10999,7 +11072,7 @@ void ReturnValue::Set(int32_t i) { template void ReturnValue::Set(uint32_t i) { - TYPE_CHECK(T, Integer); + static_assert(std::is_base_of::value, "type check"); // Can't simply use INT32_MAX here for whatever reason. bool fits_into_int32_t = (i & (1U << 31)) == 0; if (V8_LIKELY(fits_into_int32_t)) { @@ -11011,7 +11084,7 @@ void ReturnValue::Set(uint32_t i) { template void ReturnValue::Set(bool value) { - TYPE_CHECK(T, Boolean); + static_assert(std::is_base_of::value, "type check"); typedef internal::Internals I; int root_index; if (value) { @@ -11024,21 +11097,21 @@ void ReturnValue::Set(bool value) { template void ReturnValue::SetNull() { - TYPE_CHECK(T, Primitive); + static_assert(std::is_base_of::value, "type check"); typedef internal::Internals I; *value_ = *I::GetRoot(GetIsolate(), I::kNullValueRootIndex); } template void ReturnValue::SetUndefined() { - TYPE_CHECK(T, Primitive); + static_assert(std::is_base_of::value, "type check"); typedef internal::Internals I; *value_ = *I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); } template void ReturnValue::SetEmptyString() { - TYPE_CHECK(T, String); + static_assert(std::is_base_of::value, "type check"); typedef internal::Internals I; *value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); } @@ -11060,8 +11133,7 @@ Local ReturnValue::Get() const { template template void ReturnValue::Set(S* whatever) { - // Uncompilable to prevent inadvertent misuse. - TYPE_CHECK(S*, Primitive); + static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse"); } template @@ -11078,14 +11150,24 @@ FunctionCallbackInfo::FunctionCallbackInfo(internal::Address* implicit_args, template Local FunctionCallbackInfo::operator[](int i) const { + // values_ points to the first argument (not the receiver). if (i < 0 || length_ <= i) return Local(*Undefined(GetIsolate())); +#ifdef V8_REVERSE_JSARGS + return Local(reinterpret_cast(values_ + i)); +#else return Local(reinterpret_cast(values_ - i)); +#endif } template Local FunctionCallbackInfo::This() const { + // values_ points to the first argument (not the receiver). +#ifdef V8_REVERSE_JSARGS + return Local(reinterpret_cast(values_ - 1)); +#else return Local(reinterpret_cast(values_ + 1)); +#endif } @@ -11854,9 +11936,9 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( reinterpret_cast(this) + I::kExternalMemoryOffset); int64_t* external_memory_limit = reinterpret_cast( reinterpret_cast(this) + I::kExternalMemoryLimitOffset); - int64_t* external_memory_at_last_mc = + int64_t* external_memory_low_since_mc = reinterpret_cast(reinterpret_cast(this) + - I::kExternalMemoryAtLastMarkCompactOffset); + I::kExternalMemoryLowSinceMarkCompactOffset); // Embedders are weird: we see both over- and underflows here. Perform the // addition with unsigned types to avoid undefined behavior. @@ -11865,23 +11947,22 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( static_cast(*external_memory)); *external_memory = amount; - int64_t allocation_diff_since_last_mc = - static_cast(static_cast(*external_memory) - - static_cast(*external_memory_at_last_mc)); + if (amount < *external_memory_low_since_mc) { + *external_memory_low_since_mc = amount; + *external_memory_limit = amount + I::kExternalAllocationSoftLimit; + } + + if (change_in_bytes <= 0) return *external_memory; + + int64_t allocation_diff_since_last_mc = static_cast( + static_cast(*external_memory) - + static_cast(*external_memory_low_since_mc)); // Only check memory pressure and potentially trigger GC if the amount of // external memory increased. if (allocation_diff_since_last_mc > kMemoryReducerActivationLimit) { CheckMemoryPressure(); } - - if (change_in_bytes < 0) { - const int64_t lower_limit = - static_cast(static_cast(*external_memory_limit) + - static_cast(change_in_bytes)); - if (lower_limit > I::kExternalAllocationSoftLimit) { - *external_memory_limit = lower_limit; - } - } else if (change_in_bytes > 0 && amount > *external_memory_limit) { + if (amount > *external_memory_limit) { ReportExternalAllocationLimitReached(); } return *external_memory; @@ -11963,8 +12044,4 @@ size_t SnapshotCreator::AddData(Local object) { } // namespace v8 - -#undef TYPE_CHECK - - #endif // INCLUDE_V8_H_ diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl index b26f1a1f08a2dc..6c3379b5cbc34e 100644 --- a/deps/v8/infra/testing/builders.pyl +++ b/deps/v8/infra/testing/builders.pyl @@ -288,7 +288,8 @@ {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 3}, {'name': 'v8testing', 'variant': 'extra', 'shards': 3}, - {'name': 'v8testing', 'variant': 'minor_mc', 'shards': 1}, + {'name': 'v8testing', 'variant': 'minor_mc'}, + {'name': 'v8testing', 'variant': 'no_lfa'}, {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'}, ], }, @@ -346,6 +347,7 @@ {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'assert_types'}, {'name': 'v8testing', 'variant': 'extra'}, + {'name': 'v8testing', 'variant': 'no_lfa'}, {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'}, ], }, @@ -381,6 +383,7 @@ {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'variant': 'minor_mc'}, + {'name': 'v8testing', 'variant': 'no_lfa'}, {'name': 'v8testing', 'variant': 'slow_path'}, {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'}, ], @@ -849,7 +852,8 @@ {'name': 'v8testing'}, {'name': 'v8testing', 'variant': 'assert_types'}, {'name': 'v8testing', 'variant': 'extra'}, - {'name': 'v8testing', 'variant': 'minor_mc', 'shards': 1}, + {'name': 'v8testing', 'variant': 'minor_mc'}, + {'name': 'v8testing', 'variant': 'no_lfa'}, {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'}, # Noavx. { @@ -906,8 +910,9 @@ {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, - {'name': 'v8testing', 'variant': 'minor_mc', 'shards': 1}, - {'name': 'v8testing', 'variant': 'slow_path', 'shards': 1}, + {'name': 'v8testing', 'variant': 'minor_mc'}, + {'name': 'v8testing', 'variant': 'no_lfa'}, + {'name': 'v8testing', 'variant': 'slow_path'}, {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'}, # Noavx. { @@ -1417,7 +1422,7 @@ {'name': 'mozilla'}, {'name': 'test262', 'variant': 'default'}, {'name': 'v8testing', 'shards': 3}, - {'name': 'v8testing', 'variant': 'extra'}, + {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'variant': 'trusted'}, ], }, diff --git a/deps/v8/samples/hello-world.cc b/deps/v8/samples/hello-world.cc index d75dcb3c3cc4ef..6e506475e45182 100644 --- a/deps/v8/samples/hello-world.cc +++ b/deps/v8/samples/hello-world.cc @@ -37,9 +37,7 @@ int main(int argc, char* argv[]) { { // Create a string containing the JavaScript source code. v8::Local source = - v8::String::NewFromUtf8(isolate, "'Hello' + ', World!'", - v8::NewStringType::kNormal) - .ToLocalChecked(); + v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'"); // Compile the source code. v8::Local script = @@ -63,7 +61,7 @@ int main(int argc, char* argv[]) { // get_local 1 // i32.add) // - const char* csource = R"( + const char csource[] = R"( let bytes = new Uint8Array([ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, @@ -77,8 +75,7 @@ int main(int argc, char* argv[]) { // Create a string containing the JavaScript source code. v8::Local source = - v8::String::NewFromUtf8(isolate, csource, v8::NewStringType::kNormal) - .ToLocalChecked(); + v8::String::NewFromUtf8Literal(isolate, csource); // Compile the source code. v8::Local script = diff --git a/deps/v8/samples/process.cc b/deps/v8/samples/process.cc index e4f6fd9cee733d..b23329dc107f12 100644 --- a/deps/v8/samples/process.cc +++ b/deps/v8/samples/process.cc @@ -183,8 +183,7 @@ bool JsHttpRequestProcessor::Initialize(map* opts, // Create a template for the global object where we set the // built-in global functions. Local global = ObjectTemplate::New(GetIsolate()); - global->Set(String::NewFromUtf8(GetIsolate(), "log", NewStringType::kNormal) - .ToLocalChecked(), + global->Set(String::NewFromUtf8Literal(GetIsolate(), "log"), FunctionTemplate::New(GetIsolate(), LogCallback)); // Each processor gets its own context so different processors don't @@ -210,8 +209,7 @@ bool JsHttpRequestProcessor::Initialize(map* opts, // The script compiled and ran correctly. Now we fetch out the // Process function from the global object. Local process_name = - String::NewFromUtf8(GetIsolate(), "Process", NewStringType::kNormal) - .ToLocalChecked(); + String::NewFromUtf8Literal(GetIsolate(), "Process"); Local process_val; // If there is no Process function, or if it is not a function, // bail out @@ -276,17 +274,13 @@ bool JsHttpRequestProcessor::InstallMaps(map* opts, // Set the options object as a property on the global object. context->Global() - ->Set(context, - String::NewFromUtf8(GetIsolate(), "options", NewStringType::kNormal) - .ToLocalChecked(), + ->Set(context, String::NewFromUtf8Literal(GetIsolate(), "options"), opts_obj) .FromJust(); Local output_obj = WrapMap(output); context->Global() - ->Set(context, - String::NewFromUtf8(GetIsolate(), "output", NewStringType::kNormal) - .ToLocalChecked(), + ->Set(context, String::NewFromUtf8Literal(GetIsolate(), "output"), output_obj) .FromJust(); @@ -563,21 +557,17 @@ Local JsHttpRequestProcessor::MakeRequestTemplate( // Add accessors for each of the fields of the request. result->SetAccessor( - String::NewFromUtf8(isolate, "path", NewStringType::kInternalized) - .ToLocalChecked(), + String::NewFromUtf8Literal(isolate, "path", NewStringType::kInternalized), GetPath); + result->SetAccessor(String::NewFromUtf8Literal(isolate, "referrer", + NewStringType::kInternalized), + GetReferrer); result->SetAccessor( - String::NewFromUtf8(isolate, "referrer", NewStringType::kInternalized) - .ToLocalChecked(), - GetReferrer); - result->SetAccessor( - String::NewFromUtf8(isolate, "host", NewStringType::kInternalized) - .ToLocalChecked(), + String::NewFromUtf8Literal(isolate, "host", NewStringType::kInternalized), GetHost); - result->SetAccessor( - String::NewFromUtf8(isolate, "userAgent", NewStringType::kInternalized) - .ToLocalChecked(), - GetUserAgent); + result->SetAccessor(String::NewFromUtf8Literal(isolate, "userAgent", + NewStringType::kInternalized), + GetUserAgent); // Again, return the result through the current handle scope. return handle_scope.Escape(result); diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc index 81b028720c8d2f..aed050ceccd283 100644 --- a/deps/v8/samples/shell.cc +++ b/deps/v8/samples/shell.cc @@ -108,27 +108,20 @@ v8::Local CreateShellContext(v8::Isolate* isolate) { // Create a template for the global object. v8::Local global = v8::ObjectTemplate::New(isolate); // Bind the global 'print' function to the C++ Print callback. - global->Set( - v8::String::NewFromUtf8(isolate, "print", v8::NewStringType::kNormal) - .ToLocalChecked(), - v8::FunctionTemplate::New(isolate, Print)); + global->Set(v8::String::NewFromUtf8Literal(isolate, "print"), + v8::FunctionTemplate::New(isolate, Print)); // Bind the global 'read' function to the C++ Read callback. - global->Set(v8::String::NewFromUtf8( - isolate, "read", v8::NewStringType::kNormal).ToLocalChecked(), + global->Set(v8::String::NewFromUtf8Literal(isolate, "read"), v8::FunctionTemplate::New(isolate, Read)); // Bind the global 'load' function to the C++ Load callback. - global->Set(v8::String::NewFromUtf8( - isolate, "load", v8::NewStringType::kNormal).ToLocalChecked(), + global->Set(v8::String::NewFromUtf8Literal(isolate, "load"), v8::FunctionTemplate::New(isolate, Load)); // Bind the 'quit' function - global->Set(v8::String::NewFromUtf8( - isolate, "quit", v8::NewStringType::kNormal).ToLocalChecked(), + global->Set(v8::String::NewFromUtf8Literal(isolate, "quit"), v8::FunctionTemplate::New(isolate, Quit)); // Bind the 'version' function - global->Set( - v8::String::NewFromUtf8(isolate, "version", v8::NewStringType::kNormal) - .ToLocalChecked(), - v8::FunctionTemplate::New(isolate, Version)); + global->Set(v8::String::NewFromUtf8Literal(isolate, "version"), + v8::FunctionTemplate::New(isolate, Version)); return v8::Context::New(isolate, NULL, global); } @@ -161,22 +154,19 @@ void Print(const v8::FunctionCallbackInfo& args) { void Read(const v8::FunctionCallbackInfo& args) { if (args.Length() != 1) { args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Bad parameters", - v8::NewStringType::kNormal).ToLocalChecked()); + v8::String::NewFromUtf8Literal(args.GetIsolate(), "Bad parameters")); return; } v8::String::Utf8Value file(args.GetIsolate(), args[0]); if (*file == NULL) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Error loading file", - v8::NewStringType::kNormal).ToLocalChecked()); + args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( + args.GetIsolate(), "Error loading file")); return; } v8::Local source; if (!ReadFile(args.GetIsolate(), *file).ToLocal(&source)) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Error loading file", - v8::NewStringType::kNormal).ToLocalChecked()); + args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( + args.GetIsolate(), "Error loading file")); return; } @@ -191,22 +181,19 @@ void Load(const v8::FunctionCallbackInfo& args) { v8::HandleScope handle_scope(args.GetIsolate()); v8::String::Utf8Value file(args.GetIsolate(), args[i]); if (*file == NULL) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Error loading file", - v8::NewStringType::kNormal).ToLocalChecked()); + args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( + args.GetIsolate(), "Error loading file")); return; } v8::Local source; if (!ReadFile(args.GetIsolate(), *file).ToLocal(&source)) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Error loading file", - v8::NewStringType::kNormal).ToLocalChecked()); + args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( + args.GetIsolate(), "Error loading file")); return; } if (!ExecuteString(args.GetIsolate(), source, args[i], false, false)) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(args.GetIsolate(), "Error executing file", - v8::NewStringType::kNormal).ToLocalChecked()); + args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( + args.GetIsolate(), "Error executing file")); return; } } @@ -228,8 +215,8 @@ void Quit(const v8::FunctionCallbackInfo& args) { void Version(const v8::FunctionCallbackInfo& args) { args.GetReturnValue().Set( - v8::String::NewFromUtf8(args.GetIsolate(), v8::V8::GetVersion(), - v8::NewStringType::kNormal).ToLocalChecked()); + v8::String::NewFromUtf8(args.GetIsolate(), v8::V8::GetVersion()) + .ToLocalChecked()); } @@ -276,12 +263,9 @@ int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc, } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { // Execute argument given to -e option directly. v8::Local file_name = - v8::String::NewFromUtf8(isolate, "unnamed", - v8::NewStringType::kNormal).ToLocalChecked(); + v8::String::NewFromUtf8Literal(isolate, "unnamed"); v8::Local source; - if (!v8::String::NewFromUtf8(isolate, argv[++i], - v8::NewStringType::kNormal) - .ToLocal(&source)) { + if (!v8::String::NewFromUtf8(isolate, argv[++i]).ToLocal(&source)) { return 1; } bool success = ExecuteString(isolate, source, file_name, false, true); @@ -290,8 +274,7 @@ int RunMain(v8::Isolate* isolate, v8::Platform* platform, int argc, } else { // Use all other arguments as names of files to load and run. v8::Local file_name = - v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal) - .ToLocalChecked(); + v8::String::NewFromUtf8(isolate, str).ToLocalChecked(); v8::Local source; if (!ReadFile(isolate, str).ToLocal(&source)) { fprintf(stderr, "Error reading '%s'\n", str); @@ -313,8 +296,7 @@ void RunShell(v8::Local context, v8::Platform* platform) { // Enter the execution environment before evaluating any code. v8::Context::Scope context_scope(context); v8::Local name( - v8::String::NewFromUtf8(context->GetIsolate(), "(shell)", - v8::NewStringType::kNormal).ToLocalChecked()); + v8::String::NewFromUtf8Literal(context->GetIsolate(), "(shell)")); while (true) { char buffer[kBufferSize]; fprintf(stderr, "> "); @@ -323,8 +305,7 @@ void RunShell(v8::Local context, v8::Platform* platform) { v8::HandleScope handle_scope(context->GetIsolate()); ExecuteString( context->GetIsolate(), - v8::String::NewFromUtf8(context->GetIsolate(), str, - v8::NewStringType::kNormal).ToLocalChecked(), + v8::String::NewFromUtf8(context->GetIsolate(), str).ToLocalChecked(), name, true, true); while (v8::platform::PumpMessageLoop(platform, context->GetIsolate())) continue; diff --git a/deps/v8/src/DEPS b/deps/v8/src/DEPS index 3e802dac975826..772ad53b326066 100644 --- a/deps/v8/src/DEPS +++ b/deps/v8/src/DEPS @@ -16,6 +16,7 @@ include_rules = [ "+src/heap/heap-inl.h", "+src/heap/heap-write-barrier-inl.h", "+src/heap/heap-write-barrier.h", + "+src/heap/local-heap.h", "+src/heap/off-thread-factory-inl.h", "+src/heap/off-thread-factory.h", "+src/heap/read-only-heap-inl.h", diff --git a/deps/v8/src/api/api-inl.h b/deps/v8/src/api/api-inl.h index 217d21222def88..0d2ad2f8a0f8ce 100644 --- a/deps/v8/src/api/api-inl.h +++ b/deps/v8/src/api/api-inl.h @@ -86,7 +86,7 @@ MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView) MAKE_TO_LOCAL(ToLocal, JSDataView, DataView) MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray) MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer) -MAKE_TO_LOCAL(ToLocal, JSFinalizationGroup, FinalizationGroup) +MAKE_TO_LOCAL(ToLocal, JSFinalizationRegistry, FinalizationGroup) TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY) diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index 7fe974de24e8db..b2d6db3661a564 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -13,6 +13,7 @@ #include "src/api/api-inl.h" +#include "include/v8-fast-api-calls.h" #include "include/v8-profiler.h" #include "include/v8-util.h" #include "src/api/api-natives.h" @@ -309,6 +310,7 @@ class CallDepthScope { #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY if (do_callback) CheckMicrotasksScopesConsistency(microtask_queue); #endif + DCHECK(CheckKeptObjectsClearedAfterMicrotaskCheckpoint(microtask_queue)); isolate_->set_next_v8_call_is_safe_for_termination(safe_for_termination_); } @@ -323,6 +325,15 @@ class CallDepthScope { } private: + bool CheckKeptObjectsClearedAfterMicrotaskCheckpoint( + i::MicrotaskQueue* microtask_queue) { + bool did_perform_microtask_checkpoint = + do_callback && microtask_queue && + microtask_queue->microtasks_policy() == MicrotasksPolicy::kAuto; + return !did_perform_microtask_checkpoint || + isolate_->heap()->weak_refs_keep_during_job().IsUndefined(isolate_); + } + i::Isolate* const isolate_; Local context_; bool escaped_; @@ -453,11 +464,13 @@ void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location, // BUG(1718): Don't use the take_snapshot since we don't support // HeapObjectIterator here without doing a special GC. isolate->heap()->RecordStats(&heap_stats, false); - char* first_newline = strchr(last_few_messages, '\n'); - if (first_newline == nullptr || first_newline[1] == '\0') - first_newline = last_few_messages; - PrintF("\n<--- Last few GCs --->\n%s\n", first_newline); - PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace); + if (!FLAG_correctness_fuzzer_suppressions) { + char* first_newline = strchr(last_few_messages, '\n'); + if (first_newline == nullptr || first_newline[1] == '\0') + first_newline = last_few_messages; + base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline); + base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace); + } } Utils::ReportOOMFailure(isolate, location, is_heap_oom); // If the fatal error handler returns, we stop execution. @@ -542,6 +555,21 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { } void Free(void* data, size_t) override { free(data); } + + void* Reallocate(void* data, size_t old_length, size_t new_length) override { +#if V8_OS_AIX && _LINUX_SOURCE_COMPAT + // Work around for GCC bug on AIX + // 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); +#endif + if (new_length > old_length) { + memset(reinterpret_cast(new_data) + old_length, 0, + new_length - old_length); + } + return new_data; + } }; struct SnapshotCreatorData { @@ -867,6 +895,8 @@ StartupData SnapshotCreator::CreateBlob( startup_serializer.SerializeWeakReferencesAndDeferred(); can_be_rehashed = can_be_rehashed && startup_serializer.can_be_rehashed(); + startup_serializer.CheckNoDirtyFinalizationRegistries(); + read_only_serializer.FinalizeSerialization(); can_be_rehashed = can_be_rehashed && read_only_serializer.can_be_rehashed(); @@ -985,7 +1015,7 @@ void ResourceConstraints::ConfigureDefaultsFromHeapSize( set_initial_young_generation_size_in_bytes(young_generation); set_initial_old_generation_size_in_bytes(old_generation); } - if (i::kRequiresCodeRange) { + if (i::kPlatformRequiresCodeRange) { set_code_range_size_in_bytes( i::Min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes)); } @@ -1000,7 +1030,7 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, set_max_young_generation_size_in_bytes(young_generation); set_max_old_generation_size_in_bytes(old_generation); - if (virtual_memory_limit > 0 && i::kRequiresCodeRange) { + if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) { set_code_range_size_in_bytes( i::Min(i::kMaximalCodeRangeSize, static_cast(virtual_memory_limit / 8))); @@ -1442,7 +1472,8 @@ static Local FunctionTemplateNew( i::Isolate* isolate, FunctionCallback callback, v8::Local data, v8::Local signature, int length, bool do_not_cache, v8::Local cached_property_name = v8::Local(), - SideEffectType side_effect_type = SideEffectType::kHasSideEffect) { + SideEffectType side_effect_type = SideEffectType::kHasSideEffect, + const CFunction* c_function = nullptr) { i::Handle struct_obj = isolate->factory()->NewStruct( i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld); i::Handle obj = @@ -1460,7 +1491,8 @@ static Local FunctionTemplateNew( obj->set_serial_number(i::Smi::FromInt(next_serial_number)); } if (callback != nullptr) { - Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type); + Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type, + c_function); } obj->set_undetectable(false); obj->set_needs_access_check(false); @@ -1478,14 +1510,15 @@ static Local FunctionTemplateNew( Local FunctionTemplate::New( Isolate* isolate, FunctionCallback callback, v8::Local data, v8::Local signature, int length, ConstructorBehavior behavior, - SideEffectType side_effect_type) { + SideEffectType side_effect_type, const CFunction* c_function) { i::Isolate* i_isolate = reinterpret_cast(isolate); // Changes to the environment cannot be captured in the snapshot. Expect no // function templates when the isolate is created for serialization. LOG_API(i_isolate, FunctionTemplate, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); - auto templ = FunctionTemplateNew(i_isolate, callback, data, signature, length, - false, Local(), side_effect_type); + auto templ = + FunctionTemplateNew(i_isolate, callback, data, signature, length, false, + Local(), side_effect_type, c_function); if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype(); return templ; } @@ -1534,7 +1567,8 @@ Local AccessorSignature::New( void FunctionTemplate::SetCallHandler(FunctionCallback callback, v8::Local data, - SideEffectType side_effect_type) { + SideEffectType side_effect_type, + const CFunction* c_function) { auto info = Utils::OpenHandle(this); EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler"); i::Isolate* isolate = info->GetIsolate(); @@ -1548,6 +1582,15 @@ void FunctionTemplate::SetCallHandler(FunctionCallback callback, data = v8::Undefined(reinterpret_cast(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); + if (c_function != nullptr) { + DCHECK_NOT_NULL(c_function->GetAddress()); + i::FunctionTemplateInfo::SetCFunction( + isolate, info, + i::handle(*FromCData(isolate, c_function->GetAddress()), isolate)); + i::FunctionTemplateInfo::SetCSignature( + isolate, info, + i::handle(*FromCData(isolate, c_function->GetTypeInfo()), isolate)); + } info->set_call_code(*obj); } @@ -3462,7 +3505,6 @@ VALUE_IS_SPECIFIC_TYPE(Set, JSSet) VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject) VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap) VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet) -VALUE_IS_SPECIFIC_TYPE(WebAssemblyCompiledModule, WasmModuleObject) #undef VALUE_IS_SPECIFIC_TYPE @@ -3784,6 +3826,28 @@ bool v8::BackingStore::IsShared() const { return reinterpret_cast(this)->is_shared(); } +// static +std::unique_ptr v8::BackingStore::Reallocate( + v8::Isolate* isolate, std::unique_ptr backing_store, + size_t byte_length) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + LOG_API(i_isolate, ArrayBuffer, BackingStore_Reallocate); + CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + i::BackingStore* i_backing_store = + reinterpret_cast(backing_store.get()); + if (!i_backing_store->Reallocate(i_isolate, byte_length)) { + i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate"); + } + return backing_store; +} + +// static +void v8::BackingStore::EmptyDeleter(void* data, size_t length, + void* deleter_data) { + DCHECK_NULL(deleter_data); +} + std::shared_ptr v8::ArrayBuffer::GetBackingStore() { i::Handle self = Utils::OpenHandle(this); std::shared_ptr backing_store = self->GetBackingStore(); @@ -4800,6 +4864,11 @@ bool v8::Object::IsApiWrapper() { return self->IsApiWrapper(); } +bool v8::Object::IsUndetectable() { + auto self = i::Handle::cast(Utils::OpenHandle(this)); + return self->IsUndetectable(); +} + MaybeLocal Object::CallAsFunction(Local context, Local recv, int argc, Local argv[]) { @@ -6085,6 +6154,24 @@ void Context::SetAbortScriptExecution( } } +Local Context::GetContinuationPreservedEmbedderData() const { + i::Handle context = Utils::OpenHandle(this); + i::Isolate* isolate = context->GetIsolate(); + i::Handle data( + context->native_context().continuation_preserved_embedder_data(), + isolate); + return ToApiHandle(data); +} + +void Context::SetContinuationPreservedEmbedderData(Local data) { + i::Handle context = Utils::OpenHandle(this); + i::Isolate* isolate = context->GetIsolate(); + if (data.IsEmpty()) + data = v8::Undefined(reinterpret_cast(isolate)); + context->native_context().set_continuation_preserved_embedder_data( + *i::Handle::cast(Utils::OpenHandle(*data))); +} + namespace { i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate, i::FixedArray list, size_t index) { @@ -6290,6 +6377,19 @@ STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); result = Utils::ToLocal(handle_result); \ } +Local String::NewFromUtf8Literal(Isolate* isolate, const char* literal, + NewStringType type, int length) { + DCHECK_LE(length, i::String::kMaxLength); + i::Isolate* i_isolate = reinterpret_cast(isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + LOG_API(i_isolate, String, NewFromUtf8Literal); + i::Handle handle_result = + NewString(i_isolate->factory(), type, + i::Vector(literal, length)) + .ToHandleChecked(); + return Utils::ToLocal(handle_result); +} + MaybeLocal String::NewFromUtf8(Isolate* isolate, const char* data, NewStringType type, int length) { NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length); @@ -7197,57 +7297,6 @@ MaybeLocal WasmModuleObject::FromCompiledModule( Utils::ToLocal(i::Handle::cast(module_object))); } -MaybeLocal WasmModuleObject::Deserialize( - Isolate* isolate, MemorySpan serialized_module, - MemorySpan wire_bytes) { - i::Isolate* i_isolate = reinterpret_cast(isolate); - i::MaybeHandle maybe_module_object = - i::wasm::DeserializeNativeModule( - i_isolate, {serialized_module.data(), serialized_module.size()}, - {wire_bytes.data(), wire_bytes.size()}, {}); - i::Handle module_object; - if (!maybe_module_object.ToHandle(&module_object)) { - return MaybeLocal(); - } - return Local::Cast( - Utils::ToLocal(i::Handle::cast(module_object))); -} - -MaybeLocal WasmModuleObject::DeserializeOrCompile( - Isolate* isolate, MemorySpan serialized_module, - MemorySpan wire_bytes) { - MaybeLocal ret = - Deserialize(isolate, serialized_module, wire_bytes); - if (!ret.IsEmpty()) { - return ret; - } - return Compile(isolate, wire_bytes.data(), wire_bytes.size()); -} - -MaybeLocal WasmModuleObject::Compile(Isolate* isolate, - const uint8_t* start, - size_t length) { - i::Isolate* i_isolate = reinterpret_cast(isolate); - if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { - return MaybeLocal(); - } - i::MaybeHandle maybe_compiled; - { - i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()"); - auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate); - maybe_compiled = i_isolate->wasm_engine()->SyncCompile( - i_isolate, enabled_features, &thrower, - i::wasm::ModuleWireBytes(start, start + length)); - } - CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception()); - if (maybe_compiled.is_null()) { - i_isolate->OptionalRescheduleException(false); - return MaybeLocal(); - } - return Local::Cast( - Utils::ToLocal(maybe_compiled.ToHandleChecked())); -} - WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming( Isolate* isolate) { USE(isolate_); @@ -7262,6 +7311,21 @@ void WasmModuleObjectBuilderStreaming::Finish() {} void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal exception) {} +void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length, + size_t new_length) { + if (old_length == new_length) return data; + uint8_t* new_data = + reinterpret_cast(AllocateUninitialized(new_length)); + if (new_data == nullptr) return nullptr; + size_t bytes_to_copy = std::min(old_length, new_length); + memcpy(new_data, data, bytes_to_copy); + if (new_length > bytes_to_copy) { + memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy); + } + Free(data, old_length); + return new_data; +} + // static v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() { return new ArrayBufferAllocator(); @@ -7519,7 +7583,7 @@ std::unique_ptr v8::ArrayBuffer::NewBackingStore( } std::unique_ptr v8::ArrayBuffer::NewBackingStore( - void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, void* deleter_data) { CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); std::unique_ptr backing_store = @@ -7848,7 +7912,7 @@ std::unique_ptr v8::SharedArrayBuffer::NewBackingStore( } std::unique_ptr v8::SharedArrayBuffer::NewBackingStore( - void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, void* deleter_data) { CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); std::unique_ptr backing_store = @@ -8328,16 +8392,17 @@ void Isolate::SetHostCleanupFinalizationGroupCallback( Maybe FinalizationGroup::Cleanup( Local finalization_group) { - i::Handle fg = Utils::OpenHandle(*finalization_group); - i::Isolate* isolate = fg->native_context().GetIsolate(); - i::Handle i_context(fg->native_context(), isolate); + i::Handle fr = + Utils::OpenHandle(*finalization_group); + i::Isolate* isolate = fr->native_context().GetIsolate(); + i::Handle i_context(fr->native_context(), isolate); Local context = Utils::ToLocal(i_context); ENTER_V8(isolate, context, FinalizationGroup, Cleanup, Nothing(), i::HandleScope); - i::Handle callback(fg->cleanup(), isolate); - fg->set_scheduled_for_cleanup(false); + i::Handle callback(fr->cleanup(), isolate); + fr->set_scheduled_for_cleanup(false); has_pending_exception = - i::JSFinalizationGroup::Cleanup(isolate, fg, callback).IsNothing(); + i::JSFinalizationRegistry::Cleanup(isolate, fr, callback).IsNothing(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return Just(true); } @@ -8455,6 +8520,8 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory(); heap_statistics->total_available_size_ = heap->Available(); heap_statistics->used_heap_size_ = heap->SizeOfObjects(); + heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize(); + heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize(); #ifndef V8_SHARED_RO_HEAP i::ReadOnlySpace* ro_space = heap->read_only_space(); @@ -8655,10 +8722,10 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { isolate->SetPromiseRejectCallback(callback); } -void Isolate::RunMicrotasks() { +void Isolate::PerformMicrotaskCheckpoint() { DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy()); i::Isolate* isolate = reinterpret_cast(this); - isolate->default_microtask_queue()->RunMicrotasks(isolate); + isolate->default_microtask_queue()->PerformCheckpoint(this); } void Isolate::EnqueueMicrotask(Local v8_function) { @@ -9265,6 +9332,34 @@ MaybeLocal debug::GetInternalProperties(Isolate* v8_isolate, return Utils::ToLocal(result); } +namespace { +void CollectPrivateMethodsAndAccessorsFromContext( + i::Isolate* isolate, i::Handle context, + i::IsStaticFlag is_static_flag, std::vector>* names_out, + std::vector>* values_out) { + i::Handle scope_info(context->scope_info(), isolate); + int local_count = scope_info->ContextLocalCount(); + for (int j = 0; j < local_count; ++j) { + i::VariableMode mode = scope_info->ContextLocalMode(j); + i::IsStaticFlag flag = scope_info->ContextLocalIsStaticFlag(j); + if (!i::IsPrivateMethodOrAccessorVariableMode(mode) || + flag != is_static_flag) { + continue; + } + + i::Handle name(scope_info->ContextLocalName(j), isolate); + int context_index = scope_info->ContextHeaderLength() + j; + i::Handle slot_value(context->get(context_index), isolate); + DCHECK_IMPLIES(mode == i::VariableMode::kPrivateMethod, + slot_value->IsJSFunction()); + DCHECK_IMPLIES(mode != i::VariableMode::kPrivateMethod, + slot_value->IsAccessorPair()); + names_out->push_back(Utils::ToLocal(name)); + values_out->push_back(Utils::ToLocal(slot_value)); + } +} +} // anonymous namespace + bool debug::GetPrivateMembers(Local context, Local value, std::vector>* names_out, std::vector>* values_out) { @@ -9285,7 +9380,7 @@ bool debug::GetPrivateMembers(Local context, Local value, i::GetKeysConversion::kConvertToString), false); - // Estimate number of private entries to return in the FixedArray. + // Estimate number of private fields and private instance methods/accessors. int private_entries_count = 0; for (int i = 0; i < keys->length(); ++i) { // Exclude the private brand symbols. @@ -9305,10 +9400,42 @@ bool debug::GetPrivateMembers(Local context, Local value, } } + // Estimate number of static private methods/accessors for classes. + bool has_static_private_methods_or_accessors = false; + if (receiver->IsJSFunction()) { + i::Handle func(i::JSFunction::cast(*receiver), isolate); + i::Handle shared(func->shared(), isolate); + if (shared->is_class_constructor() && + shared->has_static_private_methods_or_accessors()) { + has_static_private_methods_or_accessors = true; + i::Handle context(func->context(), isolate); + i::Handle scope_info(context->scope_info(), isolate); + int local_count = scope_info->ContextLocalCount(); + for (int j = 0; j < local_count; ++j) { + i::VariableMode mode = scope_info->ContextLocalMode(j); + i::IsStaticFlag is_static_flag = + scope_info->ContextLocalIsStaticFlag(j); + if (i::IsPrivateMethodOrAccessorVariableMode(mode) && + is_static_flag == i::IsStaticFlag::kStatic) { + private_entries_count += local_count; + break; + } + } + } + } + DCHECK(names_out->empty()); names_out->reserve(private_entries_count); DCHECK(values_out->empty()); values_out->reserve(private_entries_count); + + if (has_static_private_methods_or_accessors) { + i::Handle context(i::JSFunction::cast(*receiver).context(), + isolate); + CollectPrivateMethodsAndAccessorsFromContext( + isolate, context, i::IsStaticFlag::kStatic, names_out, values_out); + } + for (int i = 0; i < keys->length(); ++i) { i::Handle obj_key(keys->get(i), isolate); i::Handle key(i::Symbol::cast(*obj_key), isolate); @@ -9320,25 +9447,8 @@ bool debug::GetPrivateMembers(Local context, Local value, if (key->is_private_brand()) { DCHECK(value->IsContext()); i::Handle context(i::Context::cast(*value), isolate); - i::Handle scope_info(context->scope_info(), isolate); - int local_count = scope_info->ContextLocalCount(); - - for (int j = 0; j < local_count; ++j) { - i::VariableMode mode = scope_info->ContextLocalMode(j); - if (!i::IsPrivateMethodOrAccessorVariableMode(mode)) { - continue; - } - - i::Handle name(scope_info->ContextLocalName(j), isolate); - int context_index = scope_info->ContextHeaderLength() + j; - i::Handle slot_value(context->get(context_index), isolate); - DCHECK_IMPLIES(mode == i::VariableMode::kPrivateMethod, - slot_value->IsJSFunction()); - DCHECK_IMPLIES(mode != i::VariableMode::kPrivateMethod, - slot_value->IsAccessorPair()); - names_out->push_back(Utils::ToLocal(name)); - values_out->push_back(Utils::ToLocal(slot_value)); - } + CollectPrivateMethodsAndAccessorsFromContext( + isolate, context, i::IsStaticFlag::kNotStatic, names_out, values_out); } else { // Private fields i::Handle name( i::String::cast(i::Symbol::cast(*key).description()), isolate); @@ -9397,6 +9507,12 @@ void debug::BreakRightNow(Isolate* v8_isolate) { isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed); } +void debug::SetTerminateOnResume(Isolate* v8_isolate) { + i::Isolate* isolate = reinterpret_cast(v8_isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); + isolate->debug()->SetTerminateOnResume(); +} + bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) { i::Isolate* isolate = reinterpret_cast(v8_isolate); ENTER_V8_DO_NOT_USE(isolate); @@ -9438,7 +9554,7 @@ std::vector debug::Script::LineEnds() const { i::Isolate* isolate = script->GetIsolate(); i::HandleScope scope(isolate); - i::Script::InitLineEnds(script); + i::Script::InitLineEnds(isolate, script); CHECK(script->line_ends().IsFixedArray()); i::Handle line_ends(i::FixedArray::cast(script->line_ends()), isolate); @@ -9530,9 +9646,9 @@ bool debug::Script::GetPossibleBreakpoints( locations); } - i::Script::InitLineEnds(script); - CHECK(script->line_ends().IsFixedArray()); i::Isolate* isolate = script->GetIsolate(); + i::Script::InitLineEnds(isolate, script); + CHECK(script->line_ends().IsFixedArray()); i::Handle line_ends = i::Handle::cast(i::handle(script->line_ends(), isolate)); CHECK(line_ends->length()); @@ -9585,7 +9701,7 @@ int debug::Script::GetSourceOffset(const debug::Location& location) const { column = std::max(0, column - script->column_offset()); } - i::Script::InitLineEnds(script); + i::Script::InitLineEnds(script->GetIsolate(), script); CHECK(script->line_ends().IsFixedArray()); i::Handle line_ends = i::Handle::cast( i::handle(script->line_ends(), script->GetIsolate())); @@ -9732,6 +9848,15 @@ uint32_t debug::WasmScript::GetFunctionHash(int function_index) { function_bytes.length(), 0); } +int debug::WasmScript::CodeOffset() const { + i::Handle script = Utils::OpenHandle(this); + DCHECK_EQ(i::Script::TYPE_WASM, script->type()); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); + + return module->code.offset(); +} + debug::Location::Location(int line_number, int column_number) : line_number_(line_number), column_number_(column_number), @@ -9797,6 +9922,16 @@ MaybeLocal debug::CompileInspectorScript(Isolate* v8_isolate, RETURN_ESCAPED(ToApiHandle(result)); } +void debug::TierDownAllModulesPerIsolate(Isolate* v8_isolate) { + i::Isolate* isolate = reinterpret_cast(v8_isolate); + isolate->wasm_engine()->TierDownAllModulesPerIsolate(isolate); +} + +void debug::TierUpAllModulesPerIsolate(Isolate* v8_isolate) { + i::Isolate* isolate = reinterpret_cast(v8_isolate); + isolate->wasm_engine()->TierUpAllModulesPerIsolate(isolate); +} + void debug::SetDebugDelegate(Isolate* v8_isolate, debug::DebugDelegate* delegate) { i::Isolate* isolate = reinterpret_cast(v8_isolate); @@ -9911,7 +10046,7 @@ debug::ConsoleCallArguments::ConsoleCallArguments( : v8::FunctionCallbackInfo( nullptr, // Drop the first argument (receiver, i.e. the "console" object). - args.address_of_arg_at(args.length() > 1 ? 1 : 0), + args.length() > 1 ? args.address_of_first_argument() : nullptr, args.length() - 1) {} int debug::GetStackFrameId(v8::Local frame) { @@ -10826,6 +10961,34 @@ void EmbedderHeapTracer::ResetHandleInNonTracingGC( UNREACHABLE(); } +const void* CTypeInfo::GetWrapperInfo() const { + DCHECK(payload_ & kWrapperTypeInfoMask); + return reinterpret_cast(payload_ & kWrapperTypeInfoMask); +} + +CFunction::CFunction(const void* address, const CFunctionInfo* type_info) + : address_(address), type_info_(type_info) { + CHECK_NOT_NULL(address_); + CHECK_NOT_NULL(type_info_); + for (unsigned int i = 0; i < type_info_->ArgumentCount(); ++i) { + if (type_info_->ArgumentInfo(i).IsArray()) { + // Array args require an integer passed for their length + // as the next argument. + DCHECK_LT(i + 1, type_info_->ArgumentCount()); + switch (type_info_->ArgumentInfo(i + 1).GetType()) { + case CTypeInfo::Type::kInt32: + case CTypeInfo::Type::kUint32: + case CTypeInfo::Type::kInt64: + case CTypeInfo::Type::kUint64: + break; + default: + UNREACHABLE(); + break; + } + } + } +} + namespace internal { const size_t HandleScopeImplementer::kEnteredContextsOffset = @@ -11007,6 +11170,27 @@ void InvokeFunctionCallback(const v8::FunctionCallbackInfo& info, callback(info); } +void InvokeFinalizationRegistryCleanupFromTask( + Handle context, + Handle finalization_registry, + Handle callback) { + Isolate* isolate = finalization_registry->native_context().GetIsolate(); + RuntimeCallTimerScope timer( + isolate, RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask); + // Do not use ENTER_V8 because this is always called from a running + // FinalizationRegistryCleanupTask within V8 and we should not log it as an + // API call. This method is implemented here to avoid duplication of the + // exception handling and microtask running logic in CallDepthScope. + if (IsExecutionTerminatingCheck(isolate)) return; + Local api_context = Utils::ToLocal(context); + CallDepthScope call_depth_scope(isolate, api_context); + VMState state(isolate); + if (JSFinalizationRegistry::Cleanup(isolate, finalization_registry, callback) + .IsNothing()) { + call_depth_scope.Escape(); + } +} + // Undefine macros for jumbo build. #undef LOG_API #undef ENTER_V8_DO_NOT_USE diff --git a/deps/v8/src/api/api.h b/deps/v8/src/api/api.h index 004740099cb78e..4c383d3e43caf3 100644 --- a/deps/v8/src/api/api.h +++ b/deps/v8/src/api/api.h @@ -26,6 +26,7 @@ namespace v8 { namespace internal { class JSArrayBufferView; +class JSFinalizationRegistry; } // namespace internal namespace debug { @@ -92,7 +93,7 @@ class RegisteredExtension { V(Data, Object) \ V(RegExp, JSRegExp) \ V(Object, JSReceiver) \ - V(FinalizationGroup, JSFinalizationGroup) \ + V(FinalizationGroup, JSFinalizationRegistry) \ V(Array, JSArray) \ V(Map, JSMap) \ V(Set, JSSet) \ @@ -205,7 +206,7 @@ class Utils { static inline Local ToLocalBigUint64Array( v8::internal::Handle obj); static inline Local ToLocal( - v8::internal::Handle obj); + v8::internal::Handle obj); static inline Local ToLocalShared( v8::internal::Handle obj); @@ -561,6 +562,11 @@ void InvokeAccessorGetterCallback( void InvokeFunctionCallback(const v8::FunctionCallbackInfo& info, v8::FunctionCallback callback); +void InvokeFinalizationRegistryCleanupFromTask( + Handle context, + Handle finalization_registry, + Handle callback); + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/asmjs/asm-js.cc b/deps/v8/src/asmjs/asm-js.cc index 033efc45b3ad20..5a6846c33f4e5c 100644 --- a/deps/v8/src/asmjs/asm-js.cc +++ b/deps/v8/src/asmjs/asm-js.cc @@ -132,13 +132,11 @@ void Report(Handle - diff --git a/deps/v8/tools/heap-stats/details-selection.js b/deps/v8/tools/heap-stats/details-selection.js index 1e9cc83cff304d..f7e32733d97e7e 100644 --- a/deps/v8/tools/heap-stats/details-selection.js +++ b/deps/v8/tools/heap-stats/details-selection.js @@ -4,19 +4,18 @@ 'use strict'; -const details_selection_template = - document.currentScript.ownerDocument.querySelector( - '#details-selection-template'); +import {CATEGORIES, CATEGORY_NAMES} from './categories.js'; -const VIEW_BY_INSTANCE_TYPE = 'by-instance-type'; -const VIEW_BY_INSTANCE_CATEGORY = 'by-instance-category'; -const VIEW_BY_FIELD_TYPE = 'by-field-type'; +export const VIEW_BY_INSTANCE_TYPE = 'by-instance-type'; +export const VIEW_BY_INSTANCE_CATEGORY = 'by-instance-category'; +export const VIEW_BY_FIELD_TYPE = 'by-field-type'; -class DetailsSelection extends HTMLElement { +defineCustomElement('details-selection', (templateText) => + class DetailsSelection extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({mode: 'open'}); - shadowRoot.appendChild(details_selection_template.content.cloneNode(true)); + shadowRoot.innerHTML = templateText; this.isolateSelect.addEventListener( 'change', e => this.handleIsolateChange(e)); this.dataViewSelect.addEventListener( @@ -403,6 +402,4 @@ class DetailsSelection extends HTMLElement { link.click(); this.shadowRoot.removeChild(link); } -} - -customElements.define('details-selection', DetailsSelection); +}); diff --git a/deps/v8/tools/heap-stats/global-timeline.html b/deps/v8/tools/heap-stats/global-timeline-template.html similarity index 73% rename from deps/v8/tools/heap-stats/global-timeline.html rename to deps/v8/tools/heap-stats/global-timeline-template.html index 788f966735f921..bb11b44961fafe 100644 --- a/deps/v8/tools/heap-stats/global-timeline.html +++ b/deps/v8/tools/heap-stats/global-timeline-template.html @@ -1,7 +1,6 @@ -